New upstream version 1.6.6+ds0
authorIOhannes m zmölnig (Debian/GNU) <umlaeute@debian.org>
Thu, 10 Nov 2022 08:51:58 +0000 (09:51 +0100)
committerIOhannes m zmölnig (Debian/GNU) <umlaeute@debian.org>
Thu, 10 Nov 2022 08:51:58 +0000 (09:51 +0100)
90 files changed:
CMakeLists.txt
build
docs/changelog.yml
faust-src/tonedsp.dsp [new file with mode: 0644]
faust-src/volumedsp.dsp [new file with mode: 0644]
jacktrip.pro
linux/icons/jacktrip_48x48_alt.png [new file with mode: 0644]
linux/icons/jacktrip_alt.svg [new file with mode: 0644]
macos/assemble_app.sh
macos/jacktrip_alt.icns [new file with mode: 0644]
macos/jacktrip_alt.iconset/icon_128x128.png [new file with mode: 0644]
macos/jacktrip_alt.iconset/icon_128x128@2x.png [new file with mode: 0644]
macos/jacktrip_alt.iconset/icon_16x16.png [new file with mode: 0644]
macos/jacktrip_alt.iconset/icon_16x16@2x.png [new file with mode: 0644]
macos/jacktrip_alt.iconset/icon_256x256.png [new file with mode: 0644]
macos/jacktrip_alt.iconset/icon_256x256@2x.png [new file with mode: 0644]
macos/jacktrip_alt.iconset/icon_32x32.png [new file with mode: 0644]
macos/jacktrip_alt.iconset/icon_32x32@2x.png [new file with mode: 0644]
macos/jacktrip_alt.iconset/icon_512x512.png [new file with mode: 0644]
macos/jacktrip_alt.iconset/icon_512x512@2x.png [new file with mode: 0644]
macos/sign-stuff.sh [new file with mode: 0755]
meson.build
releases/edge/mac-manifests.json
releases/edge/win-manifests.json
releases/stable/linux-manifests.json [new file with mode: 0644]
releases/stable/mac-manifests.json
releases/stable/win-manifests.json
rtaudio.pro
src/AudioInterface.cpp
src/AudioInterface.h
src/Auth.cpp
src/JackAudioInterface.cpp
src/JackAudioInterface.h
src/JackTripWorker.cpp
src/JackTripWorker.h
src/Meter.cpp
src/RtAudioInterface.cpp
src/RtAudioInterface.h
src/Settings.cpp
src/Tone.cpp [new file with mode: 0644]
src/Tone.h [new file with mode: 0644]
src/UdpHubListener.cpp
src/UdpHubListener.h
src/Volume.cpp [new file with mode: 0644]
src/Volume.h [new file with mode: 0644]
src/compressordsp.h
src/dblsqd/feed.cpp
src/dblsqd/semver.cpp
src/dblsqd/semver.h
src/freeverbdsp.h
src/freeverbmonodsp.h
src/gui/Connected.qml
src/gui/Jacktrip.ai [deleted file]
src/gui/Settings.qml
src/gui/Setup.qml
src/gui/Studio.qml
src/gui/about.cpp
src/gui/about.ui
src/gui/alt/Jacktrip.ai [new file with mode: 0644]
src/gui/alt/about.png [new file with mode: 0644]
src/gui/alt/about@2x.png [new file with mode: 0644]
src/gui/alt/icon.png [new file with mode: 0644]
src/gui/micoff.svg [new file with mode: 0644]
src/gui/qjacktrip.cpp
src/gui/qjacktrip.h
src/gui/qjacktrip.qrc
src/gui/qjacktrip.ui
src/gui/qjacktrip_novs.ui [deleted file]
src/gui/virtualstudio.cpp
src/gui/virtualstudio.h
src/gui/vsAudioInterface.cpp [new file with mode: 0644]
src/gui/vsAudioInterface.h [new file with mode: 0644]
src/gui/vsConstants.h [new file with mode: 0644]
src/gui/vsDevice.cpp
src/gui/vsDevice.h
src/gui/vsWebSocket.cpp
src/jacktrip_globals.h
src/limiterdsp.h
src/main.cpp
src/meterdsp.h
src/tonedsp.h [new file with mode: 0644]
src/volumedsp.h [new file with mode: 0644]
src/zitarevdsp.h
src/zitarevmonodsp.h
win/build_installer.bat
win/dialog_alt.bmp [new file with mode: 0644]
win/files.wxs
win/getCsv.sh [new file with mode: 0755]
win/jacktrip.wxs
win/jacktrip_alt.ico [new file with mode: 0644]

index 81717bf45a1f0aed473dc69d506307e08f0aad0d..b33c4293d7eecf47413c681dbabb40834845c68f 100644 (file)
@@ -1,44 +1,72 @@
 cmake_minimum_required(VERSION 3.12)
-set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13)
-set(CMAKE_OSX_ARCHITECTURES arm64;x86_64)
+set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14)
 project(QJackTrip)
 
 set(nogui FALSE)
 set(rtaudio TRUE)
 set(weakjack TRUE)
-set(novs TRUE)
+set(novs FALSE)
+set(noupdater FALSE)
+set(psi FALSE)
+set(QtVersion "5")
+
+if (${QtVersion} MATCHES "5")
+  set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13)
+  set(CMAKE_OSX_ARCHITECTURES arm64;x86_64)
+endif ()
 
 message(STATUS "Hello Aaron! For anyone else, heed the following warning:")
 message(WARNING "The CMake build of JackTrip is currently NOT officially supported. Meson or QMake are recommended for a full featured build."
         "https://jacktrip.github.io/jacktrip/Build/Meson_build/")
 
-add_compile_definitions(PSI)
-add_compile_definitions(NO_UPDATER)
-#add_compile_definitions(BUILD_TYPE="psi-borg.org NO_VS binary")
-#string(TIMESTAMP BUILD_DATE "%Y%m%d")
-#set(BUILD_NUMBER "00")
-#add_compile_definitions(BUILD_ID="${BUILD_DATE}${BUILD_NUMBER}")
-#add_compile_definitions(NDEBUG)
-add_compile_definitions(QT_OPENSOURCE)
-
 if (nogui)
   add_compile_definitions(NO_GUI)
   set(novs TRUE)
+  set(noupdater TRUE)
 endif ()
 
-if (rtaudio)
-  add_compile_definitions(RT_AUDIO)
+if (novs)
+  set(QRC_FILE "src/gui/qjacktrip_novs.qrc")
+else ()
+  set(QRC_FILE "src/gui/qjacktrip.qrc")
 endif ()
 
-if (weakjack)
-  add_compile_definitions(USE_WEAK_JACK)
-  include_directories("externals/weakjack")
-endif()
+if (psi)
+  add_compile_definitions(PSI)
+  set(novs TRUE)
+  if (novs)
+    add_compile_definitions(BUILD_TYPE="psi-borg.org NO_VS binary")
+  else ()
+    add_compile_definitions(BUILD_TYPE="psi-borg.org binary")
+  endif ()
+
+  file(READ "${QRC_FILE}" QRC_CONTENTS)
+  string(REPLACE "<file>about@2x.png" "<file alias=\"about@2x.png\">alt/about@2x.png" QRC_CONTENTS "${QRC_CONTENTS}")
+  string(REPLACE "<file>about.png" "<file alias=\"about.png\">alt/about.png" QRC_CONTENTS "${QRC_CONTENTS}")
+  string(REPLACE "<file>icon.png" "<file alias=\"icon.png\">alt/icon.png" QRC_CONTENTS "${QRC_CONTENTS}")
+  file(WRITE "${QRC_FILE}" "${QRC_CONTENTS}")
+  string(TIMESTAMP BUILD_DATE "%Y%m%d")
+  set(BUILD_NUMBER "00")
+  add_compile_definitions(BUILD_ID="${BUILD_DATE}${BUILD_NUMBER}")
+  add_compile_definitions(NDEBUG)
+else ()
+  file(READ "${QRC_FILE}" QRC_CONTENTS)
+  string(REPLACE "<file alias=\"about@2x.png\">alt/about@2x.png" "<file>about@2x.png" QRC_CONTENTS "${QRC_CONTENTS}")
+  string(REPLACE "<file alias=\"about.png\">alt/about.png" "<file>about.png" QRC_CONTENTS "${QRC_CONTENTS}")
+  string(REPLACE "<file alias=\"icon.png\">alt/icon.png" "<file>icon.png" QRC_CONTENTS "${QRC_CONTENTS}")
+  file(WRITE "${QRC_FILE}" "${QRC_CONTENTS}")
+endif ()
 
 if (novs)
   add_compile_definitions(NO_VS)
 endif ()
 
+if (noupdater)
+  add_compile_definitions(NO_UPDATER)
+endif ()
+
+add_compile_definitions(QT_OPENSOURCE)
+
 if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
   set (ENV{PKG_CONFIG_PATH} "/usr/local/lib/pkgconfig")
 elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
@@ -50,13 +78,18 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
     include_directories("C:/Program Files (x86)/Jack/includes")
     set (jacklib "C:/Program Files (x86)/Jack/lib/libjack64.lib")
   endif ()
-  set (CMAKE_PREFIX_PATH "C:/Qt/5.15.2/mingw81_64/lib/cmake")
+  file(GLOB QtDirs "C:/Qt/${QtVersion}.*.*/mingw*_64")
+  list(GET QtDirs 0 QtDir)
+  message(STATUS "Using Qt found at ${QtDir}")
+  set (CMAKE_PREFIX_PATH "${QtDir}")
   if (rtaudio)
     include_directories("C:/Program Files (x86)/RtAudio/include")
     set (rtaudiolib "C:/Program Files (x86)/RtAudio/lib/librtaudio.dll.a")
   endif ()
 endif ()
 
+string(PREPEND QtVersion "Qt")
+
 if (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
   find_package(PkgConfig REQUIRED)
   pkg_check_modules(JACK REQUIRED IMPORTED_TARGET jack)
@@ -81,14 +114,14 @@ set(CMAKE_AUTORCC ON)
 
 # Find the QtWidgets library
 if (NOT nogui)
-  find_package(Qt5Widgets CONFIG REQUIRED)
+  find_package(${QtVersion}Widgets CONFIG REQUIRED)
   if (NOT novs)
-    find_package(Qt5Quick CONFIG REQUIRED)
-    find_package(Qt5NetworkAuth CONFIG REQUIRED)
-    find_package(Qt5WebSockets CONFIG REQUIRED)
+    find_package(${QtVersion}Quick CONFIG REQUIRED)
+    find_package(${QtVersion}NetworkAuth CONFIG REQUIRED)
+    find_package(${QtVersion}WebSockets CONFIG REQUIRED)
   endif ()
 endif ()
-find_package(Qt5Network CONFIG REQUIRED)
+find_package(${QtVersion}Network CONFIG REQUIRED)
 
 set(qjacktrip_SRC
   src/main.cpp
@@ -109,21 +142,24 @@ set(qjacktrip_SRC
   src/Regulator.cpp
   src/Compressor.cpp
   src/Limiter.cpp
-  src/Meter.cpp
   src/Reverb.cpp
   src/AudioTester.cpp
   src/Patcher.cpp
   src/SslServer.cpp
   src/Auth.cpp
+  src/ProcessPlugin.cpp
 )
 
 if (rtaudio)
+  add_compile_definitions(RT_AUDIO)
   set (qjacktrip_SRC ${qjacktrip_SRC}
     src/RtAudioInterface.cpp
   )
 endif ()
 
 if (weakjack)
+  add_compile_definitions(USE_WEAK_JACK)
+  include_directories("externals/weakjack")
   set (qjacktrip_SRC ${qjacktrip_SRC}
     externals/weakjack/weak_libjack.c
   )
@@ -145,17 +181,38 @@ if (NOT nogui)
       src/gui/vsPing.cpp
       src/gui/vsPinger.cpp
       src/gui/vsDevice.cpp
+      src/gui/vsAudioInterface.cpp
       src/gui/vsUrlHandler.cpp
       src/gui/vsWebSocket.cpp
       src/gui/qjacktrip.qrc
+      src/Meter.cpp
+      src/Volume.cpp
+      src/Tone.cpp
       # Need to include this for AUTOMOC to do its thing
       src/JTApplication.h
+      src/gui/vsQmlClipboard.h
     )
   else ()
     set (qjacktrip_SRC ${qjacktrip_SRC} src/gui/qjacktrip_novs.qrc)
   endif ()
+  
+  if (NOT noupdater)
+    set (qjacktrip_SRC ${qjacktrip_SRC}
+      src/dblsqd/feed.cpp
+      src/dblsqd/release.cpp
+      src/dblsqd/semver.cpp
+      src/dblsqd/update_dialog.cpp
+    )
+  endif ()
 
   if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+    file(READ "win/qjacktrip.rc" RC_CONTENTS)
+    if (psi)
+      string(REPLACE "jacktrip.ico" "jacktrip_alt.ico" RC_CONTENTS "${RC_CONTENTS}")
+    else ()
+      string(REPLACE "jacktrip_alt.ico" "jacktrip.ico" RC_CONTENTS "${RC_CONTENTS}")
+    endif ()
+    file(WRITE "win/qjacktrip.rc" "${RC_CONTENTS}")
     set (qjacktrip_SRC ${qjacktrip_SRC} win/qjacktrip.rc)
   elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
     set (qjacktrip_SRC ${qjacktrip_SRC} src/gui/NoNap.mm)
@@ -170,11 +227,11 @@ add_compile_definitions(WAIRTOHUB)
 add_executable(jacktrip ${qjacktrip_SRC})
 
 # Set our libraries for our linker
-set (qjacktrip_LIBS Qt5::Network)
+set (qjacktrip_LIBS ${QtVersion}::Network)
 if (NOT nogui)
-  set (qjacktrip_LIBS ${qjacktrip_LIBS} Qt5::Widgets)
+  set (qjacktrip_LIBS ${qjacktrip_LIBS} ${QtVersion}::Widgets)
   if (NOT novs)
-    set (qjacktrip_LIBS ${qjacktrip_LIBS} Qt5::Quick Qt5::NetworkAuth Qt5::WebSockets)
+    set (qjacktrip_LIBS ${qjacktrip_LIBS} ${QtVersion}::Quick ${QtVersion}::NetworkAuth ${QtVersion}::WebSockets)
   endif ()
 endif ()
 
@@ -199,5 +256,16 @@ endif ()
 
 target_link_libraries(jacktrip ${qjacktrip_LIBS})
 
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+  add_custom_command(
+    TARGET jacktrip POST_BUILD
+    COMMAND help2man --no-info --section=1 --output=jacktrip.1 ./jacktrip
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+  )
+endif ()
+
 # Install the executable
 install(TARGETS jacktrip DESTINATION bin)
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+  install(FILES ${CMAKE_BINARY_DIR}/jacktrip.1 DESTINATION share/man/man1)
+endif ()
diff --git a/build b/build
index b4141be34a81c7941c97980326b07f1340b010b2..cd05509e74dc3aa88c8666eaa18cda24d58caabd 100755 (executable)
--- a/build
+++ b/build
@@ -102,15 +102,9 @@ if [[ $platform == 'linux' ]]; then
   echo "Using qmake"
   QCMD=qmake
 fi
-QSPEC=linux-g++
 MCMD=make
 elif [[ $platform == 'macosx' ]]; then
   QCMD=qmake
-  QSPEC=macx-clang
-  arch=`arch`
-  if [[ "$arch" == 'arm64' ]]; then
-    QSPEC=macx-clang-arm64
-  fi  
   # if qmake is not in path, try homebrew qt5
   echo "path to qmake"
   echo "$(which qmake)"
@@ -128,13 +122,16 @@ elif [[ $platform == 'macosx' ]]; then
   MCMD=make
 elif [[ $platform == 'mingw' ]]; then
   QCMD=qmake
-  QSPEC=win32-g++
   MCMD=mingw32-make
 elif [[ $platform == 'unknown' ]]; then
   echo "Unregonized platform, exiting"
   exit
 fi
 
+# detect spec
+QSPEC=`$QCMD -query | grep QMAKE_SPEC`
+QSPEC=${QSPEC##QMAKE_SPEC:}
+
 # check for RtAudio
 if [[ $RTAUDIO == 1 ]]; then
   pkg-config --exists rtaudio 2> /dev/null
@@ -167,13 +164,14 @@ cd builddir
 set -e
 
 # Build
+QCMDARGS=(-spec $QSPEC $CONFIG "$UNKNOWN_OPTIONS" $PRO_FILE)
 echo "qmake command:"
-echo "$QCMD -spec $QSPEC $CONFIG $PRO_FILE" $UNKNOWN_OPTIONS
+echo $QCMD ${QCMDARGS[@]}
 if [[ $clean == 1 ]]; then
-  $QCMD -spec $QSPEC $CONFIG $PRO_FILE $UNKNOWN_OPTIONS
+  $QCMD ${QCMDARGS[@]}
   $MCMD clean
 fi
-$QCMD -spec $QSPEC $CONFIG $PRO_FILE $UNKNOWN_OPTIONS
+$QCMD ${QCMDARGS[@]}
 $MCMD release
 if [[ "$install" == 1 ]]; then
   echo "*** Installing JackTrip ***"
index b424738235cadc1767e0a0ca128d4ed7edccb5be..ce32d2b6015cb70e5285f728020d09ec3b237790 100644 (file)
@@ -1,3 +1,27 @@
+- Version: "1.6.6"
+  Date: 2022-11-01
+  Description:
+  - (fixed) Notarization scripts for macOS
+  - Note - this version replaces 1.6.5, as that release was mistakenly deleted
+- Version: "1.6.5"
+  Date: 2022-10-28
+  Description:
+  - (added) Input/output volume control and input mute in VS
+  - (added) Volume plugin
+  - (added) Linux manifests used for download links
+  - (added) VS Test mode for jacktrip.org users
+  - (added) Qt6 support for NO_VS builds
+  - (added) Show Qt version in About dialog
+  - (updated) VS - makes inactive, admin'd studios visible by default
+  - (updated) using -q auto3 for buffer length with plc
+  - (updated) updated notarization process to use notarytool
+  - (updated) link to Qt source as it has changed
+  - (updated) Classic GUI reverts some pre-VS changes
+  - (updated) QMake build scripts more in line with documentation
+  - (fixed) new user screen in VS mode
+  - (fixed) logout freezing jacktrip
+  - (fixed) NO_VS builds work without setting NO_UPDATER
+  - (fixed) volume meter-related crash
 - Version: "1.6.4"
   Date: 2022-09-16
   Description:
diff --git a/faust-src/tonedsp.dsp b/faust-src/tonedsp.dsp
new file mode 100644 (file)
index 0000000..0f7a902
--- /dev/null
@@ -0,0 +1,17 @@
+// Source: https://faustdoc.grame.fr/examples/smartKeyboard/#turenas
+
+import("stdfaust.lib");
+
+y = hslider("y",0,0,1,0.01);
+freq = hslider("freq",400,50,2000,0.01);
+gate = button("gate");
+res = hslider("res[acc: 0 0 -10 0 10]",2.5,0.01,5,0.01);
+nModes = 6;
+maxModeSpread = 5;
+modeSpread = y*maxModeSpread;
+modeFreqRatios = par(i,nModes,1+(i+1)/nModes*modeSpread);
+minModeGain = 0.3;
+modeGains = par(i,nModes,1-(i+1)/(nModes*minModeGain));
+modeRes = res : si.smoo;
+
+process = sy.additiveDrum(freq,modeFreqRatios,modeGains,0.8,0.001,modeRes,gate)*0.05;
diff --git a/faust-src/volumedsp.dsp b/faust-src/volumedsp.dsp
new file mode 100644 (file)
index 0000000..1a1a617
--- /dev/null
@@ -0,0 +1,14 @@
+declare name "volume";
+declare version "1.0";
+declare author "Matt Horton, adapted from GRAME";
+declare license "MIT Style STK-4.2";
+declare description "Volume Control Faust Plugin for JackTrip, based on Faust examples";
+
+
+import("stdfaust.lib");
+mute = checkbox("[1] Mute");
+gain(v) = v : ba.db2linear : si.smoo : _;
+gainVMute(v) = _ * gain(v), 0 : select2(mute) : _;
+zeroCutoff(v) = _ , 0 : select2(v == -40) : _;
+volume = hslider("[0] Volume", 0, -40, 0, 0.1);
+process = _ <: vgroup("Volume Control", _ : gainVMute(volume) : zeroCutoff(volume));
index 80fc9c19971d79964d351bdc9a4797db9390bd2f..77cb80dac20ae7eccdf1c316d8cdba96092b4710 100644 (file)
@@ -103,11 +103,7 @@ bundled_rtaudio {
 
 macx {
   message(Building on MAC OS X)
-  QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9
-  #QMAKE_MAC_SDK = macosx10.9
   CONFIG -= app_bundle
-  #CONFIG += x86 #ppc #### If you have both libraries installed, you
-  # can change between 32bits (x86) or 64bits(x86_64) Change this to go back to 32 bits (x86)
   LIBS += -framework CoreAudio -framework CoreFoundation
   !nogui {
     LIBS += -framework Foundation
@@ -207,6 +203,8 @@ HEADERS += src/DataProtocol.h \
            src/Regulator.h \
            src/Reverb.h \
            src/Meter.h \
+           src/Volume.h \
+           src/Tone.h \
            src/AudioTester.h \
            src/jacktrip_globals.h \
            src/jacktrip_types.h \
@@ -225,6 +223,8 @@ HEADERS += src/DataProtocol.h \
            src/limiterdsp.h \
            src/freeverbdsp.h \
            src/meterdsp.h \
+           src/volumedsp.h \
+           src/tonedsp.h \
            src/SslServer.h \
            src/Auth.h
 #(Removed JackTripThread.h JackTripWorkerMessages.h NetKS.h TestRingBuffer.h ThreadPoolTest.h)
@@ -243,6 +243,7 @@ HEADERS += src/DataProtocol.h \
   !novs {
     HEADERS += src/gui/virtualstudio.h \
                src/gui/vsDevice.h \
+               src/gui/vsAudioInterface.h \
                src/gui/vsServerInfo.h \
                src/gui/vsQuickView.h \
                src/gui/vsWebSocket.h \
@@ -271,6 +272,8 @@ SOURCES += src/DataProtocol.cpp \
            src/Regulator.cpp \
            src/Reverb.cpp \
            src/Meter.cpp \
+           src/Volume.cpp \
+           src/Tone.cpp \
            src/AudioTester.cpp \
            src/jacktrip_globals.cpp \
            src/JackTripWorker.cpp \
@@ -301,6 +304,7 @@ SOURCES += src/DataProtocol.cpp \
   !novs {
     SOURCES += src/gui/virtualstudio.cpp \
                src/gui/vsDevice.cpp \
+               src/gui/vsAudioInterface.cpp \
                src/gui/vsServerInfo.cpp \
                src/gui/vsQuickView.cpp \
                src/gui/vsWebSocket.cpp \
diff --git a/linux/icons/jacktrip_48x48_alt.png b/linux/icons/jacktrip_48x48_alt.png
new file mode 100644 (file)
index 0000000..115f265
Binary files /dev/null and b/linux/icons/jacktrip_48x48_alt.png differ
diff --git a/linux/icons/jacktrip_alt.svg b/linux/icons/jacktrip_alt.svg
new file mode 100644 (file)
index 0000000..ed23ed8
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   version="1.1"
+   id="svg2"
+   xml:space="preserve"
+   width="1365.3333"
+   height="1365.3333"
+   viewBox="0 0 1365.3333 1365.3333"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6"><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath24"><path
+         d="M 0,1024 H 1024 V 0 H 0 Z"
+         id="path22" /></clipPath></defs><g
+     id="g10"
+     transform="matrix(1.3333333,0,0,-1.3333333,0,1365.3333)"><path
+       d="m 681.391,888.908 h -31.223 v 19.043 h 31.223 z"
+       style="fill:#d3d3d3;fill-opacity:1;fill-rule:nonzero;stroke:none"
+       id="path12" /><g
+       id="g14"
+       transform="translate(665,280)"><path
+         d="M 0,0 V 252.232"
+         style="fill:none;stroke:#000000;stroke-width:42;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+         id="path16" /></g><g
+       id="g18"><g
+         id="g20"
+         clip-path="url(#clipPath24)"><g
+           id="g26"
+           transform="translate(312.3477,281.6523)"><path
+             d="M 0,0 C 0,-97.73 79.082,-176.812 176.812,-176.812"
+             style="fill:none;stroke:#000000;stroke-width:42;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+             id="path28" /></g><g
+           id="g30"
+           transform="translate(487.96,105.0908)"><path
+             d="M 0,0 C 97.73,0 176.812,79.081 176.812,176.812"
+             style="fill:none;stroke:#000000;stroke-width:42;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+             id="path32" /></g><g
+           id="g34"
+           transform="translate(626.5,747.5)"><path
+             d="m 0,0 v -104.385 -81.524 c 0,-14.58 12.403,-26.4 27.703,-26.4 h 23.594 c 15.3,0 27.703,11.82 27.703,26.4 V 0 Z"
+             style="fill:#5f709b;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path36" /></g><g
+           id="g38"
+           transform="translate(626.5,747.5)"><path
+             d="m 0,0 v -104.385 -81.524 c 0,-14.58 12.403,-26.4 27.703,-26.4 h 23.594 c 15.3,0 27.703,11.82 27.703,26.4 V 0 Z"
+             style="fill:none;stroke:#000000;stroke-width:16;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+             id="path40" /></g><path
+           d="m 686,752 h -40 v 76 h 40 z"
+           style="fill:#d3d3d3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+           id="path42" /><path
+           d="m 686,834 h -40 v 24 h 40 z"
+           style="fill:#d3d3d3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+           id="path44" /><path
+           d="m 686,864 h -40 v 24 h 40 z"
+           style="fill:#d3d3d3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+           id="path46" /><g
+           id="g48"
+           transform="translate(652.6396,908.0542)"><path
+             d="M 0,0 -6.786,-16.832"
+             style="fill:#d3d3d3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+             id="path50" /></g><g
+           id="g52"
+           transform="translate(686.5176,891.2578)"><path
+             d="M 0,0 -6.786,16.832"
+             style="fill:#d3d3d3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+             id="path54" /></g><g
+           id="g56"
+           transform="translate(655.8232,902.8623)"><path
+             d="m 0,0 c -6.428,3.598 -10.772,10.473 -10.772,18.363 0,11.615 9.416,21.03 21.031,21.03 11.614,0 21.03,-9.415 21.03,-21.03 0,-8.028 -4.497,-15.004 -11.109,-18.549"
+             style="fill:#d3d3d3;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+             id="path58" /></g><g
+           id="g60"
+           transform="translate(260.0122,300.8564)"><path
+             d="M 0,0 H 104.874"
+             style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+             id="path62" /></g><g
+           id="g64"
+           transform="translate(303.1138,271.2197)"><path
+             d="M 0,0 C 0,15.936 -18.204,28.829 -40.7,28.829"
+             style="fill:none;stroke:#000000;stroke-width:22;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+             id="path66" /></g><g
+           id="g68"
+           transform="translate(322.312,272.6973)"><path
+             d="M 0,0 C 0,14.682 16.772,26.562 37.5,26.562"
+             style="fill:none;stroke:#000000;stroke-width:22;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+             id="path70" /></g><path
+           d="m 315.307,279.838 h -6.542 v 13.629 h 6.542 z"
+           style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+           id="path72" /></g></g></g></svg>
index bf9324489513cf5589df3f81e915beda16c5be0f..dc0928cfcb4c541c38185dc6f770696f82a1731d 100755 (executable)
@@ -8,14 +8,18 @@ NOTARIZE=false
 #If you're lazy like I am, you can pre-populate these variables to save you stuffing about with command line options.
 #CERTIFICATE=""
 #PACKAGE_CERT=""
-#USERNAME=""
-#PASSWORD=""
-#ASC_PROVIDER=""
+USERNAME=""
+PASSWORD=""
+TEAM_ID=""
+KEY_STORE="AC_PASSWORD"
+TEMP_KEYCHAIN=""
+USE_DEFAULT_KEYCHAIN=false
 BINARY="../builddir/jacktrip"
+PSI=false
 
 OPTIND=1
 
-while getopts ":inhc:d:u:p:a:b:" opt; do
+while getopts ":inhqklc:d:u:p:t:b:" opt; do
     case $opt in
       i)
         BUILD_INSTALLER=true
@@ -23,6 +27,12 @@ while getopts ":inhc:d:u:p:a:b:" opt; do
       n)
         NOTARIZE=true
         ;;
+      k)
+        TEMP_KEYCHAIN="$(pwd)/notarytool_temp.db"
+        ;;
+      l)
+        USE_DEFAULT_KEYCHAIN=true
+        ;;
       c)
         CERTIFICATE=$OPTARG
         ;;
@@ -35,12 +45,15 @@ while getopts ":inhc:d:u:p:a:b:" opt; do
       p)
         PASSWORD=$OPTARG
         ;;
-      a)
-        ASC_PROVIDER=$OPTARG
+      t)
+        TEAM_ID=$OPTARG
         ;;
       b)
         BINARY=$OPTARG
         ;;
+      q)
+        PSI=true
+        ;;
       \?)
         echo "Invalid option -$OPTARG ignored."
         ;;
@@ -57,13 +70,22 @@ while getopts ":inhc:d:u:p:a:b:" opt; do
         echo " -n                 Send a notarization request to Apple. (Only takes effect if building an installer.)"
         echo " -c <certname>      Name of the developer certificate to use for code signing. (No signing by default.)"
         echo " -d <certname>      Name of the certificate to use for package signing. (No signing by default.)"
+        echo
+        echo "Important: If supplying one of the next three options, you must supply all of them."
         echo " -u <username>      Apple ID username (email address) for installer notarization."
         echo " -p <password>      App specific password for installer notarization."
-        echo " -a <ascprovider>   ASC provider for notarization. (Only required if you belong to multiple dev teams.)"
+        echo " -t <teamid>        Team ID for notarization."
+        echo
+        echo " -k                 Use a temporary keychain to store notarization credentials. (Overrides -l.)"
+        echo " -l                 Use the default keychain instead of the login keychain to store credentials."
         echo " -h                 Display this help screen and exit."
         echo
         echo "By default, appname is set to JackTrip and bundlename is org.jacktrip.jacktrip."
         echo "(These should be left as is for official builds.)"
+        echo
+        echo "The username, password, and team ID are saved in the login keychain by notarytool."
+        echo "They only need to be supplied once, or in the event that you need to change them."
+        echo "(They need to be supplied every time if you opt to use a temporary keychain.)"
  
         exit 0
         ;;
@@ -97,6 +119,8 @@ cp -f $BINARY "$APPNAME.app/Contents/MacOS/"
 cp -f ../LICENSE.md "$APPNAME.app/Contents/Resources/"
 cp -Rf ../LICENSES "$APPNAME.app/Contents/Resources/"
 
+[ $PSI = true ] && cp jacktrip_alt.icns "$APPNAME.app/Contents/Resources/jacktrip.icns"
+
 DYNAMIC_QT=$(otool -L $BINARY | grep QtCore)
 DYNAMIC_VS=$(otool -L $BINARY | grep QtQml)
 
@@ -109,15 +133,17 @@ sed -i '' "s/%BUNDLENAME%/$APPNAME/" "$APPNAME.app/Contents/Info.plist"
 sed -i '' "s/%BUNDLEID%/$BUNDLE_ID/" "$APPNAME.app/Contents/Info.plist"
 
 if [ ! -z "$DYNAMIC_QT" ]; then
+    QT_VERSION="qt$(echo "$DYNAMIC_QT" | sed -E '1!d;s/.*compatibility version ([0-9]+)\.[0-9]+\.[0-9]+.*/\1/g')"
+    echo "Detected a Qt$QT_VERSION binary"
     DEPLOY_CMD="$(which macdeployqt)"
     if [ -z "$DEPLOY_CMD" ]; then
         # Attempt to find macdeployqt. Try macports location first, then brew.
-        if [ -x "/opt/local/libexec/qt5/bin/macdeployqt" ]; then
-            DEPLOY_CMD="/opt/local/libexec/qt5/bin/macdeployqt"
-        elif [ ! -z $(which brew) ] && [ ! -z $(brew --prefix qt5) ]; then
-            DEPLOY_CMD="$(brew --prefix qt5)/bin/macdeployqt"
+        if [ -x "/opt/local/libexec/$QT_VERSION/bin/macdeployqt" ]; then
+            DEPLOY_CMD="/opt/local/libexec/$QT_VERSION/bin/macdeployqt"
+        elif [ ! -z $(which brew) ] && [ ! -z $(brew --prefix $QT_VERSION) ]; then
+            DEPLOY_CMD="$(brew --prefix $QT_VERSION)/bin/macdeployqt"
         else
-            echo "The Qt bin folder needs to be in your PATH for this script to work."
+            echo "Error: The Qt bin folder needs to be in your PATH for this script to work."
             exit 1
         fi
     fi
@@ -135,7 +161,12 @@ fi
 [ $BUILD_INSTALLER = true ] || exit 0
 
 # If you have Packages installed, you can build an installer for the newly created app bundle.
-[ -z $(which packagesbuild) ] && { echo "You need to have Packages installed to build a package."; exit 1; }
+[ -z $(which packagesbuild) ] && { echo "Error: You need to have Packages installed to build a package."; exit 1; }
+
+if [ $PSI = true ]; then
+    cp "package/postinstall.sh" "package/postinstall.sh.bak"
+    sed -i '' "s/^open/#open/" "package/postinstall.sh"
+fi
 
 # Needed for notarization.
 [ ! -z "$CERTIFICATE" ] && codesign -f -s "$CERTIFICATE" --entitlements entitlements.plist --options "runtime" "$APPNAME.app"
@@ -165,6 +196,7 @@ sed -i '' "s/%BUNDLENAME%/$APPNAME/" package/JackTrip.pkgproj
 sed -i '' "s/%BUNDLEID%/$BUNDLE_ID/" package/JackTrip.pkgproj
 
 packagesbuild package/JackTrip.pkgproj
+[ $PSI = true ] && mv "package/postinstall.sh.bak" "package/postinstall.sh"
 if pkgutil --check-signature package/build/JackTrip.pkg; then
     echo "Package already signed."
     SIGNED=true
@@ -185,41 +217,47 @@ fi
 
 [ $NOTARIZE = true ] || exit 0
 
-# Submit a notarization request to apple if we have the required credentials.
-if [ -z "$CERTIFICATE" ] || [ -z "$USERNAME" ] || [ -z "$PASSWORD" ] || [ $SIGNED = false ] ; then
-    echo "Not sending notarization request: incomplete credentials."
+# Submit a notarization request to apple if we've chosen to and signed our package.
+if [ $SIGNED = false ]; then
+    echo "Not sending notarization request: package not signed."
     exit 1
 fi
 
-ASC=""
-if [ ! -z "$ASC_PROVIDER" ]; then
-    ASC=" --asc-provider $ASC_PROVIDER"
+if [ ! -z "$USERNAME" ] || [ ! -z "$PASSWORD" ] || [ ! -z "$TEAM_ID" ] || [ ! -z "$TEMP_KEYCHAIN" ]; then
+    if [ -z "$USERNAME" ] || [ -z "$PASSWORD" ] || [ -z "$TEAM_ID" ]; then
+        echo "Error: Missing credentials. Make sure you supply a username, password and team ID."
+        exit 1
+    fi
+fi 
+
+KEYCHAIN=""
+if [ ! -z "$TEMP_KEYCHAIN" ]; then
+    echo "Using a temporary keychain"
+    [ -e "$TEMP_KEYCHAIN" ] && rm "$TEMP_KEYCHAIN"
+    security create-keychain -p "supersecretpassword" "$TEMP_KEYCHAIN"
+    security set-keychain-settings -lut 3600 "$TEMP_KEYCHAIN"
+    security unlock-keychain -p "supersecretpassword" "$TEMP_KEYCHAIN"
+    KEYCHAIN=" --keychain \"$TEMP_KEYCHAIN\""
+elif [ $USE_DEFAULT_KEYCHAIN = true ]; then
+    echo "Using the default keychain"
+    DEFAULT_KEYCHAIN=$(security default-keychain | cut -d '"' -f2)
+    KEYCHAIN=" --keychain \"$DEFAULT_KEYCHAIN\""
 fi
-CREDENTIALS="--username $USERNAME --password $PASSWORD$ASC"
 
-echo "Sending notarization request"
-UUID=$(xcrun altool --notarize-app --primary-bundle-id "$BUNDLE_ID" $CREDENTIALS --file "package/build/$APPNAME.pkg" | awk '/RequestUUID/{print $NF}')
-if [ -z "$UUID" ]; then
-    echo "Error sending notarization request"
-    exit 1
+if [ ! -z "$USERNAME" ]; then
+    # We have new credentials. Store them in the keychain so we can use them.
+    ARGS="notarytool store-credentials \"$KEY_STORE\" --apple-id \"$USERNAME\" --password \"$PASSWORD\" --team-id \"$TEAM_ID\"$KEYCHAIN"
+    echo $ARGS | xargs xcrun
 fi
-echo "Package uploaded"
-echo "Request UUID is $UUID"
-echo "Awaiting response from Apple"
-STATUS="in progress"
-ELAPSED=0
-while [ "$STATUS" = "in progress" ]; do
-    sleep 60
-    ((ELAPSED++))
-    STATUS=$(xcrun altool --notarization-info "$UUID" $CREDENTIALS | awk '/Status:/{for(i = 2; i <= NF - 1; i++) printf $i" "; print $NF}')
-    echo "Waited $ELAPSED minute(s). Current status: $STATUS"
-done
-#read -n1 -rsp "Press any key to staple the notarization once it's been approved..."
-#echo
 
-if [ "$STATUS" = "success" ]; then
+echo "Sending notarization request"
+ARGS="notarytool submit \"package/build/$APPNAME.pkg\" --keychain-profile \"$KEY_STORE\" --wait$KEYCHAIN"
+echo $ARGS | xargs xcrun
+if [ $? -eq 0 ]; then
+    [ ! -z "$TEMP_KEYCHAIN" ] && security delete-keychain "$TEMP_KEYCHAIN"
     xcrun stapler staple "package/build/$APPNAME.pkg"
 else
-    echo "Notarization failed"
+    [ ! -z "$TEMP_KEYCHAIN" ] && security delete-keychain "$TEMP_KEYCHAIN"
+    echo "Error: Notarization failed"
     exit 1
 fi
diff --git a/macos/jacktrip_alt.icns b/macos/jacktrip_alt.icns
new file mode 100644 (file)
index 0000000..4f205c1
Binary files /dev/null and b/macos/jacktrip_alt.icns differ
diff --git a/macos/jacktrip_alt.iconset/icon_128x128.png b/macos/jacktrip_alt.iconset/icon_128x128.png
new file mode 100644 (file)
index 0000000..99d8c77
Binary files /dev/null and b/macos/jacktrip_alt.iconset/icon_128x128.png differ
diff --git a/macos/jacktrip_alt.iconset/icon_128x128@2x.png b/macos/jacktrip_alt.iconset/icon_128x128@2x.png
new file mode 100644 (file)
index 0000000..0b2f82c
Binary files /dev/null and b/macos/jacktrip_alt.iconset/icon_128x128@2x.png differ
diff --git a/macos/jacktrip_alt.iconset/icon_16x16.png b/macos/jacktrip_alt.iconset/icon_16x16.png
new file mode 100644 (file)
index 0000000..76b0f2f
Binary files /dev/null and b/macos/jacktrip_alt.iconset/icon_16x16.png differ
diff --git a/macos/jacktrip_alt.iconset/icon_16x16@2x.png b/macos/jacktrip_alt.iconset/icon_16x16@2x.png
new file mode 100644 (file)
index 0000000..d6a2d90
Binary files /dev/null and b/macos/jacktrip_alt.iconset/icon_16x16@2x.png differ
diff --git a/macos/jacktrip_alt.iconset/icon_256x256.png b/macos/jacktrip_alt.iconset/icon_256x256.png
new file mode 100644 (file)
index 0000000..0b2f82c
Binary files /dev/null and b/macos/jacktrip_alt.iconset/icon_256x256.png differ
diff --git a/macos/jacktrip_alt.iconset/icon_256x256@2x.png b/macos/jacktrip_alt.iconset/icon_256x256@2x.png
new file mode 100644 (file)
index 0000000..5befa4a
Binary files /dev/null and b/macos/jacktrip_alt.iconset/icon_256x256@2x.png differ
diff --git a/macos/jacktrip_alt.iconset/icon_32x32.png b/macos/jacktrip_alt.iconset/icon_32x32.png
new file mode 100644 (file)
index 0000000..d6a2d90
Binary files /dev/null and b/macos/jacktrip_alt.iconset/icon_32x32.png differ
diff --git a/macos/jacktrip_alt.iconset/icon_32x32@2x.png b/macos/jacktrip_alt.iconset/icon_32x32@2x.png
new file mode 100644 (file)
index 0000000..233148c
Binary files /dev/null and b/macos/jacktrip_alt.iconset/icon_32x32@2x.png differ
diff --git a/macos/jacktrip_alt.iconset/icon_512x512.png b/macos/jacktrip_alt.iconset/icon_512x512.png
new file mode 100644 (file)
index 0000000..5befa4a
Binary files /dev/null and b/macos/jacktrip_alt.iconset/icon_512x512.png differ
diff --git a/macos/jacktrip_alt.iconset/icon_512x512@2x.png b/macos/jacktrip_alt.iconset/icon_512x512@2x.png
new file mode 100644 (file)
index 0000000..cf7614e
Binary files /dev/null and b/macos/jacktrip_alt.iconset/icon_512x512@2x.png differ
diff --git a/macos/sign-stuff.sh b/macos/sign-stuff.sh
new file mode 100755 (executable)
index 0000000..ed020aa
--- /dev/null
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+# Set these for signing
+CERTIFICATE=""
+PACKAGE_CERT=""
+USERNAME=""
+PASSWORD=""
+TEAM_ID=""
+
+if [ -z $1 ]; then
+       echo "You need to provide a version number as an argument"
+       exit 1
+fi
+VERSION="v$1"
+
+if [ ! -z $2 ]; then
+       SCRIPT_BRANCH="$2"
+fi
+
+CHECK=$(echo "$1" | sed "s/-/./g")
+MAJOR=$(echo $CHECK | cut -d. -f1)
+MINOR=$(echo $CHECK | cut -d. -f2)
+REVISION=$(echo $CHECK | cut -d. -f3)
+
+if [ $MAJOR -le 1 ] && [ $MINOR -le 6 ] && [ $REVISION -lt 5 ] && [ -z "$SCRIPT_BRANCH" ]; then
+       echo "\033[1mVersion earlier than 1.6.5 detected\033[0m"
+       echo "\033[1mUsing assemble_app.sh script from dev branch\033[1m"
+       echo
+       SCRIPT_BRANCH="dev"
+fi
+
+if [ -d "$VERSION" ]; then
+       rm -rf $VERSION
+fi
+echo "\033[1mDownloading $VERSION from Github\033[0m"
+git clone --branch $VERSION https://github.com/jacktrip/jacktrip.git $VERSION || { echo "\n\033[1mCould not find tagged release for $VERSION\033[0m"; exit 1; }
+if [ ! -z "$SCRIPT_BRANCH" ]; then
+       if ! curl "https://raw.githubusercontent.com/jacktrip/jacktrip/$SCRIPT_BRANCH/macos/assemble_app.sh" -f -o "$VERSION/macos/assemble_app.sh"; then
+               echo "\033[1mUnable to download assemble_app.sh from $SCRIPT_BRANCH\033[0m"
+               echo "(Does this branch exist?)"
+               exit 1
+       fi
+fi
+echo "\n\033[1mDownloading compiled binary\033[0m"
+if ! curl "https://github.com/jacktrip/jacktrip/releases/download/$VERSION/JackTrip-$VERSION-macOS-x64-application.zip" -f -L -o binary.zip; then
+       echo "\033[1mUnable to download binary\033[0m"
+       exit 1
+fi
+echo "\n\033[1mExtracting binary\033[0m"
+mkdir -p "$VERSION/builddir"
+unzip -j binary.zip "JackTrip.app/Contents/MacOS/jacktrip" -d "$VERSION/builddir"
+rm binary.zip
+echo "\n\033[1mBuilding installer\033[0m"
+cd "$VERSION/macos"
+if ./assemble_app.sh -in -c "$CERTIFICATE" -d "$PACKAGE_CERT" -u "$USERNAME" -p "$PASSWORD" -t "$TEAM_ID"; then
+       echo "\n\033[1mCopying signed package to current directory and performing clean up\033[0m"
+       cp "package/build/JackTrip.pkg" ../../
+else
+       echo "\n\033[1mBuilding installer failed. Performing clean up.\033[0m"
+fi
+cd "../.."
+rm -rf $VERSION
index 8bb8b9f3dd1d10d21459ac189ab295a82e0f1bfe..63830396c64ae194e04a710e7c3cc6f790f01cb5 100644 (file)
@@ -36,6 +36,8 @@ src = [       'src/DataProtocol.cpp',
        'src/Compressor.cpp',
        'src/Limiter.cpp',
        'src/Meter.cpp',
+       'src/Volume.cpp',
+       'src/Tone.cpp',
        'src/Reverb.cpp',
        'src/main.cpp',
        'src/SslServer.cpp',
@@ -45,6 +47,8 @@ moc_h = ['src/DataProtocol.h',
        'src/JackTrip.h',
        'src/ProcessPlugin.h',
        'src/Meter.h',
+       'src/Volume.h',
+       'src/Tone.h',
        'src/JackTripWorker.h',
        'src/PacketHeader.h',
        'src/Settings.h',
@@ -110,6 +114,7 @@ else
                src += [
                        'src/gui/virtualstudio.cpp',
                        'src/gui/vsDevice.cpp',
+                       'src/gui/vsAudioInterface.cpp',
                        'src/gui/vsServerInfo.cpp',
                        'src/gui/vsQuickView.cpp',
                        'src/gui/vsWebSocket.cpp',
@@ -120,6 +125,7 @@ else
                moc_h += [
                        'src/gui/virtualstudio.h',
                        'src/gui/vsDevice.h',
+                       'src/gui/vsAudioInterface.h',
                        'src/gui/vsServerInfo.h',
                        'src/gui/vsQuickView.h',
                        'src/gui/vsWebSocket.h',
index 2622246a515fe7f1b7f147af851af2d0579629dc..c38c9a588c1923b940aad64ebcc884b7cdcc0e81 100644 (file)
@@ -1,6 +1,26 @@
 {
     "app_name": "JackTrip",
     "releases": [
+        {
+            "version": "1.6.5-rc.1",
+            "changelog": "Adding volume controls, mute, early Qt6 support, and bug fixes: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.5-rc1",
+            "download": {
+                "date": "2022-10-21T00:00:00Z",
+                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.5-rc1/JackTrip-v1.6.5-rc1-macOS-x64-installer.pkg",
+                "downloadSize": 11481049,
+                "sha256": "cea18dd189d84eb9ca3be115819c597900e7bba7771185b61308518aa0e3d716"
+            }
+        },
+        {
+            "version": "1.6.4",
+            "changelog": "Adding volume meters, bugfixes around Windows hanging, device disconnects, and PLC: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.4",
+            "download": {
+                "date": "2022-09-16T00:00:00Z",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.4-macOS-x64-installer.pkg",
+                "downloadSize": 11554866,
+                "sha256": "e5898f3ff57fc2d734590decb4f82a28ad9208a33cad97152f119716cdcea1a9"
+            }
+        },
         {
             "version": "1.6.4-rc.2",
             "changelog": "Adding volume meters, bugfixes around Windows hanging, device disconnects, and PLC: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.4-rc2",
@@ -26,7 +46,7 @@
             "changelog": "Fixes around Linux desktop file and hub server mode: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.3",
             "download": {
                 "date": "2022-08-23T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.3/JackTrip-v1.6.3-macOS-x64-installer.pkg",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.3-macOS-x64-installer.pkg",
                 "downloadSize": 11533023,
                 "sha256": "0b597c62544e9813949f859cc7b7c13bef893f6896f96b34a19889faf4855116"
             }
@@ -36,7 +56,7 @@
             "changelog": "Ability to open app via URL schemes, displaying latency stats, and Virtual Studio device support. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.2",
             "download": {
                 "date": "2022-08-17T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.2/JackTrip-v1.6.2-macOS-x64-installer.pkg",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.2-macOS-x64-installer.pkg",
                 "downloadSize": 11536442,
                 "sha256": "450222f4db1922275e07286d0be6ea2df2873a8a39c3b23096bcfbce342b7b3c"
             }
@@ -76,7 +96,7 @@
             "changelog": "Bugfixes around UDP timeout and 'Logging In' screen navigation. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.1",
             "download": {
                 "date": "2022-06-21T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.1/JackTrip-v1.6.1-macOS-x64-installer.pkg",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.1-macOS-x64-installer.pkg",
                 "downloadSize": 11476305,
                 "sha256": "eaf05c842d6b3ae799208a40b37da1cdb13e3700dcbbd97443c80cad81f4d2ac"
             }
             "changelog": "Full integration with JackTrip Virtual Studio. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.0",
             "download": {
                 "date": "2022-06-01T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.0/JackTrip-v1.6.0-macOS-x64-installer.pkg",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.0-macOS-x64-installer.pkg",
                 "downloadSize": 11474299,
                 "sha256": "27259600ecd879106ebbf97754d72d6236075a049eafa0de6271d33f753f13e4"
             }
index 2331018e8247beb2a13018fbdecc78c8925f1ead..9b2f0b0e610e38b9da1d0cf2d20ebbca8c811b35 100644 (file)
@@ -1,6 +1,26 @@
 {
     "app_name": "JackTrip",
     "releases": [
+        {
+            "version": "1.6.5-rc.1",
+            "changelog": "Adding volume controls, mute, early Qt6 support, and bug fixes: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.5-rc1",
+            "download": {
+                "date": "2022-10-21T00:00:00Z",
+                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.5-rc1/JackTrip-v1.6.5-rc1-Windows-x64-installer.msi",
+                "downloadSize": 44408832,
+                "sha256": "99404fa7bf1a07df76a1b1048c7a0e64a0d5f552e2ca5dfb12e7cbaac0c6fb24"
+            }
+        },
+        {
+            "version": "1.6.4",
+            "changelog": "Adding volume meters, bugfixes around Windows hanging, device disconnects, and PLC: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.4",
+            "download": {
+                "date": "2022-09-16T00:00:00Z",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.4-Windows-x64-installer.msi",
+                "downloadSize": 43663360,
+                "sha256": "58dcbba584e1cc82373b8aa159800ad360eec7933ce9462e413ca347f09f3c26"
+            }
+        },
         {
             "version": "1.6.4-rc.2",
             "changelog": "Adding volume meters, bugfixes around Windows hanging, device disconnects, and PLC: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.4-rc2",
@@ -26,7 +46,7 @@
             "changelog": "Fixes around Linux desktop file and hub server mode: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.3",
             "download": {
                 "date": "2022-08-23T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.3/JackTrip-v1.6.3-Windows-x64-installer.msi",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.3-Windows-x64-installer.msi",
                 "downloadSize": 43606016,
                 "sha256": "83a4def2a8c8fde24d147d39e70f60ee144e9425828f34eda2340c23ce72b1da"
             }
@@ -36,7 +56,7 @@
             "changelog": "Ability to open app via URL schemes, displaying latency stats, and Virtual Studio device support. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.2",
             "download": {
                 "date": "2022-08-17T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.2/JackTrip-v1.6.2-Windows-x64-installer.msi",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.2-Windows-x64-installer.msi",
                 "downloadSize": 43606016,
                 "sha256": "2bb06fe3624df447d56da0d72fef1f4328346fd92c6dffccf66ba37253ec5e62"
             }
@@ -76,7 +96,7 @@
             "changelog": "Bugfixes around UDP timeout and 'Logging In' screen navigation. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.1",
             "download": {
                 "date": "2022-06-21T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.1/JackTrip-v1.6.1-Windows-x64-installer.msi",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.1-Windows-x64-installer.msi",
                 "downloadSize": 43368448,
                 "sha256": "8eac390617488d849c0356e3305c96a59bbe46a8174d02b0321bb1dc86774b87"
             }
             "changelog": "Full integration with JackTrip Virtual Studio. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.0",
             "download": {
                 "date": "2022-06-01T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.0/JackTrip-v1.6.0-Windows-x64-installer.msi",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.0-Windows-x64-installer.msi",
                 "downloadSize": 43364352,
                 "sha256": "9562ab654202bfc432e05caa3bd2bf1d0b52c50581b0a567f0546983fe46c078"
             }
diff --git a/releases/stable/linux-manifests.json b/releases/stable/linux-manifests.json
new file mode 100644 (file)
index 0000000..9cb7d67
--- /dev/null
@@ -0,0 +1,15 @@
+{
+    "app_name": "JackTrip",
+    "releases": [
+        {
+            "version": "1.6.4",
+            "changelog": "Adding volume meters, bugfixes around Windows hanging, device disconnects, and PLC: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.4",
+            "download": {
+                "date": "2022-09-16T00:00:00Z",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.4-Linux-x64-binary.zip",
+                "downloadSize": 22233485,
+                "sha256": "f1b9585e4eb72c07c735ee6f4dc94ad1d1a4c70474799eb1111bb5a39a99e295"
+            }
+        }
+    ]
+}
index 49cf17d0a028bde654c5b83ca85e660745e12b60..febfe6aba976363d751940a5e66de6a9a54b0c5b 100644 (file)
@@ -1,12 +1,22 @@
 {
     "app_name": "JackTrip",
     "releases": [
+        {
+            "version": "1.6.4",
+            "changelog": "Adding volume meters, bugfixes around Windows hanging, device disconnects, and PLC: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.4",
+            "download": {
+                "date": "2022-09-16T00:00:00Z",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.4-macOS-x64-installer.pkg",
+                "downloadSize": 11554866,
+                "sha256": "e5898f3ff57fc2d734590decb4f82a28ad9208a33cad97152f119716cdcea1a9"
+            }
+        },
         {
             "version": "1.6.3",
             "changelog": "Fixes around Linux desktop file and hub server mode: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.3",
             "download": {
                 "date": "2022-08-23T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.3/JackTrip-v1.6.3-macOS-x64-installer.pkg",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.3-macOS-x64-installer.pkg",
                 "downloadSize": 11533023,
                 "sha256": "0b597c62544e9813949f859cc7b7c13bef893f6896f96b34a19889faf4855116"
             }
@@ -16,7 +26,7 @@
             "changelog": "Ability to open app via URL schemes, displaying latency stats, and Virtual Studio device support. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.2",
             "download": {
                 "date": "2022-08-17T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.2/JackTrip-v1.6.2-macOS-x64-installer.pkg",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.2-macOS-x64-installer.pkg",
                 "downloadSize": 11536442,
                 "sha256": "450222f4db1922275e07286d0be6ea2df2873a8a39c3b23096bcfbce342b7b3c"
             }
@@ -26,7 +36,7 @@
             "changelog": "Bugfixes around UDP timeout and 'Logging In' screen navigation. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.1",
             "download": {
                 "date": "2022-06-21T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.1/JackTrip-v1.6.1-macOS-x64-installer.pkg",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.1-macOS-x64-installer.pkg",
                 "downloadSize": 11476305,
                 "sha256": "eaf05c842d6b3ae799208a40b37da1cdb13e3700dcbbd97443c80cad81f4d2ac"
             }
@@ -36,7 +46,7 @@
             "changelog": "Full integration with JackTrip Virtual Studio. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.0",
             "download": {
                 "date": "2022-06-01T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.0/JackTrip-v1.6.0-macOS-x64-installer.pkg",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.0-macOS-x64-installer.pkg",
                 "downloadSize": 11474299,
                 "sha256": "27259600ecd879106ebbf97754d72d6236075a049eafa0de6271d33f753f13e4"
             }
index 74cb51df0672375c976575fe9f5b3cdb70db2a8b..d5d5454a99daf48e2eea626b4bee9b7de9073271 100644 (file)
@@ -1,12 +1,22 @@
 {
     "app_name": "JackTrip",
     "releases": [
+        {
+            "version": "1.6.4",
+            "changelog": "Adding volume meters, bugfixes around Windows hanging, device disconnects, and PLC: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.4",
+            "download": {
+                "date": "2022-09-16T00:00:00Z",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.4-Windows-x64-installer.msi",
+                "downloadSize": 43663360,
+                "sha256": "58dcbba584e1cc82373b8aa159800ad360eec7933ce9462e413ca347f09f3c26"
+            }
+        },
         {
             "version": "1.6.3",
             "changelog": "Fixes around Linux desktop file and hub server mode: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.3",
             "download": {
                 "date": "2022-08-23T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.3/JackTrip-v1.6.3-Windows-x64-installer.msi",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.3-Windows-x64-installer.msi",
                 "downloadSize": 43606016,
                 "sha256": "83a4def2a8c8fde24d147d39e70f60ee144e9425828f34eda2340c23ce72b1da"
             }
@@ -16,7 +26,7 @@
             "changelog": "Ability to open app via URL schemes, displaying latency stats, and Virtual Studio device support. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.2",
             "download": {
                 "date": "2022-08-17T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.2/JackTrip-v1.6.2-Windows-x64-installer.msi",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.2-Windows-x64-installer.msi",
                 "downloadSize": 43606016,
                 "sha256": "2bb06fe3624df447d56da0d72fef1f4328346fd92c6dffccf66ba37253ec5e62"
             }
@@ -26,7 +36,7 @@
             "changelog": "Bugfixes around UDP timeout and 'Logging In' screen navigation. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.1",
             "download": {
                 "date": "2022-06-21T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.1/JackTrip-v1.6.1-Windows-x64-installer.msi",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.1-Windows-x64-installer.msi",
                 "downloadSize": 43368448,
                 "sha256": "8eac390617488d849c0356e3305c96a59bbe46a8174d02b0321bb1dc86774b87"
             }
@@ -36,7 +46,7 @@
             "changelog": "Full integration with JackTrip Virtual Studio. Learn more here: https://github.com/jacktrip/jacktrip/releases/tag/v1.6.0",
             "download": {
                 "date": "2022-06-01T00:00:00Z",
-                "url": "https://github.com/jacktrip/jacktrip/releases/download/v1.6.0/JackTrip-v1.6.0-Windows-x64-installer.msi",
+                "url": "https://files.jacktrip.org/app-builds/JackTrip-v1.6.0-Windows-x64-installer.msi",
                 "downloadSize": 43364352,
                 "sha256": "9562ab654202bfc432e05caa3bd2bf1d0b52c50581b0a567f0546983fe46c078"
             }
index 51586bebc1cebcae0854c7f0698f57eff59a10b6..6934b19bd36425b5f0d9a74b4e0517465850fa58 100644 (file)
@@ -15,7 +15,6 @@ linux-g++ | linux-g++-64 {
 }
 macx {
   QMAKE_CXXFLAGS += -D__MACOSX_CORE__
-  QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9 # the same deployment target as in jacktrip.pro
 }
 win32 {
   QMAKE_CXXFLAGS += -D__WINDOWS_ASIO__ -D__WINDOWS_WASAPI__
index 1244aaa779975dea59efc23e05b16e0339c2bcdd..8ee34b1fd7a1129ebe29bb012d3c2030b6b806a9 100644 (file)
@@ -51,7 +51,8 @@ AudioInterface::AudioInterface(JackTrip* jacktrip, int NumInChans, int NumOutCha
 #ifdef WAIR  // wair
                                int NumNetRevChans,
 #endif  // endwhere
-                               audioBitResolutionT AudioBitResolution)
+                               audioBitResolutionT AudioBitResolution,
+                               bool processWithNetwork)
     : mJackTrip(jacktrip)
     , mNumInChans(NumInChans)
     , mNumOutChans(NumOutChans)
@@ -67,6 +68,7 @@ AudioInterface::AudioInterface(JackTrip* jacktrip, int NumInChans, int NumOutCha
     , mAudioInputPacket(NULL)
     , mAudioOutputPacket(NULL)
     , mLoopBack(false)
+    , mProcessWithNetwork(processWithNetwork)
     , mProcessingAudio(false)
 {
 #ifndef WAIR
@@ -239,7 +241,9 @@ void AudioInterface::callback(QVarLengthArray<sample_t*>& in_buffer,
 #endif  // endwhere
 
     // ==== RECEIVE AUDIO CHANNELS FROM NETWORK ====
-    computeProcessFromNetwork(out_buffer, n_frames);
+    if (mProcessWithNetwork) {
+        computeProcessFromNetwork(out_buffer, n_frames);
+    }
     // =============================================
 
     // out_buffer is from the network and goes "out" to local audio
@@ -321,10 +325,14 @@ void AudioInterface::callback(QVarLengthArray<sample_t*>& in_buffer,
                 mInBufCopy,
                 n_frames);  // writes last channel of mInBufCopy with test impulse
         }
-        computeProcessToNetwork(mInBufCopy, n_frames);
+        if (mProcessWithNetwork) {
+            computeProcessToNetwork(mInBufCopy, n_frames);
+        }
     } else {  // copy saved if no plugins and no audio testing in progress:
-        computeProcessToNetwork(
-            in_buffer, n_frames);  // send processed input audio to network - OUTGOING
+        if (mProcessWithNetwork) {
+            computeProcessToNetwork(
+                in_buffer, n_frames);  // send processed input audio to network - OUTGOING
+        }
     }
 
 #ifdef WAIR  // WAIR
index 293e84a2689b07dde822bd6bad72bca0edeb9d10..ba1753995ccc8cd721bb7b259e79a25260099031 100644 (file)
@@ -87,7 +87,8 @@ class AudioInterface
 #ifdef WAIR  // wair
         int NumNetRevChans,
 #endif  // endwhere
-        AudioInterface::audioBitResolutionT AudioBitResolution = AudioInterface::BIT16);
+        AudioInterface::audioBitResolutionT AudioBitResolution = AudioInterface::BIT16,
+        bool processWithNetwork                                = true);
     /// \brief The class destructor
     virtual ~AudioInterface();
 
@@ -255,6 +256,7 @@ class AudioInterface
     int8_t* mAudioOutputPacket;  ///< Packet containing all the channels to send to the
                                  ///< RingBuffer
     bool mLoopBack;
+    bool mProcessWithNetwork;  ///< whether or not to send/receive data via the network
     AudioTester* mAudioTesterP{nullptr};
 
    protected:
index 40eaeef00fc6859cea4cd6217eb29d7b43eeb8c2..c23771c3d6b91888bf285300b1e17f1493478bd2 100644 (file)
@@ -245,7 +245,7 @@ QByteArray Auth::generateSha512Hash(const QString& passwordString,
     for (n = passwd.length(); n > 64; n -= 64) {
         a.addData(bResult);
     }
-    a.addData(bResult.constData(), n);
+    a.addData(bResult.left(n));
 
     // Step 11
     n = passwd.length();
index 516e9b9fdc1f3d061d536f3d1b20ce3e5682c9b1..1df61d3fc0491941b2d545e82dc54efebe363790 100644 (file)
@@ -80,9 +80,39 @@ JackAudioInterface::JackAudioInterface(
     , mClient(NULL)
     , mClientName(ClientName)
     , mBroadcast(false)
+    , mJackTrip(jacktrip)
 {
 }
 
+//*******************************************************************************
+JackAudioInterface::JackAudioInterface(
+    int NumInChans, int NumOutChans,
+#ifdef WAIR  // wair
+    int NumNetRevChans,
+#endif  // endwhere
+    AudioInterface::audioBitResolutionT AudioBitResolution, const QString& ClientName)
+    : AudioInterface(nullptr, NumInChans, NumOutChans,
+#ifdef WAIR  // wair
+                     NumNetRevChans,
+#endif  // endwhere
+                     AudioBitResolution, false)
+    , mNumInChans(NumInChans)
+    , mNumOutChans(NumOutChans)
+#ifdef WAIR  // WAIR
+    , mNumNetRevChans(NumNetRevChans)
+#endif  // endwhere
+    , mClient(NULL)
+    , mClientName(ClientName)
+    , mBroadcast(false)
+    , mJackTrip(nullptr)
+{
+    JackAudioInterface(nullptr, NumInChans, NumOutChans,
+#ifdef WAIR  // wair
+                       NumNetRevChans,
+#endif  // endwhere
+                       AudioBitResolution, ClientName);
+}
+
 //*******************************************************************************
 JackAudioInterface::~JackAudioInterface() {}
 
@@ -111,6 +141,9 @@ void JackAudioInterface::setupClient()
     // was  jack_options_t options = JackNoStartServer;
     // and then jack_options_t options = JackLoadName;
     jack_options_t options = JackNullOption;  // from jackSimpleClient example
+    if (mJackTrip == nullptr) {
+        options = JackNoStartServer;
+    }
     jack_status_t status;
 
     // Try to connect to the server
@@ -267,7 +300,8 @@ int JackAudioInterface::stopProcess() const
 }
 
 //*******************************************************************************
-void JackAudioInterface::jackShutdown(jack_status_t code, const char* reason, void* arg)
+void JackAudioInterface::jackShutdown(jack_status_t /*code*/, const char* reason,
+                                      void* /*arg*/)
 {
     std::cout << reason << std::endl;
     JackTrip::sJackStopped = true;
index 81ee103ff45b50088933b1b6ad474e7d149be152..b85d4ec452e881dd6477a298b9baf986d36d14f9 100644 (file)
@@ -77,6 +77,14 @@ class JackAudioInterface : public AudioInterface
         JackTrip* jacktrip, int NumInChans, int NumOutChans,
 #ifdef WAIR  // wair
         int NumNetRevChans,
+#endif  // endwhere
+        AudioInterface::audioBitResolutionT AudioBitResolution = AudioInterface::BIT16,
+        const QString& ClientName = QStringLiteral("JackTrip"));
+    /// \brief Overloaded class constructor with null JackTrip pointer
+    JackAudioInterface(
+        int NumInChans, int NumOutChans,
+#ifdef WAIR  // wair
+        int NumNetRevChans,
 #endif  // endwhere
         AudioInterface::audioBitResolutionT AudioBitResolution = AudioInterface::BIT16,
         const QString& ClientName = QStringLiteral("JackTrip"));
@@ -195,6 +203,7 @@ class JackAudioInterface : public AudioInterface
     bool mBroadcast;
     QVector<ProcessPlugin*> mProcessPlugins;  ///< Vector of ProcesPlugin<EM>s</EM>
     static QMutex sJackMutex;  ///< Mutex to make thread safe jack functions that are not
+    JackTrip* mJackTrip;       ///< JackTrip Mediator Class pointer
 };
 
 #endif
index 7130a0f0edfaac566216f03af52dc5cef9c5abf4..21654909d03d265d6caa74b062bc6582726b0c95 100644 (file)
@@ -58,12 +58,14 @@ using std::endl;
 //*******************************************************************************
 JackTripWorker::JackTripWorker(UdpHubListener* udphublistener, int BufferQueueLength,
                                JackTrip::underrunModeT UnderRunMode,
+                               AudioInterface::audioBitResolutionT AudioBitResolution,
                                const QString& clientName)
     : mAppendThreadID(false)
     , mSleepTime(100)
     , mUdpHubListener(udphublistener)
     , mBufferQueueLength(BufferQueueLength)
     , mUnderRunMode(UnderRunMode)
+    , mAudioBitResolution(AudioBitResolution)
     , mClientName(clientName)
 {
     // mNetks = new NetKS;
@@ -167,8 +169,9 @@ void JackTripWorker::start()
 
     mJackTrip->setConnectDefaultAudioPorts(m_connectDefaultAudioPorts);
 
-    // Set our underrun mode
+    // Set our underrun mode and bit resolution
     mJackTrip->setUnderRunMode(mUnderRunMode);
+    mJackTrip->setAudioBitResolution(mAudioBitResolution);
     if (mIOStatTimeout > 0) {
         mJackTrip->setIOStatTimeout(mIOStatTimeout);
         mJackTrip->setIOStatStream(mIOStatStream);
index 7ce1d9e5cf64e76f1f89a0bb18f1542e5a280153..5effcc19c525921860190e5e4ce1bed8edfd9f11 100644 (file)
@@ -70,10 +70,11 @@ class JackTripWorker : public QObject
 
    public:
     /// \brief The class constructor
-    JackTripWorker(UdpHubListener* udphublistener,
-                   int BufferQueueLength                = gDefaultQueueLength,
-                   JackTrip::underrunModeT UnderRunMode = JackTrip::WAVETABLE,
-                   const QString& clientName            = QLatin1String(""));
+    JackTripWorker(
+        UdpHubListener* udphublistener, int BufferQueueLength = gDefaultQueueLength,
+        JackTrip::underrunModeT UnderRunMode                   = JackTrip::WAVETABLE,
+        AudioInterface::audioBitResolutionT AudioBitResolution = AudioInterface::BIT16,
+        const QString& clientName                              = QLatin1String(""));
     /// \brief The class destructor
     ~JackTripWorker() = default;
 
@@ -161,6 +162,7 @@ class JackTripWorker : public QObject
 
     int mBufferQueueLength;
     JackTrip::underrunModeT mUnderRunMode;
+    AudioInterface::audioBitResolutionT mAudioBitResolution;
     QString mClientName;
     QString mAssignedClientName;
 
index a58f8b6e87fc5e82b91e7974ccdda25edefe3bc0..14b26edf83d4eb7beff93616484cb51de5875e77 100644 (file)
@@ -122,6 +122,11 @@ void Meter::compute(int nframes, float** inputs, float** /*_*/)
 //*******************************************************************************
 void Meter::updateNumChannels(int nChansIn, int nChansOut)
 {
+    // this should only be called before init!
+    if (inited) {
+        return;
+    }
+
     if (outgoingPluginToNetwork) {
         mNumChannels = nChansIn;
     } else {
@@ -140,7 +145,9 @@ void Meter::onTick()
 {
     if (hasProcessedAudio) {
         /* Send the measurements to whatever other component requests it */
-        emit onComputedVolumeMeasurements(mValues);
+        QVector<float> valuesCopy(mValues);
+        valuesCopy.detach();
+        emit onComputedVolumeMeasurements(valuesCopy);
 
         /* Set meter values to the default floor */
         QVector<float>::iterator it;
index 3c8a62ece2ff851f4186eacac96e11970aa8a759..5f89eb5306b45660e0d865381757a04e419ecbe6 100644 (file)
@@ -53,6 +53,15 @@ RtAudioInterface::RtAudioInterface(JackTrip* jacktrip, int NumInChans, int NumOu
 {
 }
 
+//*******************************************************************************
+RtAudioInterface::RtAudioInterface(int NumInChans, int NumOutChans,
+                                   audioBitResolutionT AudioBitResolution)
+    : AudioInterface(nullptr, NumInChans, NumOutChans, AudioBitResolution, false)
+    , mRtAudio(NULL)
+{
+    RtAudioInterface(nullptr, NumInChans, NumOutChans, AudioBitResolution);
+}
+
 //*******************************************************************************
 RtAudioInterface::~RtAudioInterface()
 {
index 1397e688d5a1f017d1f84da715884952763d98e6..afcfba0050bc6084ad06db266fb0e98a8ebbc915 100644 (file)
@@ -57,6 +57,10 @@ class RtAudioInterface : public AudioInterface
     RtAudioInterface(JackTrip* jacktrip, int NumInChans = gDefaultNumInChannels,
                      int NumOutChans                        = gDefaultNumOutChannels,
                      audioBitResolutionT AudioBitResolution = BIT16);
+    /// \brief Overloaded class constructor with null JackTrip pointer
+    RtAudioInterface(int NumInChans                         = gDefaultNumInChannels,
+                     int NumOutChans                        = gDefaultNumOutChannels,
+                     audioBitResolutionT AudioBitResolution = BIT16);
     /// \brief The class destructor
     virtual ~RtAudioInterface();
 
index e964815c6bcd9f264c4e6446241f9210d74993dc..bd7fd5932e6c37ef659acd05b4c6fbce75eaf291 100644 (file)
@@ -915,6 +915,7 @@ UdpHubListener* Settings::getConfiguredHubServer()
         cout << gPrintSeparator << std::endl;
         udpHub->setUnderRunMode(mUnderrunMode);
     }
+    udpHub->setAudioBitResolution(mAudioBitResolution);
     udpHub->setBufferQueueLength(mBufferQueueLength);
 
     udpHub->setBufferStrategy(mBufferStrategy);
diff --git a/src/Tone.cpp b/src/Tone.cpp
new file mode 100644 (file)
index 0000000..6b7e5a1
--- /dev/null
@@ -0,0 +1,95 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2020 Julius Smith, Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  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.
+*/
+//*****************************************************************
+
+/**
+ * \file Tone.cpp
+ * \author Nelson Wang
+ * \date October 2022
+ * \license MIT
+ */
+
+#include "Tone.h"
+
+#include "jacktrip_types.h"
+
+//*******************************************************************************
+void Tone::init(int samplingRate)
+{
+    ProcessPlugin::init(samplingRate);
+    if (samplingRate != fSamplingFreq) {
+        std::cerr << "Sampling rate not set by superclass!\n";
+        std::exit(1);
+    }
+    fs = float(fSamplingFreq);
+
+    for (int i = 0; i < mNumChannels; i++) {
+        toneP[i]->init(fs);  // compression filter parameters depend on sampling rate
+    }
+    inited = true;
+}
+
+//*******************************************************************************
+void Tone::compute(int nframes, float** inputs, float** outputs)
+{
+    if (not inited) {
+        std::cerr << "*** Tone " << this << ": init never called! Doing it now.\n";
+        if (fSamplingFreq <= 0) {
+            fSamplingFreq = 48000;
+            std::cout << "Tone " << this
+                      << ": *** HAD TO GUESS the sampling rate (chose 48000 Hz) ***\n";
+        }
+        init(fSamplingFreq);
+    }
+
+    for (int i = 0; i < mNumChannels; i++) {
+        /* Run the signal through Faust  */
+        toneP[i]->compute(nframes, &inputs[i], &outputs[i]);
+    }
+}
+
+//*******************************************************************************
+void Tone::updateNumChannels(int nChansIn, int nChansOut)
+{
+    if (outgoingPluginToNetwork) {
+        mNumChannels = nChansIn;
+    } else {
+        mNumChannels = nChansOut;
+    }
+}
+
+void Tone::triggerPlayback()
+{
+    for (int i = 0; i < mNumChannels; i++) {
+        int ndx = toneUIP[i]->getParamIndex("gate");
+        int v   = toneUIP[i]->getParamValue(ndx);
+        toneUIP[i]->setParamValue(ndx, v + 1);
+    }
+}
diff --git a/src/Tone.h b/src/Tone.h
new file mode 100644 (file)
index 0000000..36ce568
--- /dev/null
@@ -0,0 +1,96 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2020 Julius Smith, Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  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.
+*/
+//*****************************************************************
+
+/**
+ * \file Tone.h
+ * \author Nelson Wang
+ * \date October 2022
+ * \license MIT
+ */
+
+#ifndef __TONE_H__
+#define __TONE_H__
+
+#include <QObject>
+#include <iostream>
+#include <vector>
+
+#include "ProcessPlugin.h"
+#include "tonedsp.h"
+
+/** \brief The Tone plugin plays some arbitrary sample audio
+ */
+class Tone : public ProcessPlugin
+{
+    Q_OBJECT;
+
+   public:
+    /// \brief The class constructor sets the number of channels to measure
+    Tone(int numchans, bool verboseFlag = false) : mNumChannels(numchans)
+    {
+        setVerbose(verboseFlag);
+        for (int i = 0; i < mNumChannels; i++) {
+            toneP.push_back(new tonedsp);
+            toneUIP.push_back(new APIUI);  // #included in tonedsp.h
+            toneP[i]->buildUserInterface(toneUIP[i]);
+        }
+    }
+
+    /// \brief The class destructor
+    virtual ~Tone()
+    {
+        for (int i = 0; i < mNumChannels; i++) {
+            delete toneP[i];
+            delete toneUIP[i];
+        }
+        toneP.clear();
+        toneUIP.clear();
+    }
+
+    void init(int samplingRate) override;
+    int getNumInputs() override { return (mNumChannels); }
+    int getNumOutputs() override { return (mNumChannels); }
+    void compute(int nframes, float** inputs, float** outputs) override;
+    const char* getName() const override { return "Tone"; };
+
+    void updateNumChannels(int nChansIn, int nChansOut) override;
+
+   public slots:
+    void triggerPlayback();
+
+   private:
+    std::vector<tonedsp*> toneP;
+    std::vector<APIUI*> toneUIP;
+    float fs;
+    int mNumChannels;
+};
+
+#endif
\ No newline at end of file
index 5ee1806668805a09d593991101ffb25219a4f1eb..b9bd65bf9cf9832baa2d1f3b6ed8be2f8bc5a946 100644 (file)
@@ -522,8 +522,9 @@ int UdpHubListener::getJackTripWorker(const QString& address,
         if (mAppendThreadID) {
             clientName = clientName + QStringLiteral("_%1").arg(id + 1);
         }
-        mJTWorkers->replace(
-            id, new JackTripWorker(this, mBufferQueueLength, mUnderRunMode, clientName));
+        mJTWorkers->replace(id,
+                            new JackTripWorker(this, mBufferQueueLength, mUnderRunMode,
+                                               mAudioBitResolution, clientName));
         mJTWorkers->at(id)->setJackTrip(
             id, address, mBasePort + id,
             0,  // Set client port to 0 initially until we receive a UDP packet.
index d0a078d4bf6731e3c52a31d0c60f0bb671f29632..58f07372abba9df330066503919b5de86f9ed5ab 100644 (file)
@@ -178,6 +178,7 @@ class UdpHubListener : public QObject
     int mTotalRunningThreads;  ///< Number of Threads running in the pool
     QMutex mMutex;
     JackTrip::underrunModeT mUnderRunMode;
+    AudioInterface::audioBitResolutionT mAudioBitResolution;
     int mBufferQueueLength;
 
     QStringList mHubPatchDescriptions;
@@ -244,6 +245,10 @@ class UdpHubListener : public QObject
     {
         mUnderRunMode = UnderRunMode;
     }
+    void setAudioBitResolution(AudioInterface::audioBitResolutionT AudioBitResolution)
+    {
+        mAudioBitResolution = AudioBitResolution;
+    }
     void setBufferQueueLength(int BufferQueueLength)
     {
         mBufferQueueLength = BufferQueueLength;
diff --git a/src/Volume.cpp b/src/Volume.cpp
new file mode 100644 (file)
index 0000000..d290f3e
--- /dev/null
@@ -0,0 +1,113 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2020 Julius Smith, Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  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.
+*/
+//*****************************************************************
+
+/**
+ * \file Volume.cpp
+ * \author Matt Horton
+ * \date September 2022
+ * \license MIT
+ */
+
+#include "Volume.h"
+
+#include <QVector>
+
+#include "jacktrip_types.h"
+
+//*******************************************************************************
+void Volume::init(int samplingRate)
+{
+    ProcessPlugin::init(samplingRate);
+    if (samplingRate != fSamplingFreq) {
+        std::cerr << "Sampling rate not set by superclass!\n";
+        std::exit(1);
+    }
+    fs = float(fSamplingFreq);
+
+    for (int i = 0; i < mNumChannels; i++) {
+        volumeP[i]->init(fs);  // compression filter parameters depend on sampling rate
+        int ndx = volumeUIP[i]->getParamIndex("Volume");
+        volumeUIP[i]->setParamValue(ndx, mVolMultiplier);
+        ndx = volumeUIP[i]->getParamIndex("Mute");
+        volumeUIP[i]->setParamValue(ndx, isMuted ? 1 : 0);
+    }
+    inited = true;
+}
+
+//*******************************************************************************
+void Volume::compute(int nframes, float** inputs, float** outputs)
+{
+    if (not inited) {
+        std::cerr << "*** Volume " << this << ": init never called! Doing it now.\n";
+        if (fSamplingFreq <= 0) {
+            fSamplingFreq = 48000;
+            std::cout << "Volume " << this
+                      << ": *** HAD TO GUESS the sampling rate (chose 48000 Hz) ***\n";
+        }
+        init(fSamplingFreq);
+    }
+
+    for (int i = 0; i < mNumChannels; i++) {
+        /* Run the signal through Faust  */
+        volumeP[i]->compute(nframes, &inputs[i], &outputs[i]);
+    }
+}
+
+//*******************************************************************************
+void Volume::updateNumChannels(int nChansIn, int nChansOut)
+{
+    if (outgoingPluginToNetwork) {
+        mNumChannels = nChansIn;
+    } else {
+        mNumChannels = nChansOut;
+    }
+}
+
+void Volume::volumeUpdated(float multiplier)
+{
+    // maps 0.0-1.0 to a -40 dB to 0 dB range
+    // update if volumedsp.dsp and/or volumedsp.h
+    // change their ranges
+    mVolMultiplier = 40.0 * multiplier - 40.0;
+    for (int i = 0; i < mNumChannels; i++) {
+        int ndx = volumeUIP[i]->getParamIndex("Volume");
+        volumeUIP[i]->setParamValue(ndx, mVolMultiplier);
+    }
+}
+
+void Volume::muteUpdated(bool muted)
+{
+    isMuted = muted;
+    for (int i = 0; i < mNumChannels; i++) {
+        int ndx = volumeUIP[i]->getParamIndex("Mute");
+        volumeUIP[i]->setParamValue(ndx, isMuted ? 1 : 0);
+    }
+}
\ No newline at end of file
diff --git a/src/Volume.h b/src/Volume.h
new file mode 100644 (file)
index 0000000..59548bb
--- /dev/null
@@ -0,0 +1,101 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2020 Julius Smith, Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  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.
+*/
+//*****************************************************************
+
+/**
+ * \file Volume.h
+ * \author Matt Horton
+ * \date September 2022
+ * \license MIT
+ */
+
+#ifndef __VOLUME_H__
+#define __VOLUME_H__
+
+#include <QObject>
+#include <QTimer>
+#include <QVector>
+#include <iostream>
+#include <vector>
+
+#include "ProcessPlugin.h"
+#include "volumedsp.h"
+
+/** \brief The Volume plugin adjusts the level of the signal via multiplication
+ */
+class Volume : public ProcessPlugin
+{
+    Q_OBJECT;
+
+   public:
+    /// \brief The class constructor sets the number of channels to measure
+    Volume(int numchans, bool verboseFlag = false) : mNumChannels(numchans)
+    {
+        setVerbose(verboseFlag);
+        for (int i = 0; i < mNumChannels; i++) {
+            volumeP.push_back(new volumedsp);
+            volumeUIP.push_back(new APIUI);  // #included in volumedsp.h
+            volumeP[i]->buildUserInterface(volumeUIP[i]);
+        }
+    }
+
+    /// \brief The class destructor
+    virtual ~Volume()
+    {
+        for (int i = 0; i < mNumChannels; i++) {
+            delete volumeP[i];
+            delete volumeUIP[i];
+        }
+        volumeP.clear();
+        volumeUIP.clear();
+    }
+
+    void init(int samplingRate) override;
+    int getNumInputs() override { return (mNumChannels); }
+    int getNumOutputs() override { return (mNumChannels); }
+    void compute(int nframes, float** inputs, float** outputs) override;
+    const char* getName() const override { return "Volume"; };
+
+    void updateNumChannels(int nChansIn, int nChansOut) override;
+
+   public slots:
+    void volumeUpdated(float multiplier);
+    void muteUpdated(bool muted);
+
+   private:
+    std::vector<volumedsp*> volumeP;
+    std::vector<APIUI*> volumeUIP;
+    float fs;
+    int mNumChannels;
+    float mVolMultiplier = 0.0;
+    bool isMuted         = false;
+};
+
+#endif
\ No newline at end of file
index a9f03bd1df6fa764a6b208ab62f75f6a47f79d10..2fcd14fd740077453dca833d0d515773c1996f43 100644 (file)
@@ -3,8 +3,9 @@ author: "Julius Smith"
 license: "MIT Style STK-4.2"
 name: "compressor"
 version: "0.0"
-Code generated with Faust 2.28.6 (https://faust.grame.fr)
-Compilation options: -lang cpp -inpl -scal -ftz 0
+Code generated with Faust 2.41.1 (https://faust.grame.fr)
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn compressordsp -es 1 -mcd
+16 -single -ftz 0
 ------------------------------------------------------------ */
 
 #ifndef __compressordsp_H__
@@ -17,23 +18,23 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 // aimed at creating a simple C++ header file (.h) containing a Faust DSP.
 // See the Makefile for how to use it.
 
-/************************** BEGIN dsp.h **************************/
-/************************************************************************
+/************************** BEGIN dsp.h ********************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -47,29 +48,111 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 #include <string>
 #include <vector>
 
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __export__
+#define __export__
+
+#define FAUSTVERSION "2.41.1"
+
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
+
+#ifdef _WIN32
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API    __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
+#else
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#else
+#define FAUST_API    __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
+#endif
+
+#endif
+
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
 
-struct UI;
-struct Meta;
+struct FAUST_API UI;
+struct FAUST_API Meta;
 
 /**
  * DSP memory manager.
  */
 
-struct dsp_memory_manager {
+struct FAUST_API dsp_memory_manager {
     virtual ~dsp_memory_manager() {}
 
+    /**
+     * Inform the Memory Manager with the number of expected memory zones.
+     * @param count - the number of expected memory zones
+     */
+    virtual void begin(size_t /*count*/) {}
+
+    /**
+     * Give the Memory Manager information on a given memory zone.
+     * @param size - the size in bytes of the memory zone
+     * @param reads - the number of Read access to the zone used to compute one frame
+     * @param writes - the number of Write access to the zone used to compute one frame
+     */
+    virtual void info(size_t /*size*/, size_t /*reads*/, size_t /*writes*/) {}
+
+    /**
+     * Inform the Memory Manager that all memory zones have been described,
+     * to possibly start a 'compute the best allocation strategy' step.
+     */
+    virtual void end() {}
+
+    /**
+     * Allocate a memory zone.
+     * @param size - the memory zone size in bytes
+     */
     virtual void* allocate(size_t size) = 0;
-    virtual void destroy(void* ptr)     = 0;
+
+    /**
+     * Destroy a memory zone.
+     * @param ptr - the memory zone pointer to be deallocated
+     */
+    virtual void destroy(void* ptr) = 0;
 };
 
 /**
  * Signal processor definition.
  */
 
-class dsp
+class FAUST_API dsp
 {
    public:
     dsp() {}
@@ -89,7 +172,7 @@ class dsp
      */
     virtual void buildUserInterface(UI* ui_interface) = 0;
 
-    /* Returns the sample rate currently used by the instance */
+    /* Return the sample rate currently used by the instance */
     virtual int getSampleRate() = 0;
 
     /**
@@ -97,28 +180,28 @@ class dsp
      * - static class 'classInit': static tables initialization
      * - 'instanceInit': constants and instance state initialization
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void init(int sample_rate) = 0;
 
     /**
      * Init instance state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceInit(int sample_rate) = 0;
 
     /**
      * Init instance constant state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceConstants(int sample_rate) = 0;
 
     /* Init default control parameters values */
     virtual void instanceResetUserInterface() = 0;
 
-    /* Init instance state (delay lines...) */
+    /* Init instance state (like delay lines...) but keep the control parameter values */
     virtual void instanceClear() = 0;
 
     /**
@@ -170,7 +253,7 @@ class dsp
  * Generic DSP decorator.
  */
 
-class decorator_dsp : public dsp
+class FAUST_API decorator_dsp : public dsp
 {
    protected:
     dsp* fDSP;
@@ -209,10 +292,11 @@ class decorator_dsp : public dsp
 };
 
 /**
- * DSP factory class.
+ * DSP factory class, used with LLVM and Interpreter backends
+ * to create DSP instances from a compiled DSP program.
  */
 
-class dsp_factory
+class FAUST_API dsp_factory
 {
    protected:
     // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
@@ -232,75 +316,114 @@ class dsp_factory
     virtual dsp_memory_manager* getMemoryManager()             = 0;
 };
 
-/**
- * On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
- * flags to avoid costly denormals.
- */
+// Denormal handling
 
-#ifdef __SSE__
+#if defined(__SSE__)
 #include <xmmintrin.h>
-#ifdef __SSE2__
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
+#endif
+
+class FAUST_API ScopedNoDenormals
+{
+   private:
+    intptr_t fpsr;
+
+    void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("msr fpcr, %0" : : "ri"(fpsr_aux));
+#elif defined(__SSE__)
+        _mm_setcsr(static_cast<uint32_t>(fpsr_aux));
+#endif
+    }
+
+    void getFpStatusRegister() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("mrs %0, fpcr" : "=r"(fpsr));
+#elif defined(__SSE__)
+        fpsr          = static_cast<intptr_t>(_mm_getcsr());
+#endif
+    }
+
+   public:
+    ScopedNoDenormals() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        intptr_t mask = (1 << 24 /* FZ */);
 #else
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
+#if defined(__SSE__)
+#if defined(__SSE2__)
+        intptr_t mask = 0x8040;
+#else
+        intptr_t mask = 0x8000;
 #endif
 #else
-#define AVOIDDENORMALS
+        intptr_t mask = 0x0000;
 #endif
-
 #endif
-/**************************  END  dsp.h **************************/
+        getFpStatusRegister();
+        setFpStatusRegister(fpsr | mask);
+    }
 
-/************************** BEGIN APIUI.h **************************/
-/************************************************************************
- FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
- ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
+    ~ScopedNoDenormals() noexcept { setFpStatusRegister(fpsr); }
+};
 
- This program 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 General Public License for more details.
+#define AVOIDDENORMALS ScopedNoDenormals();
 
- You should have received a copy of the GNU General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+#endif
 
- EXCEPTION : As a special exception, you may create a larger work
- that contains this FAUST architecture section and distribute
- that work under terms of your choice, so long as this FAUST
- architecture section is not modified.
- ************************************************************************/
+/************************** END dsp.h **************************/
+/************************** BEGIN APIUI.h *****************************
+FAUST Architecture File
+Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+---------------------------------------------------------------------
+This program 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 program 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 program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+EXCEPTION : As a special exception, you may create a larger work
+that contains this FAUST architecture section and distribute
+that work under terms of your choice, so long as this FAUST
+architecture section is not modified.
+************************************************************************/
 
 #ifndef API_UI_H
 #define API_UI_H
 
-#include <iostream>
+#include <stdio.h>
+
 #include <map>
 #include <sstream>
 #include <string>
 #include <vector>
 
-/************************** BEGIN meta.h **************************/
-/************************************************************************
+/************************** BEGIN meta.h *******************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -311,36 +434,40 @@ class dsp_factory
 #ifndef __meta__
 #define __meta__
 
-struct Meta {
-    virtual ~Meta(){};
+/**
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
+ (key, value) metadata.
+ */
+struct FAUST_API Meta {
+    virtual ~Meta() {}
     virtual void declare(const char* key, const char* value) = 0;
 };
 
 #endif
 /**************************  END  meta.h **************************/
-/************************** BEGIN UI.h **************************/
-/************************************************************************
+/************************** BEGIN UI.h *****************************
  FAUST Architecture File
- Copyright (C) 2003-2020 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __UI_H__
 #define __UI_H__
@@ -359,7 +486,7 @@ struct Meta {
 struct Soundfile;
 
 template<typename REAL>
-struct UIReal {
+struct FAUST_API UIReal {
     UIReal() {}
     virtual ~UIReal() {}
 
@@ -390,38 +517,41 @@ struct UIReal {
 
     // -- soundfiles
 
-    virtual void addSoundfile(const char* label, const char* filename,
-                              Soundfile** sf_zone) = 0;
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+                              Soundfile** /*sf_zone*/) = 0;
 
     // -- metadata declarations
 
     virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
+
+    // To be used by LLVM client
+    virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
 };
 
-struct UI : public UIReal<FAUSTFLOAT> {
+struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
     UI() {}
     virtual ~UI() {}
 };
 
 #endif
 /**************************  END  UI.h **************************/
-/************************** BEGIN PathBuilder.h **************************/
-/************************************************************************
+/************************** BEGIN PathBuilder.h **************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -429,10 +559,13 @@ struct UI : public UIReal<FAUSTFLOAT> {
  architecture section is not modified.
  ************************************************************************/
 
-#ifndef FAUST_PATHBUILDER_H
-#define FAUST_PATHBUILDER_H
+#ifndef __PathBuilder__
+#define __PathBuilder__
 
 #include <algorithm>
+#include <map>
+#include <regex>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -441,113 +574,266 @@ struct UI : public UIReal<FAUSTFLOAT> {
  * Helper class to build complete hierarchical path for UI items.
  ******************************************************************************/
 
-class PathBuilder
+class FAUST_API PathBuilder
 {
    protected:
     std::vector<std::string> fControlsLevel;
+    std::vector<std::string> fFullPaths;
+    std::map<std::string, std::string> fFull2Short;  // filled by computeShortNames()
+
+    /**
+     * @brief check if a character is acceptable for an ID
+     *
+     * @param c
+     * @return true is the character is acceptable for an ID
+     */
+    bool isIDChar(char c) const
+    {
+        return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+               || ((c >= '0') && (c <= '9'));
+    }
+
+    /**
+     * @brief remove all "/0x00" parts
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string remove0x00(const std::string& src) const
+    {
+        return std::regex_replace(src, std::regex("/0x00"), "");
+    }
+
+    /**
+     * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string str2ID(const std::string& src) const
+    {
+        std::string dst;
+        bool need_underscore = false;
+        for (char c : src) {
+            if (isIDChar(c) || (c == '/')) {
+                if (need_underscore) {
+                    dst.push_back('_');
+                    need_underscore = false;
+                }
+                dst.push_back(c);
+            } else {
+                need_underscore = true;
+            }
+        }
+        return dst;
+    }
+
+    /**
+     * @brief Keep only the last n slash-parts
+     *
+     * @param src
+     * @param n : 1 indicates the last slash-part
+     * @return modified string
+     */
+    std::string cut(const std::string& src, int n) const
+    {
+        std::string rdst;
+        for (int i = int(src.length()) - 1; i >= 0; i--) {
+            char c = src[i];
+            if (c != '/') {
+                rdst.push_back(c);
+            } else if (n == 1) {
+                std::string dst;
+                for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+                    dst.push_back(rdst[j]);
+                }
+                return dst;
+            } else {
+                n--;
+                rdst.push_back(c);
+            }
+        }
+        return src;
+    }
+
+    void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+    /**
+     * @brief Compute the mapping between full path and short names
+     */
+    void computeShortNames()
+    {
+        std::vector<std::string>
+            uniquePaths;  // all full paths transformed but made unique with a prefix
+        std::map<std::string, std::string>
+            unique2full;  // all full paths transformed but made unique with a prefix
+        char num_buffer[16];
+        int pnum = 0;
+
+        for (const auto& s : fFullPaths) {
+            sprintf(num_buffer, "%d", pnum++);
+            std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+            uniquePaths.push_back(u);
+            unique2full[u] = s;  // remember the full path associated to a unique path
+        }
+
+        std::map<std::string, int> uniquePath2level;  // map path to level
+        for (const auto& s : uniquePaths)
+            uniquePath2level[s] = 1;  // we init all levels to 1
+        bool have_collisions = true;
+
+        while (have_collisions) {
+            // compute collision list
+            std::set<std::string> collisionSet;
+            std::map<std::string, std::string> short2full;
+            have_collisions = false;
+            for (const auto& it : uniquePath2level) {
+                std::string u         = it.first;
+                int n                 = it.second;
+                std::string shortName = cut(u, n);
+                auto p                = short2full.find(shortName);
+                if (p == short2full.end()) {
+                    // no collision
+                    short2full[shortName] = u;
+                } else {
+                    // we have a collision, add the two paths to the collision set
+                    have_collisions = true;
+                    collisionSet.insert(u);
+                    collisionSet.insert(p->second);
+                }
+            }
+            for (const auto& s : collisionSet)
+                uniquePath2level[s]++;  // increase level of colliding path
+        }
+
+        for (const auto& it : uniquePath2level) {
+            std::string u               = it.first;
+            int n                       = it.second;
+            std::string shortName       = replaceCharList(cut(u, n), {'/'}, '_');
+            fFull2Short[unique2full[u]] = shortName;
+        }
+    }
+
+    std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+                                char ch2)
+    {
+        auto beg        = ch1.begin();
+        auto end        = ch1.end();
+        std::string res = str;
+        for (size_t i = 0; i < str.length(); ++i) {
+            if (std::find(beg, end, str[i]) != end)
+                res[i] = ch2;
+        }
+        return res;
+    }
 
    public:
     PathBuilder() {}
     virtual ~PathBuilder() {}
 
+    // Return true for the first level of groups
+    bool pushLabel(const std::string& label)
+    {
+        fControlsLevel.push_back(label);
+        return fControlsLevel.size() == 1;
+    }
+
+    // Return true for the last level of groups
+    bool popLabel()
+    {
+        fControlsLevel.pop_back();
+        return fControlsLevel.size() == 0;
+    }
+
     std::string buildPath(const std::string& label)
     {
         std::string res = "/";
         for (size_t i = 0; i < fControlsLevel.size(); i++) {
-            res += fControlsLevel[i];
-            res += "/";
+            res = res + fControlsLevel[i] + "/";
         }
         res += label;
-        std::replace(res.begin(), res.end(), ' ', '_');
-        return res;
-    }
-
-    std::string buildLabel(std::string label)
-    {
-        std::replace(label.begin(), label.end(), ' ', '_');
-        return label;
+        return replaceCharList(
+            res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
     }
-
-    void pushLabel(const std::string& label) { fControlsLevel.push_back(label); }
-    void popLabel() { fControlsLevel.pop_back(); }
 };
 
-#endif  // FAUST_PATHBUILDER_H
+#endif  // __PathBuilder__
 /**************************  END  PathBuilder.h **************************/
-/************************** BEGIN ValueConverter.h **************************/
-/************************************************************************
+/************************** BEGIN ValueConverter.h ********************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __ValueConverter__
 #define __ValueConverter__
 
 /***************************************************************************************
                                                               ValueConverter.h
                           (GRAME, Copyright 2015-2019)
+ ValueConverter.h
+ (GRAME, Copyright 2015-2019)
 
-Set of conversion objects used to map user interface values (for example a gui slider
-delivering values between 0 and 1) to faust values (for example a vslider between
-20 and 20000) using a log scale.
+ Set of conversion objects used to map user interface values (for example a gui slider
+ delivering values between 0 and 1) to faust values (for example a vslider between
+ 20 and 20000) using a log scale.
 
--- Utilities
+ -- Utilities
 
-Range(lo,hi) : clip a value x between lo and hi
-Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
+ Range(lo,hi) : clip a value x between lo and hi
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
 v2 Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1
 vm v2
 
--- Value Converters
+ -- Value Converters
 
-ValueConverter::ui2faust(x)
-ValueConverter::faust2ui(x)
+ ValueConverter::ui2faust(x)
+ ValueConverter::faust2ui(x)
 
--- ValueConverters used for sliders depending of the scale
+ -- ValueConverters used for sliders depending of the scale
 
-LinearValueConverter(umin, umax, fmin, fmax)
-LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
-LogValueConverter(umin, umax, fmin, fmax)
-ExpValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
+ LogValueConverter(umin, umax, fmin, fmax)
+ ExpValueConverter(umin, umax, fmin, fmax)
 
--- ValueConverters used for accelerometers based on 3 points
+ -- ValueConverters used for accelerometers based on 3 points
 
-AccUpConverter(amin, amid, amax, fmin, fmid, fmax)             -- curve 0
-AccDownConverter(amin, amid, amax, fmin, fmid, fmax)   -- curve 1
-AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 2
-AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 3
+ AccUpConverter(amin, amid, amax, fmin, fmid, fmax)        -- curve 0
+ AccDownConverter(amin, amid, amax, fmin, fmid, fmax)      -- curve 1
+ AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 2
+ AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 3
 
--- lists of ZoneControl are used to implement accelerometers metadata for each axes
+ -- lists of ZoneControl are used to implement accelerometers metadata for each axes
 
-ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
+ ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
 
--- ZoneReader are used to implement screencolor metadata
+ -- ZoneReader are used to implement screencolor metadata
 
-ZoneReader(zone, valueConverter) : a zone with a data converter
+ ZoneReader(zone, valueConverter) : a zone with a data converter
 
 ****************************************************************************************/
 
+#include <assert.h>
+#include <float.h>
+
 #include <algorithm>  // std::max
-#include <cassert>
-#include <cfloat>
 #include <cmath>
 #include <vector>
 
@@ -555,12 +841,12 @@ ZoneReader(zone, valueConverter) : a zone with a data converter
 // Interpolator(lo,hi,v1,v2)
 // Maps a value x between lo and hi to a value y between v1 and v2
 // y = v1 + (x-lo)/(hi-lo)*(v2-v1)
-// y = v1 + (x-lo) * coef              with coef = (v2-v1)/(hi-lo)
+// y = v1 + (x-lo) * coef           with coef = (v2-v1)/(hi-lo)
 // y = v1 + x*coef - lo*coef
 // y = v1 - lo*coef + x*coef
-// y = offset + x*coef                         with offset = v1 - lo*coef
+// y = offset + x*coef              with offset = v1 - lo*coef
 //--------------------------------------------------------------------------------------
-class Interpolator
+class FAUST_API Interpolator
 {
    private:
     //--------------------------------------------------------------------------------------
@@ -611,7 +897,7 @@ class Interpolator
 // Interpolator3pt(lo,mi,hi,v1,vm,v2)
 // Map values between lo mid hi to values between v1 vm v2
 //--------------------------------------------------------------------------------------
-class Interpolator3pt
+class FAUST_API Interpolator3pt
 {
    private:
     Interpolator fSegment1;
@@ -635,19 +921,19 @@ class Interpolator3pt
 //--------------------------------------------------------------------------------------
 // Abstract ValueConverter class. Converts values between UI and Faust representations
 //--------------------------------------------------------------------------------------
-class ValueConverter
+class FAUST_API ValueConverter
 {
    public:
     virtual ~ValueConverter() {}
-    virtual double ui2faust(double x) = 0;
-    virtual double faust2ui(double x) = 0;
+    virtual double ui2faust(double x) { return x; };
+    virtual double faust2ui(double x) { return x; };
 };
 
 //--------------------------------------------------------------------------------------
 // A converter than can be updated
 //--------------------------------------------------------------------------------------
 
-class UpdatableValueConverter : public ValueConverter
+class FAUST_API UpdatableValueConverter : public ValueConverter
 {
    protected:
     bool fActive;
@@ -667,7 +953,7 @@ class UpdatableValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter : public ValueConverter
+class FAUST_API LinearValueConverter : public ValueConverter
 {
    private:
     Interpolator fUI2F;
@@ -687,7 +973,7 @@ class LinearValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Two segments linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter2 : public UpdatableValueConverter
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fUI2F;
@@ -723,7 +1009,7 @@ class LinearValueConverter2 : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Logarithmic conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LogValueConverter : public LinearValueConverter
+class FAUST_API LogValueConverter : public LinearValueConverter
 {
    public:
     LogValueConverter(double umin, double umax, double fmin, double fmax)
@@ -745,7 +1031,7 @@ class LogValueConverter : public LinearValueConverter
 //--------------------------------------------------------------------------------------
 // Exponential conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class ExpValueConverter : public LinearValueConverter
+class FAUST_API ExpValueConverter : public LinearValueConverter
 {
    public:
     ExpValueConverter(double umin, double umax, double fmin, double fmax)
@@ -768,7 +1054,7 @@ class ExpValueConverter : public LinearValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up curve (curve 0)
 //--------------------------------------------------------------------------------------
-class AccUpConverter : public UpdatableValueConverter
+class FAUST_API AccUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -804,7 +1090,7 @@ class AccUpConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down curve (curve 1)
 //--------------------------------------------------------------------------------------
-class AccDownConverter : public UpdatableValueConverter
+class FAUST_API AccDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -840,15 +1126,15 @@ class AccDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up-Down curve (curve 2)
 //--------------------------------------------------------------------------------------
-class AccUpDownConverter : public UpdatableValueConverter
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccUpDownConverter(double amin, double amid, double amax, double fmin,
-                       double /*fmid*/, double fmax)
+    AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
+                       double fmax)
         : fA2F(amin, amid, amax, fmin, fmax, fmin)
         , fF2A(fmin, fmax, amin,
                amax)  // Special, pseudo inverse of a non monotonic function
@@ -877,15 +1163,15 @@ class AccUpDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down-Up curve (curve 3)
 //--------------------------------------------------------------------------------------
-class AccDownUpConverter : public UpdatableValueConverter
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccDownUpConverter(double amin, double amid, double amax, double fmin,
-                       double /*fmid*/, double fmax)
+    AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
+                       double fmax)
         : fA2F(amin, amid, amax, fmax, fmin, fmax)
         , fF2A(fmin, fmax, amin,
                amax)  // Special, pseudo inverse of a non monotonic function
@@ -913,7 +1199,7 @@ class AccDownUpConverter : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Base class for ZoneControl
 //--------------------------------------------------------------------------------------
-class ZoneControl
+class FAUST_API ZoneControl
 {
    protected:
     FAUSTFLOAT* fZone;
@@ -924,9 +1210,8 @@ class ZoneControl
 
     virtual void update(double /*v*/) const {}
 
-    virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
-                                  double /*amax*/, double /*min*/, double /*init*/,
-                                  double /*max*/)
+    virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
+                                  double /*min*/, double /*init*/, double /*max*/)
     {
     }
     virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
@@ -942,7 +1227,7 @@ class ZoneControl
 //--------------------------------------------------------------------------------------
 //  Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class ConverterZoneControl : public ZoneControl
+class FAUST_API ConverterZoneControl : public ZoneControl
 {
    protected:
     ValueConverter* fValueConverter;
@@ -957,7 +1242,10 @@ class ConverterZoneControl : public ZoneControl
         delete fValueConverter;
     }  // Assuming fValueConverter is not kept elsewhere...
 
-    virtual void update(double v) const { *fZone = fValueConverter->ui2faust(v); }
+    virtual void update(double v) const
+    {
+        *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v));
+    }
 
     ValueConverter* getConverter() { return fValueConverter; }
 };
@@ -966,7 +1254,7 @@ class ConverterZoneControl : public ZoneControl
 // Association of a zone and a four value converter, each one for each possible curve.
 // Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class CurveZoneControl : public ZoneControl
+class FAUST_API CurveZoneControl : public ZoneControl
 {
    private:
     std::vector<UpdatableValueConverter*> fValueConverters;
@@ -989,15 +1277,14 @@ class CurveZoneControl : public ZoneControl
     }
     virtual ~CurveZoneControl()
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            delete (*it);
+        for (const auto& it : fValueConverters) {
+            delete it;
         }
     }
     void update(double v) const
     {
         if (fValueConverters[fCurve]->getActive())
-            *fZone = fValueConverters[fCurve]->ui2faust(v);
+            *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v));
     }
 
     void setMappingValues(int curve, double amin, double amid, double amax, double min,
@@ -1014,16 +1301,15 @@ class CurveZoneControl : public ZoneControl
 
     void setActive(bool on_off)
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            (*it)->setActive(on_off);
+        for (const auto& it : fValueConverters) {
+            it->setActive(on_off);
         }
     }
 
     int getCurve() { return fCurve; }
 };
 
-class ZoneReader
+class FAUST_API ZoneReader
 {
    private:
     FAUSTFLOAT* fZone;
@@ -1043,6 +1329,8 @@ class ZoneReader
 #endif
 /**************************  END  ValueConverter.h **************************/
 
+typedef unsigned int uint;
+
 class APIUI
     : public PathBuilder
     , public Meta
@@ -1058,22 +1346,42 @@ class APIUI
         kHBargraph,
         kVBargraph
     };
+    enum Type { kAcc = 0, kGyr = 1, kNoType };
 
    protected:
-    enum { kLin = 0, kLog = 1, kExp = 2 };
-
-    int fNumParameters;
-    std::vector<std::string> fPaths;
-    std::vector<std::string> fLabels;
-    std::map<std::string, int> fPathMap;
-    std::map<std::string, int> fLabelMap;
-    std::vector<ValueConverter*> fConversion;
-    std::vector<FAUSTFLOAT*> fZone;
-    std::vector<FAUSTFLOAT> fInit;
-    std::vector<FAUSTFLOAT> fMin;
-    std::vector<FAUSTFLOAT> fMax;
-    std::vector<FAUSTFLOAT> fStep;
-    std::vector<ItemType> fItemType;
+    enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+    struct Item {
+        std::string fLabel;
+        std::string fShortname;
+        std::string fPath;
+        ValueConverter* fConversion;
+        FAUSTFLOAT* fZone;
+        FAUSTFLOAT fInit;
+        FAUSTFLOAT fMin;
+        FAUSTFLOAT fMax;
+        FAUSTFLOAT fStep;
+        ItemType fItemType;
+
+        Item(const std::string& label, const std::string& short_name,
+             const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+             FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+             ItemType item_type)
+            : fLabel(label)
+            , fShortname(short_name)
+            , fPath(path)
+            , fConversion(conversion)
+            , fZone(zone)
+            , fInit(init)
+            , fMin(min)
+            , fMax(max)
+            , fStep(step)
+            , fItemType(item_type)
+        {
+        }
+    };
+    std::vector<Item> fItems;
+
     std::vector<std::map<std::string, std::string> > fMetaData;
     std::vector<ZoneControl*> fAcc[3];
     std::vector<ZoneControl*> fGyr[3];
@@ -1100,33 +1408,31 @@ class APIUI
                               ItemType type)
     {
         std::string path = buildPath(label);
-        fPathMap[path] = fLabelMap[label] = fNumParameters++;
-        fPaths.push_back(path);
-        fLabels.push_back(label);
-        fZone.push_back(zone);
-        fInit.push_back(init);
-        fMin.push_back(min);
-        fMax.push_back(max);
-        fStep.push_back(step);
-        fItemType.push_back(type);
+        fFullPaths.push_back(path);
 
         // handle scale metadata
+        ValueConverter* converter = nullptr;
         switch (fCurrentScale) {
         case kLin:
-            fConversion.push_back(new LinearValueConverter(0, 1, min, max));
+            converter = new LinearValueConverter(0, 1, min, max);
             break;
         case kLog:
-            fConversion.push_back(new LogValueConverter(0, 1, min, max));
+            converter = new LogValueConverter(0, 1, min, max);
             break;
         case kExp:
-            fConversion.push_back(new ExpValueConverter(0, 1, min, max));
+            converter = new ExpValueConverter(0, 1, min, max);
             break;
         }
         fCurrentScale = kLin;
 
+        fItems.push_back(
+            Item(label, "", path, converter, zone, init, min, max, step, type));
+
         if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
-            std::cerr << "warning : 'acc' and 'gyr' metadata used for the same " << label
-                      << " parameter !!\n";
+            fprintf(
+                stderr,
+                "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n",
+                label);
         }
 
         // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
@@ -1141,7 +1447,7 @@ class APIUI
                 fAcc[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect acc metadata : " << fCurrentAcc << std::endl;
+                fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
             }
             fCurrentAcc = "";
         }
@@ -1158,31 +1464,31 @@ class APIUI
                 fGyr[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect gyr metadata : " << fCurrentGyr << std::endl;
+                fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
             }
             fCurrentGyr = "";
         }
 
         // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
         if (fCurrentColor.size() > 0) {
-            if ((fCurrentColor == "red") && (fRedReader == 0)) {
+            if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "green") && (fGreenReader == 0)) {
+            } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "blue") && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "white") && (fRedReader == 0)
-                       && (fGreenReader == 0) && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "white") && (fRedReader == nullptr)
+                       && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
             } else {
-                std::cerr << "incorrect screencolor metadata : " << fCurrentColor
-                          << std::endl;
+                fprintf(stderr, "incorrect screencolor metadata : %s \n",
+                        fCurrentColor.c_str());
             }
         }
         fCurrentColor = "";
@@ -1193,7 +1499,7 @@ class APIUI
 
     int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
     {
-        FAUSTFLOAT* zone = fZone[p];
+        FAUSTFLOAT* zone = fItems[uint(p)].fZone;
         for (size_t i = 0; i < table[val].size(); i++) {
             if (zone == table[val][i]->getZone())
                 return int(i);
@@ -1210,11 +1516,11 @@ class APIUI
 
         // Deactivates everywhere..
         if (id1 != -1)
-            table[0][id1]->setActive(false);
+            table[0][uint(id1)]->setActive(false);
         if (id2 != -1)
-            table[1][id2]->setActive(false);
+            table[1][uint(id2)]->setActive(false);
         if (id3 != -1)
-            table[2][id3]->setActive(false);
+            table[2][uint(id3)]->setActive(false);
 
         if (val == -1) {  // Means: no more mapping...
             // So stay all deactivated...
@@ -1222,14 +1528,16 @@ class APIUI
             int id4 = getZoneIndex(table, p, val);
             if (id4 != -1) {
                 // Reactivate the one we edit...
-                table[val][id4]->setMappingValues(curve, amin, amid, amax, fMin[p],
-                                                  fInit[p], fMax[p]);
-                table[val][id4]->setActive(true);
+                table[val][uint(id4)]->setMappingValues(
+                    curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit,
+                    fItems[uint(p)].fMax);
+                table[val][uint(id4)]->setActive(true);
             } else {
                 // Allocate a new CurveZoneControl which is 'active' by default
-                FAUSTFLOAT* zone = fZone[p];
-                table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax,
-                                                          fMin[p], fInit[p], fMax[p]));
+                FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+                table[val].push_back(new CurveZoneControl(
+                    zone, curve, amin, amid, amax, fItems[uint(p)].fMin,
+                    fItems[uint(p)].fInit, fItems[uint(p)].fMax));
             }
         }
     }
@@ -1243,16 +1551,16 @@ class APIUI
 
         if (id1 != -1) {
             val   = 0;
-            curve = table[val][id1]->getCurve();
-            table[val][id1]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id1)]->getCurve();
+            table[val][uint(id1)]->getMappingValues(amin, amid, amax);
         } else if (id2 != -1) {
             val   = 1;
-            curve = table[val][id2]->getCurve();
-            table[val][id2]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id2)]->getCurve();
+            table[val][uint(id2)]->getMappingValues(amin, amid, amax);
         } else if (id3 != -1) {
             val   = 2;
-            curve = table[val][id3]->getCurve();
-            table[val][id3]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id3)]->getCurve();
+            table[val][uint(id3)]->getMappingValues(amin, amid, amax);
         } else {
             val   = -1;  // No mapping
             curve = 0;
@@ -1263,26 +1571,23 @@ class APIUI
     }
 
    public:
-    enum Type { kAcc = 0, kGyr = 1, kNoType };
-
     APIUI()
-        : fNumParameters(0)
-        , fHasScreenControl(false)
-        , fRedReader(0)
-        , fGreenReader(0)
-        , fBlueReader(0)
+        : fHasScreenControl(false)
+        , fRedReader(nullptr)
+        , fGreenReader(nullptr)
+        , fBlueReader(nullptr)
         , fCurrentScale(kLin)
     {
     }
 
     virtual ~APIUI()
     {
-        for (auto& it : fConversion)
-            delete it;
+        for (const auto& it : fItems)
+            delete it.fConversion;
         for (int i = 0; i < 3; i++) {
-            for (auto& it : fAcc[i])
+            for (const auto& it : fAcc[i])
                 delete it;
-            for (auto& it : fGyr[i])
+            for (const auto& it : fGyr[i])
                 delete it;
         }
         delete fRedReader;
@@ -1295,7 +1600,18 @@ class APIUI
     virtual void openTabBox(const char* label) { pushLabel(label); }
     virtual void openHorizontalBox(const char* label) { pushLabel(label); }
     virtual void openVerticalBox(const char* label) { pushLabel(label); }
-    virtual void closeBox() { popLabel(); }
+    virtual void closeBox()
+    {
+        if (popLabel()) {
+            // Shortnames can be computed when all fullnames are known
+            computeShortNames();
+            // Fill 'shortname' field for each item
+            for (const auto& it : fFull2Short) {
+                int index                = getParamIndex(it.first.c_str());
+                fItems[index].fShortname = it.second;
+            }
+        }
+    }
 
     // -- active widgets
 
@@ -1332,13 +1648,13 @@ class APIUI
     virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone,
                                        FAUSTFLOAT min, FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kHBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kHBargraph);
     }
 
     virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min,
                                      FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kVBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kVBargraph);
     }
 
     // -- soundfiles
@@ -1381,23 +1697,25 @@ class APIUI
     //-------------------------------------------------------------------------------
     // Simple API part
     //-------------------------------------------------------------------------------
-    int getParamsCount() { return fNumParameters; }
-    int getParamIndex(const char* path)
+    int getParamsCount() { return int(fItems.size()); }
+
+    int getParamIndex(const char* path_aux)
     {
-        if (fPathMap.find(path) != fPathMap.end()) {
-            return fPathMap[path];
-        } else if (fLabelMap.find(path) != fLabelMap.end()) {
-            return fLabelMap[path];
-        } else {
-            return -1;
-        }
+        std::string path = std::string(path_aux);
+        auto it          = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+            return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+                 });
+        return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
     }
-    const char* getParamAddress(int p) { return fPaths[p].c_str(); }
-    const char* getParamLabel(int p) { return fLabels[p].c_str(); }
+
+    const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
+    const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
+    const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+
     std::map<const char*, const char*> getMetadata(int p)
     {
         std::map<const char*, const char*> res;
-        std::map<std::string, std::string> metadata = fMetaData[p];
+        std::map<std::string, std::string> metadata = fMetaData[uint(p)];
         for (const auto& it : metadata) {
             res[it.first.c_str()] = it.second.c_str();
         }
@@ -1406,26 +1724,62 @@ class APIUI
 
     const char* getMetadata(int p, const char* key)
     {
-        return (fMetaData[p].find(key) != fMetaData[p].end()) ? fMetaData[p][key].c_str()
-                                                              : "";
+        return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end())
+                   ? fMetaData[uint(p)][key].c_str()
+                   : "";
     }
-    FAUSTFLOAT getParamMin(int p) { return fMin[p]; }
-    FAUSTFLOAT getParamMax(int p) { return fMax[p]; }
-    FAUSTFLOAT getParamStep(int p) { return fStep[p]; }
-    FAUSTFLOAT getParamInit(int p) { return fInit[p]; }
+    FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
+    FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
+    FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
+    FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
 
-    FAUSTFLOAT* getParamZone(int p) { return fZone[p]; }
-    FAUSTFLOAT getParamValue(int p) { return *fZone[p]; }
-    void setParamValue(int p, FAUSTFLOAT v) { *fZone[p] = v; }
+    FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
 
-    double getParamRatio(int p) { return fConversion[p]->faust2ui(*fZone[p]); }
-    void setParamRatio(int p, double r) { *fZone[p] = fConversion[p]->ui2faust(r); }
+    FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
+    FAUSTFLOAT getParamValue(const char* path)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            return getParamValue(index);
+        } else {
+            fprintf(stderr, "getParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+            return FAUSTFLOAT(0);
+        }
+    }
 
-    double value2ratio(int p, double r) { return fConversion[p]->faust2ui(r); }
-    double ratio2value(int p, double r) { return fConversion[p]->ui2faust(r); }
+    void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+    void setParamValue(const char* path, FAUSTFLOAT v)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            setParamValue(index, v);
+        } else {
+            fprintf(stderr, "setParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+        }
+    }
+
+    double getParamRatio(int p)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone);
+    }
+    void setParamRatio(int p, double r)
+    {
+        *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r));
+    }
+
+    double value2ratio(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(r);
+    }
+    double ratio2value(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->ui2faust(r);
+    }
 
     /**
-     * Return the control type (kAcc, kGyr, or -1) for a given parameter
+     * Return the control type (kAcc, kGyr, or -1) for a given parameter.
      *
      * @param p - the UI parameter index
      *
@@ -1447,13 +1801,13 @@ class APIUI
 
     /**
      * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry,
-     * kHBargraph, kVBargraph) for a given parameter
+     * kHBargraph, kVBargraph) for a given parameter.
      *
      * @param p - the UI parameter index
      *
      * @return the Item type
      */
-    ItemType getParamItemType(int p) { return fItemType[p]; }
+    ItemType getParamItemType(int p) { return fItems[uint(p)].fItemType; }
 
     /**
      * Set a new value coming from an accelerometer, propagate it to all relevant
@@ -1493,7 +1847,7 @@ class APIUI
      * given UI parameter.
      *
      * @param p - the UI parameter index
-     * @param acc - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+     * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
      * mapping")
      * @param curve - between 0 and 3
      * @param amin - mapping 'min' point
@@ -1558,7 +1912,7 @@ class APIUI
     }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer
+     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
      *
      * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
      * @return the number of zones
@@ -1567,7 +1921,7 @@ class APIUI
     int getAccCount(int acc) { return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0; }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope
+     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
      *
      * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
      * @param the number of zones
@@ -1604,8 +1958,11 @@ class APIUI
 #define FAUSTFLOAT float
 #endif
 
+#include <math.h>
+
 #include <algorithm>
 #include <cmath>
+#include <cstdint>
 
 #ifndef FAUSTCLASS
 #define FAUSTCLASS compressordsp
@@ -1616,20 +1973,24 @@ class APIUI
 #define exp10  __exp10
 #endif
 
+#if defined(_WIN32)
+#define RESTRICT __restrict
+#else
+#define RESTRICT __restrict__
+#endif
+
 class compressordsp : public dsp
 {
    private:
     FAUSTFLOAT fCheckbox0;
     FAUSTFLOAT fHslider0;
+    FAUSTFLOAT fHslider1;
     int fSampleRate;
     float fConst0;
-    FAUSTFLOAT fHslider1;
     FAUSTFLOAT fHslider2;
     FAUSTFLOAT fHslider3;
-    float fRec5[2];
-    float fRec4[2];
-    FAUSTFLOAT fHslider4;
     float fRec3[2];
+    FAUSTFLOAT fHslider4;
     float fRec2[2];
     float fRec1[2];
     float fRec0[2];
@@ -1638,11 +1999,17 @@ class compressordsp : public dsp
    public:
     void metadata(Meta* m)
     {
+        m->declare("analyzers.lib/amp_follower_ar:author",
+                   "Jonatan Liljedahl, revised by Romain Michon");
         m->declare("analyzers.lib/name", "Faust Analyzer Library");
-        m->declare("analyzers.lib/version", "0.1");
+        m->declare("analyzers.lib/version", "0.2");
         m->declare("author", "Julius Smith");
+        m->declare("basics.lib/bypass1:author", "Julius Smith");
         m->declare("basics.lib/name", "Faust Basic Element Library");
-        m->declare("basics.lib/version", "0.1");
+        m->declare("basics.lib/version", "0.8");
+        m->declare("compile_options",
+                   "-a faust2header.cpp -lang cpp -i -inpl -cn compressordsp -es 1 -mcd "
+                   "16 -single -ftz 0");
         m->declare("compressors.lib/compression_gain_mono:author", "Julius O. Smith III");
         m->declare(
             "compressors.lib/compression_gain_mono:copyright",
@@ -1662,7 +2029,7 @@ class compressordsp : public dsp
         m->declare("compressors.lib/compressor_mono:license",
                    "MIT-style STK-4.3 license");
         m->declare("compressors.lib/name", "Faust Compressor Effect Library");
-        m->declare("compressors.lib/version", "0.0");
+        m->declare("compressors.lib/version", "0.2");
         m->declare("description",
                    "Compressor demo application, adapted from the Faust Library's "
                    "dm.compressor_demo in demos.lib");
@@ -1674,47 +2041,20 @@ class compressordsp : public dsp
         m->declare("maths.lib/copyright", "GRAME");
         m->declare("maths.lib/license", "LGPL with exception");
         m->declare("maths.lib/name", "Faust Math Library");
-        m->declare("maths.lib/version", "2.3");
+        m->declare("maths.lib/version", "2.5");
         m->declare("name", "compressor");
         m->declare("platform.lib/name", "Generic Platform Library");
-        m->declare("platform.lib/version", "0.1");
+        m->declare("platform.lib/version", "0.2");
         m->declare("signals.lib/name", "Faust Signal Routing Library");
-        m->declare("signals.lib/version", "0.0");
+        m->declare("signals.lib/onePoleSwitching:author",
+                   "Jonatan Liljedahl, revised by Dario Sanfilippo");
+        m->declare("signals.lib/onePoleSwitching:licence", "STK-4.3");
+        m->declare("signals.lib/version", "0.3");
         m->declare("version", "0.0");
     }
 
     virtual int getNumInputs() { return 1; }
     virtual int getNumOutputs() { return 1; }
-    virtual int getInputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
-    virtual int getOutputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
 
     static void classInit(int /*sample_rate*/) {}
 
@@ -1722,39 +2062,32 @@ class compressordsp : public dsp
     {
         fSampleRate = sample_rate;
         fConst0 =
-            (1.0f
-             / std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate))));
+            1.0f / std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
     }
 
     virtual void instanceResetUserInterface()
     {
         fCheckbox0 = FAUSTFLOAT(0.0f);
         fHslider0  = FAUSTFLOAT(2.0f);
-        fHslider1  = FAUSTFLOAT(15.0f);
-        fHslider2  = FAUSTFLOAT(2.0f);
-        fHslider3  = FAUSTFLOAT(40.0f);
+        fHslider1  = FAUSTFLOAT(2.0f);
+        fHslider2  = FAUSTFLOAT(40.0f);
+        fHslider3  = FAUSTFLOAT(15.0f);
         fHslider4  = FAUSTFLOAT(-24.0f);
     }
 
     virtual void instanceClear()
     {
-        for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
-            fRec5[l0] = 0.0f;
-        }
-        for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) {
-            fRec4[l1] = 0.0f;
-        }
-        for (int l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
-            fRec3[l2] = 0.0f;
+        for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
+            fRec3[l0] = 0.0f;
         }
-        for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) {
-            fRec2[l3] = 0.0f;
+        for (int l1 = 0; l1 < 2; l1 = l1 + 1) {
+            fRec2[l1] = 0.0f;
         }
-        for (int l4 = 0; (l4 < 2); l4 = (l4 + 1)) {
-            fRec1[l4] = 0.0f;
+        for (int l2 = 0; l2 < 2; l2 = l2 + 1) {
+            fRec1[l2] = 0.0f;
         }
-        for (int l5 = 0; (l5 < 2); l5 = (l5 + 1)) {
-            fRec0[l5] = 0.0f;
+        for (int l3 = 0; l3 < 2; l3 = l3 + 1) {
+            fRec0[l3] = 0.0f;
         }
     }
 
@@ -1792,54 +2125,58 @@ class compressordsp : public dsp
         ui_interface->declare(&fHbargraph0, "1", "");
         ui_interface->declare(&fHbargraph0, "tooltip", "Compressor gain in dB");
         ui_interface->declare(&fHbargraph0, "unit", "dB");
-        ui_interface->addHorizontalBargraph("Compressor Gain", &fHbargraph0, -50.0f,
-                                            10.0f);
+        ui_interface->addHorizontalBargraph("Compressor Gain", &fHbargraph0,
+                                            FAUSTFLOAT(-50.0f), FAUSTFLOAT(10.0f));
         ui_interface->closeBox();
         ui_interface->declare(0, "1", "");
         ui_interface->openHorizontalBox("0x00");
         ui_interface->declare(0, "3", "");
         ui_interface->openHorizontalBox("Compression Control");
-        ui_interface->declare(&fHslider2, "0", "");
-        ui_interface->declare(&fHslider2, "style", "knob");
+        ui_interface->declare(&fHslider1, "0", "");
+        ui_interface->declare(&fHslider1, "style", "knob");
         ui_interface->declare(
-            &fHslider2, "tooltip",
+            &fHslider1, "tooltip",
             "A compression Ratio of N means that for each N dB increase in input         "
             "signal level above Threshold, the output level goes up 1 dB");
-        ui_interface->addHorizontalSlider("Ratio", &fHslider2, 2.0f, 1.0f, 20.0f,
-                                          0.100000001f);
+        ui_interface->addHorizontalSlider("Ratio", &fHslider1, FAUSTFLOAT(2.0f),
+                                          FAUSTFLOAT(1.0f), FAUSTFLOAT(20.0f),
+                                          FAUSTFLOAT(0.100000001f));
         ui_interface->declare(&fHslider4, "1", "");
         ui_interface->declare(&fHslider4, "style", "knob");
         ui_interface->declare(&fHslider4, "tooltip",
                               "When the signal level exceeds the Threshold (in dB), its "
                               "level         is compressed according to the Ratio");
         ui_interface->declare(&fHslider4, "unit", "dB");
-        ui_interface->addHorizontalSlider("Threshold", &fHslider4, -24.0f, -100.0f, 10.0f,
-                                          0.100000001f);
+        ui_interface->addHorizontalSlider("Threshold", &fHslider4, FAUSTFLOAT(-24.0f),
+                                          FAUSTFLOAT(-100.0f), FAUSTFLOAT(10.0f),
+                                          FAUSTFLOAT(0.100000001f));
         ui_interface->closeBox();
         ui_interface->declare(0, "4", "");
         ui_interface->openHorizontalBox("Compression Response");
-        ui_interface->declare(&fHslider1, "1", "");
-        ui_interface->declare(&fHslider1, "scale", "log");
-        ui_interface->declare(&fHslider1, "style", "knob");
+        ui_interface->declare(&fHslider3, "1", "");
+        ui_interface->declare(&fHslider3, "scale", "log");
+        ui_interface->declare(&fHslider3, "style", "knob");
         ui_interface->declare(
-            &fHslider1, "tooltip",
+            &fHslider3, "tooltip",
             "Time constant in ms (1/e smoothing time) for the compression gain         "
             "to approach (exponentially) a new lower target level (the compression       "
             "  `kicking in')");
-        ui_interface->declare(&fHslider1, "unit", "ms");
-        ui_interface->addHorizontalSlider("Attack", &fHslider1, 15.0f, 1.0f, 1000.0f,
-                                          0.100000001f);
-        ui_interface->declare(&fHslider3, "2", "");
-        ui_interface->declare(&fHslider3, "scale", "log");
-        ui_interface->declare(&fHslider3, "style", "knob");
+        ui_interface->declare(&fHslider3, "unit", "ms");
+        ui_interface->addHorizontalSlider("Attack", &fHslider3, FAUSTFLOAT(15.0f),
+                                          FAUSTFLOAT(1.0f), FAUSTFLOAT(1000.0f),
+                                          FAUSTFLOAT(0.100000001f));
+        ui_interface->declare(&fHslider2, "2", "");
+        ui_interface->declare(&fHslider2, "scale", "log");
+        ui_interface->declare(&fHslider2, "style", "knob");
         ui_interface->declare(
-            &fHslider3, "tooltip",
+            &fHslider2, "tooltip",
             "Time constant in ms (1/e smoothing time) for the compression gain         "
             "to approach (exponentially) a new higher target level (the compression      "
             "   'releasing')");
-        ui_interface->declare(&fHslider3, "unit", "ms");
-        ui_interface->addHorizontalSlider("Release", &fHslider3, 40.0f, 1.0f, 1000.0f,
-                                          0.100000001f);
+        ui_interface->declare(&fHslider2, "unit", "ms");
+        ui_interface->addHorizontalSlider("Release", &fHslider2, FAUSTFLOAT(40.0f),
+                                          FAUSTFLOAT(1.0f), FAUSTFLOAT(1000.0f),
+                                          FAUSTFLOAT(0.100000001f));
         ui_interface->closeBox();
         ui_interface->closeBox();
         ui_interface->declare(&fHslider0, "5", "");
@@ -1848,8 +2185,9 @@ class compressordsp : public dsp
             "The compressed-signal output level is increased by this amount         (in "
             "dB) to make up for the level lost due to compression");
         ui_interface->declare(&fHslider0, "unit", "dB");
-        ui_interface->addHorizontalSlider("MakeUpGain", &fHslider0, 2.0f, -96.0f, 96.0f,
-                                          0.100000001f);
+        ui_interface->addHorizontalSlider("MakeUpGain", &fHslider0, FAUSTFLOAT(2.0f),
+                                          FAUSTFLOAT(-96.0f), FAUSTFLOAT(96.0f),
+                                          FAUSTFLOAT(0.100000001f));
         ui_interface->closeBox();
     }
 
@@ -1858,54 +2196,58 @@ class compressordsp : public dsp
         FAUSTFLOAT* input0  = inputs[0];
         FAUSTFLOAT* output0 = outputs[0];
         int iSlow0          = int(float(fCheckbox0));
-        float fSlow1        = std::pow(10.0f, (0.0500000007f * float(fHslider0)));
-        float fSlow2 = std::max<float>(fConst0, (0.00100000005f * float(fHslider1)));
-        float fSlow3 = (0.5f * fSlow2);
-        int iSlow4   = (std::fabs(fSlow3) < 1.1920929e-07f);
-        float fSlow5 =
-            (iSlow4 ? 0.0f : std::exp((0.0f - (fConst0 / (iSlow4 ? 1.0f : fSlow3)))));
-        float fSlow6 =
-            ((1.0f / std::max<float>(1.00000001e-07f, float(fHslider2))) + -1.0f);
-        int iSlow7 = (std::fabs(fSlow2) < 1.1920929e-07f);
-        float fSlow8 =
-            (iSlow7 ? 0.0f : std::exp((0.0f - (fConst0 / (iSlow7 ? 1.0f : fSlow2)))));
-        float fSlow9 = std::max<float>(fConst0, (0.00100000005f * float(fHslider3)));
-        int iSlow10  = (std::fabs(fSlow9) < 1.1920929e-07f);
-        float fSlow11 =
-            (iSlow10 ? 0.0f : std::exp((0.0f - (fConst0 / (iSlow10 ? 1.0f : fSlow9)))));
-        float fSlow12 = float(fHslider4);
-        float fSlow13 = (1.0f - fSlow5);
-        for (int i = 0; (i < count); i = (i + 1)) {
-            float fTemp0 = float(input0[i]);
-            float fTemp1 = (iSlow0 ? 0.0f : fTemp0);
+        float fSlow1        = std::pow(10.0f, 0.0500000007f * float(fHslider0));
+        float fSlow2  = 1.0f / std::max<float>(1.1920929e-07f, float(fHslider1)) + -1.0f;
+        float fSlow3  = std::max<float>(fConst0, 0.00100000005f * float(fHslider2));
+        int iSlow4    = std::fabs(fSlow3) < 1.1920929e-07f;
+        float fThen2  = std::exp(0.0f - fConst0 / ((iSlow4) ? 1.0f : fSlow3));
+        float fSlow5  = ((iSlow4) ? 0.0f : fThen2);
+        float fSlow6  = std::max<float>(fConst0, 0.00100000005f * float(fHslider3));
+        int iSlow7    = std::fabs(fSlow6) < 1.1920929e-07f;
+        float fThen4  = std::exp(0.0f - fConst0 / ((iSlow7) ? 1.0f : fSlow6));
+        float fSlow8  = ((iSlow7) ? 0.0f : fThen4);
+        float fSlow9  = float(fHslider4);
+        float fSlow10 = 0.5f * fSlow6;
+        int iSlow11   = std::fabs(fSlow10) < 1.1920929e-07f;
+        float fThen7  = std::exp(0.0f - fConst0 / ((iSlow11) ? 1.0f : fSlow10));
+        float fSlow12 = ((iSlow11) ? 0.0f : fThen7);
+        float fSlow13 = 1.0f - fSlow12;
+        for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+            float fTemp0 = float(input0[i0]);
+            float fTemp1 = ((iSlow0) ? 0.0f : fTemp0);
             float fTemp2 = std::fabs(fTemp1);
-            float fTemp3 = ((fRec4[1] > fTemp2) ? fSlow11 : fSlow8);
-            fRec5[0]     = ((fRec5[1] * fTemp3) + (fTemp2 * (1.0f - fTemp3)));
-            fRec4[0]     = fRec5[0];
-            fRec3[0] =
-                ((fRec3[1] * fSlow5)
-                 + (fSlow6
-                    * (std::max<float>(((20.0f * std::log10(fRec4[0])) - fSlow12), 0.0f)
-                       * fSlow13)));
-            float fTemp4 = (fTemp1 * std::pow(10.0f, (0.0500000007f * fRec3[0])));
-            float fTemp5 = std::fabs(fTemp4);
-            float fTemp6 = ((fRec1[1] > fTemp5) ? fSlow11 : fSlow8);
-            fRec2[0]     = ((fRec2[1] * fTemp6) + (fTemp5 * (1.0f - fTemp6)));
-            fRec1[0]     = fRec2[0];
+            float fTemp3 = ((fTemp2 > fRec3[1]) ? fSlow8 : fSlow5);
+            fRec3[0]     = fTemp2 * (1.0f - fTemp3) + fRec3[1] * fTemp3;
+            fRec2[0] =
+                fSlow2
+                    * std::max<float>(
+                        20.0f * std::log10(std::max<float>(1.17549435e-38f, fRec3[0]))
+                            - fSlow9,
+                        0.0f)
+                    * fSlow13
+                + fSlow12 * fRec2[1];
+            float fTemp4 = fTemp1 * std::pow(10.0f, 0.0500000007f * fRec2[0]);
+            float fTemp5 = std::fabs(std::fabs(fTemp4));
+            float fTemp6 = ((fTemp5 > fRec1[1]) ? fSlow8 : fSlow5);
+            fRec1[0]     = fTemp5 * (1.0f - fTemp6) + fRec1[1] * fTemp6;
             fRec0[0] =
-                ((fSlow5 * fRec0[1])
-                 + (fSlow6
-                    * (std::max<float>(((20.0f * std::log10(fRec1[0])) - fSlow12), 0.0f)
-                       * fSlow13)));
+                fSlow2
+                    * std::max<float>(
+                        20.0f * std::log10(std::max<float>(1.17549435e-38f, fRec1[0]))
+                            - fSlow9,
+                        0.0f)
+                    * fSlow13
+                + fSlow12 * fRec0[1];
             fHbargraph0 = FAUSTFLOAT(
-                (20.0f * std::log10(std::pow(10.0f, (0.0500000007f * fRec0[0])))));
-            output0[i] = FAUSTFLOAT((iSlow0 ? fTemp0 : (fSlow1 * fTemp4)));
-            fRec5[1]   = fRec5[0];
-            fRec4[1]   = fRec4[0];
-            fRec3[1]   = fRec3[0];
-            fRec2[1]   = fRec2[0];
-            fRec1[1]   = fRec1[0];
-            fRec0[1]   = fRec0[0];
+                20.0f
+                * std::log10(std::max<float>(1.17549435e-38f,
+                                             std::pow(10.0f, 0.0500000007f * fRec0[0]))));
+            float fThen9 = fSlow1 * fTemp4;
+            output0[i0]  = FAUSTFLOAT(((iSlow0) ? fTemp0 : fThen9));
+            fRec3[1]     = fRec3[0];
+            fRec2[1]     = fRec2[0];
+            fRec1[1]     = fRec1[0];
+            fRec0[1]     = fRec0[0];
         }
     }
 };
index a24215e9b248145ec361daa1e856aac4b6a1a72c..6a71fc20c314aa50ac3672f3d1cb08870d1a706a 100644 (file)
@@ -277,14 +277,15 @@ void Feed::handleDownloadReadyRead()
         QString host = url.host();
         if (host.contains("github", Qt::CaseInsensitive) && url.hasQuery()) {
             QString query = url.query();
-            QRegExp rx("filename%3D(.*)(&|$)");
-            rx.setMinimal(true);
-            if (rx.indexIn(query) > -1) {
-                fileName = rx.cap(1);
+            QRegularExpression rx("filename%3D(.*?)(&|$)");
+            QRegularExpressionMatch match = rx.match(query);
+            if (match.hasMatch()) {
+                fileName = match.captured(1);
             }
         }
         // End workaround
-        int extensionPos = fileName.indexOf(QRegExp("(?:\\.tar)?\\.[a-zA-Z0-9]+$"));
+        int extensionPos =
+            fileName.indexOf(QRegularExpression("(?:\\.tar)?\\.[a-zA-Z0-9]+$"));
         if (extensionPos > -1) {
             fileName.insert(extensionPos, "-XXXXXX");
         }
index 0aa77d0c3959f83891d14176046a1d9530534b60..a15e2f595466a60e6d7cf8a1bb6a6956035fd681 100644 (file)
@@ -14,13 +14,14 @@ namespace dblsqd
  */
 SemVer::SemVer(QString version) : original(version), valid(false)
 {
-    QRegExp rx(getRegExp());
-    if (rx.indexIn(version) > -1) {
-        this->major      = rx.cap(1).toInt();
-        this->minor      = rx.cap(2).toInt();
-        this->patch      = rx.cap(3).toInt();
-        this->prerelease = rx.cap(4);
-        this->build      = rx.cap(5);
+    QRegularExpression rx(getRegExp());
+    QRegularExpressionMatch match = rx.match(version);
+    if (match.hasMatch()) {
+        this->major      = match.captured(1).toInt();
+        this->minor      = match.captured(2).toInt();
+        this->patch      = match.captured(3).toInt();
+        this->prerelease = match.captured(4);
+        this->build      = match.captured(5);
         this->valid      = true;
     } else {
         this->major      = 0;
index 18ebcdaa035409014d0dfa0432e011118dbddbb6..eb60a4e8bbf6f674c719b13fbe742f38e8c3826f 100644 (file)
@@ -2,7 +2,7 @@
 #define DBLSQD_SEMVER_H
 
 #include <QObject>
-#include <QRegExp>
+#include <QRegularExpression>
 
 namespace dblsqd
 {
index 23dabfaca1f864955fca0c8ac348431f1ddebe5e..f22c8f028e944288745af69471c2fdbed68e3982 100644 (file)
@@ -3,8 +3,9 @@ author: "Romain Michon"
 license: "LGPL"
 name: "freeverb"
 version: "0.0"
-Code generated with Faust 2.28.6 (https://faust.grame.fr)
-Compilation options: -lang cpp -inpl -scal -ftz 0
+Code generated with Faust 2.41.1 (https://faust.grame.fr)
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn freeverbdsp -es 1 -mcd 16
+-single -ftz 0
 ------------------------------------------------------------ */
 
 #ifndef __freeverbdsp_H__
@@ -17,23 +18,23 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 // aimed at creating a simple C++ header file (.h) containing a Faust DSP.
 // See the Makefile for how to use it.
 
-/************************** BEGIN dsp.h **************************/
-/************************************************************************
+/************************** BEGIN dsp.h ********************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -47,29 +48,111 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 #include <string>
 #include <vector>
 
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __export__
+#define __export__
+
+#define FAUSTVERSION "2.41.1"
+
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
+
+#ifdef _WIN32
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API    __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
+#else
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#else
+#define FAUST_API    __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
+#endif
+
+#endif
+
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
 
-struct UI;
-struct Meta;
+struct FAUST_API UI;
+struct FAUST_API Meta;
 
 /**
  * DSP memory manager.
  */
 
-struct dsp_memory_manager {
+struct FAUST_API dsp_memory_manager {
     virtual ~dsp_memory_manager() {}
 
+    /**
+     * Inform the Memory Manager with the number of expected memory zones.
+     * @param count - the number of expected memory zones
+     */
+    virtual void begin(size_t /*count*/) {}
+
+    /**
+     * Give the Memory Manager information on a given memory zone.
+     * @param size - the size in bytes of the memory zone
+     * @param reads - the number of Read access to the zone used to compute one frame
+     * @param writes - the number of Write access to the zone used to compute one frame
+     */
+    virtual void info(size_t /*size*/, size_t /*reads*/, size_t /*writes*/) {}
+
+    /**
+     * Inform the Memory Manager that all memory zones have been described,
+     * to possibly start a 'compute the best allocation strategy' step.
+     */
+    virtual void end() {}
+
+    /**
+     * Allocate a memory zone.
+     * @param size - the memory zone size in bytes
+     */
     virtual void* allocate(size_t size) = 0;
-    virtual void destroy(void* ptr)     = 0;
+
+    /**
+     * Destroy a memory zone.
+     * @param ptr - the memory zone pointer to be deallocated
+     */
+    virtual void destroy(void* ptr) = 0;
 };
 
 /**
  * Signal processor definition.
  */
 
-class dsp
+class FAUST_API dsp
 {
    public:
     dsp() {}
@@ -89,7 +172,7 @@ class dsp
      */
     virtual void buildUserInterface(UI* ui_interface) = 0;
 
-    /* Returns the sample rate currently used by the instance */
+    /* Return the sample rate currently used by the instance */
     virtual int getSampleRate() = 0;
 
     /**
@@ -97,28 +180,28 @@ class dsp
      * - static class 'classInit': static tables initialization
      * - 'instanceInit': constants and instance state initialization
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void init(int sample_rate) = 0;
 
     /**
      * Init instance state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceInit(int sample_rate) = 0;
 
     /**
      * Init instance constant state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceConstants(int sample_rate) = 0;
 
     /* Init default control parameters values */
     virtual void instanceResetUserInterface() = 0;
 
-    /* Init instance state (delay lines...) */
+    /* Init instance state (like delay lines...) but keep the control parameter values */
     virtual void instanceClear() = 0;
 
     /**
@@ -170,7 +253,7 @@ class dsp
  * Generic DSP decorator.
  */
 
-class decorator_dsp : public dsp
+class FAUST_API decorator_dsp : public dsp
 {
    protected:
     dsp* fDSP;
@@ -209,10 +292,11 @@ class decorator_dsp : public dsp
 };
 
 /**
- * DSP factory class.
+ * DSP factory class, used with LLVM and Interpreter backends
+ * to create DSP instances from a compiled DSP program.
  */
 
-class dsp_factory
+class FAUST_API dsp_factory
 {
    protected:
     // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
@@ -232,75 +316,114 @@ class dsp_factory
     virtual dsp_memory_manager* getMemoryManager()             = 0;
 };
 
-/**
- * On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
- * flags to avoid costly denormals.
- */
+// Denormal handling
 
-#ifdef __SSE__
+#if defined(__SSE__)
 #include <xmmintrin.h>
-#ifdef __SSE2__
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
+#endif
+
+class FAUST_API ScopedNoDenormals
+{
+   private:
+    intptr_t fpsr;
+
+    void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("msr fpcr, %0" : : "ri"(fpsr_aux));
+#elif defined(__SSE__)
+        _mm_setcsr(static_cast<uint32_t>(fpsr_aux));
+#endif
+    }
+
+    void getFpStatusRegister() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("mrs %0, fpcr" : "=r"(fpsr));
+#elif defined(__SSE__)
+        fpsr          = static_cast<intptr_t>(_mm_getcsr());
+#endif
+    }
+
+   public:
+    ScopedNoDenormals() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        intptr_t mask = (1 << 24 /* FZ */);
+#else
+#if defined(__SSE__)
+#if defined(__SSE2__)
+        intptr_t mask = 0x8040;
 #else
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
+        intptr_t mask = 0x8000;
 #endif
 #else
-#define AVOIDDENORMALS
+        intptr_t mask = 0x0000;
 #endif
-
 #endif
-/**************************  END  dsp.h **************************/
+        getFpStatusRegister();
+        setFpStatusRegister(fpsr | mask);
+    }
 
-/************************** BEGIN APIUI.h **************************/
-/************************************************************************
- FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
- ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
+    ~ScopedNoDenormals() noexcept { setFpStatusRegister(fpsr); }
+};
 
- This program 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 General Public License for more details.
+#define AVOIDDENORMALS ScopedNoDenormals();
 
- You should have received a copy of the GNU General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+#endif
 
- EXCEPTION : As a special exception, you may create a larger work
- that contains this FAUST architecture section and distribute
- that work under terms of your choice, so long as this FAUST
- architecture section is not modified.
- ************************************************************************/
+/************************** END dsp.h **************************/
+/************************** BEGIN APIUI.h *****************************
+FAUST Architecture File
+Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+---------------------------------------------------------------------
+This program 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 program 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 program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+EXCEPTION : As a special exception, you may create a larger work
+that contains this FAUST architecture section and distribute
+that work under terms of your choice, so long as this FAUST
+architecture section is not modified.
+************************************************************************/
 
 #ifndef API_UI_H
 #define API_UI_H
 
-#include <iostream>
+#include <stdio.h>
+
 #include <map>
 #include <sstream>
 #include <string>
 #include <vector>
 
-/************************** BEGIN meta.h **************************/
-/************************************************************************
+/************************** BEGIN meta.h *******************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -311,36 +434,40 @@ class dsp_factory
 #ifndef __meta__
 #define __meta__
 
-struct Meta {
-    virtual ~Meta(){};
+/**
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
+ (key, value) metadata.
+ */
+struct FAUST_API Meta {
+    virtual ~Meta() {}
     virtual void declare(const char* key, const char* value) = 0;
 };
 
 #endif
 /**************************  END  meta.h **************************/
-/************************** BEGIN UI.h **************************/
-/************************************************************************
+/************************** BEGIN UI.h *****************************
  FAUST Architecture File
- Copyright (C) 2003-2020 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __UI_H__
 #define __UI_H__
@@ -359,7 +486,7 @@ struct Meta {
 struct Soundfile;
 
 template<typename REAL>
-struct UIReal {
+struct FAUST_API UIReal {
     UIReal() {}
     virtual ~UIReal() {}
 
@@ -390,38 +517,41 @@ struct UIReal {
 
     // -- soundfiles
 
-    virtual void addSoundfile(const char* label, const char* filename,
-                              Soundfile** sf_zone) = 0;
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+                              Soundfile** /*sf_zone*/) = 0;
 
     // -- metadata declarations
 
     virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
+
+    // To be used by LLVM client
+    virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
 };
 
-struct UI : public UIReal<FAUSTFLOAT> {
+struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
     UI() {}
     virtual ~UI() {}
 };
 
 #endif
 /**************************  END  UI.h **************************/
-/************************** BEGIN PathBuilder.h **************************/
-/************************************************************************
+/************************** BEGIN PathBuilder.h **************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -429,10 +559,13 @@ struct UI : public UIReal<FAUSTFLOAT> {
  architecture section is not modified.
  ************************************************************************/
 
-#ifndef FAUST_PATHBUILDER_H
-#define FAUST_PATHBUILDER_H
+#ifndef __PathBuilder__
+#define __PathBuilder__
 
 #include <algorithm>
+#include <map>
+#include <regex>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -441,113 +574,266 @@ struct UI : public UIReal<FAUSTFLOAT> {
  * Helper class to build complete hierarchical path for UI items.
  ******************************************************************************/
 
-class PathBuilder
+class FAUST_API PathBuilder
 {
    protected:
     std::vector<std::string> fControlsLevel;
+    std::vector<std::string> fFullPaths;
+    std::map<std::string, std::string> fFull2Short;  // filled by computeShortNames()
+
+    /**
+     * @brief check if a character is acceptable for an ID
+     *
+     * @param c
+     * @return true is the character is acceptable for an ID
+     */
+    bool isIDChar(char c) const
+    {
+        return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+               || ((c >= '0') && (c <= '9'));
+    }
+
+    /**
+     * @brief remove all "/0x00" parts
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string remove0x00(const std::string& src) const
+    {
+        return std::regex_replace(src, std::regex("/0x00"), "");
+    }
+
+    /**
+     * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string str2ID(const std::string& src) const
+    {
+        std::string dst;
+        bool need_underscore = false;
+        for (char c : src) {
+            if (isIDChar(c) || (c == '/')) {
+                if (need_underscore) {
+                    dst.push_back('_');
+                    need_underscore = false;
+                }
+                dst.push_back(c);
+            } else {
+                need_underscore = true;
+            }
+        }
+        return dst;
+    }
+
+    /**
+     * @brief Keep only the last n slash-parts
+     *
+     * @param src
+     * @param n : 1 indicates the last slash-part
+     * @return modified string
+     */
+    std::string cut(const std::string& src, int n) const
+    {
+        std::string rdst;
+        for (int i = int(src.length()) - 1; i >= 0; i--) {
+            char c = src[i];
+            if (c != '/') {
+                rdst.push_back(c);
+            } else if (n == 1) {
+                std::string dst;
+                for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+                    dst.push_back(rdst[j]);
+                }
+                return dst;
+            } else {
+                n--;
+                rdst.push_back(c);
+            }
+        }
+        return src;
+    }
+
+    void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+    /**
+     * @brief Compute the mapping between full path and short names
+     */
+    void computeShortNames()
+    {
+        std::vector<std::string>
+            uniquePaths;  // all full paths transformed but made unique with a prefix
+        std::map<std::string, std::string>
+            unique2full;  // all full paths transformed but made unique with a prefix
+        char num_buffer[16];
+        int pnum = 0;
+
+        for (const auto& s : fFullPaths) {
+            sprintf(num_buffer, "%d", pnum++);
+            std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+            uniquePaths.push_back(u);
+            unique2full[u] = s;  // remember the full path associated to a unique path
+        }
+
+        std::map<std::string, int> uniquePath2level;  // map path to level
+        for (const auto& s : uniquePaths)
+            uniquePath2level[s] = 1;  // we init all levels to 1
+        bool have_collisions = true;
+
+        while (have_collisions) {
+            // compute collision list
+            std::set<std::string> collisionSet;
+            std::map<std::string, std::string> short2full;
+            have_collisions = false;
+            for (const auto& it : uniquePath2level) {
+                std::string u         = it.first;
+                int n                 = it.second;
+                std::string shortName = cut(u, n);
+                auto p                = short2full.find(shortName);
+                if (p == short2full.end()) {
+                    // no collision
+                    short2full[shortName] = u;
+                } else {
+                    // we have a collision, add the two paths to the collision set
+                    have_collisions = true;
+                    collisionSet.insert(u);
+                    collisionSet.insert(p->second);
+                }
+            }
+            for (const auto& s : collisionSet)
+                uniquePath2level[s]++;  // increase level of colliding path
+        }
+
+        for (const auto& it : uniquePath2level) {
+            std::string u               = it.first;
+            int n                       = it.second;
+            std::string shortName       = replaceCharList(cut(u, n), {'/'}, '_');
+            fFull2Short[unique2full[u]] = shortName;
+        }
+    }
+
+    std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+                                char ch2)
+    {
+        auto beg        = ch1.begin();
+        auto end        = ch1.end();
+        std::string res = str;
+        for (size_t i = 0; i < str.length(); ++i) {
+            if (std::find(beg, end, str[i]) != end)
+                res[i] = ch2;
+        }
+        return res;
+    }
 
    public:
     PathBuilder() {}
     virtual ~PathBuilder() {}
 
+    // Return true for the first level of groups
+    bool pushLabel(const std::string& label)
+    {
+        fControlsLevel.push_back(label);
+        return fControlsLevel.size() == 1;
+    }
+
+    // Return true for the last level of groups
+    bool popLabel()
+    {
+        fControlsLevel.pop_back();
+        return fControlsLevel.size() == 0;
+    }
+
     std::string buildPath(const std::string& label)
     {
         std::string res = "/";
         for (size_t i = 0; i < fControlsLevel.size(); i++) {
-            res += fControlsLevel[i];
-            res += "/";
+            res = res + fControlsLevel[i] + "/";
         }
         res += label;
-        std::replace(res.begin(), res.end(), ' ', '_');
-        return res;
-    }
-
-    std::string buildLabel(std::string label)
-    {
-        std::replace(label.begin(), label.end(), ' ', '_');
-        return label;
+        return replaceCharList(
+            res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
     }
-
-    void pushLabel(const std::string& label) { fControlsLevel.push_back(label); }
-    void popLabel() { fControlsLevel.pop_back(); }
 };
 
-#endif  // FAUST_PATHBUILDER_H
+#endif  // __PathBuilder__
 /**************************  END  PathBuilder.h **************************/
-/************************** BEGIN ValueConverter.h **************************/
-/************************************************************************
+/************************** BEGIN ValueConverter.h ********************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __ValueConverter__
 #define __ValueConverter__
 
 /***************************************************************************************
                                                               ValueConverter.h
                           (GRAME, Copyright 2015-2019)
+ ValueConverter.h
+ (GRAME, Copyright 2015-2019)
 
-Set of conversion objects used to map user interface values (for example a gui slider
-delivering values between 0 and 1) to faust values (for example a vslider between
-20 and 20000) using a log scale.
+ Set of conversion objects used to map user interface values (for example a gui slider
+ delivering values between 0 and 1) to faust values (for example a vslider between
+ 20 and 20000) using a log scale.
 
--- Utilities
+ -- Utilities
 
-Range(lo,hi) : clip a value x between lo and hi
-Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
+ Range(lo,hi) : clip a value x between lo and hi
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
 v2 Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1
 vm v2
 
--- Value Converters
+ -- Value Converters
 
-ValueConverter::ui2faust(x)
-ValueConverter::faust2ui(x)
+ ValueConverter::ui2faust(x)
+ ValueConverter::faust2ui(x)
 
--- ValueConverters used for sliders depending of the scale
+ -- ValueConverters used for sliders depending of the scale
 
-LinearValueConverter(umin, umax, fmin, fmax)
-LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
-LogValueConverter(umin, umax, fmin, fmax)
-ExpValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
+ LogValueConverter(umin, umax, fmin, fmax)
+ ExpValueConverter(umin, umax, fmin, fmax)
 
--- ValueConverters used for accelerometers based on 3 points
+ -- ValueConverters used for accelerometers based on 3 points
 
-AccUpConverter(amin, amid, amax, fmin, fmid, fmax)             -- curve 0
-AccDownConverter(amin, amid, amax, fmin, fmid, fmax)   -- curve 1
-AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 2
-AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 3
+ AccUpConverter(amin, amid, amax, fmin, fmid, fmax)        -- curve 0
+ AccDownConverter(amin, amid, amax, fmin, fmid, fmax)      -- curve 1
+ AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 2
+ AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 3
 
--- lists of ZoneControl are used to implement accelerometers metadata for each axes
+ -- lists of ZoneControl are used to implement accelerometers metadata for each axes
 
-ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
+ ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
 
--- ZoneReader are used to implement screencolor metadata
+ -- ZoneReader are used to implement screencolor metadata
 
-ZoneReader(zone, valueConverter) : a zone with a data converter
+ ZoneReader(zone, valueConverter) : a zone with a data converter
 
 ****************************************************************************************/
 
+#include <assert.h>
+#include <float.h>
+
 #include <algorithm>  // std::max
-#include <cassert>
-#include <cfloat>
 #include <cmath>
 #include <vector>
 
@@ -555,12 +841,12 @@ ZoneReader(zone, valueConverter) : a zone with a data converter
 // Interpolator(lo,hi,v1,v2)
 // Maps a value x between lo and hi to a value y between v1 and v2
 // y = v1 + (x-lo)/(hi-lo)*(v2-v1)
-// y = v1 + (x-lo) * coef              with coef = (v2-v1)/(hi-lo)
+// y = v1 + (x-lo) * coef           with coef = (v2-v1)/(hi-lo)
 // y = v1 + x*coef - lo*coef
 // y = v1 - lo*coef + x*coef
-// y = offset + x*coef                         with offset = v1 - lo*coef
+// y = offset + x*coef              with offset = v1 - lo*coef
 //--------------------------------------------------------------------------------------
-class Interpolator
+class FAUST_API Interpolator
 {
    private:
     //--------------------------------------------------------------------------------------
@@ -611,7 +897,7 @@ class Interpolator
 // Interpolator3pt(lo,mi,hi,v1,vm,v2)
 // Map values between lo mid hi to values between v1 vm v2
 //--------------------------------------------------------------------------------------
-class Interpolator3pt
+class FAUST_API Interpolator3pt
 {
    private:
     Interpolator fSegment1;
@@ -635,19 +921,19 @@ class Interpolator3pt
 //--------------------------------------------------------------------------------------
 // Abstract ValueConverter class. Converts values between UI and Faust representations
 //--------------------------------------------------------------------------------------
-class ValueConverter
+class FAUST_API ValueConverter
 {
    public:
     virtual ~ValueConverter() {}
-    virtual double ui2faust(double x) = 0;
-    virtual double faust2ui(double x) = 0;
+    virtual double ui2faust(double x) { return x; };
+    virtual double faust2ui(double x) { return x; };
 };
 
 //--------------------------------------------------------------------------------------
 // A converter than can be updated
 //--------------------------------------------------------------------------------------
 
-class UpdatableValueConverter : public ValueConverter
+class FAUST_API UpdatableValueConverter : public ValueConverter
 {
    protected:
     bool fActive;
@@ -667,7 +953,7 @@ class UpdatableValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter : public ValueConverter
+class FAUST_API LinearValueConverter : public ValueConverter
 {
    private:
     Interpolator fUI2F;
@@ -687,7 +973,7 @@ class LinearValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Two segments linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter2 : public UpdatableValueConverter
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fUI2F;
@@ -723,7 +1009,7 @@ class LinearValueConverter2 : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Logarithmic conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LogValueConverter : public LinearValueConverter
+class FAUST_API LogValueConverter : public LinearValueConverter
 {
    public:
     LogValueConverter(double umin, double umax, double fmin, double fmax)
@@ -745,7 +1031,7 @@ class LogValueConverter : public LinearValueConverter
 //--------------------------------------------------------------------------------------
 // Exponential conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class ExpValueConverter : public LinearValueConverter
+class FAUST_API ExpValueConverter : public LinearValueConverter
 {
    public:
     ExpValueConverter(double umin, double umax, double fmin, double fmax)
@@ -768,7 +1054,7 @@ class ExpValueConverter : public LinearValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up curve (curve 0)
 //--------------------------------------------------------------------------------------
-class AccUpConverter : public UpdatableValueConverter
+class FAUST_API AccUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -804,7 +1090,7 @@ class AccUpConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down curve (curve 1)
 //--------------------------------------------------------------------------------------
-class AccDownConverter : public UpdatableValueConverter
+class FAUST_API AccDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -840,15 +1126,15 @@ class AccDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up-Down curve (curve 2)
 //--------------------------------------------------------------------------------------
-class AccUpDownConverter : public UpdatableValueConverter
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccUpDownConverter(double amin, double amid, double amax, double fmin,
-                       double /*fmid*/, double fmax)
+    AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
+                       double fmax)
         : fA2F(amin, amid, amax, fmin, fmax, fmin)
         , fF2A(fmin, fmax, amin,
                amax)  // Special, pseudo inverse of a non monotonic function
@@ -877,15 +1163,15 @@ class AccUpDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down-Up curve (curve 3)
 //--------------------------------------------------------------------------------------
-class AccDownUpConverter : public UpdatableValueConverter
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccDownUpConverter(double amin, double amid, double amax, double fmin,
-                       double /*fmid*/, double fmax)
+    AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
+                       double fmax)
         : fA2F(amin, amid, amax, fmax, fmin, fmax)
         , fF2A(fmin, fmax, amin,
                amax)  // Special, pseudo inverse of a non monotonic function
@@ -913,7 +1199,7 @@ class AccDownUpConverter : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Base class for ZoneControl
 //--------------------------------------------------------------------------------------
-class ZoneControl
+class FAUST_API ZoneControl
 {
    protected:
     FAUSTFLOAT* fZone;
@@ -924,9 +1210,8 @@ class ZoneControl
 
     virtual void update(double /*v*/) const {}
 
-    virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
-                                  double /*amax*/, double /*min*/, double /*init*/,
-                                  double /*max*/)
+    virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
+                                  double /*min*/, double /*init*/, double /*max*/)
     {
     }
     virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
@@ -942,7 +1227,7 @@ class ZoneControl
 //--------------------------------------------------------------------------------------
 //  Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class ConverterZoneControl : public ZoneControl
+class FAUST_API ConverterZoneControl : public ZoneControl
 {
    protected:
     ValueConverter* fValueConverter;
@@ -957,7 +1242,10 @@ class ConverterZoneControl : public ZoneControl
         delete fValueConverter;
     }  // Assuming fValueConverter is not kept elsewhere...
 
-    virtual void update(double v) const { *fZone = fValueConverter->ui2faust(v); }
+    virtual void update(double v) const
+    {
+        *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v));
+    }
 
     ValueConverter* getConverter() { return fValueConverter; }
 };
@@ -966,7 +1254,7 @@ class ConverterZoneControl : public ZoneControl
 // Association of a zone and a four value converter, each one for each possible curve.
 // Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class CurveZoneControl : public ZoneControl
+class FAUST_API CurveZoneControl : public ZoneControl
 {
    private:
     std::vector<UpdatableValueConverter*> fValueConverters;
@@ -989,15 +1277,14 @@ class CurveZoneControl : public ZoneControl
     }
     virtual ~CurveZoneControl()
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            delete (*it);
+        for (const auto& it : fValueConverters) {
+            delete it;
         }
     }
     void update(double v) const
     {
         if (fValueConverters[fCurve]->getActive())
-            *fZone = fValueConverters[fCurve]->ui2faust(v);
+            *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v));
     }
 
     void setMappingValues(int curve, double amin, double amid, double amax, double min,
@@ -1014,16 +1301,15 @@ class CurveZoneControl : public ZoneControl
 
     void setActive(bool on_off)
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            (*it)->setActive(on_off);
+        for (const auto& it : fValueConverters) {
+            it->setActive(on_off);
         }
     }
 
     int getCurve() { return fCurve; }
 };
 
-class ZoneReader
+class FAUST_API ZoneReader
 {
    private:
     FAUSTFLOAT* fZone;
@@ -1043,6 +1329,8 @@ class ZoneReader
 #endif
 /**************************  END  ValueConverter.h **************************/
 
+typedef unsigned int uint;
+
 class APIUI
     : public PathBuilder
     , public Meta
@@ -1058,22 +1346,42 @@ class APIUI
         kHBargraph,
         kVBargraph
     };
+    enum Type { kAcc = 0, kGyr = 1, kNoType };
 
    protected:
-    enum { kLin = 0, kLog = 1, kExp = 2 };
-
-    int fNumParameters;
-    std::vector<std::string> fPaths;
-    std::vector<std::string> fLabels;
-    std::map<std::string, int> fPathMap;
-    std::map<std::string, int> fLabelMap;
-    std::vector<ValueConverter*> fConversion;
-    std::vector<FAUSTFLOAT*> fZone;
-    std::vector<FAUSTFLOAT> fInit;
-    std::vector<FAUSTFLOAT> fMin;
-    std::vector<FAUSTFLOAT> fMax;
-    std::vector<FAUSTFLOAT> fStep;
-    std::vector<ItemType> fItemType;
+    enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+    struct Item {
+        std::string fLabel;
+        std::string fShortname;
+        std::string fPath;
+        ValueConverter* fConversion;
+        FAUSTFLOAT* fZone;
+        FAUSTFLOAT fInit;
+        FAUSTFLOAT fMin;
+        FAUSTFLOAT fMax;
+        FAUSTFLOAT fStep;
+        ItemType fItemType;
+
+        Item(const std::string& label, const std::string& short_name,
+             const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+             FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+             ItemType item_type)
+            : fLabel(label)
+            , fShortname(short_name)
+            , fPath(path)
+            , fConversion(conversion)
+            , fZone(zone)
+            , fInit(init)
+            , fMin(min)
+            , fMax(max)
+            , fStep(step)
+            , fItemType(item_type)
+        {
+        }
+    };
+    std::vector<Item> fItems;
+
     std::vector<std::map<std::string, std::string> > fMetaData;
     std::vector<ZoneControl*> fAcc[3];
     std::vector<ZoneControl*> fGyr[3];
@@ -1100,33 +1408,31 @@ class APIUI
                               ItemType type)
     {
         std::string path = buildPath(label);
-        fPathMap[path] = fLabelMap[label] = fNumParameters++;
-        fPaths.push_back(path);
-        fLabels.push_back(label);
-        fZone.push_back(zone);
-        fInit.push_back(init);
-        fMin.push_back(min);
-        fMax.push_back(max);
-        fStep.push_back(step);
-        fItemType.push_back(type);
+        fFullPaths.push_back(path);
 
         // handle scale metadata
+        ValueConverter* converter = nullptr;
         switch (fCurrentScale) {
         case kLin:
-            fConversion.push_back(new LinearValueConverter(0, 1, min, max));
+            converter = new LinearValueConverter(0, 1, min, max);
             break;
         case kLog:
-            fConversion.push_back(new LogValueConverter(0, 1, min, max));
+            converter = new LogValueConverter(0, 1, min, max);
             break;
         case kExp:
-            fConversion.push_back(new ExpValueConverter(0, 1, min, max));
+            converter = new ExpValueConverter(0, 1, min, max);
             break;
         }
         fCurrentScale = kLin;
 
+        fItems.push_back(
+            Item(label, "", path, converter, zone, init, min, max, step, type));
+
         if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
-            std::cerr << "warning : 'acc' and 'gyr' metadata used for the same " << label
-                      << " parameter !!\n";
+            fprintf(
+                stderr,
+                "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n",
+                label);
         }
 
         // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
@@ -1141,7 +1447,7 @@ class APIUI
                 fAcc[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect acc metadata : " << fCurrentAcc << std::endl;
+                fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
             }
             fCurrentAcc = "";
         }
@@ -1158,31 +1464,31 @@ class APIUI
                 fGyr[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect gyr metadata : " << fCurrentGyr << std::endl;
+                fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
             }
             fCurrentGyr = "";
         }
 
         // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
         if (fCurrentColor.size() > 0) {
-            if ((fCurrentColor == "red") && (fRedReader == 0)) {
+            if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "green") && (fGreenReader == 0)) {
+            } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "blue") && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "white") && (fRedReader == 0)
-                       && (fGreenReader == 0) && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "white") && (fRedReader == nullptr)
+                       && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
             } else {
-                std::cerr << "incorrect screencolor metadata : " << fCurrentColor
-                          << std::endl;
+                fprintf(stderr, "incorrect screencolor metadata : %s \n",
+                        fCurrentColor.c_str());
             }
         }
         fCurrentColor = "";
@@ -1193,7 +1499,7 @@ class APIUI
 
     int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
     {
-        FAUSTFLOAT* zone = fZone[p];
+        FAUSTFLOAT* zone = fItems[uint(p)].fZone;
         for (size_t i = 0; i < table[val].size(); i++) {
             if (zone == table[val][i]->getZone())
                 return int(i);
@@ -1210,11 +1516,11 @@ class APIUI
 
         // Deactivates everywhere..
         if (id1 != -1)
-            table[0][id1]->setActive(false);
+            table[0][uint(id1)]->setActive(false);
         if (id2 != -1)
-            table[1][id2]->setActive(false);
+            table[1][uint(id2)]->setActive(false);
         if (id3 != -1)
-            table[2][id3]->setActive(false);
+            table[2][uint(id3)]->setActive(false);
 
         if (val == -1) {  // Means: no more mapping...
             // So stay all deactivated...
@@ -1222,14 +1528,16 @@ class APIUI
             int id4 = getZoneIndex(table, p, val);
             if (id4 != -1) {
                 // Reactivate the one we edit...
-                table[val][id4]->setMappingValues(curve, amin, amid, amax, fMin[p],
-                                                  fInit[p], fMax[p]);
-                table[val][id4]->setActive(true);
+                table[val][uint(id4)]->setMappingValues(
+                    curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit,
+                    fItems[uint(p)].fMax);
+                table[val][uint(id4)]->setActive(true);
             } else {
                 // Allocate a new CurveZoneControl which is 'active' by default
-                FAUSTFLOAT* zone = fZone[p];
-                table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax,
-                                                          fMin[p], fInit[p], fMax[p]));
+                FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+                table[val].push_back(new CurveZoneControl(
+                    zone, curve, amin, amid, amax, fItems[uint(p)].fMin,
+                    fItems[uint(p)].fInit, fItems[uint(p)].fMax));
             }
         }
     }
@@ -1243,16 +1551,16 @@ class APIUI
 
         if (id1 != -1) {
             val   = 0;
-            curve = table[val][id1]->getCurve();
-            table[val][id1]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id1)]->getCurve();
+            table[val][uint(id1)]->getMappingValues(amin, amid, amax);
         } else if (id2 != -1) {
             val   = 1;
-            curve = table[val][id2]->getCurve();
-            table[val][id2]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id2)]->getCurve();
+            table[val][uint(id2)]->getMappingValues(amin, amid, amax);
         } else if (id3 != -1) {
             val   = 2;
-            curve = table[val][id3]->getCurve();
-            table[val][id3]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id3)]->getCurve();
+            table[val][uint(id3)]->getMappingValues(amin, amid, amax);
         } else {
             val   = -1;  // No mapping
             curve = 0;
@@ -1263,26 +1571,23 @@ class APIUI
     }
 
    public:
-    enum Type { kAcc = 0, kGyr = 1, kNoType };
-
     APIUI()
-        : fNumParameters(0)
-        , fHasScreenControl(false)
-        , fRedReader(0)
-        , fGreenReader(0)
-        , fBlueReader(0)
+        : fHasScreenControl(false)
+        , fRedReader(nullptr)
+        , fGreenReader(nullptr)
+        , fBlueReader(nullptr)
         , fCurrentScale(kLin)
     {
     }
 
     virtual ~APIUI()
     {
-        for (auto& it : fConversion)
-            delete it;
+        for (const auto& it : fItems)
+            delete it.fConversion;
         for (int i = 0; i < 3; i++) {
-            for (auto& it : fAcc[i])
+            for (const auto& it : fAcc[i])
                 delete it;
-            for (auto& it : fGyr[i])
+            for (const auto& it : fGyr[i])
                 delete it;
         }
         delete fRedReader;
@@ -1295,7 +1600,18 @@ class APIUI
     virtual void openTabBox(const char* label) { pushLabel(label); }
     virtual void openHorizontalBox(const char* label) { pushLabel(label); }
     virtual void openVerticalBox(const char* label) { pushLabel(label); }
-    virtual void closeBox() { popLabel(); }
+    virtual void closeBox()
+    {
+        if (popLabel()) {
+            // Shortnames can be computed when all fullnames are known
+            computeShortNames();
+            // Fill 'shortname' field for each item
+            for (const auto& it : fFull2Short) {
+                int index                = getParamIndex(it.first.c_str());
+                fItems[index].fShortname = it.second;
+            }
+        }
+    }
 
     // -- active widgets
 
@@ -1332,13 +1648,13 @@ class APIUI
     virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone,
                                        FAUSTFLOAT min, FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kHBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kHBargraph);
     }
 
     virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min,
                                      FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kVBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kVBargraph);
     }
 
     // -- soundfiles
@@ -1381,23 +1697,25 @@ class APIUI
     //-------------------------------------------------------------------------------
     // Simple API part
     //-------------------------------------------------------------------------------
-    int getParamsCount() { return fNumParameters; }
-    int getParamIndex(const char* path)
+    int getParamsCount() { return int(fItems.size()); }
+
+    int getParamIndex(const char* path_aux)
     {
-        if (fPathMap.find(path) != fPathMap.end()) {
-            return fPathMap[path];
-        } else if (fLabelMap.find(path) != fLabelMap.end()) {
-            return fLabelMap[path];
-        } else {
-            return -1;
-        }
+        std::string path = std::string(path_aux);
+        auto it          = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+            return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+                 });
+        return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
     }
-    const char* getParamAddress(int p) { return fPaths[p].c_str(); }
-    const char* getParamLabel(int p) { return fLabels[p].c_str(); }
+
+    const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
+    const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
+    const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+
     std::map<const char*, const char*> getMetadata(int p)
     {
         std::map<const char*, const char*> res;
-        std::map<std::string, std::string> metadata = fMetaData[p];
+        std::map<std::string, std::string> metadata = fMetaData[uint(p)];
         for (const auto& it : metadata) {
             res[it.first.c_str()] = it.second.c_str();
         }
@@ -1406,26 +1724,62 @@ class APIUI
 
     const char* getMetadata(int p, const char* key)
     {
-        return (fMetaData[p].find(key) != fMetaData[p].end()) ? fMetaData[p][key].c_str()
-                                                              : "";
+        return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end())
+                   ? fMetaData[uint(p)][key].c_str()
+                   : "";
     }
-    FAUSTFLOAT getParamMin(int p) { return fMin[p]; }
-    FAUSTFLOAT getParamMax(int p) { return fMax[p]; }
-    FAUSTFLOAT getParamStep(int p) { return fStep[p]; }
-    FAUSTFLOAT getParamInit(int p) { return fInit[p]; }
+    FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
+    FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
+    FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
+    FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
+
+    FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
 
-    FAUSTFLOAT* getParamZone(int p) { return fZone[p]; }
-    FAUSTFLOAT getParamValue(int p) { return *fZone[p]; }
-    void setParamValue(int p, FAUSTFLOAT v) { *fZone[p] = v; }
+    FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
+    FAUSTFLOAT getParamValue(const char* path)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            return getParamValue(index);
+        } else {
+            fprintf(stderr, "getParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+            return FAUSTFLOAT(0);
+        }
+    }
 
-    double getParamRatio(int p) { return fConversion[p]->faust2ui(*fZone[p]); }
-    void setParamRatio(int p, double r) { *fZone[p] = fConversion[p]->ui2faust(r); }
+    void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+    void setParamValue(const char* path, FAUSTFLOAT v)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            setParamValue(index, v);
+        } else {
+            fprintf(stderr, "setParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+        }
+    }
 
-    double value2ratio(int p, double r) { return fConversion[p]->faust2ui(r); }
-    double ratio2value(int p, double r) { return fConversion[p]->ui2faust(r); }
+    double getParamRatio(int p)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone);
+    }
+    void setParamRatio(int p, double r)
+    {
+        *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r));
+    }
+
+    double value2ratio(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(r);
+    }
+    double ratio2value(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->ui2faust(r);
+    }
 
     /**
-     * Return the control type (kAcc, kGyr, or -1) for a given parameter
+     * Return the control type (kAcc, kGyr, or -1) for a given parameter.
      *
      * @param p - the UI parameter index
      *
@@ -1447,13 +1801,13 @@ class APIUI
 
     /**
      * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry,
-     * kHBargraph, kVBargraph) for a given parameter
+     * kHBargraph, kVBargraph) for a given parameter.
      *
      * @param p - the UI parameter index
      *
      * @return the Item type
      */
-    ItemType getParamItemType(int p) { return fItemType[p]; }
+    ItemType getParamItemType(int p) { return fItems[uint(p)].fItemType; }
 
     /**
      * Set a new value coming from an accelerometer, propagate it to all relevant
@@ -1493,7 +1847,7 @@ class APIUI
      * given UI parameter.
      *
      * @param p - the UI parameter index
-     * @param acc - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+     * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
      * mapping")
      * @param curve - between 0 and 3
      * @param amin - mapping 'min' point
@@ -1558,7 +1912,7 @@ class APIUI
     }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer
+     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
      *
      * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
      * @return the number of zones
@@ -1567,7 +1921,7 @@ class APIUI
     int getAccCount(int acc) { return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0; }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope
+     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
      *
      * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
      * @param the number of zones
@@ -1604,8 +1958,11 @@ class APIUI
 #define FAUSTFLOAT float
 #endif
 
+#include <math.h>
+
 #include <algorithm>
 #include <cmath>
+#include <cstdint>
 
 #ifndef FAUSTCLASS
 #define FAUSTCLASS freeverbdsp
@@ -1616,18 +1973,23 @@ class APIUI
 #define exp10  __exp10
 #endif
 
+#if defined(_WIN32)
+#define RESTRICT __restrict
+#else
+#define RESTRICT __restrict__
+#endif
+
 class freeverbdsp : public dsp
 {
    private:
     int fSampleRate;
-    float fConst0;
     float fConst1;
     FAUSTFLOAT fVslider0;
     float fConst2;
     FAUSTFLOAT fVslider1;
     float fRec9[2];
     FAUSTFLOAT fVslider2;
-    int IOTA;
+    int IOTA0;
     float fVec0[8192];
     int iConst3;
     float fRec8[2];
@@ -1714,6 +2076,9 @@ class freeverbdsp : public dsp
     void metadata(Meta* m)
     {
         m->declare("author", "Romain Michon");
+        m->declare("compile_options",
+                   "-a faust2header.cpp -lang cpp -i -inpl -cn freeverbdsp -es 1 -mcd 16 "
+                   "-single -ftz 0");
         m->declare("delays.lib/name", "Faust Delay Library");
         m->declare("delays.lib/version", "0.1");
         m->declare("description",
@@ -1727,86 +2092,52 @@ class freeverbdsp : public dsp
         m->declare("filters.lib/allpass_comb:license", "MIT-style STK-4.3 license");
         m->declare("filters.lib/lowpass0_highpass1", "MIT-style STK-4.3 license");
         m->declare("filters.lib/name", "Faust Filters Library");
+        m->declare("filters.lib/version", "0.3");
         m->declare("license", "LGPL");
         m->declare("maths.lib/author", "GRAME");
         m->declare("maths.lib/copyright", "GRAME");
         m->declare("maths.lib/license", "LGPL with exception");
         m->declare("maths.lib/name", "Faust Math Library");
-        m->declare("maths.lib/version", "2.3");
+        m->declare("maths.lib/version", "2.5");
         m->declare("name", "freeverb");
         m->declare("platform.lib/name", "Generic Platform Library");
-        m->declare("platform.lib/version", "0.1");
+        m->declare("platform.lib/version", "0.2");
+        m->declare("reverbs.lib/mono_freeverb:author", "Romain Michon");
         m->declare("reverbs.lib/name", "Faust Reverb Library");
-        m->declare("reverbs.lib/version", "0.0");
+        m->declare("reverbs.lib/stereo_freeverb:author", "Romain Michon");
+        m->declare("reverbs.lib/version", "0.2");
         m->declare("version", "0.0");
     }
 
     virtual int getNumInputs() { return 2; }
     virtual int getNumOutputs() { return 2; }
-    virtual int getInputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        case 1: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
-    virtual int getOutputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        case 1: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
 
     static void classInit(int /*sample_rate*/) {}
 
     virtual void instanceConstants(int sample_rate)
     {
         fSampleRate = sample_rate;
-        fConst0  = std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
-        fConst1  = (12348.0f / fConst0);
-        fConst2  = (17640.0f / fConst0);
-        iConst3  = int((0.0253061224f * fConst0));
-        iConst4  = int((0.0269387756f * fConst0));
-        iConst5  = int((0.0289569162f * fConst0));
-        iConst6  = int((0.0307482984f * fConst0));
-        iConst7  = int((0.0322448984f * fConst0));
-        iConst8  = int((0.033809524f * fConst0));
-        iConst9  = int((0.0353061222f * fConst0));
-        iConst10 = int((0.0366666652f * fConst0));
-        iConst11 = int((0.0126077095f * fConst0));
-        iConst12 = std::min<int>(1024, std::max<int>(0, (iConst11 + -1)));
-        iConst13 = int((0.00999999978f * fConst0));
-        iConst14 = std::min<int>(1024, std::max<int>(0, (iConst13 + -1)));
-        iConst15 = int((0.00773242628f * fConst0));
-        iConst16 = std::min<int>(1024, std::max<int>(0, (iConst15 + -1)));
-        iConst17 = int((0.00510204071f * fConst0));
-        iConst18 = std::min<int>(1024, std::max<int>(0, (iConst17 + -1)));
-        fConst19 = (0.00104308384f * fConst0);
+        float fConst0 =
+            std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
+        fConst1  = 12348.0f / fConst0;
+        fConst2  = 17640.0f / fConst0;
+        iConst3  = int(0.0253061224f * fConst0);
+        iConst4  = int(0.0269387756f * fConst0);
+        iConst5  = int(0.0289569162f * fConst0);
+        iConst6  = int(0.0307482984f * fConst0);
+        iConst7  = int(0.0322448984f * fConst0);
+        iConst8  = int(0.033809524f * fConst0);
+        iConst9  = int(0.0353061222f * fConst0);
+        iConst10 = int(0.0366666652f * fConst0);
+        iConst11 = int(0.0126077095f * fConst0);
+        iConst12 = std::min<int>(1024, std::max<int>(0, iConst11 + -1));
+        iConst13 = int(0.00999999978f * fConst0);
+        iConst14 = std::min<int>(1024, std::max<int>(0, iConst13 + -1));
+        iConst15 = int(0.00773242628f * fConst0);
+        iConst16 = std::min<int>(1024, std::max<int>(0, iConst15 + -1));
+        iConst17 = int(0.00510204071f * fConst0);
+        iConst18 = std::min<int>(1024, std::max<int>(0, iConst17 + -1));
+        fConst19 = 0.00104308384f * fConst0;
     }
 
     virtual void instanceResetUserInterface()
@@ -1819,197 +2150,197 @@ class freeverbdsp : public dsp
 
     virtual void instanceClear()
     {
-        for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
+        for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
             fRec9[l0] = 0.0f;
         }
-        IOTA = 0;
-        for (int l1 = 0; (l1 < 8192); l1 = (l1 + 1)) {
+        IOTA0 = 0;
+        for (int l1 = 0; l1 < 8192; l1 = l1 + 1) {
             fVec0[l1] = 0.0f;
         }
-        for (int l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
+        for (int l2 = 0; l2 < 2; l2 = l2 + 1) {
             fRec8[l2] = 0.0f;
         }
-        for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) {
+        for (int l3 = 0; l3 < 2; l3 = l3 + 1) {
             fRec11[l3] = 0.0f;
         }
-        for (int l4 = 0; (l4 < 8192); l4 = (l4 + 1)) {
+        for (int l4 = 0; l4 < 8192; l4 = l4 + 1) {
             fVec1[l4] = 0.0f;
         }
-        for (int l5 = 0; (l5 < 2); l5 = (l5 + 1)) {
+        for (int l5 = 0; l5 < 2; l5 = l5 + 1) {
             fRec10[l5] = 0.0f;
         }
-        for (int l6 = 0; (l6 < 2); l6 = (l6 + 1)) {
+        for (int l6 = 0; l6 < 2; l6 = l6 + 1) {
             fRec13[l6] = 0.0f;
         }
-        for (int l7 = 0; (l7 < 8192); l7 = (l7 + 1)) {
+        for (int l7 = 0; l7 < 8192; l7 = l7 + 1) {
             fVec2[l7] = 0.0f;
         }
-        for (int l8 = 0; (l8 < 2); l8 = (l8 + 1)) {
+        for (int l8 = 0; l8 < 2; l8 = l8 + 1) {
             fRec12[l8] = 0.0f;
         }
-        for (int l9 = 0; (l9 < 2); l9 = (l9 + 1)) {
+        for (int l9 = 0; l9 < 2; l9 = l9 + 1) {
             fRec15[l9] = 0.0f;
         }
-        for (int l10 = 0; (l10 < 8192); l10 = (l10 + 1)) {
+        for (int l10 = 0; l10 < 8192; l10 = l10 + 1) {
             fVec3[l10] = 0.0f;
         }
-        for (int l11 = 0; (l11 < 2); l11 = (l11 + 1)) {
+        for (int l11 = 0; l11 < 2; l11 = l11 + 1) {
             fRec14[l11] = 0.0f;
         }
-        for (int l12 = 0; (l12 < 2); l12 = (l12 + 1)) {
+        for (int l12 = 0; l12 < 2; l12 = l12 + 1) {
             fRec17[l12] = 0.0f;
         }
-        for (int l13 = 0; (l13 < 8192); l13 = (l13 + 1)) {
+        for (int l13 = 0; l13 < 8192; l13 = l13 + 1) {
             fVec4[l13] = 0.0f;
         }
-        for (int l14 = 0; (l14 < 2); l14 = (l14 + 1)) {
+        for (int l14 = 0; l14 < 2; l14 = l14 + 1) {
             fRec16[l14] = 0.0f;
         }
-        for (int l15 = 0; (l15 < 2); l15 = (l15 + 1)) {
+        for (int l15 = 0; l15 < 2; l15 = l15 + 1) {
             fRec19[l15] = 0.0f;
         }
-        for (int l16 = 0; (l16 < 8192); l16 = (l16 + 1)) {
+        for (int l16 = 0; l16 < 8192; l16 = l16 + 1) {
             fVec5[l16] = 0.0f;
         }
-        for (int l17 = 0; (l17 < 2); l17 = (l17 + 1)) {
+        for (int l17 = 0; l17 < 2; l17 = l17 + 1) {
             fRec18[l17] = 0.0f;
         }
-        for (int l18 = 0; (l18 < 2); l18 = (l18 + 1)) {
+        for (int l18 = 0; l18 < 2; l18 = l18 + 1) {
             fRec21[l18] = 0.0f;
         }
-        for (int l19 = 0; (l19 < 8192); l19 = (l19 + 1)) {
+        for (int l19 = 0; l19 < 8192; l19 = l19 + 1) {
             fVec6[l19] = 0.0f;
         }
-        for (int l20 = 0; (l20 < 2); l20 = (l20 + 1)) {
+        for (int l20 = 0; l20 < 2; l20 = l20 + 1) {
             fRec20[l20] = 0.0f;
         }
-        for (int l21 = 0; (l21 < 2); l21 = (l21 + 1)) {
+        for (int l21 = 0; l21 < 2; l21 = l21 + 1) {
             fRec23[l21] = 0.0f;
         }
-        for (int l22 = 0; (l22 < 8192); l22 = (l22 + 1)) {
+        for (int l22 = 0; l22 < 8192; l22 = l22 + 1) {
             fVec7[l22] = 0.0f;
         }
-        for (int l23 = 0; (l23 < 2); l23 = (l23 + 1)) {
+        for (int l23 = 0; l23 < 2; l23 = l23 + 1) {
             fRec22[l23] = 0.0f;
         }
-        for (int l24 = 0; (l24 < 2048); l24 = (l24 + 1)) {
+        for (int l24 = 0; l24 < 2048; l24 = l24 + 1) {
             fVec8[l24] = 0.0f;
         }
-        for (int l25 = 0; (l25 < 2); l25 = (l25 + 1)) {
+        for (int l25 = 0; l25 < 2; l25 = l25 + 1) {
             fRec6[l25] = 0.0f;
         }
-        for (int l26 = 0; (l26 < 2048); l26 = (l26 + 1)) {
+        for (int l26 = 0; l26 < 2048; l26 = l26 + 1) {
             fVec9[l26] = 0.0f;
         }
-        for (int l27 = 0; (l27 < 2); l27 = (l27 + 1)) {
+        for (int l27 = 0; l27 < 2; l27 = l27 + 1) {
             fRec4[l27] = 0.0f;
         }
-        for (int l28 = 0; (l28 < 2048); l28 = (l28 + 1)) {
+        for (int l28 = 0; l28 < 2048; l28 = l28 + 1) {
             fVec10[l28] = 0.0f;
         }
-        for (int l29 = 0; (l29 < 2); l29 = (l29 + 1)) {
+        for (int l29 = 0; l29 < 2; l29 = l29 + 1) {
             fRec2[l29] = 0.0f;
         }
-        for (int l30 = 0; (l30 < 1024); l30 = (l30 + 1)) {
+        for (int l30 = 0; l30 < 1024; l30 = l30 + 1) {
             fVec11[l30] = 0.0f;
         }
-        for (int l31 = 0; (l31 < 2); l31 = (l31 + 1)) {
+        for (int l31 = 0; l31 < 2; l31 = l31 + 1) {
             fRec0[l31] = 0.0f;
         }
-        for (int l32 = 0; (l32 < 2); l32 = (l32 + 1)) {
+        for (int l32 = 0; l32 < 2; l32 = l32 + 1) {
             fRec33[l32] = 0.0f;
         }
-        for (int l33 = 0; (l33 < 8192); l33 = (l33 + 1)) {
+        for (int l33 = 0; l33 < 8192; l33 = l33 + 1) {
             fVec12[l33] = 0.0f;
         }
-        for (int l34 = 0; (l34 < 2); l34 = (l34 + 1)) {
+        for (int l34 = 0; l34 < 2; l34 = l34 + 1) {
             fRec32[l34] = 0.0f;
         }
-        for (int l35 = 0; (l35 < 2); l35 = (l35 + 1)) {
+        for (int l35 = 0; l35 < 2; l35 = l35 + 1) {
             fRec35[l35] = 0.0f;
         }
-        for (int l36 = 0; (l36 < 8192); l36 = (l36 + 1)) {
+        for (int l36 = 0; l36 < 8192; l36 = l36 + 1) {
             fVec13[l36] = 0.0f;
         }
-        for (int l37 = 0; (l37 < 2); l37 = (l37 + 1)) {
+        for (int l37 = 0; l37 < 2; l37 = l37 + 1) {
             fRec34[l37] = 0.0f;
         }
-        for (int l38 = 0; (l38 < 2); l38 = (l38 + 1)) {
+        for (int l38 = 0; l38 < 2; l38 = l38 + 1) {
             fRec37[l38] = 0.0f;
         }
-        for (int l39 = 0; (l39 < 8192); l39 = (l39 + 1)) {
+        for (int l39 = 0; l39 < 8192; l39 = l39 + 1) {
             fVec14[l39] = 0.0f;
         }
-        for (int l40 = 0; (l40 < 2); l40 = (l40 + 1)) {
+        for (int l40 = 0; l40 < 2; l40 = l40 + 1) {
             fRec36[l40] = 0.0f;
         }
-        for (int l41 = 0; (l41 < 2); l41 = (l41 + 1)) {
+        for (int l41 = 0; l41 < 2; l41 = l41 + 1) {
             fRec39[l41] = 0.0f;
         }
-        for (int l42 = 0; (l42 < 8192); l42 = (l42 + 1)) {
+        for (int l42 = 0; l42 < 8192; l42 = l42 + 1) {
             fVec15[l42] = 0.0f;
         }
-        for (int l43 = 0; (l43 < 2); l43 = (l43 + 1)) {
+        for (int l43 = 0; l43 < 2; l43 = l43 + 1) {
             fRec38[l43] = 0.0f;
         }
-        for (int l44 = 0; (l44 < 2); l44 = (l44 + 1)) {
+        for (int l44 = 0; l44 < 2; l44 = l44 + 1) {
             fRec41[l44] = 0.0f;
         }
-        for (int l45 = 0; (l45 < 8192); l45 = (l45 + 1)) {
+        for (int l45 = 0; l45 < 8192; l45 = l45 + 1) {
             fVec16[l45] = 0.0f;
         }
-        for (int l46 = 0; (l46 < 2); l46 = (l46 + 1)) {
+        for (int l46 = 0; l46 < 2; l46 = l46 + 1) {
             fRec40[l46] = 0.0f;
         }
-        for (int l47 = 0; (l47 < 2); l47 = (l47 + 1)) {
+        for (int l47 = 0; l47 < 2; l47 = l47 + 1) {
             fRec43[l47] = 0.0f;
         }
-        for (int l48 = 0; (l48 < 8192); l48 = (l48 + 1)) {
+        for (int l48 = 0; l48 < 8192; l48 = l48 + 1) {
             fVec17[l48] = 0.0f;
         }
-        for (int l49 = 0; (l49 < 2); l49 = (l49 + 1)) {
+        for (int l49 = 0; l49 < 2; l49 = l49 + 1) {
             fRec42[l49] = 0.0f;
         }
-        for (int l50 = 0; (l50 < 2); l50 = (l50 + 1)) {
+        for (int l50 = 0; l50 < 2; l50 = l50 + 1) {
             fRec45[l50] = 0.0f;
         }
-        for (int l51 = 0; (l51 < 8192); l51 = (l51 + 1)) {
+        for (int l51 = 0; l51 < 8192; l51 = l51 + 1) {
             fVec18[l51] = 0.0f;
         }
-        for (int l52 = 0; (l52 < 2); l52 = (l52 + 1)) {
+        for (int l52 = 0; l52 < 2; l52 = l52 + 1) {
             fRec44[l52] = 0.0f;
         }
-        for (int l53 = 0; (l53 < 2); l53 = (l53 + 1)) {
+        for (int l53 = 0; l53 < 2; l53 = l53 + 1) {
             fRec47[l53] = 0.0f;
         }
-        for (int l54 = 0; (l54 < 8192); l54 = (l54 + 1)) {
+        for (int l54 = 0; l54 < 8192; l54 = l54 + 1) {
             fVec19[l54] = 0.0f;
         }
-        for (int l55 = 0; (l55 < 2); l55 = (l55 + 1)) {
+        for (int l55 = 0; l55 < 2; l55 = l55 + 1) {
             fRec46[l55] = 0.0f;
         }
-        for (int l56 = 0; (l56 < 2048); l56 = (l56 + 1)) {
+        for (int l56 = 0; l56 < 2048; l56 = l56 + 1) {
             fVec20[l56] = 0.0f;
         }
-        for (int l57 = 0; (l57 < 2); l57 = (l57 + 1)) {
+        for (int l57 = 0; l57 < 2; l57 = l57 + 1) {
             fRec30[l57] = 0.0f;
         }
-        for (int l58 = 0; (l58 < 2048); l58 = (l58 + 1)) {
+        for (int l58 = 0; l58 < 2048; l58 = l58 + 1) {
             fVec21[l58] = 0.0f;
         }
-        for (int l59 = 0; (l59 < 2); l59 = (l59 + 1)) {
+        for (int l59 = 0; l59 < 2; l59 = l59 + 1) {
             fRec28[l59] = 0.0f;
         }
-        for (int l60 = 0; (l60 < 2048); l60 = (l60 + 1)) {
+        for (int l60 = 0; l60 < 2048; l60 = l60 + 1) {
             fVec22[l60] = 0.0f;
         }
-        for (int l61 = 0; (l61 < 2); l61 = (l61 + 1)) {
+        for (int l61 = 0; l61 < 2; l61 = l61 + 1) {
             fRec26[l61] = 0.0f;
         }
-        for (int l62 = 0; (l62 < 2048); l62 = (l62 + 1)) {
+        for (int l62 = 0; l62 < 2048; l62 = l62 + 1) {
             fVec23[l62] = 0.0f;
         }
-        for (int l63 = 0; (l63 < 2); l63 = (l63 + 1)) {
+        for (int l63 = 0; l63 < 2; l63 = l63 + 1) {
             fRec24[l63] = 0.0f;
         }
     }
@@ -2039,29 +2370,33 @@ class freeverbdsp : public dsp
         ui_interface->declare(&fVslider1, "style", "knob");
         ui_interface->declare(&fVslider1, "tooltip",
                               "Somehow control the   density of the reverb.");
-        ui_interface->addVerticalSlider("Damp", &fVslider1, 0.5f, 0.0f, 1.0f,
-                                        0.0250000004f);
+        ui_interface->addVerticalSlider("Damp", &fVslider1, FAUSTFLOAT(0.5f),
+                                        FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+                                        FAUSTFLOAT(0.0250000004f));
         ui_interface->declare(&fVslider0, "1", "");
         ui_interface->declare(&fVslider0, "style", "knob");
         ui_interface->declare(
             &fVslider0, "tooltip",
             "The room size   between 0 and 1 with 1 for the largest room.");
-        ui_interface->addVerticalSlider("RoomSize", &fVslider0, 0.100000001f, 0.0f, 1.0f,
-                                        0.0250000004f);
+        ui_interface->addVerticalSlider("RoomSize", &fVslider0, FAUSTFLOAT(0.100000001f),
+                                        FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+                                        FAUSTFLOAT(0.0250000004f));
         ui_interface->declare(&fVslider3, "2", "");
         ui_interface->declare(&fVslider3, "style", "knob");
         ui_interface->declare(
             &fVslider3, "tooltip",
             "Spatial   spread between 0 and 1 with 1 for maximum spread.");
-        ui_interface->addVerticalSlider("Stereo Spread", &fVslider3, 0.5f, 0.0f, 1.0f,
-                                        0.00999999978f);
+        ui_interface->addVerticalSlider("Stereo Spread", &fVslider3, FAUSTFLOAT(0.5f),
+                                        FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+                                        FAUSTFLOAT(0.00999999978f));
         ui_interface->closeBox();
         ui_interface->declare(&fVslider2, "1", "");
         ui_interface->declare(&fVslider2, "tooltip",
                               "The amount of reverb applied to the signal   between 0 "
                               "and 1 with 1 for the maximum amount of reverb.");
-        ui_interface->addVerticalSlider("Wet", &fVslider2, 0.100000001f, 0.0f, 1.0f,
-                                        0.0250000004f);
+        ui_interface->addVerticalSlider("Wet", &fVslider2, FAUSTFLOAT(0.100000001f),
+                                        FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+                                        FAUSTFLOAT(0.0250000004f));
         ui_interface->closeBox();
     }
 
@@ -2071,163 +2406,155 @@ class freeverbdsp : public dsp
         FAUSTFLOAT* input1  = inputs[1];
         FAUSTFLOAT* output0 = outputs[0];
         FAUSTFLOAT* output1 = outputs[1];
-        float fSlow0        = ((fConst1 * float(fVslider0)) + 0.699999988f);
-        float fSlow1        = (fConst2 * float(fVslider1));
-        float fSlow2        = (1.0f - fSlow1);
+        float fSlow0        = fConst1 * float(fVslider0) + 0.699999988f;
+        float fSlow1        = fConst2 * float(fVslider1);
+        float fSlow2        = 1.0f - fSlow1;
         float fSlow3        = float(fVslider2);
-        float fSlow4        = (0.100000001f * fSlow3);
-        float fSlow5        = (1.0f - fSlow3);
-        int iSlow6          = int((fConst19 * float(fVslider3)));
-        int iSlow7          = (iConst3 + iSlow6);
-        int iSlow8          = (iConst4 + iSlow6);
-        int iSlow9          = (iConst5 + iSlow6);
-        int iSlow10         = (iConst6 + iSlow6);
-        int iSlow11         = (iConst7 + iSlow6);
-        int iSlow12         = (iConst8 + iSlow6);
-        int iSlow13         = (iConst9 + iSlow6);
-        int iSlow14         = (iConst10 + iSlow6);
-        int iSlow15         = (iSlow6 + -1);
-        int iSlow16         = std::min<int>(1024, std::max<int>(0, (iConst11 + iSlow15)));
-        int iSlow17         = std::min<int>(1024, std::max<int>(0, (iConst13 + iSlow15)));
-        int iSlow18         = std::min<int>(1024, std::max<int>(0, (iConst15 + iSlow15)));
-        int iSlow19         = std::min<int>(1024, std::max<int>(0, (iConst17 + iSlow15)));
-        for (int i = 0; (i < count); i = (i + 1)) {
-            float fTemp0         = float(input0[i]);
-            float fTemp1         = float(input1[i]);
-            fRec9[0]             = ((fSlow1 * fRec9[1]) + (fSlow2 * fRec8[1]));
-            float fTemp2         = (fSlow4 * (fTemp0 + fTemp1));
-            fVec0[(IOTA & 8191)] = ((fSlow0 * fRec9[0]) + fTemp2);
-            fRec8[0]             = fVec0[((IOTA - iConst3) & 8191)];
-            fRec11[0]            = ((fSlow1 * fRec11[1]) + (fSlow2 * fRec10[1]));
-            fVec1[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec11[0]));
-            fRec10[0]            = fVec1[((IOTA - iConst4) & 8191)];
-            fRec13[0]            = ((fSlow1 * fRec13[1]) + (fSlow2 * fRec12[1]));
-            fVec2[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec13[0]));
-            fRec12[0]            = fVec2[((IOTA - iConst5) & 8191)];
-            fRec15[0]            = ((fSlow1 * fRec15[1]) + (fSlow2 * fRec14[1]));
-            fVec3[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec15[0]));
-            fRec14[0]            = fVec3[((IOTA - iConst6) & 8191)];
-            fRec17[0]            = ((fSlow1 * fRec17[1]) + (fSlow2 * fRec16[1]));
-            fVec4[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec17[0]));
-            fRec16[0]            = fVec4[((IOTA - iConst7) & 8191)];
-            fRec19[0]            = ((fSlow1 * fRec19[1]) + (fSlow2 * fRec18[1]));
-            fVec5[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec19[0]));
-            fRec18[0]            = fVec5[((IOTA - iConst8) & 8191)];
-            fRec21[0]            = ((fSlow1 * fRec21[1]) + (fSlow2 * fRec20[1]));
-            fVec6[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec21[0]));
-            fRec20[0]            = fVec6[((IOTA - iConst9) & 8191)];
-            fRec23[0]            = ((fSlow1 * fRec23[1]) + (fSlow2 * fRec22[1]));
-            fVec7[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec23[0]));
-            fRec22[0]            = fVec7[((IOTA - iConst10) & 8191)];
-            float fTemp3 =
-                ((((((((fRec8[0] + fRec10[0]) + fRec12[0]) + fRec14[0]) + fRec16[0])
-                    + fRec18[0])
-                   + fRec20[0])
-                  + fRec22[0])
-                 + (0.5f * fRec6[1]));
-            fVec8[(IOTA & 2047)]  = fTemp3;
-            fRec6[0]              = fVec8[((IOTA - iConst12) & 2047)];
-            float fRec7           = (0.0f - (0.5f * fTemp3));
-            float fTemp4          = (fRec6[1] + (fRec7 + (0.5f * fRec4[1])));
-            fVec9[(IOTA & 2047)]  = fTemp4;
-            fRec4[0]              = fVec9[((IOTA - iConst14) & 2047)];
-            float fRec5           = (0.0f - (0.5f * fTemp4));
-            float fTemp5          = (fRec4[1] + (fRec5 + (0.5f * fRec2[1])));
-            fVec10[(IOTA & 2047)] = fTemp5;
-            fRec2[0]              = fVec10[((IOTA - iConst16) & 2047)];
-            float fRec3           = (0.0f - (0.5f * fTemp5));
-            float fTemp6          = (fRec2[1] + (fRec3 + (0.5f * fRec0[1])));
-            fVec11[(IOTA & 1023)] = fTemp6;
-            fRec0[0]              = fVec11[((IOTA - iConst18) & 1023)];
-            float fRec1           = (0.0f - (0.5f * fTemp6));
-            output0[i]            = FAUSTFLOAT(((fRec1 + fRec0[1]) + (fSlow5 * fTemp0)));
-            fRec33[0]             = ((fSlow1 * fRec33[1]) + (fSlow2 * fRec32[1]));
-            fVec12[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec33[0]));
-            fRec32[0]             = fVec12[((IOTA - iSlow7) & 8191)];
-            fRec35[0]             = ((fSlow1 * fRec35[1]) + (fSlow2 * fRec34[1]));
-            fVec13[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec35[0]));
-            fRec34[0]             = fVec13[((IOTA - iSlow8) & 8191)];
-            fRec37[0]             = ((fSlow1 * fRec37[1]) + (fSlow2 * fRec36[1]));
-            fVec14[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec37[0]));
-            fRec36[0]             = fVec14[((IOTA - iSlow9) & 8191)];
-            fRec39[0]             = ((fSlow1 * fRec39[1]) + (fSlow2 * fRec38[1]));
-            fVec15[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec39[0]));
-            fRec38[0]             = fVec15[((IOTA - iSlow10) & 8191)];
-            fRec41[0]             = ((fSlow1 * fRec41[1]) + (fSlow2 * fRec40[1]));
-            fVec16[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec41[0]));
-            fRec40[0]             = fVec16[((IOTA - iSlow11) & 8191)];
-            fRec43[0]             = ((fSlow1 * fRec43[1]) + (fSlow2 * fRec42[1]));
-            fVec17[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec43[0]));
-            fRec42[0]             = fVec17[((IOTA - iSlow12) & 8191)];
-            fRec45[0]             = ((fSlow1 * fRec45[1]) + (fSlow2 * fRec44[1]));
-            fVec18[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec45[0]));
-            fRec44[0]             = fVec18[((IOTA - iSlow13) & 8191)];
-            fRec47[0]             = ((fSlow1 * fRec47[1]) + (fSlow2 * fRec46[1]));
-            fVec19[(IOTA & 8191)] = (fTemp2 + (fSlow0 * fRec47[0]));
-            fRec46[0]             = fVec19[((IOTA - iSlow14) & 8191)];
-            float fTemp7 =
-                ((((((((fRec32[0] + fRec34[0]) + fRec36[0]) + fRec38[0]) + fRec40[0])
-                    + fRec42[0])
-                   + fRec44[0])
-                  + fRec46[0])
-                 + (0.5f * fRec30[1]));
-            fVec20[(IOTA & 2047)] = fTemp7;
-            fRec30[0]             = fVec20[((IOTA - iSlow16) & 2047)];
-            float fRec31          = (0.0f - (0.5f * fTemp7));
-            float fTemp8          = (fRec30[1] + (fRec31 + (0.5f * fRec28[1])));
-            fVec21[(IOTA & 2047)] = fTemp8;
-            fRec28[0]             = fVec21[((IOTA - iSlow17) & 2047)];
-            float fRec29          = (0.0f - (0.5f * fTemp8));
-            float fTemp9          = (fRec28[1] + (fRec29 + (0.5f * fRec26[1])));
-            fVec22[(IOTA & 2047)] = fTemp9;
-            fRec26[0]             = fVec22[((IOTA - iSlow18) & 2047)];
-            float fRec27          = (0.0f - (0.5f * fTemp9));
-            float fTemp10         = (fRec26[1] + (fRec27 + (0.5f * fRec24[1])));
-            fVec23[(IOTA & 2047)] = fTemp10;
-            fRec24[0]             = fVec23[((IOTA - iSlow19) & 2047)];
-            float fRec25          = (0.0f - (0.5f * fTemp10));
-            output1[i] = FAUSTFLOAT(((fRec25 + fRec24[1]) + (fSlow5 * fTemp1)));
-            fRec9[1]   = fRec9[0];
-            IOTA       = (IOTA + 1);
-            fRec8[1]   = fRec8[0];
-            fRec11[1]  = fRec11[0];
-            fRec10[1]  = fRec10[0];
-            fRec13[1]  = fRec13[0];
-            fRec12[1]  = fRec12[0];
-            fRec15[1]  = fRec15[0];
-            fRec14[1]  = fRec14[0];
-            fRec17[1]  = fRec17[0];
-            fRec16[1]  = fRec16[0];
-            fRec19[1]  = fRec19[0];
-            fRec18[1]  = fRec18[0];
-            fRec21[1]  = fRec21[0];
-            fRec20[1]  = fRec20[0];
-            fRec23[1]  = fRec23[0];
-            fRec22[1]  = fRec22[0];
-            fRec6[1]   = fRec6[0];
-            fRec4[1]   = fRec4[0];
-            fRec2[1]   = fRec2[0];
-            fRec0[1]   = fRec0[0];
-            fRec33[1]  = fRec33[0];
-            fRec32[1]  = fRec32[0];
-            fRec35[1]  = fRec35[0];
-            fRec34[1]  = fRec34[0];
-            fRec37[1]  = fRec37[0];
-            fRec36[1]  = fRec36[0];
-            fRec39[1]  = fRec39[0];
-            fRec38[1]  = fRec38[0];
-            fRec41[1]  = fRec41[0];
-            fRec40[1]  = fRec40[0];
-            fRec43[1]  = fRec43[0];
-            fRec42[1]  = fRec42[0];
-            fRec45[1]  = fRec45[0];
-            fRec44[1]  = fRec44[0];
-            fRec47[1]  = fRec47[0];
-            fRec46[1]  = fRec46[0];
-            fRec30[1]  = fRec30[0];
-            fRec28[1]  = fRec28[0];
-            fRec26[1]  = fRec26[0];
-            fRec24[1]  = fRec24[0];
+        float fSlow4        = 0.100000001f * fSlow3;
+        float fSlow5        = 1.0f - fSlow3;
+        int iSlow6          = int(fConst19 * float(fVslider3));
+        int iSlow7          = iConst3 + iSlow6;
+        int iSlow8          = iConst4 + iSlow6;
+        int iSlow9          = iConst5 + iSlow6;
+        int iSlow10         = iConst6 + iSlow6;
+        int iSlow11         = iConst7 + iSlow6;
+        int iSlow12         = iConst8 + iSlow6;
+        int iSlow13         = iConst9 + iSlow6;
+        int iSlow14         = iConst10 + iSlow6;
+        int iSlow15         = iSlow6 + -1;
+        int iSlow16         = std::min<int>(1024, std::max<int>(0, iConst11 + iSlow15));
+        int iSlow17         = std::min<int>(1024, std::max<int>(0, iConst13 + iSlow15));
+        int iSlow18         = std::min<int>(1024, std::max<int>(0, iConst15 + iSlow15));
+        int iSlow19         = std::min<int>(1024, std::max<int>(0, iConst17 + iSlow15));
+        for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+            float fTemp0        = float(input0[i0]);
+            float fTemp1        = float(input1[i0]);
+            fRec9[0]            = fSlow1 * fRec9[1] + fSlow2 * fRec8[1];
+            float fTemp2        = fSlow4 * (fTemp0 + fTemp1);
+            fVec0[IOTA0 & 8191] = fSlow0 * fRec9[0] + fTemp2;
+            fRec8[0]            = fVec0[(IOTA0 - iConst3) & 8191];
+            fRec11[0]           = fSlow1 * fRec11[1] + fSlow2 * fRec10[1];
+            fVec1[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec11[0];
+            fRec10[0]           = fVec1[(IOTA0 - iConst4) & 8191];
+            fRec13[0]           = fSlow1 * fRec13[1] + fSlow2 * fRec12[1];
+            fVec2[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec13[0];
+            fRec12[0]           = fVec2[(IOTA0 - iConst5) & 8191];
+            fRec15[0]           = fSlow1 * fRec15[1] + fSlow2 * fRec14[1];
+            fVec3[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec15[0];
+            fRec14[0]           = fVec3[(IOTA0 - iConst6) & 8191];
+            fRec17[0]           = fSlow1 * fRec17[1] + fSlow2 * fRec16[1];
+            fVec4[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec17[0];
+            fRec16[0]           = fVec4[(IOTA0 - iConst7) & 8191];
+            fRec19[0]           = fSlow1 * fRec19[1] + fSlow2 * fRec18[1];
+            fVec5[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec19[0];
+            fRec18[0]           = fVec5[(IOTA0 - iConst8) & 8191];
+            fRec21[0]           = fSlow1 * fRec21[1] + fSlow2 * fRec20[1];
+            fVec6[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec21[0];
+            fRec20[0]           = fVec6[(IOTA0 - iConst9) & 8191];
+            fRec23[0]           = fSlow1 * fRec23[1] + fSlow2 * fRec22[1];
+            fVec7[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec23[0];
+            fRec22[0]           = fVec7[(IOTA0 - iConst10) & 8191];
+            float fTemp3        = fRec8[0] + fRec10[0] + fRec12[0] + fRec14[0] + fRec16[0]
+                           + fRec18[0] + fRec20[0] + fRec22[0] + 0.5f * fRec6[1];
+            fVec8[IOTA0 & 2047]  = fTemp3;
+            fRec6[0]             = fVec8[(IOTA0 - iConst12) & 2047];
+            float fRec7          = 0.0f - 0.5f * fTemp3;
+            float fTemp4         = fRec6[1] + fRec7 + 0.5f * fRec4[1];
+            fVec9[IOTA0 & 2047]  = fTemp4;
+            fRec4[0]             = fVec9[(IOTA0 - iConst14) & 2047];
+            float fRec5          = 0.0f - 0.5f * fTemp4;
+            float fTemp5         = fRec4[1] + fRec5 + 0.5f * fRec2[1];
+            fVec10[IOTA0 & 2047] = fTemp5;
+            fRec2[0]             = fVec10[(IOTA0 - iConst16) & 2047];
+            float fRec3          = 0.0f - 0.5f * fTemp5;
+            float fTemp6         = fRec2[1] + fRec3 + 0.5f * fRec0[1];
+            fVec11[IOTA0 & 1023] = fTemp6;
+            fRec0[0]             = fVec11[(IOTA0 - iConst18) & 1023];
+            float fRec1          = 0.0f - 0.5f * fTemp6;
+            output0[i0]          = FAUSTFLOAT(fRec1 + fRec0[1] + fSlow5 * fTemp0);
+            fRec33[0]            = fSlow1 * fRec33[1] + fSlow2 * fRec32[1];
+            fVec12[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec33[0];
+            fRec32[0]            = fVec12[(IOTA0 - iSlow7) & 8191];
+            fRec35[0]            = fSlow1 * fRec35[1] + fSlow2 * fRec34[1];
+            fVec13[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec35[0];
+            fRec34[0]            = fVec13[(IOTA0 - iSlow8) & 8191];
+            fRec37[0]            = fSlow1 * fRec37[1] + fSlow2 * fRec36[1];
+            fVec14[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec37[0];
+            fRec36[0]            = fVec14[(IOTA0 - iSlow9) & 8191];
+            fRec39[0]            = fSlow1 * fRec39[1] + fSlow2 * fRec38[1];
+            fVec15[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec39[0];
+            fRec38[0]            = fVec15[(IOTA0 - iSlow10) & 8191];
+            fRec41[0]            = fSlow1 * fRec41[1] + fSlow2 * fRec40[1];
+            fVec16[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec41[0];
+            fRec40[0]            = fVec16[(IOTA0 - iSlow11) & 8191];
+            fRec43[0]            = fSlow1 * fRec43[1] + fSlow2 * fRec42[1];
+            fVec17[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec43[0];
+            fRec42[0]            = fVec17[(IOTA0 - iSlow12) & 8191];
+            fRec45[0]            = fSlow1 * fRec45[1] + fSlow2 * fRec44[1];
+            fVec18[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec45[0];
+            fRec44[0]            = fVec18[(IOTA0 - iSlow13) & 8191];
+            fRec47[0]            = fSlow1 * fRec47[1] + fSlow2 * fRec46[1];
+            fVec19[IOTA0 & 8191] = fTemp2 + fSlow0 * fRec47[0];
+            fRec46[0]            = fVec19[(IOTA0 - iSlow14) & 8191];
+            float fTemp7 = fRec32[0] + fRec34[0] + fRec36[0] + fRec38[0] + fRec40[0]
+                           + fRec42[0] + fRec44[0] + fRec46[0] + 0.5f * fRec30[1];
+            fVec20[IOTA0 & 2047] = fTemp7;
+            fRec30[0]            = fVec20[(IOTA0 - iSlow16) & 2047];
+            float fRec31         = 0.0f - 0.5f * fTemp7;
+            float fTemp8         = fRec30[1] + fRec31 + 0.5f * fRec28[1];
+            fVec21[IOTA0 & 2047] = fTemp8;
+            fRec28[0]            = fVec21[(IOTA0 - iSlow17) & 2047];
+            float fRec29         = 0.0f - 0.5f * fTemp8;
+            float fTemp9         = fRec28[1] + fRec29 + 0.5f * fRec26[1];
+            fVec22[IOTA0 & 2047] = fTemp9;
+            fRec26[0]            = fVec22[(IOTA0 - iSlow18) & 2047];
+            float fRec27         = 0.0f - 0.5f * fTemp9;
+            float fTemp10        = fRec26[1] + fRec27 + 0.5f * fRec24[1];
+            fVec23[IOTA0 & 2047] = fTemp10;
+            fRec24[0]            = fVec23[(IOTA0 - iSlow19) & 2047];
+            float fRec25         = 0.0f - 0.5f * fTemp10;
+            output1[i0]          = FAUSTFLOAT(fRec25 + fRec24[1] + fSlow5 * fTemp1);
+            fRec9[1]             = fRec9[0];
+            IOTA0                = IOTA0 + 1;
+            fRec8[1]             = fRec8[0];
+            fRec11[1]            = fRec11[0];
+            fRec10[1]            = fRec10[0];
+            fRec13[1]            = fRec13[0];
+            fRec12[1]            = fRec12[0];
+            fRec15[1]            = fRec15[0];
+            fRec14[1]            = fRec14[0];
+            fRec17[1]            = fRec17[0];
+            fRec16[1]            = fRec16[0];
+            fRec19[1]            = fRec19[0];
+            fRec18[1]            = fRec18[0];
+            fRec21[1]            = fRec21[0];
+            fRec20[1]            = fRec20[0];
+            fRec23[1]            = fRec23[0];
+            fRec22[1]            = fRec22[0];
+            fRec6[1]             = fRec6[0];
+            fRec4[1]             = fRec4[0];
+            fRec2[1]             = fRec2[0];
+            fRec0[1]             = fRec0[0];
+            fRec33[1]            = fRec33[0];
+            fRec32[1]            = fRec32[0];
+            fRec35[1]            = fRec35[0];
+            fRec34[1]            = fRec34[0];
+            fRec37[1]            = fRec37[0];
+            fRec36[1]            = fRec36[0];
+            fRec39[1]            = fRec39[0];
+            fRec38[1]            = fRec38[0];
+            fRec41[1]            = fRec41[0];
+            fRec40[1]            = fRec40[0];
+            fRec43[1]            = fRec43[0];
+            fRec42[1]            = fRec42[0];
+            fRec45[1]            = fRec45[0];
+            fRec44[1]            = fRec44[0];
+            fRec47[1]            = fRec47[0];
+            fRec46[1]            = fRec46[0];
+            fRec30[1]            = fRec30[0];
+            fRec28[1]            = fRec28[0];
+            fRec26[1]            = fRec26[0];
+            fRec24[1]            = fRec24[0];
         }
     }
 };
index c7ac161d82ce01d493c64b28b61dcbda67103250..33187843c48f7915e583ccd75061518479809a0d 100644 (file)
@@ -1,7 +1,8 @@
 /* ------------------------------------------------------------
 name: "freeverbmonodsp"
-Code generated with Faust 2.28.6 (https://faust.grame.fr)
-Compilation options: -lang cpp -inpl -scal -ftz 0
+Code generated with Faust 2.41.1 (https://faust.grame.fr)
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn freeverbmonodsp -es 1 -mcd
+16 -single -ftz 0
 ------------------------------------------------------------ */
 
 #ifndef __freeverbmonodsp_H__
@@ -14,23 +15,23 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 // aimed at creating a simple C++ header file (.h) containing a Faust DSP.
 // See the Makefile for how to use it.
 
-/************************** BEGIN dsp.h **************************/
-/************************************************************************
+/************************** BEGIN dsp.h ********************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -44,29 +45,111 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 #include <string>
 #include <vector>
 
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __export__
+#define __export__
+
+#define FAUSTVERSION "2.41.1"
+
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
+
+#ifdef _WIN32
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API    __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
+#else
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#else
+#define FAUST_API    __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
+#endif
+
+#endif
+
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
 
-struct UI;
-struct Meta;
+struct FAUST_API UI;
+struct FAUST_API Meta;
 
 /**
  * DSP memory manager.
  */
 
-struct dsp_memory_manager {
+struct FAUST_API dsp_memory_manager {
     virtual ~dsp_memory_manager() {}
 
+    /**
+     * Inform the Memory Manager with the number of expected memory zones.
+     * @param count - the number of expected memory zones
+     */
+    virtual void begin(size_t /*count*?) {}
+
+    /**
+     * Give the Memory Manager information on a given memory zone.
+     * @param size - the size in bytes of the memory zone
+     * @param reads - the number of Read access to the zone used to compute one frame
+     * @param writes - the number of Write access to the zone used to compute one frame
+     */
+    virtual void info(size_t /*size*/, size_t /*reads*/, size_t /*writes*/) {}
+
+    /**
+     * Inform the Memory Manager that all memory zones have been described,
+     * to possibly start a 'compute the best allocation strategy' step.
+     */
+    virtual void end() {}
+
+    /**
+     * Allocate a memory zone.
+     * @param size - the memory zone size in bytes
+     */
     virtual void* allocate(size_t size) = 0;
-    virtual void destroy(void* ptr)     = 0;
+
+    /**
+     * Destroy a memory zone.
+     * @param ptr - the memory zone pointer to be deallocated
+     */
+    virtual void destroy(void* ptr) = 0;
 };
 
 /**
  * Signal processor definition.
  */
 
-class dsp
+class FAUST_API dsp
 {
    public:
     dsp() {}
@@ -86,7 +169,7 @@ class dsp
      */
     virtual void buildUserInterface(UI* ui_interface) = 0;
 
-    /* Returns the sample rate currently used by the instance */
+    /* Return the sample rate currently used by the instance */
     virtual int getSampleRate() = 0;
 
     /**
@@ -94,28 +177,28 @@ class dsp
      * - static class 'classInit': static tables initialization
      * - 'instanceInit': constants and instance state initialization
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void init(int sample_rate) = 0;
 
     /**
      * Init instance state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceInit(int sample_rate) = 0;
 
     /**
      * Init instance constant state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceConstants(int sample_rate) = 0;
 
     /* Init default control parameters values */
     virtual void instanceResetUserInterface() = 0;
 
-    /* Init instance state (delay lines...) */
+    /* Init instance state (like delay lines...) but keep the control parameter values */
     virtual void instanceClear() = 0;
 
     /**
@@ -167,7 +250,7 @@ class dsp
  * Generic DSP decorator.
  */
 
-class decorator_dsp : public dsp
+class FAUST_API decorator_dsp : public dsp
 {
    protected:
     dsp* fDSP;
@@ -206,10 +289,11 @@ class decorator_dsp : public dsp
 };
 
 /**
- * DSP factory class.
+ * DSP factory class, used with LLVM and Interpreter backends
+ * to create DSP instances from a compiled DSP program.
  */
 
-class dsp_factory
+class FAUST_API dsp_factory
 {
    protected:
     // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
@@ -229,75 +313,114 @@ class dsp_factory
     virtual dsp_memory_manager* getMemoryManager()             = 0;
 };
 
-/**
- * On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
- * flags to avoid costly denormals.
- */
+// Denormal handling
 
-#ifdef __SSE__
+#if defined(__SSE__)
 #include <xmmintrin.h>
-#ifdef __SSE2__
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
+#endif
+
+class FAUST_API ScopedNoDenormals
+{
+   private:
+    intptr_t fpsr;
+
+    void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("msr fpcr, %0" : : "ri"(fpsr_aux));
+#elif defined(__SSE__)
+        _mm_setcsr(static_cast<uint32_t>(fpsr_aux));
+#endif
+    }
+
+    void getFpStatusRegister() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("mrs %0, fpcr" : "=r"(fpsr));
+#elif defined(__SSE__)
+        fpsr          = static_cast<intptr_t>(_mm_getcsr());
+#endif
+    }
+
+   public:
+    ScopedNoDenormals() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        intptr_t mask = (1 << 24 /* FZ */);
 #else
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
+#if defined(__SSE__)
+#if defined(__SSE2__)
+        intptr_t mask = 0x8040;
+#else
+        intptr_t mask = 0x8000;
 #endif
 #else
-#define AVOIDDENORMALS
+        intptr_t mask = 0x0000;
 #endif
-
 #endif
-/**************************  END  dsp.h **************************/
+        getFpStatusRegister();
+        setFpStatusRegister(fpsr | mask);
+    }
 
-/************************** BEGIN APIUI.h **************************/
-/************************************************************************
- FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
- ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
+    ~ScopedNoDenormals() noexcept { setFpStatusRegister(fpsr); }
+};
 
- This program 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 General Public License for more details.
+#define AVOIDDENORMALS ScopedNoDenormals();
 
- You should have received a copy of the GNU General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+#endif
 
- EXCEPTION : As a special exception, you may create a larger work
- that contains this FAUST architecture section and distribute
- that work under terms of your choice, so long as this FAUST
- architecture section is not modified.
- ************************************************************************/
+/************************** END dsp.h **************************/
+/************************** BEGIN APIUI.h *****************************
+FAUST Architecture File
+Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+---------------------------------------------------------------------
+This program 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 program 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 program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+EXCEPTION : As a special exception, you may create a larger work
+that contains this FAUST architecture section and distribute
+that work under terms of your choice, so long as this FAUST
+architecture section is not modified.
+************************************************************************/
 
 #ifndef API_UI_H
 #define API_UI_H
 
-#include <iostream>
+#include <stdio.h>
+
 #include <map>
 #include <sstream>
 #include <string>
 #include <vector>
 
-/************************** BEGIN meta.h **************************/
-/************************************************************************
+/************************** BEGIN meta.h *******************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -308,36 +431,40 @@ class dsp_factory
 #ifndef __meta__
 #define __meta__
 
-struct Meta {
-    virtual ~Meta(){};
+/**
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
+ (key, value) metadata.
+ */
+struct FAUST_API Meta {
+    virtual ~Meta() {}
     virtual void declare(const char* key, const char* value) = 0;
 };
 
 #endif
 /**************************  END  meta.h **************************/
-/************************** BEGIN UI.h **************************/
-/************************************************************************
+/************************** BEGIN UI.h *****************************
  FAUST Architecture File
- Copyright (C) 2003-2020 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __UI_H__
 #define __UI_H__
@@ -356,7 +483,7 @@ struct Meta {
 struct Soundfile;
 
 template<typename REAL>
-struct UIReal {
+struct FAUST_API UIReal {
     UIReal() {}
     virtual ~UIReal() {}
 
@@ -387,38 +514,41 @@ struct UIReal {
 
     // -- soundfiles
 
-    virtual void addSoundfile(const char* label, const char* filename,
-                              Soundfile** sf_zone) = 0;
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+                              Soundfile** /*sf_zone*/) = 0;
 
     // -- metadata declarations
 
-    virtual void declare(REAL* zone, const char* key, const char* val) {}
+    virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
+
+    // To be used by LLVM client
+    virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
 };
 
-struct UI : public UIReal<FAUSTFLOAT> {
+struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
     UI() {}
     virtual ~UI() {}
 };
 
 #endif
 /**************************  END  UI.h **************************/
-/************************** BEGIN PathBuilder.h **************************/
-/************************************************************************
+/************************** BEGIN PathBuilder.h **************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -426,10 +556,13 @@ struct UI : public UIReal<FAUSTFLOAT> {
  architecture section is not modified.
  ************************************************************************/
 
-#ifndef FAUST_PATHBUILDER_H
-#define FAUST_PATHBUILDER_H
+#ifndef __PathBuilder__
+#define __PathBuilder__
 
 #include <algorithm>
+#include <map>
+#include <regex>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -438,113 +571,266 @@ struct UI : public UIReal<FAUSTFLOAT> {
  * Helper class to build complete hierarchical path for UI items.
  ******************************************************************************/
 
-class PathBuilder
+class FAUST_API PathBuilder
 {
    protected:
     std::vector<std::string> fControlsLevel;
+    std::vector<std::string> fFullPaths;
+    std::map<std::string, std::string> fFull2Short;  // filled by computeShortNames()
+
+    /**
+     * @brief check if a character is acceptable for an ID
+     *
+     * @param c
+     * @return true is the character is acceptable for an ID
+     */
+    bool isIDChar(char c) const
+    {
+        return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+               || ((c >= '0') && (c <= '9'));
+    }
+
+    /**
+     * @brief remove all "/0x00" parts
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string remove0x00(const std::string& src) const
+    {
+        return std::regex_replace(src, std::regex("/0x00"), "");
+    }
+
+    /**
+     * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string str2ID(const std::string& src) const
+    {
+        std::string dst;
+        bool need_underscore = false;
+        for (char c : src) {
+            if (isIDChar(c) || (c == '/')) {
+                if (need_underscore) {
+                    dst.push_back('_');
+                    need_underscore = false;
+                }
+                dst.push_back(c);
+            } else {
+                need_underscore = true;
+            }
+        }
+        return dst;
+    }
+
+    /**
+     * @brief Keep only the last n slash-parts
+     *
+     * @param src
+     * @param n : 1 indicates the last slash-part
+     * @return modified string
+     */
+    std::string cut(const std::string& src, int n) const
+    {
+        std::string rdst;
+        for (int i = int(src.length()) - 1; i >= 0; i--) {
+            char c = src[i];
+            if (c != '/') {
+                rdst.push_back(c);
+            } else if (n == 1) {
+                std::string dst;
+                for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+                    dst.push_back(rdst[j]);
+                }
+                return dst;
+            } else {
+                n--;
+                rdst.push_back(c);
+            }
+        }
+        return src;
+    }
+
+    void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+    /**
+     * @brief Compute the mapping between full path and short names
+     */
+    void computeShortNames()
+    {
+        std::vector<std::string>
+            uniquePaths;  // all full paths transformed but made unique with a prefix
+        std::map<std::string, std::string>
+            unique2full;  // all full paths transformed but made unique with a prefix
+        char num_buffer[16];
+        int pnum = 0;
+
+        for (const auto& s : fFullPaths) {
+            sprintf(num_buffer, "%d", pnum++);
+            std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+            uniquePaths.push_back(u);
+            unique2full[u] = s;  // remember the full path associated to a unique path
+        }
+
+        std::map<std::string, int> uniquePath2level;  // map path to level
+        for (const auto& s : uniquePaths)
+            uniquePath2level[s] = 1;  // we init all levels to 1
+        bool have_collisions = true;
+
+        while (have_collisions) {
+            // compute collision list
+            std::set<std::string> collisionSet;
+            std::map<std::string, std::string> short2full;
+            have_collisions = false;
+            for (const auto& it : uniquePath2level) {
+                std::string u         = it.first;
+                int n                 = it.second;
+                std::string shortName = cut(u, n);
+                auto p                = short2full.find(shortName);
+                if (p == short2full.end()) {
+                    // no collision
+                    short2full[shortName] = u;
+                } else {
+                    // we have a collision, add the two paths to the collision set
+                    have_collisions = true;
+                    collisionSet.insert(u);
+                    collisionSet.insert(p->second);
+                }
+            }
+            for (const auto& s : collisionSet)
+                uniquePath2level[s]++;  // increase level of colliding path
+        }
+
+        for (const auto& it : uniquePath2level) {
+            std::string u               = it.first;
+            int n                       = it.second;
+            std::string shortName       = replaceCharList(cut(u, n), {'/'}, '_');
+            fFull2Short[unique2full[u]] = shortName;
+        }
+    }
+
+    std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+                                char ch2)
+    {
+        auto beg        = ch1.begin();
+        auto end        = ch1.end();
+        std::string res = str;
+        for (size_t i = 0; i < str.length(); ++i) {
+            if (std::find(beg, end, str[i]) != end)
+                res[i] = ch2;
+        }
+        return res;
+    }
 
    public:
     PathBuilder() {}
     virtual ~PathBuilder() {}
 
+    // Return true for the first level of groups
+    bool pushLabel(const std::string& label)
+    {
+        fControlsLevel.push_back(label);
+        return fControlsLevel.size() == 1;
+    }
+
+    // Return true for the last level of groups
+    bool popLabel()
+    {
+        fControlsLevel.pop_back();
+        return fControlsLevel.size() == 0;
+    }
+
     std::string buildPath(const std::string& label)
     {
         std::string res = "/";
         for (size_t i = 0; i < fControlsLevel.size(); i++) {
-            res += fControlsLevel[i];
-            res += "/";
+            res = res + fControlsLevel[i] + "/";
         }
         res += label;
-        std::replace(res.begin(), res.end(), ' ', '_');
-        return res;
-    }
-
-    std::string buildLabel(std::string label)
-    {
-        std::replace(label.begin(), label.end(), ' ', '_');
-        return label;
+        return replaceCharList(
+            res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
     }
-
-    void pushLabel(const std::string& label) { fControlsLevel.push_back(label); }
-    void popLabel() { fControlsLevel.pop_back(); }
 };
 
-#endif  // FAUST_PATHBUILDER_H
+#endif  // __PathBuilder__
 /**************************  END  PathBuilder.h **************************/
-/************************** BEGIN ValueConverter.h **************************/
-/************************************************************************
+/************************** BEGIN ValueConverter.h ********************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __ValueConverter__
 #define __ValueConverter__
 
 /***************************************************************************************
                                                               ValueConverter.h
                           (GRAME, Copyright 2015-2019)
+ ValueConverter.h
+ (GRAME, Copyright 2015-2019)
 
-Set of conversion objects used to map user interface values (for example a gui slider
-delivering values between 0 and 1) to faust values (for example a vslider between
-20 and 20000) using a log scale.
+ Set of conversion objects used to map user interface values (for example a gui slider
+ delivering values between 0 and 1) to faust values (for example a vslider between
+ 20 and 20000) using a log scale.
 
--- Utilities
+ -- Utilities
 
-Range(lo,hi) : clip a value x between lo and hi
-Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
+ Range(lo,hi) : clip a value x between lo and hi
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
 v2 Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1
 vm v2
 
--- Value Converters
+ -- Value Converters
 
-ValueConverter::ui2faust(x)
-ValueConverter::faust2ui(x)
+ ValueConverter::ui2faust(x)
+ ValueConverter::faust2ui(x)
 
--- ValueConverters used for sliders depending of the scale
+ -- ValueConverters used for sliders depending of the scale
 
-LinearValueConverter(umin, umax, fmin, fmax)
-LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
-LogValueConverter(umin, umax, fmin, fmax)
-ExpValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
+ LogValueConverter(umin, umax, fmin, fmax)
+ ExpValueConverter(umin, umax, fmin, fmax)
 
--- ValueConverters used for accelerometers based on 3 points
+ -- ValueConverters used for accelerometers based on 3 points
 
-AccUpConverter(amin, amid, amax, fmin, fmid, fmax)             -- curve 0
-AccDownConverter(amin, amid, amax, fmin, fmid, fmax)   -- curve 1
-AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 2
-AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 3
+ AccUpConverter(amin, amid, amax, fmin, fmid, fmax)        -- curve 0
+ AccDownConverter(amin, amid, amax, fmin, fmid, fmax)      -- curve 1
+ AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 2
+ AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 3
 
--- lists of ZoneControl are used to implement accelerometers metadata for each axes
+ -- lists of ZoneControl are used to implement accelerometers metadata for each axes
 
-ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
+ ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
 
--- ZoneReader are used to implement screencolor metadata
+ -- ZoneReader are used to implement screencolor metadata
 
-ZoneReader(zone, valueConverter) : a zone with a data converter
+ ZoneReader(zone, valueConverter) : a zone with a data converter
 
 ****************************************************************************************/
 
+#include <assert.h>
+#include <float.h>
+
 #include <algorithm>  // std::max
-#include <cassert>
-#include <cfloat>
 #include <cmath>
 #include <vector>
 
@@ -552,12 +838,12 @@ ZoneReader(zone, valueConverter) : a zone with a data converter
 // Interpolator(lo,hi,v1,v2)
 // Maps a value x between lo and hi to a value y between v1 and v2
 // y = v1 + (x-lo)/(hi-lo)*(v2-v1)
-// y = v1 + (x-lo) * coef              with coef = (v2-v1)/(hi-lo)
+// y = v1 + (x-lo) * coef           with coef = (v2-v1)/(hi-lo)
 // y = v1 + x*coef - lo*coef
 // y = v1 - lo*coef + x*coef
-// y = offset + x*coef                         with offset = v1 - lo*coef
+// y = offset + x*coef              with offset = v1 - lo*coef
 //--------------------------------------------------------------------------------------
-class Interpolator
+class FAUST_API Interpolator
 {
    private:
     //--------------------------------------------------------------------------------------
@@ -608,7 +894,7 @@ class Interpolator
 // Interpolator3pt(lo,mi,hi,v1,vm,v2)
 // Map values between lo mid hi to values between v1 vm v2
 //--------------------------------------------------------------------------------------
-class Interpolator3pt
+class FAUST_API Interpolator3pt
 {
    private:
     Interpolator fSegment1;
@@ -632,19 +918,19 @@ class Interpolator3pt
 //--------------------------------------------------------------------------------------
 // Abstract ValueConverter class. Converts values between UI and Faust representations
 //--------------------------------------------------------------------------------------
-class ValueConverter
+class FAUST_API ValueConverter
 {
    public:
     virtual ~ValueConverter() {}
-    virtual double ui2faust(double x) = 0;
-    virtual double faust2ui(double x) = 0;
+    virtual double ui2faust(double x) { return x; };
+    virtual double faust2ui(double x) { return x; };
 };
 
 //--------------------------------------------------------------------------------------
 // A converter than can be updated
 //--------------------------------------------------------------------------------------
 
-class UpdatableValueConverter : public ValueConverter
+class FAUST_API UpdatableValueConverter : public ValueConverter
 {
    protected:
     bool fActive;
@@ -664,7 +950,7 @@ class UpdatableValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter : public ValueConverter
+class FAUST_API LinearValueConverter : public ValueConverter
 {
    private:
     Interpolator fUI2F;
@@ -684,7 +970,7 @@ class LinearValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Two segments linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter2 : public UpdatableValueConverter
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fUI2F;
@@ -720,7 +1006,7 @@ class LinearValueConverter2 : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Logarithmic conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LogValueConverter : public LinearValueConverter
+class FAUST_API LogValueConverter : public LinearValueConverter
 {
    public:
     LogValueConverter(double umin, double umax, double fmin, double fmax)
@@ -742,7 +1028,7 @@ class LogValueConverter : public LinearValueConverter
 //--------------------------------------------------------------------------------------
 // Exponential conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class ExpValueConverter : public LinearValueConverter
+class FAUST_API ExpValueConverter : public LinearValueConverter
 {
    public:
     ExpValueConverter(double umin, double umax, double fmin, double fmax)
@@ -765,7 +1051,7 @@ class ExpValueConverter : public LinearValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up curve (curve 0)
 //--------------------------------------------------------------------------------------
-class AccUpConverter : public UpdatableValueConverter
+class FAUST_API AccUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -801,7 +1087,7 @@ class AccUpConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down curve (curve 1)
 //--------------------------------------------------------------------------------------
-class AccDownConverter : public UpdatableValueConverter
+class FAUST_API AccDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -837,14 +1123,14 @@ class AccDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up-Down curve (curve 2)
 //--------------------------------------------------------------------------------------
-class AccUpDownConverter : public UpdatableValueConverter
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccUpDownConverter(double amin, double amid, double amax, double fmin, double fmid,
+    AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
                        double fmax)
         : fA2F(amin, amid, amax, fmin, fmax, fmin)
         , fF2A(fmin, fmax, amin,
@@ -856,7 +1142,7 @@ class AccUpDownConverter : public UpdatableValueConverter
     virtual double faust2ui(double x) { return fF2A(x); }
 
     virtual void setMappingValues(double amin, double amid, double amax, double fmin,
-                                  double fmid, double fmax)
+                                  double /*fmid*/, double fmax)
     {
         //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f
         //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
@@ -874,14 +1160,14 @@ class AccUpDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down-Up curve (curve 3)
 //--------------------------------------------------------------------------------------
-class AccDownUpConverter : public UpdatableValueConverter
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccDownUpConverter(double amin, double amid, double amax, double fmin, double fmid,
+    AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
                        double fmax)
         : fA2F(amin, amid, amax, fmax, fmin, fmax)
         , fF2A(fmin, fmax, amin,
@@ -893,7 +1179,7 @@ class AccDownUpConverter : public UpdatableValueConverter
     virtual double faust2ui(double x) { return fF2A(x); }
 
     virtual void setMappingValues(double amin, double amid, double amax, double fmin,
-                                  double fmid, double fmax)
+                                  double /*fmid*/, double fmax)
     {
         //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f
         //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
@@ -910,7 +1196,7 @@ class AccDownUpConverter : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Base class for ZoneControl
 //--------------------------------------------------------------------------------------
-class ZoneControl
+class FAUST_API ZoneControl
 {
    protected:
     FAUSTFLOAT* fZone;
@@ -919,17 +1205,17 @@ class ZoneControl
     ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
     virtual ~ZoneControl() {}
 
-    virtual void update(double v) const {}
+    virtual void update(double /*v*/) const {}
 
-    virtual void setMappingValues(int curve, double amin, double amid, double amax,
-                                  double min, double init, double max)
+    virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
+                                  double /*min*/, double /*init*/, double /*max*/)
     {
     }
-    virtual void getMappingValues(double& amin, double& amid, double& amax) {}
+    virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
 
     FAUSTFLOAT* getZone() { return fZone; }
 
-    virtual void setActive(bool on_off) {}
+    virtual void setActive(bool /*on_off*/) {}
     virtual bool getActive() { return false; }
 
     virtual int getCurve() { return -1; }
@@ -938,7 +1224,7 @@ class ZoneControl
 //--------------------------------------------------------------------------------------
 //  Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class ConverterZoneControl : public ZoneControl
+class FAUST_API ConverterZoneControl : public ZoneControl
 {
    protected:
     ValueConverter* fValueConverter;
@@ -953,7 +1239,10 @@ class ConverterZoneControl : public ZoneControl
         delete fValueConverter;
     }  // Assuming fValueConverter is not kept elsewhere...
 
-    virtual void update(double v) const { *fZone = fValueConverter->ui2faust(v); }
+    virtual void update(double v) const
+    {
+        *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v));
+    }
 
     ValueConverter* getConverter() { return fValueConverter; }
 };
@@ -962,7 +1251,7 @@ class ConverterZoneControl : public ZoneControl
 // Association of a zone and a four value converter, each one for each possible curve.
 // Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class CurveZoneControl : public ZoneControl
+class FAUST_API CurveZoneControl : public ZoneControl
 {
    private:
     std::vector<UpdatableValueConverter*> fValueConverters;
@@ -985,15 +1274,14 @@ class CurveZoneControl : public ZoneControl
     }
     virtual ~CurveZoneControl()
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            delete (*it);
+        for (const auto& it : fValueConverters) {
+            delete it;
         }
     }
     void update(double v) const
     {
         if (fValueConverters[fCurve]->getActive())
-            *fZone = fValueConverters[fCurve]->ui2faust(v);
+            *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v));
     }
 
     void setMappingValues(int curve, double amin, double amid, double amax, double min,
@@ -1010,16 +1298,15 @@ class CurveZoneControl : public ZoneControl
 
     void setActive(bool on_off)
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            (*it)->setActive(on_off);
+        for (const auto& it : fValueConverters) {
+            it->setActive(on_off);
         }
     }
 
     int getCurve() { return fCurve; }
 };
 
-class ZoneReader
+class FAUST_API ZoneReader
 {
    private:
     FAUSTFLOAT* fZone;
@@ -1039,6 +1326,8 @@ class ZoneReader
 #endif
 /**************************  END  ValueConverter.h **************************/
 
+typedef unsigned int uint;
+
 class APIUI
     : public PathBuilder
     , public Meta
@@ -1054,22 +1343,42 @@ class APIUI
         kHBargraph,
         kVBargraph
     };
+    enum Type { kAcc = 0, kGyr = 1, kNoType };
 
    protected:
-    enum { kLin = 0, kLog = 1, kExp = 2 };
-
-    int fNumParameters;
-    std::vector<std::string> fPaths;
-    std::vector<std::string> fLabels;
-    std::map<std::string, int> fPathMap;
-    std::map<std::string, int> fLabelMap;
-    std::vector<ValueConverter*> fConversion;
-    std::vector<FAUSTFLOAT*> fZone;
-    std::vector<FAUSTFLOAT> fInit;
-    std::vector<FAUSTFLOAT> fMin;
-    std::vector<FAUSTFLOAT> fMax;
-    std::vector<FAUSTFLOAT> fStep;
-    std::vector<ItemType> fItemType;
+    enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+    struct Item {
+        std::string fLabel;
+        std::string fShortname;
+        std::string fPath;
+        ValueConverter* fConversion;
+        FAUSTFLOAT* fZone;
+        FAUSTFLOAT fInit;
+        FAUSTFLOAT fMin;
+        FAUSTFLOAT fMax;
+        FAUSTFLOAT fStep;
+        ItemType fItemType;
+
+        Item(const std::string& label, const std::string& short_name,
+             const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+             FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+             ItemType item_type)
+            : fLabel(label)
+            , fShortname(short_name)
+            , fPath(path)
+            , fConversion(conversion)
+            , fZone(zone)
+            , fInit(init)
+            , fMin(min)
+            , fMax(max)
+            , fStep(step)
+            , fItemType(item_type)
+        {
+        }
+    };
+    std::vector<Item> fItems;
+
     std::vector<std::map<std::string, std::string> > fMetaData;
     std::vector<ZoneControl*> fAcc[3];
     std::vector<ZoneControl*> fGyr[3];
@@ -1096,33 +1405,31 @@ class APIUI
                               ItemType type)
     {
         std::string path = buildPath(label);
-        fPathMap[path] = fLabelMap[label] = fNumParameters++;
-        fPaths.push_back(path);
-        fLabels.push_back(label);
-        fZone.push_back(zone);
-        fInit.push_back(init);
-        fMin.push_back(min);
-        fMax.push_back(max);
-        fStep.push_back(step);
-        fItemType.push_back(type);
+        fFullPaths.push_back(path);
 
         // handle scale metadata
+        ValueConverter* converter = nullptr;
         switch (fCurrentScale) {
         case kLin:
-            fConversion.push_back(new LinearValueConverter(0, 1, min, max));
+            converter = new LinearValueConverter(0, 1, min, max);
             break;
         case kLog:
-            fConversion.push_back(new LogValueConverter(0, 1, min, max));
+            converter = new LogValueConverter(0, 1, min, max);
             break;
         case kExp:
-            fConversion.push_back(new ExpValueConverter(0, 1, min, max));
+            converter = new ExpValueConverter(0, 1, min, max);
             break;
         }
         fCurrentScale = kLin;
 
+        fItems.push_back(
+            Item(label, "", path, converter, zone, init, min, max, step, type));
+
         if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
-            std::cerr << "warning : 'acc' and 'gyr' metadata used for the same " << label
-                      << " parameter !!\n";
+            fprintf(
+                stderr,
+                "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n",
+                label);
         }
 
         // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
@@ -1137,7 +1444,7 @@ class APIUI
                 fAcc[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect acc metadata : " << fCurrentAcc << std::endl;
+                fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
             }
             fCurrentAcc = "";
         }
@@ -1154,31 +1461,31 @@ class APIUI
                 fGyr[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect gyr metadata : " << fCurrentGyr << std::endl;
+                fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
             }
             fCurrentGyr = "";
         }
 
         // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
         if (fCurrentColor.size() > 0) {
-            if ((fCurrentColor == "red") && (fRedReader == 0)) {
+            if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "green") && (fGreenReader == 0)) {
+            } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "blue") && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "white") && (fRedReader == 0)
-                       && (fGreenReader == 0) && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "white") && (fRedReader == nullptr)
+                       && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
             } else {
-                std::cerr << "incorrect screencolor metadata : " << fCurrentColor
-                          << std::endl;
+                fprintf(stderr, "incorrect screencolor metadata : %s \n",
+                        fCurrentColor.c_str());
             }
         }
         fCurrentColor = "";
@@ -1189,7 +1496,7 @@ class APIUI
 
     int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
     {
-        FAUSTFLOAT* zone = fZone[p];
+        FAUSTFLOAT* zone = fItems[uint(p)].fZone;
         for (size_t i = 0; i < table[val].size(); i++) {
             if (zone == table[val][i]->getZone())
                 return int(i);
@@ -1206,11 +1513,11 @@ class APIUI
 
         // Deactivates everywhere..
         if (id1 != -1)
-            table[0][id1]->setActive(false);
+            table[0][uint(id1)]->setActive(false);
         if (id2 != -1)
-            table[1][id2]->setActive(false);
+            table[1][uint(id2)]->setActive(false);
         if (id3 != -1)
-            table[2][id3]->setActive(false);
+            table[2][uint(id3)]->setActive(false);
 
         if (val == -1) {  // Means: no more mapping...
             // So stay all deactivated...
@@ -1218,14 +1525,16 @@ class APIUI
             int id4 = getZoneIndex(table, p, val);
             if (id4 != -1) {
                 // Reactivate the one we edit...
-                table[val][id4]->setMappingValues(curve, amin, amid, amax, fMin[p],
-                                                  fInit[p], fMax[p]);
-                table[val][id4]->setActive(true);
+                table[val][uint(id4)]->setMappingValues(
+                    curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit,
+                    fItems[uint(p)].fMax);
+                table[val][uint(id4)]->setActive(true);
             } else {
                 // Allocate a new CurveZoneControl which is 'active' by default
-                FAUSTFLOAT* zone = fZone[p];
-                table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax,
-                                                          fMin[p], fInit[p], fMax[p]));
+                FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+                table[val].push_back(new CurveZoneControl(
+                    zone, curve, amin, amid, amax, fItems[uint(p)].fMin,
+                    fItems[uint(p)].fInit, fItems[uint(p)].fMax));
             }
         }
     }
@@ -1239,16 +1548,16 @@ class APIUI
 
         if (id1 != -1) {
             val   = 0;
-            curve = table[val][id1]->getCurve();
-            table[val][id1]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id1)]->getCurve();
+            table[val][uint(id1)]->getMappingValues(amin, amid, amax);
         } else if (id2 != -1) {
             val   = 1;
-            curve = table[val][id2]->getCurve();
-            table[val][id2]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id2)]->getCurve();
+            table[val][uint(id2)]->getMappingValues(amin, amid, amax);
         } else if (id3 != -1) {
             val   = 2;
-            curve = table[val][id3]->getCurve();
-            table[val][id3]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id3)]->getCurve();
+            table[val][uint(id3)]->getMappingValues(amin, amid, amax);
         } else {
             val   = -1;  // No mapping
             curve = 0;
@@ -1259,26 +1568,23 @@ class APIUI
     }
 
    public:
-    enum Type { kAcc = 0, kGyr = 1, kNoType };
-
     APIUI()
-        : fNumParameters(0)
-        , fHasScreenControl(false)
-        , fRedReader(0)
-        , fGreenReader(0)
-        , fBlueReader(0)
+        : fHasScreenControl(false)
+        , fRedReader(nullptr)
+        , fGreenReader(nullptr)
+        , fBlueReader(nullptr)
         , fCurrentScale(kLin)
     {
     }
 
     virtual ~APIUI()
     {
-        for (auto& it : fConversion)
-            delete it;
+        for (const auto& it : fItems)
+            delete it.fConversion;
         for (int i = 0; i < 3; i++) {
-            for (auto& it : fAcc[i])
+            for (const auto& it : fAcc[i])
                 delete it;
-            for (auto& it : fGyr[i])
+            for (const auto& it : fGyr[i])
                 delete it;
         }
         delete fRedReader;
@@ -1291,7 +1597,18 @@ class APIUI
     virtual void openTabBox(const char* label) { pushLabel(label); }
     virtual void openHorizontalBox(const char* label) { pushLabel(label); }
     virtual void openVerticalBox(const char* label) { pushLabel(label); }
-    virtual void closeBox() { popLabel(); }
+    virtual void closeBox()
+    {
+        if (popLabel()) {
+            // Shortnames can be computed when all fullnames are known
+            computeShortNames();
+            // Fill 'shortname' field for each item
+            for (const auto& it : fFull2Short) {
+                int index                = getParamIndex(it.first.c_str());
+                fItems[index].fShortname = it.second;
+            }
+        }
+    }
 
     // -- active widgets
 
@@ -1328,25 +1645,25 @@ class APIUI
     virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone,
                                        FAUSTFLOAT min, FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kHBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kHBargraph);
     }
 
     virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min,
                                      FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kVBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kVBargraph);
     }
 
     // -- soundfiles
 
-    virtual void addSoundfile(const char* label, const char* filename,
-                              Soundfile** sf_zone)
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+                              Soundfile** /*sf_zone*/)
     {
     }
 
     // -- metadata declarations
 
-    virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+    virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
     {
         // Keep metadata
         fCurrentMetadata[key] = val;
@@ -1372,29 +1689,31 @@ class APIUI
         }
     }
 
-    virtual void declare(const char* key, const char* val) {}
+    virtual void declare(const char* /*key*/, const char* /*val*/) {}
 
     //-------------------------------------------------------------------------------
     // Simple API part
     //-------------------------------------------------------------------------------
-    int getParamsCount() { return fNumParameters; }
-    int getParamIndex(const char* path)
+    int getParamsCount() { return int(fItems.size()); }
+
+    int getParamIndex(const char* path_aux)
     {
-        if (fPathMap.find(path) != fPathMap.end()) {
-            return fPathMap[path];
-        } else if (fLabelMap.find(path) != fLabelMap.end()) {
-            return fLabelMap[path];
-        } else {
-            return -1;
-        }
+        std::string path = std::string(path_aux);
+        auto it          = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+            return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+                 });
+        return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
     }
-    const char* getParamAddress(int p) { return fPaths[p].c_str(); }
-    const char* getParamLabel(int p) { return fLabels[p].c_str(); }
+
+    const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
+    const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
+    const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+
     std::map<const char*, const char*> getMetadata(int p)
     {
         std::map<const char*, const char*> res;
-        std::map<std::string, std::string> metadata = fMetaData[p];
-        for (auto it : metadata) {
+        std::map<std::string, std::string> metadata = fMetaData[uint(p)];
+        for (const auto& it : metadata) {
             res[it.first.c_str()] = it.second.c_str();
         }
         return res;
@@ -1402,26 +1721,62 @@ class APIUI
 
     const char* getMetadata(int p, const char* key)
     {
-        return (fMetaData[p].find(key) != fMetaData[p].end()) ? fMetaData[p][key].c_str()
-                                                              : "";
+        return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end())
+                   ? fMetaData[uint(p)][key].c_str()
+                   : "";
     }
-    FAUSTFLOAT getParamMin(int p) { return fMin[p]; }
-    FAUSTFLOAT getParamMax(int p) { return fMax[p]; }
-    FAUSTFLOAT getParamStep(int p) { return fStep[p]; }
-    FAUSTFLOAT getParamInit(int p) { return fInit[p]; }
+    FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
+    FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
+    FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
+    FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
 
-    FAUSTFLOAT* getParamZone(int p) { return fZone[p]; }
-    FAUSTFLOAT getParamValue(int p) { return *fZone[p]; }
-    void setParamValue(int p, FAUSTFLOAT v) { *fZone[p] = v; }
+    FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
 
-    double getParamRatio(int p) { return fConversion[p]->faust2ui(*fZone[p]); }
-    void setParamRatio(int p, double r) { *fZone[p] = fConversion[p]->ui2faust(r); }
+    FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
+    FAUSTFLOAT getParamValue(const char* path)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            return getParamValue(index);
+        } else {
+            fprintf(stderr, "getParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+            return FAUSTFLOAT(0);
+        }
+    }
+
+    void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+    void setParamValue(const char* path, FAUSTFLOAT v)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            setParamValue(index, v);
+        } else {
+            fprintf(stderr, "setParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+        }
+    }
+
+    double getParamRatio(int p)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone);
+    }
+    void setParamRatio(int p, double r)
+    {
+        *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r));
+    }
 
-    double value2ratio(int p, double r) { return fConversion[p]->faust2ui(r); }
-    double ratio2value(int p, double r) { return fConversion[p]->ui2faust(r); }
+    double value2ratio(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(r);
+    }
+    double ratio2value(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->ui2faust(r);
+    }
 
     /**
-     * Return the control type (kAcc, kGyr, or -1) for a given parameter
+     * Return the control type (kAcc, kGyr, or -1) for a given parameter.
      *
      * @param p - the UI parameter index
      *
@@ -1443,13 +1798,13 @@ class APIUI
 
     /**
      * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry,
-     * kHBargraph, kVBargraph) for a given parameter
+     * kHBargraph, kVBargraph) for a given parameter.
      *
      * @param p - the UI parameter index
      *
      * @return the Item type
      */
-    ItemType getParamItemType(int p) { return fItemType[p]; }
+    ItemType getParamItemType(int p) { return fItems[uint(p)].fItemType; }
 
     /**
      * Set a new value coming from an accelerometer, propagate it to all relevant
@@ -1489,7 +1844,7 @@ class APIUI
      * given UI parameter.
      *
      * @param p - the UI parameter index
-     * @param acc - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+     * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
      * mapping")
      * @param curve - between 0 and 3
      * @param amin - mapping 'min' point
@@ -1554,7 +1909,7 @@ class APIUI
     }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer
+     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
      *
      * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
      * @return the number of zones
@@ -1563,7 +1918,7 @@ class APIUI
     int getAccCount(int acc) { return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0; }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope
+     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
      *
      * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
      * @param the number of zones
@@ -1600,8 +1955,11 @@ class APIUI
 #define FAUSTFLOAT float
 #endif
 
+#include <math.h>
+
 #include <algorithm>
 #include <cmath>
+#include <cstdint>
 
 #ifndef FAUSTCLASS
 #define FAUSTCLASS freeverbmonodsp
@@ -1612,18 +1970,23 @@ class APIUI
 #define exp10  __exp10
 #endif
 
+#if defined(_WIN32)
+#define RESTRICT __restrict
+#else
+#define RESTRICT __restrict__
+#endif
+
 class freeverbmonodsp : public dsp
 {
    private:
     FAUSTFLOAT fVslider0;
     int fSampleRate;
-    float fConst0;
     float fConst1;
     FAUSTFLOAT fVslider1;
     float fConst2;
     FAUSTFLOAT fVslider2;
     float fRec9[2];
-    int IOTA;
+    int IOTA0;
     float fVec0[8192];
     int iConst3;
     float fConst4;
@@ -1709,6 +2072,9 @@ class freeverbmonodsp : public dsp
    public:
     void metadata(Meta* m)
     {
+        m->declare("compile_options",
+                   "-a faust2header.cpp -lang cpp -i -inpl -cn freeverbmonodsp -es 1 "
+                   "-mcd 16 -single -ftz 0");
         m->declare("delays.lib/name", "Faust Delay Library");
         m->declare("delays.lib/version", "0.1");
         m->declare("filename", "freeverbmonodsp.dsp");
@@ -1719,6 +2085,7 @@ class freeverbmonodsp : public dsp
         m->declare("filters.lib/allpass_comb:license", "MIT-style STK-4.3 license");
         m->declare("filters.lib/lowpass0_highpass1", "MIT-style STK-4.3 license");
         m->declare("filters.lib/name", "Faust Filters Library");
+        m->declare("filters.lib/version", "0.3");
         m->declare("freeverbdsp.dsp/author", "Romain Michon");
         m->declare("freeverbdsp.dsp/description",
                    "Freeverb implementation in Faust, from the Faust Library's "
@@ -1730,72 +2097,45 @@ class freeverbmonodsp : public dsp
         m->declare("maths.lib/copyright", "GRAME");
         m->declare("maths.lib/license", "LGPL with exception");
         m->declare("maths.lib/name", "Faust Math Library");
-        m->declare("maths.lib/version", "2.3");
+        m->declare("maths.lib/version", "2.5");
         m->declare("name", "freeverbmonodsp");
         m->declare("platform.lib/name", "Generic Platform Library");
-        m->declare("platform.lib/version", "0.1");
+        m->declare("platform.lib/version", "0.2");
+        m->declare("reverbs.lib/mono_freeverb:author", "Romain Michon");
         m->declare("reverbs.lib/name", "Faust Reverb Library");
-        m->declare("reverbs.lib/version", "0.0");
+        m->declare("reverbs.lib/stereo_freeverb:author", "Romain Michon");
+        m->declare("reverbs.lib/version", "0.2");
     }
 
     virtual int getNumInputs() { return 1; }
     virtual int getNumOutputs() { return 1; }
-    virtual int getInputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
-    virtual int getOutputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
 
     static void classInit(int /*sample_rate*/) {}
 
     virtual void instanceConstants(int sample_rate)
     {
         fSampleRate = sample_rate;
-        fConst0  = std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
-        fConst1  = (12348.0f / fConst0);
-        fConst2  = (17640.0f / fConst0);
-        iConst3  = int((0.0253061224f * fConst0));
-        fConst4  = (0.00104308384f * fConst0);
-        iConst5  = int((0.0269387756f * fConst0));
-        iConst6  = int((0.0289569162f * fConst0));
-        iConst7  = int((0.0307482984f * fConst0));
-        iConst8  = int((0.0322448984f * fConst0));
-        iConst9  = int((0.033809524f * fConst0));
-        iConst10 = int((0.0353061222f * fConst0));
-        iConst11 = int((0.0366666652f * fConst0));
-        iConst12 = int((0.0126077095f * fConst0));
-        iConst13 = int((0.00999999978f * fConst0));
-        iConst14 = int((0.00773242628f * fConst0));
-        iConst15 = int((0.00510204071f * fConst0));
-        iConst16 = std::min<int>(1024, std::max<int>(0, (iConst12 + -1)));
-        iConst17 = std::min<int>(1024, std::max<int>(0, (iConst13 + -1)));
-        iConst18 = std::min<int>(1024, std::max<int>(0, (iConst14 + -1)));
-        iConst19 = std::min<int>(1024, std::max<int>(0, (iConst15 + -1)));
+        float fConst0 =
+            std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
+        fConst1  = 12348.0f / fConst0;
+        fConst2  = 17640.0f / fConst0;
+        iConst3  = int(0.0253061224f * fConst0);
+        fConst4  = 0.00104308384f * fConst0;
+        iConst5  = int(0.0269387756f * fConst0);
+        iConst6  = int(0.0289569162f * fConst0);
+        iConst7  = int(0.0307482984f * fConst0);
+        iConst8  = int(0.0322448984f * fConst0);
+        iConst9  = int(0.033809524f * fConst0);
+        iConst10 = int(0.0353061222f * fConst0);
+        iConst11 = int(0.0366666652f * fConst0);
+        iConst12 = int(0.0126077095f * fConst0);
+        iConst13 = int(0.00999999978f * fConst0);
+        iConst14 = int(0.00773242628f * fConst0);
+        iConst15 = int(0.00510204071f * fConst0);
+        iConst16 = std::min<int>(1024, std::max<int>(0, iConst12 + -1));
+        iConst17 = std::min<int>(1024, std::max<int>(0, iConst13 + -1));
+        iConst18 = std::min<int>(1024, std::max<int>(0, iConst14 + -1));
+        iConst19 = std::min<int>(1024, std::max<int>(0, iConst15 + -1));
     }
 
     virtual void instanceResetUserInterface()
@@ -1808,197 +2148,197 @@ class freeverbmonodsp : public dsp
 
     virtual void instanceClear()
     {
-        for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
+        for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
             fRec9[l0] = 0.0f;
         }
-        IOTA = 0;
-        for (int l1 = 0; (l1 < 8192); l1 = (l1 + 1)) {
+        IOTA0 = 0;
+        for (int l1 = 0; l1 < 8192; l1 = l1 + 1) {
             fVec0[l1] = 0.0f;
         }
-        for (int l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
+        for (int l2 = 0; l2 < 2; l2 = l2 + 1) {
             fRec8[l2] = 0.0f;
         }
-        for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) {
+        for (int l3 = 0; l3 < 2; l3 = l3 + 1) {
             fRec11[l3] = 0.0f;
         }
-        for (int l4 = 0; (l4 < 8192); l4 = (l4 + 1)) {
+        for (int l4 = 0; l4 < 8192; l4 = l4 + 1) {
             fVec1[l4] = 0.0f;
         }
-        for (int l5 = 0; (l5 < 2); l5 = (l5 + 1)) {
+        for (int l5 = 0; l5 < 2; l5 = l5 + 1) {
             fRec10[l5] = 0.0f;
         }
-        for (int l6 = 0; (l6 < 2); l6 = (l6 + 1)) {
+        for (int l6 = 0; l6 < 2; l6 = l6 + 1) {
             fRec13[l6] = 0.0f;
         }
-        for (int l7 = 0; (l7 < 8192); l7 = (l7 + 1)) {
+        for (int l7 = 0; l7 < 8192; l7 = l7 + 1) {
             fVec2[l7] = 0.0f;
         }
-        for (int l8 = 0; (l8 < 2); l8 = (l8 + 1)) {
+        for (int l8 = 0; l8 < 2; l8 = l8 + 1) {
             fRec12[l8] = 0.0f;
         }
-        for (int l9 = 0; (l9 < 2); l9 = (l9 + 1)) {
+        for (int l9 = 0; l9 < 2; l9 = l9 + 1) {
             fRec15[l9] = 0.0f;
         }
-        for (int l10 = 0; (l10 < 8192); l10 = (l10 + 1)) {
+        for (int l10 = 0; l10 < 8192; l10 = l10 + 1) {
             fVec3[l10] = 0.0f;
         }
-        for (int l11 = 0; (l11 < 2); l11 = (l11 + 1)) {
+        for (int l11 = 0; l11 < 2; l11 = l11 + 1) {
             fRec14[l11] = 0.0f;
         }
-        for (int l12 = 0; (l12 < 2); l12 = (l12 + 1)) {
+        for (int l12 = 0; l12 < 2; l12 = l12 + 1) {
             fRec17[l12] = 0.0f;
         }
-        for (int l13 = 0; (l13 < 8192); l13 = (l13 + 1)) {
+        for (int l13 = 0; l13 < 8192; l13 = l13 + 1) {
             fVec4[l13] = 0.0f;
         }
-        for (int l14 = 0; (l14 < 2); l14 = (l14 + 1)) {
+        for (int l14 = 0; l14 < 2; l14 = l14 + 1) {
             fRec16[l14] = 0.0f;
         }
-        for (int l15 = 0; (l15 < 2); l15 = (l15 + 1)) {
+        for (int l15 = 0; l15 < 2; l15 = l15 + 1) {
             fRec19[l15] = 0.0f;
         }
-        for (int l16 = 0; (l16 < 8192); l16 = (l16 + 1)) {
+        for (int l16 = 0; l16 < 8192; l16 = l16 + 1) {
             fVec5[l16] = 0.0f;
         }
-        for (int l17 = 0; (l17 < 2); l17 = (l17 + 1)) {
+        for (int l17 = 0; l17 < 2; l17 = l17 + 1) {
             fRec18[l17] = 0.0f;
         }
-        for (int l18 = 0; (l18 < 2); l18 = (l18 + 1)) {
+        for (int l18 = 0; l18 < 2; l18 = l18 + 1) {
             fRec21[l18] = 0.0f;
         }
-        for (int l19 = 0; (l19 < 8192); l19 = (l19 + 1)) {
+        for (int l19 = 0; l19 < 8192; l19 = l19 + 1) {
             fVec6[l19] = 0.0f;
         }
-        for (int l20 = 0; (l20 < 2); l20 = (l20 + 1)) {
+        for (int l20 = 0; l20 < 2; l20 = l20 + 1) {
             fRec20[l20] = 0.0f;
         }
-        for (int l21 = 0; (l21 < 2); l21 = (l21 + 1)) {
+        for (int l21 = 0; l21 < 2; l21 = l21 + 1) {
             fRec23[l21] = 0.0f;
         }
-        for (int l22 = 0; (l22 < 8192); l22 = (l22 + 1)) {
+        for (int l22 = 0; l22 < 8192; l22 = l22 + 1) {
             fVec7[l22] = 0.0f;
         }
-        for (int l23 = 0; (l23 < 2); l23 = (l23 + 1)) {
+        for (int l23 = 0; l23 < 2; l23 = l23 + 1) {
             fRec22[l23] = 0.0f;
         }
-        for (int l24 = 0; (l24 < 2048); l24 = (l24 + 1)) {
+        for (int l24 = 0; l24 < 2048; l24 = l24 + 1) {
             fVec8[l24] = 0.0f;
         }
-        for (int l25 = 0; (l25 < 2); l25 = (l25 + 1)) {
+        for (int l25 = 0; l25 < 2; l25 = l25 + 1) {
             fRec6[l25] = 0.0f;
         }
-        for (int l26 = 0; (l26 < 2048); l26 = (l26 + 1)) {
+        for (int l26 = 0; l26 < 2048; l26 = l26 + 1) {
             fVec9[l26] = 0.0f;
         }
-        for (int l27 = 0; (l27 < 2); l27 = (l27 + 1)) {
+        for (int l27 = 0; l27 < 2; l27 = l27 + 1) {
             fRec4[l27] = 0.0f;
         }
-        for (int l28 = 0; (l28 < 2048); l28 = (l28 + 1)) {
+        for (int l28 = 0; l28 < 2048; l28 = l28 + 1) {
             fVec10[l28] = 0.0f;
         }
-        for (int l29 = 0; (l29 < 2); l29 = (l29 + 1)) {
+        for (int l29 = 0; l29 < 2; l29 = l29 + 1) {
             fRec2[l29] = 0.0f;
         }
-        for (int l30 = 0; (l30 < 2048); l30 = (l30 + 1)) {
+        for (int l30 = 0; l30 < 2048; l30 = l30 + 1) {
             fVec11[l30] = 0.0f;
         }
-        for (int l31 = 0; (l31 < 2); l31 = (l31 + 1)) {
+        for (int l31 = 0; l31 < 2; l31 = l31 + 1) {
             fRec0[l31] = 0.0f;
         }
-        for (int l32 = 0; (l32 < 2); l32 = (l32 + 1)) {
+        for (int l32 = 0; l32 < 2; l32 = l32 + 1) {
             fRec33[l32] = 0.0f;
         }
-        for (int l33 = 0; (l33 < 8192); l33 = (l33 + 1)) {
+        for (int l33 = 0; l33 < 8192; l33 = l33 + 1) {
             fVec12[l33] = 0.0f;
         }
-        for (int l34 = 0; (l34 < 2); l34 = (l34 + 1)) {
+        for (int l34 = 0; l34 < 2; l34 = l34 + 1) {
             fRec32[l34] = 0.0f;
         }
-        for (int l35 = 0; (l35 < 2); l35 = (l35 + 1)) {
+        for (int l35 = 0; l35 < 2; l35 = l35 + 1) {
             fRec35[l35] = 0.0f;
         }
-        for (int l36 = 0; (l36 < 8192); l36 = (l36 + 1)) {
+        for (int l36 = 0; l36 < 8192; l36 = l36 + 1) {
             fVec13[l36] = 0.0f;
         }
-        for (int l37 = 0; (l37 < 2); l37 = (l37 + 1)) {
+        for (int l37 = 0; l37 < 2; l37 = l37 + 1) {
             fRec34[l37] = 0.0f;
         }
-        for (int l38 = 0; (l38 < 2); l38 = (l38 + 1)) {
+        for (int l38 = 0; l38 < 2; l38 = l38 + 1) {
             fRec37[l38] = 0.0f;
         }
-        for (int l39 = 0; (l39 < 8192); l39 = (l39 + 1)) {
+        for (int l39 = 0; l39 < 8192; l39 = l39 + 1) {
             fVec14[l39] = 0.0f;
         }
-        for (int l40 = 0; (l40 < 2); l40 = (l40 + 1)) {
+        for (int l40 = 0; l40 < 2; l40 = l40 + 1) {
             fRec36[l40] = 0.0f;
         }
-        for (int l41 = 0; (l41 < 2); l41 = (l41 + 1)) {
+        for (int l41 = 0; l41 < 2; l41 = l41 + 1) {
             fRec39[l41] = 0.0f;
         }
-        for (int l42 = 0; (l42 < 8192); l42 = (l42 + 1)) {
+        for (int l42 = 0; l42 < 8192; l42 = l42 + 1) {
             fVec15[l42] = 0.0f;
         }
-        for (int l43 = 0; (l43 < 2); l43 = (l43 + 1)) {
+        for (int l43 = 0; l43 < 2; l43 = l43 + 1) {
             fRec38[l43] = 0.0f;
         }
-        for (int l44 = 0; (l44 < 2); l44 = (l44 + 1)) {
+        for (int l44 = 0; l44 < 2; l44 = l44 + 1) {
             fRec41[l44] = 0.0f;
         }
-        for (int l45 = 0; (l45 < 8192); l45 = (l45 + 1)) {
+        for (int l45 = 0; l45 < 8192; l45 = l45 + 1) {
             fVec16[l45] = 0.0f;
         }
-        for (int l46 = 0; (l46 < 2); l46 = (l46 + 1)) {
+        for (int l46 = 0; l46 < 2; l46 = l46 + 1) {
             fRec40[l46] = 0.0f;
         }
-        for (int l47 = 0; (l47 < 2); l47 = (l47 + 1)) {
+        for (int l47 = 0; l47 < 2; l47 = l47 + 1) {
             fRec43[l47] = 0.0f;
         }
-        for (int l48 = 0; (l48 < 8192); l48 = (l48 + 1)) {
+        for (int l48 = 0; l48 < 8192; l48 = l48 + 1) {
             fVec17[l48] = 0.0f;
         }
-        for (int l49 = 0; (l49 < 2); l49 = (l49 + 1)) {
+        for (int l49 = 0; l49 < 2; l49 = l49 + 1) {
             fRec42[l49] = 0.0f;
         }
-        for (int l50 = 0; (l50 < 2); l50 = (l50 + 1)) {
+        for (int l50 = 0; l50 < 2; l50 = l50 + 1) {
             fRec45[l50] = 0.0f;
         }
-        for (int l51 = 0; (l51 < 8192); l51 = (l51 + 1)) {
+        for (int l51 = 0; l51 < 8192; l51 = l51 + 1) {
             fVec18[l51] = 0.0f;
         }
-        for (int l52 = 0; (l52 < 2); l52 = (l52 + 1)) {
+        for (int l52 = 0; l52 < 2; l52 = l52 + 1) {
             fRec44[l52] = 0.0f;
         }
-        for (int l53 = 0; (l53 < 2); l53 = (l53 + 1)) {
+        for (int l53 = 0; l53 < 2; l53 = l53 + 1) {
             fRec47[l53] = 0.0f;
         }
-        for (int l54 = 0; (l54 < 8192); l54 = (l54 + 1)) {
+        for (int l54 = 0; l54 < 8192; l54 = l54 + 1) {
             fVec19[l54] = 0.0f;
         }
-        for (int l55 = 0; (l55 < 2); l55 = (l55 + 1)) {
+        for (int l55 = 0; l55 < 2; l55 = l55 + 1) {
             fRec46[l55] = 0.0f;
         }
-        for (int l56 = 0; (l56 < 2048); l56 = (l56 + 1)) {
+        for (int l56 = 0; l56 < 2048; l56 = l56 + 1) {
             fVec20[l56] = 0.0f;
         }
-        for (int l57 = 0; (l57 < 2); l57 = (l57 + 1)) {
+        for (int l57 = 0; l57 < 2; l57 = l57 + 1) {
             fRec30[l57] = 0.0f;
         }
-        for (int l58 = 0; (l58 < 2048); l58 = (l58 + 1)) {
+        for (int l58 = 0; l58 < 2048; l58 = l58 + 1) {
             fVec21[l58] = 0.0f;
         }
-        for (int l59 = 0; (l59 < 2); l59 = (l59 + 1)) {
+        for (int l59 = 0; l59 < 2; l59 = l59 + 1) {
             fRec28[l59] = 0.0f;
         }
-        for (int l60 = 0; (l60 < 2048); l60 = (l60 + 1)) {
+        for (int l60 = 0; l60 < 2048; l60 = l60 + 1) {
             fVec22[l60] = 0.0f;
         }
-        for (int l61 = 0; (l61 < 2); l61 = (l61 + 1)) {
+        for (int l61 = 0; l61 < 2; l61 = l61 + 1) {
             fRec26[l61] = 0.0f;
         }
-        for (int l62 = 0; (l62 < 1024); l62 = (l62 + 1)) {
+        for (int l62 = 0; l62 < 1024; l62 = l62 + 1) {
             fVec23[l62] = 0.0f;
         }
-        for (int l63 = 0; (l63 < 2); l63 = (l63 + 1)) {
+        for (int l63 = 0; l63 < 2; l63 = l63 + 1) {
             fRec24[l63] = 0.0f;
         }
     }
@@ -2028,29 +2368,33 @@ class freeverbmonodsp : public dsp
         ui_interface->declare(&fVslider2, "style", "knob");
         ui_interface->declare(&fVslider2, "tooltip",
                               "Somehow control the   density of the reverb.");
-        ui_interface->addVerticalSlider("Damp", &fVslider2, 0.5f, 0.0f, 1.0f,
-                                        0.0250000004f);
+        ui_interface->addVerticalSlider("Damp", &fVslider2, FAUSTFLOAT(0.5f),
+                                        FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+                                        FAUSTFLOAT(0.0250000004f));
         ui_interface->declare(&fVslider1, "1", "");
         ui_interface->declare(&fVslider1, "style", "knob");
         ui_interface->declare(
             &fVslider1, "tooltip",
             "The room size   between 0 and 1 with 1 for the largest room.");
-        ui_interface->addVerticalSlider("RoomSize", &fVslider1, 0.100000001f, 0.0f, 1.0f,
-                                        0.0250000004f);
+        ui_interface->addVerticalSlider("RoomSize", &fVslider1, FAUSTFLOAT(0.100000001f),
+                                        FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+                                        FAUSTFLOAT(0.0250000004f));
         ui_interface->declare(&fVslider3, "2", "");
         ui_interface->declare(&fVslider3, "style", "knob");
         ui_interface->declare(
             &fVslider3, "tooltip",
             "Spatial   spread between 0 and 1 with 1 for maximum spread.");
-        ui_interface->addVerticalSlider("Stereo Spread", &fVslider3, 0.5f, 0.0f, 1.0f,
-                                        0.00999999978f);
+        ui_interface->addVerticalSlider("Stereo Spread", &fVslider3, FAUSTFLOAT(0.5f),
+                                        FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+                                        FAUSTFLOAT(0.00999999978f));
         ui_interface->closeBox();
         ui_interface->declare(&fVslider0, "1", "");
         ui_interface->declare(&fVslider0, "tooltip",
                               "The amount of reverb applied to the signal   between 0 "
                               "and 1 with 1 for the maximum amount of reverb.");
-        ui_interface->addVerticalSlider("Wet", &fVslider0, 0.100000001f, 0.0f, 1.0f,
-                                        0.0250000004f);
+        ui_interface->addVerticalSlider("Wet", &fVslider0, FAUSTFLOAT(0.100000001f),
+                                        FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+                                        FAUSTFLOAT(0.0250000004f));
         ui_interface->closeBox();
     }
 
@@ -2059,122 +2403,114 @@ class freeverbmonodsp : public dsp
         FAUSTFLOAT* input0  = inputs[0];
         FAUSTFLOAT* output0 = outputs[0];
         float fSlow0        = float(fVslider0);
-        float fSlow1        = (0.200000003f * fSlow0);
-        float fSlow2        = ((fConst1 * float(fVslider1)) + 0.699999988f);
-        float fSlow3        = (fConst2 * float(fVslider2));
-        float fSlow4        = (1.0f - fSlow3);
-        int iSlow5          = int((fConst4 * float(fVslider3)));
-        int iSlow6          = (iConst3 + iSlow5);
-        int iSlow7          = (iConst5 + iSlow5);
-        int iSlow8          = (iConst6 + iSlow5);
-        int iSlow9          = (iConst7 + iSlow5);
-        int iSlow10         = (iConst8 + iSlow5);
-        int iSlow11         = (iConst9 + iSlow5);
-        int iSlow12         = (iConst10 + iSlow5);
-        int iSlow13         = (iConst11 + iSlow5);
-        int iSlow14         = (iSlow5 + -1);
-        int iSlow15         = std::min<int>(1024, std::max<int>(0, (iConst12 + iSlow14)));
-        int iSlow16         = std::min<int>(1024, std::max<int>(0, (iConst13 + iSlow14)));
-        int iSlow17         = std::min<int>(1024, std::max<int>(0, (iConst14 + iSlow14)));
-        int iSlow18         = std::min<int>(1024, std::max<int>(0, (iConst15 + iSlow14)));
-        float fSlow19       = (2.0f * (1.0f - fSlow0));
-        for (int i = 0; (i < count); i = (i + 1)) {
-            float fTemp0         = float(input0[i]);
-            float fTemp1         = (fSlow1 * fTemp0);
-            fRec9[0]             = ((fSlow3 * fRec9[1]) + (fSlow4 * fRec8[1]));
-            fVec0[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec9[0]));
-            fRec8[0]             = fVec0[((IOTA - iSlow6) & 8191)];
-            fRec11[0]            = ((fSlow3 * fRec11[1]) + (fSlow4 * fRec10[1]));
-            fVec1[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec11[0]));
-            fRec10[0]            = fVec1[((IOTA - iSlow7) & 8191)];
-            fRec13[0]            = ((fSlow3 * fRec13[1]) + (fSlow4 * fRec12[1]));
-            fVec2[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec13[0]));
-            fRec12[0]            = fVec2[((IOTA - iSlow8) & 8191)];
-            fRec15[0]            = ((fSlow3 * fRec15[1]) + (fSlow4 * fRec14[1]));
-            fVec3[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec15[0]));
-            fRec14[0]            = fVec3[((IOTA - iSlow9) & 8191)];
-            fRec17[0]            = ((fSlow3 * fRec17[1]) + (fSlow4 * fRec16[1]));
-            fVec4[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec17[0]));
-            fRec16[0]            = fVec4[((IOTA - iSlow10) & 8191)];
-            fRec19[0]            = ((fSlow3 * fRec19[1]) + (fSlow4 * fRec18[1]));
-            fVec5[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec19[0]));
-            fRec18[0]            = fVec5[((IOTA - iSlow11) & 8191)];
-            fRec21[0]            = ((fSlow3 * fRec21[1]) + (fSlow4 * fRec20[1]));
-            fVec6[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec21[0]));
-            fRec20[0]            = fVec6[((IOTA - iSlow12) & 8191)];
-            fRec23[0]            = ((fSlow3 * fRec23[1]) + (fSlow4 * fRec22[1]));
-            fVec7[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec23[0]));
-            fRec22[0]            = fVec7[((IOTA - iSlow13) & 8191)];
-            float fTemp2 =
-                ((((((((fRec8[0] + fRec10[0]) + fRec12[0]) + fRec14[0]) + fRec16[0])
-                    + fRec18[0])
-                   + fRec20[0])
-                  + fRec22[0])
-                 + (0.5f * fRec6[1]));
-            fVec8[(IOTA & 2047)]  = fTemp2;
-            fRec6[0]              = fVec8[((IOTA - iSlow15) & 2047)];
-            float fRec7           = (0.0f - (0.5f * fTemp2));
-            float fTemp3          = (fRec6[1] + (fRec7 + (0.5f * fRec4[1])));
-            fVec9[(IOTA & 2047)]  = fTemp3;
-            fRec4[0]              = fVec9[((IOTA - iSlow16) & 2047)];
-            float fRec5           = (0.0f - (0.5f * fTemp3));
-            float fTemp4          = (fRec4[1] + (fRec5 + (0.5f * fRec2[1])));
-            fVec10[(IOTA & 2047)] = fTemp4;
-            fRec2[0]              = fVec10[((IOTA - iSlow17) & 2047)];
-            float fRec3           = (0.0f - (0.5f * fTemp4));
-            float fTemp5          = (fRec2[1] + (fRec3 + (0.5f * fRec0[1])));
-            fVec11[(IOTA & 2047)] = fTemp5;
-            fRec0[0]              = fVec11[((IOTA - iSlow18) & 2047)];
-            float fRec1           = (0.0f - (0.5f * fTemp5));
-            fRec33[0]             = ((fSlow3 * fRec33[1]) + (fSlow4 * fRec32[1]));
-            fVec12[(IOTA & 8191)] = ((fSlow2 * fRec33[0]) + fTemp1);
-            fRec32[0]             = fVec12[((IOTA - iConst3) & 8191)];
-            fRec35[0]             = ((fSlow3 * fRec35[1]) + (fSlow4 * fRec34[1]));
-            fVec13[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec35[0]));
-            fRec34[0]             = fVec13[((IOTA - iConst5) & 8191)];
-            fRec37[0]             = ((fSlow3 * fRec37[1]) + (fSlow4 * fRec36[1]));
-            fVec14[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec37[0]));
-            fRec36[0]             = fVec14[((IOTA - iConst6) & 8191)];
-            fRec39[0]             = ((fSlow3 * fRec39[1]) + (fSlow4 * fRec38[1]));
-            fVec15[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec39[0]));
-            fRec38[0]             = fVec15[((IOTA - iConst7) & 8191)];
-            fRec41[0]             = ((fSlow3 * fRec41[1]) + (fSlow4 * fRec40[1]));
-            fVec16[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec41[0]));
-            fRec40[0]             = fVec16[((IOTA - iConst8) & 8191)];
-            fRec43[0]             = ((fSlow3 * fRec43[1]) + (fSlow4 * fRec42[1]));
-            fVec17[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec43[0]));
-            fRec42[0]             = fVec17[((IOTA - iConst9) & 8191)];
-            fRec45[0]             = ((fSlow3 * fRec45[1]) + (fSlow4 * fRec44[1]));
-            fVec18[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec45[0]));
-            fRec44[0]             = fVec18[((IOTA - iConst10) & 8191)];
-            fRec47[0]             = ((fSlow3 * fRec47[1]) + (fSlow4 * fRec46[1]));
-            fVec19[(IOTA & 8191)] = (fTemp1 + (fSlow2 * fRec47[0]));
-            fRec46[0]             = fVec19[((IOTA - iConst11) & 8191)];
-            float fTemp6 =
-                ((((((((fRec32[0] + fRec34[0]) + fRec36[0]) + fRec38[0]) + fRec40[0])
-                    + fRec42[0])
-                   + fRec44[0])
-                  + fRec46[0])
-                 + (0.5f * fRec30[1]));
-            fVec20[(IOTA & 2047)] = fTemp6;
-            fRec30[0]             = fVec20[((IOTA - iConst16) & 2047)];
-            float fRec31          = (0.0f - (0.5f * fTemp6));
-            float fTemp7          = (fRec30[1] + (fRec31 + (0.5f * fRec28[1])));
-            fVec21[(IOTA & 2047)] = fTemp7;
-            fRec28[0]             = fVec21[((IOTA - iConst17) & 2047)];
-            float fRec29          = (0.0f - (0.5f * fTemp7));
-            float fTemp8          = (fRec28[1] + (fRec29 + (0.5f * fRec26[1])));
-            fVec22[(IOTA & 2047)] = fTemp8;
-            fRec26[0]             = fVec22[((IOTA - iConst18) & 2047)];
-            float fRec27          = (0.0f - (0.5f * fTemp8));
-            float fTemp9          = (fRec26[1] + (fRec27 + (0.5f * fRec24[1])));
-            fVec23[(IOTA & 1023)] = fTemp9;
-            fRec24[0]             = fVec23[((IOTA - iConst19) & 1023)];
-            float fRec25          = (0.0f - (0.5f * fTemp9));
-            output0[i]            = FAUSTFLOAT(
-                           (fRec0[1] + ((fRec24[1] + (fRec25 + fRec1)) + (fSlow19 * fTemp0))));
+        float fSlow1        = 0.200000003f * fSlow0;
+        float fSlow2        = fConst1 * float(fVslider1) + 0.699999988f;
+        float fSlow3        = fConst2 * float(fVslider2);
+        float fSlow4        = 1.0f - fSlow3;
+        int iSlow5          = int(fConst4 * float(fVslider3));
+        int iSlow6          = iConst3 + iSlow5;
+        int iSlow7          = iConst5 + iSlow5;
+        int iSlow8          = iConst6 + iSlow5;
+        int iSlow9          = iConst7 + iSlow5;
+        int iSlow10         = iConst8 + iSlow5;
+        int iSlow11         = iConst9 + iSlow5;
+        int iSlow12         = iConst10 + iSlow5;
+        int iSlow13         = iConst11 + iSlow5;
+        int iSlow14         = iSlow5 + -1;
+        int iSlow15         = std::min<int>(1024, std::max<int>(0, iConst12 + iSlow14));
+        int iSlow16         = std::min<int>(1024, std::max<int>(0, iConst13 + iSlow14));
+        int iSlow17         = std::min<int>(1024, std::max<int>(0, iConst14 + iSlow14));
+        int iSlow18         = std::min<int>(1024, std::max<int>(0, iConst15 + iSlow14));
+        float fSlow19       = 2.0f * (1.0f - fSlow0);
+        for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+            float fTemp0        = float(input0[i0]);
+            float fTemp1        = fSlow1 * fTemp0;
+            fRec9[0]            = fSlow3 * fRec9[1] + fSlow4 * fRec8[1];
+            fVec0[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec9[0];
+            fRec8[0]            = fVec0[(IOTA0 - iSlow6) & 8191];
+            fRec11[0]           = fSlow3 * fRec11[1] + fSlow4 * fRec10[1];
+            fVec1[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec11[0];
+            fRec10[0]           = fVec1[(IOTA0 - iSlow7) & 8191];
+            fRec13[0]           = fSlow3 * fRec13[1] + fSlow4 * fRec12[1];
+            fVec2[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec13[0];
+            fRec12[0]           = fVec2[(IOTA0 - iSlow8) & 8191];
+            fRec15[0]           = fSlow3 * fRec15[1] + fSlow4 * fRec14[1];
+            fVec3[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec15[0];
+            fRec14[0]           = fVec3[(IOTA0 - iSlow9) & 8191];
+            fRec17[0]           = fSlow3 * fRec17[1] + fSlow4 * fRec16[1];
+            fVec4[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec17[0];
+            fRec16[0]           = fVec4[(IOTA0 - iSlow10) & 8191];
+            fRec19[0]           = fSlow3 * fRec19[1] + fSlow4 * fRec18[1];
+            fVec5[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec19[0];
+            fRec18[0]           = fVec5[(IOTA0 - iSlow11) & 8191];
+            fRec21[0]           = fSlow3 * fRec21[1] + fSlow4 * fRec20[1];
+            fVec6[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec21[0];
+            fRec20[0]           = fVec6[(IOTA0 - iSlow12) & 8191];
+            fRec23[0]           = fSlow3 * fRec23[1] + fSlow4 * fRec22[1];
+            fVec7[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec23[0];
+            fRec22[0]           = fVec7[(IOTA0 - iSlow13) & 8191];
+            float fTemp2        = fRec8[0] + fRec10[0] + fRec12[0] + fRec14[0] + fRec16[0]
+                           + fRec18[0] + fRec20[0] + fRec22[0] + 0.5f * fRec6[1];
+            fVec8[IOTA0 & 2047]  = fTemp2;
+            fRec6[0]             = fVec8[(IOTA0 - iSlow15) & 2047];
+            float fRec7          = 0.0f - 0.5f * fTemp2;
+            float fTemp3         = fRec6[1] + fRec7 + 0.5f * fRec4[1];
+            fVec9[IOTA0 & 2047]  = fTemp3;
+            fRec4[0]             = fVec9[(IOTA0 - iSlow16) & 2047];
+            float fRec5          = 0.0f - 0.5f * fTemp3;
+            float fTemp4         = fRec4[1] + fRec5 + 0.5f * fRec2[1];
+            fVec10[IOTA0 & 2047] = fTemp4;
+            fRec2[0]             = fVec10[(IOTA0 - iSlow17) & 2047];
+            float fRec3          = 0.0f - 0.5f * fTemp4;
+            float fTemp5         = fRec2[1] + fRec3 + 0.5f * fRec0[1];
+            fVec11[IOTA0 & 2047] = fTemp5;
+            fRec0[0]             = fVec11[(IOTA0 - iSlow18) & 2047];
+            float fRec1          = 0.0f - 0.5f * fTemp5;
+            fRec33[0]            = fSlow3 * fRec33[1] + fSlow4 * fRec32[1];
+            fVec12[IOTA0 & 8191] = fSlow2 * fRec33[0] + fTemp1;
+            fRec32[0]            = fVec12[(IOTA0 - iConst3) & 8191];
+            fRec35[0]            = fSlow3 * fRec35[1] + fSlow4 * fRec34[1];
+            fVec13[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec35[0];
+            fRec34[0]            = fVec13[(IOTA0 - iConst5) & 8191];
+            fRec37[0]            = fSlow3 * fRec37[1] + fSlow4 * fRec36[1];
+            fVec14[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec37[0];
+            fRec36[0]            = fVec14[(IOTA0 - iConst6) & 8191];
+            fRec39[0]            = fSlow3 * fRec39[1] + fSlow4 * fRec38[1];
+            fVec15[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec39[0];
+            fRec38[0]            = fVec15[(IOTA0 - iConst7) & 8191];
+            fRec41[0]            = fSlow3 * fRec41[1] + fSlow4 * fRec40[1];
+            fVec16[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec41[0];
+            fRec40[0]            = fVec16[(IOTA0 - iConst8) & 8191];
+            fRec43[0]            = fSlow3 * fRec43[1] + fSlow4 * fRec42[1];
+            fVec17[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec43[0];
+            fRec42[0]            = fVec17[(IOTA0 - iConst9) & 8191];
+            fRec45[0]            = fSlow3 * fRec45[1] + fSlow4 * fRec44[1];
+            fVec18[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec45[0];
+            fRec44[0]            = fVec18[(IOTA0 - iConst10) & 8191];
+            fRec47[0]            = fSlow3 * fRec47[1] + fSlow4 * fRec46[1];
+            fVec19[IOTA0 & 8191] = fTemp1 + fSlow2 * fRec47[0];
+            fRec46[0]            = fVec19[(IOTA0 - iConst11) & 8191];
+            float fTemp6 = fRec32[0] + fRec34[0] + fRec36[0] + fRec38[0] + fRec40[0]
+                           + fRec42[0] + fRec44[0] + fRec46[0] + 0.5f * fRec30[1];
+            fVec20[IOTA0 & 2047] = fTemp6;
+            fRec30[0]            = fVec20[(IOTA0 - iConst16) & 2047];
+            float fRec31         = 0.0f - 0.5f * fTemp6;
+            float fTemp7         = fRec30[1] + fRec31 + 0.5f * fRec28[1];
+            fVec21[IOTA0 & 2047] = fTemp7;
+            fRec28[0]            = fVec21[(IOTA0 - iConst17) & 2047];
+            float fRec29         = 0.0f - 0.5f * fTemp7;
+            float fTemp8         = fRec28[1] + fRec29 + 0.5f * fRec26[1];
+            fVec22[IOTA0 & 2047] = fTemp8;
+            fRec26[0]            = fVec22[(IOTA0 - iConst18) & 2047];
+            float fRec27         = 0.0f - 0.5f * fTemp8;
+            float fTemp9         = fRec26[1] + fRec27 + 0.5f * fRec24[1];
+            fVec23[IOTA0 & 1023] = fTemp9;
+            fRec24[0]            = fVec23[(IOTA0 - iConst19) & 1023];
+            float fRec25         = 0.0f - 0.5f * fTemp9;
+            output0[i0] =
+                FAUSTFLOAT(fRec0[1] + fRec24[1] + fRec25 + fRec1 + fSlow19 * fTemp0);
             fRec9[1]  = fRec9[0];
-            IOTA      = (IOTA + 1);
+            IOTA0     = IOTA0 + 1;
             fRec8[1]  = fRec8[0];
             fRec11[1] = fRec11[0];
             fRec10[1] = fRec10[0];
index 2f9f1b42be8c714f50757c56e2fae3bfa6f46838..3cd5209e0c7bd5d8566d56b7f6144bd9058bc396 100644 (file)
@@ -15,10 +15,23 @@ Item {
     property int fontTiny: 8
 
     property int bodyMargin: 60
+    property int bottomToolTipMargin: 8
+    property int rightToolTipMargin: 4
     
+    property string buttonColour: virtualstudio.darkMode ? "#494646" : "#EAECEC"
+    property string muteButtonMutedColor: "#FCB6B6"
     property string textColour: virtualstudio.darkMode ? "#FAFBFB" : "#0F0D0D"
     property string meterColor: virtualstudio.darkMode ? "gray" : "#E0E0E0"
     property real imageLightnessValue: virtualstudio.darkMode ? 1.0 : 0.0
+    property real muteButtonLightnessValue: virtualstudio.darkMode ? 1.0 : 0.0
+    property real muteButtonMutedLightnessValue: 0.24
+    property real muteButtonMutedSaturationValue: 0.73
+    property string buttonStroke: virtualstudio.darkMode ? "#80827D7D" : "#34979797"
+    property string sliderColour: virtualstudio.darkMode ? "#BABCBC" :  "#EAECEC"
+    property string sliderPressedColour: virtualstudio.darkMode ? "#ACAFAF" : "#DEE0E0"
+    property string shadowColour: virtualstudio.darkMode ? "#40000000" : "#80A1A1A1"
+    property string toolTipBackgroundColour: virtualstudio.darkMode ? "#323232" : "#F3F3F3"
+    property string toolTipTextColour: textColour
 
     property string meterGreen: "#61C554"
     property string meterYellow: "#F5BF4F"
@@ -86,7 +99,7 @@ Item {
 
     Item {
         id: inputDevice
-        x: bodyMargin * virtualstudio.uiScale; y: 250 * virtualstudio.uiScale
+        x: bodyMargin * virtualstudio.uiScale; y: 230 * virtualstudio.uiScale
         width: Math.min(parent.width / 2, 320 * virtualstudio.uiScale) - x
         height: 100 * virtualstudio.uiScale
         clip: true
@@ -132,7 +145,7 @@ Item {
 
     Item {
         id: outputDevice
-        x: bodyMargin * virtualstudio.uiScale; y: 330 * virtualstudio.uiScale
+        x: bodyMargin * virtualstudio.uiScale; y: 320 * virtualstudio.uiScale
         width: Math.min(parent.width / 2, 320 * virtualstudio.uiScale) - x
         height: 100 * virtualstudio.uiScale
         clip: true
@@ -176,22 +189,139 @@ Item {
         }
     }
 
-    Meter {
-        id: inputDeviceMeters
-        x: inputDevice.x + inputDevice.width; y: 250 * virtualstudio.uiScale
+    Item {
+        id: inputControls
+        x: inputDevice.x + inputDevice.width; y: 230 * virtualstudio.uiScale
         width: parent.width - inputDevice.width - 2 * bodyMargin * virtualstudio.uiScale
-        height: 100 * virtualstudio.uiScale
-        model: inputMeterModel
-        clipped: inputClipped
+
+        Meter {
+            id: inputDeviceMeters
+            x: 0; y: 0
+            width: parent.width
+            height: 100 * virtualstudio.uiScale
+            model: inputMeterModel
+            clipped: inputClipped
+        }
+
+        Slider {
+            id: inputSlider
+            from: 0.0
+            value: virtualstudio ? virtualstudio.inputVolume : 0.5
+            onMoved: { virtualstudio.inputVolume = value }
+            to: 1.0
+            enabled: !virtualstudio.inputMuted
+            padding: 0
+            y: inputDeviceMeters.y + 36 * virtualstudio.uiScale
+            anchors.left: inputMute.right
+            anchors.leftMargin: 8 * virtualstudio.uiScale
+            anchors.right: inputDeviceMeters.right
+            opacity: virtualstudio.inputMuted ? 0.3 : 1
+            handle: Rectangle {
+                x: inputSlider.leftPadding + inputSlider.visualPosition * (inputSlider.availableWidth - width)
+                y: inputSlider.topPadding + inputSlider.availableHeight / 2 - height / 2
+                implicitWidth: 26 * virtualstudio.uiScale
+                implicitHeight: 26 * virtualstudio.uiScale
+                radius: 13 * virtualstudio.uiScale
+                color: inputSlider.pressed ? sliderPressedColour : sliderColour
+                border.color: buttonStroke
+                opacity: virtualstudio.inputMuted ? 0.3 : 1
+            }
+        }
+
+        Button {
+            id: inputMute
+            width: 24 * virtualstudio.uiScale
+            height: 24
+            anchors.left: inputDeviceMeters.left
+            anchors.verticalCenter: inputDeviceMeters.verticalCenter
+            background: Rectangle {
+                color: virtualstudio.inputMuted ? muteButtonMutedColor : buttonColour
+                width: 24 * virtualstudio.uiScale
+                radius: 4 * virtualstudio.uiScale
+            }
+            onClicked: { virtualstudio.inputMuted = !virtualstudio.inputMuted }
+            Image {
+                id: micMute
+                width: 11.57 * virtualstudio.uiScale; height: 18 * virtualstudio.uiScale
+                anchors { verticalCenter: parent.verticalCenter; horizontalCenter: parent.horizontalCenter }
+                source: virtualstudio.inputMuted ? "micoff.svg" : "mic.svg"
+            }
+            Colorize {
+                anchors.fill: micMute
+                source: micMute
+                hue: 0
+                saturation: virtualstudio.inputMuted ? muteButtonMutedSaturationValue : 0
+                lightness: virtualstudio.inputMuted ? (inputMute.hovered ? muteButtonMutedLightnessValue + .1 : muteButtonMutedLightnessValue) : (inputMute.hovered ? muteButtonLightnessValue - .1 : muteButtonLightnessValue)
+            }
+            ToolTip {
+                parent: inputMute
+                visible: inputMute.hovered
+                bottomPadding: bottomToolTipMargin * virtualstudio.uiScale
+                rightPadding: rightToolTipMargin * virtualstudio.uiScale
+                delay: 100
+                contentItem: Rectangle {
+                    color: toolTipBackgroundColour
+                    radius: 3
+                    anchors.fill: parent
+                    anchors.bottomMargin: bottomToolTipMargin * virtualstudio.uiScale
+                    anchors.rightMargin: rightToolTipMargin * virtualstudio.uiScale
+                    layer.enabled: true
+                    layer.effect: DropShadow {
+                        horizontalOffset: 1 * virtualstudio.uiScale
+                        verticalOffset: 1 * virtualstudio.uiScale
+                        radius: 10.0 * virtualstudio.uiScale
+                        samples: 21
+                        color: shadowColour
+                    }
+
+                    Text {
+                        anchors.centerIn: parent
+                        font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale}
+                        text: virtualstudio.inputMuted ?  qsTr("Click to unmute yourself") : qsTr("Click to mute yourself")
+                        color: toolTipTextColour
+                    }
+                }
+                background: Rectangle {
+                    color: "transparent"
+                }
+            }
+        }
     }
 
-    Meter {
-        id: outputDeviceMeters
-        x: outputDevice.x + outputDevice.width; y: 330 * virtualstudio.uiScale
+    Item {
+        id: outputControls
+        x: outputDevice.x + outputDevice.width; y: 320 * virtualstudio.uiScale
         width: parent.width - inputDevice.width - 2 * bodyMargin * virtualstudio.uiScale
-        height: 100 * virtualstudio.uiScale
-        model: outputMeterModel
-        clipped: outputClipped
+
+        Meter {
+            id: outputDeviceMeters
+            x: 0; y: 0
+            width: parent.width
+            height: 100 * virtualstudio.uiScale
+            model: outputMeterModel
+            clipped: outputClipped
+        }
+
+        Slider {
+            id: outputSlider
+            from: 0.0
+            value: virtualstudio ? virtualstudio.outputVolume : 0.5
+            onMoved: { virtualstudio.outputVolume = value }
+            to: 1.0
+            padding: 0
+            y: outputDeviceMeters.y + 36 * virtualstudio.uiScale
+            anchors.left: outputDeviceMeters.left
+            anchors.right: outputDeviceMeters.right
+            handle: Rectangle {
+                x: outputSlider.leftPadding + outputSlider.visualPosition * (outputSlider.availableWidth - width)
+                y: outputSlider.topPadding + outputSlider.availableHeight / 2 - height / 2
+                implicitWidth: 26 * virtualstudio.uiScale
+                implicitHeight: 26 * virtualstudio.uiScale
+                radius: 13 * virtualstudio.uiScale
+                color: outputSlider.pressed ? sliderPressedColour : sliderColour
+                border.color: buttonStroke
+            }
+        }
     }
 
     Item {
diff --git a/src/gui/Jacktrip.ai b/src/gui/Jacktrip.ai
deleted file mode 100644 (file)
index fc14ad6..0000000
+++ /dev/null
@@ -1,1014 +0,0 @@
-%PDF-1.6\r%âãÏÓ\r
-1 0 obj\r<</Metadata 2 0 R/OCProperties<</D<</ON[21 0 R]/Order 22 0 R/RBGroups[]>>/OCGs[21 0 R]>>/Pages 3 0 R/Type/Catalog>>\rendobj\r2 0 obj\r<</Length 38021/Subtype/XML/Type/Metadata>>stream\r
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
-<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 6.0-c002 79.164460, 2020/05/12-16:04:17        ">
-   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-      <rdf:Description rdf:about=""
-            xmlns:dc="http://purl.org/dc/elements/1.1/"
-            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
-            xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/"
-            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
-            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
-            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
-            xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/"
-            xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
-            xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
-            xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/"
-            xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
-         <dc:format>application/pdf</dc:format>
-         <dc:title>
-            <rdf:Alt>
-               <rdf:li xml:lang="x-default">Jacktrip</rdf:li>
-            </rdf:Alt>
-         </dc:title>
-         <xmp:CreatorTool>Adobe Illustrator 24.2 (Macintosh)</xmp:CreatorTool>
-         <xmp:CreateDate>2020-07-25T23:44:56+10:00</xmp:CreateDate>
-         <xmp:ModifyDate>2020-07-25T23:44:56+10:00</xmp:ModifyDate>
-         <xmp:MetadataDate>2020-07-25T23:44:56+10:00</xmp:MetadataDate>
-         <xmp:Thumbnails>
-            <rdf:Alt>
-               <rdf:li rdf:parseType="Resource">
-                  <xmpGImg:width>136</xmpGImg:width>
-                  <xmpGImg:height>256</xmpGImg:height>
-                  <xmpGImg:format>JPEG</xmpGImg:format>
-                  <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAACIAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq7FXylrx8yfnZ+ZPmLSbnVrjS/Inli4Nl9Rtm4PPIrPHzYGqsztEzcnB4rQAbk4&#xA;qgNU03X/AMgdX0nzB5d1e7v/ACdd3S2uraNdsGHxAvUBAiciisVcICpFDUNTFX12rKyhlIZWFVYb&#xA;gg9xireKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV8q+Svrmkf8AOR3nfQ/Lrrd+XbiZ7vVnf/dM&#xA;x/eFYyD9pLid4qdwP8nFUP8A85Atf6j518meXNYK2nkm/vYGnvVBLGYy+lKHNfh9OKT4f9Ynemyr&#xA;6yAAFBsB0GKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KviGy8h+Q/Nn5p/mV/izWH0n6lrl19S&#xA;4XNvbep6t5depX6wknLj6a/Z6V3xVLPzK/Lf8t/K0GjXflbXH1W7uNQjhuIXurW4CxEFi3GCNGG4&#xA;AqdsVfeOKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KvhyD8n/+Vi/mn+ZH+5b9F/ovXLr/AI9/&#xA;rHqfWLy5/wCLYePH0fetcVSv8x/yLHkC30jUTrZ1IXl/Ha+kLb6sVqC/IOJpf5fDFX3virsVdirs&#xA;VdirsVdirsVdirsVdirsVdirsVdir4Pu/wApda/MH80/zE/Rl5bWn6M1y89b6z6nxfWLy448eCv0&#xA;9I1riqUedvyS1/yGmlahqOoWtxHeXsdsgtfU5qxq/L94ij9nFX6D4q7FXYq7FXYq7FXYq7FXYq7F&#xA;XYq7FXYq7FXYq+Y/yY/8mn+b/wD23G/6jL7FVH/nJ7/jgeW/+2zF/wAm3xV9RYq7FXYq7FXYq7FX&#xA;Yq7FXYq7FXYq7FXYq7FXYq+Y/wAmP/Jp/m//ANtxv+oy+xVR/wCcnv8AjgeW/wDtsxf8m3xV9RYq&#xA;7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXxR/zkn5l85Qfndf6TpGtX1nFKtjHBbQXU0MQeWCMfZR&#xA;goqzb7YQLNIJp59H5G/MWO4nuY7tkuLpzJdTLdMHlckktIwNWNWJqfHL/wArNh4oW3PkT8w7oILq&#xA;5M4jbmglumcKw/aHImhx/KzXxQyr8ofMnnyH86vLujatr2oXCi+RLm3kvJ5YmBQtRlZyrDfKZRMT&#xA;RZg2+8Mil2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV8Pf8AORP/AK0k3/GXS/8Ak3Fk8X1D3sZciyPN&#xA;u4jsVYV5B/8AWldF/wC2jF/yZzV5/rLlY/pfeeUs3Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXw9/zk&#xA;T/60k3/GXS/+TcWTxfUPexlyLI827iOxVhXkH/1pXRf+2jF/yZzV5/rLlY/pfeeUs3Yq7FXYq7FX&#xA;Yq7FXYq7FXYq7FXYq7FXw9/zkT/60k3/ABl0v/k3Fk8X1D3sZciyPNu4jsVYV5B/9aV0X/toxf8A&#xA;JnNXn+suVj+l955SzdirsVdirsVdirsVdirsVdirsVdirsVfD3/ORP8A60k3/GXS/wDk3Fk8X1D3&#xA;sZciyPNu4jsVYV5B/wDWldF/7aMX/JnNXn+suVj+l955SzdirsVdirsVdirsVdirsVdirsVdirsV&#xA;fD3/ADkT/wCtJN/xl0v/AJNxZPF9Q97GXIsjzbuI7FWFeQf/AFpXRf8Atoxf8mc1ef6y5WP6X3nl&#xA;LN2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV8Pf85E/+tJN/xl0v/k3Fk8X1D3sZciyPNu4jsVYV5B/9&#xA;aV0X/toxf8mc1ef6y5WP6X3nlLN2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV8Tf85WafeaH+d1tr00R&#xA;e0vYbO7t2AorG1pFJHXpyBiBPswyUTRBQRYR1hrWlX9slzaXUcsTioIYVHswO4Psc20ZgiwXEIIV&#xA;LnU9OtYWnuLqKKJBVnZ1A/XhMgOaACxf8j7e481f85C6bf2EbfVbaeS+mkoaJBbxFVZvDm3Ffm2a&#xA;nLLikS5cRQfd+QZOxV2KuxV2KuxV2KuxV2KuxV2KuxV2KsV/Mf8ALTyv+YOgNo+vwkqp52l5FRbi&#xA;3k6c4nIbr0YEEHv2xV+fn5meTU8meetX8sR3RvY9NlVEuWT0y6vGsgqoLUID064qt/LjyafOnnbS&#xA;vLAu/qP6TkaM3ZT1fTCRtITw5Jy2T+YYq+9vyq/J/wAp/lvpMlpo6NPe3NDf6nPxM8xXovwgBI1/&#xA;ZQfTU74qznFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq/Pb/AJyR/wDJ2+af+M8P/UNFirv+cbv/&#xA;ACdvlb/jPN/1DS4q/QnFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX57f85I/+Tt80/wDGeH/q&#xA;GixV3/ON3/k7fK3/ABnm/wCoaXFX6E4q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq/Pb/nJH/y&#xA;dvmn/jPD/wBQ0WKu/wCcbv8Aydvlb/jPN/1DS4q/QnFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq&#xA;7FX57f8AOSP/AJO3zT/xnh/6hosVd/zjd/5O3yt/xnm/6hpcVfoTirsVdirsVdirsVdirsVdirsV&#xA;dirsVdirsVdir89v+ckf/J2+af8AjPD/ANQ0WKu/5xu/8nb5W/4zzf8AUNLir9CcVdirsVdirsVd&#xA;irsVdirsVdirsVdirsVdirsVfnt/zkj/AOTt80/8Z4f+oaLFXf8AON3/AJO3yt/xnm/6hpcVfoTi&#xA;rsVdirsVdirsVdirsVdirsVdirsVdirsVdir89v+ckf/ACdvmn/jPD/1DRYq7/nG7/ydvlb/AIzz&#xA;f9Q0uKv0JxV8q/8AQ8//AH5P/c0/7M8Vd/0PP/35P/c0/wCzPFXf9Dz/APfk/wDc0/7M8VTDy9/z&#xA;ml+l9f03ST5O9AajdQWnr/pLnw9eRY+fH6qtePKtKjFX01irsVdirsVdirsVdirsVdirsVfnt/zk&#xA;j/5O3zT/AMZ4f+oaLFXf843f+Tt8rf8AGeb/AKhpcVfoTir5U17/AJwgZLGWTQfM/q3qgmK3vbfh&#xA;G5/lMsbsU+fA4q+YdW0u/wBJ1S80vUIjBf2E0ltdwkglJYmKOtQSDRh2xVHeT/Kes+bvMlj5d0WN&#xA;ZdS1BykIduCAKpd3duyoilj7DbFX1L5O/wCcMrfR9V0rV9Q80PPd2FxDdvbW9qEjLwusgQSPIzFa&#xA;rSvEfIYq+lsVdirsVdirsVdirsVdirsVdir89f8AnI8k/nb5pqCP9Ii2P/MNF4Yq7/nHAkfnb5Wo&#xA;Cf8ASJdh/wAw0vjir9CsVdir88v+citObT/zp80wlQvqXS3IoAARcwpNXbx9Tf3xV3/OOuqxaX+d&#xA;XlW5kICyXT2m/TldwSWy/wDDSjFX6G4q7FXYq7FXYq7FXYq7FXYq7FXYq/N785dWTVvzW813yNzj&#xA;bU7iOJxuGSBzChG52KoMVZT/AM4q6c95+duiSBeUdlHd3MvsBayRqfoeRcVffGKuxV8Yf85o+WXs&#xA;fP8ApmvolLfWbERu/jcWjcXr/wA8pIsVeB6ZqF1pupWmo2jcLqymjuIH8JImDqfvGKv038r+YLLz&#xA;H5c0zXbI1tdTtormIVrQSKGKn3U7H3xVNMVdirsVdirsVdirsVdirsVY7+YnmyDyj5H1rzHKVB06&#xA;1kkgVujTkcIE/wBnKyrir80JZZJZHllYvJIxZ3Y1JYmpJPvir6X/AOcJPLLy695h8zSJ+6tLaPT4&#xA;HPQvcOJZOPuqwrX/AFsVfXWKuxV5F/zlD5Dk81/lbdzWkXqanoL/AKStVUfE0calbhB33iYtQdSo&#xA;xV8EYq+sP+cN/wA0Yntrn8vdSmpNGXvNCLnZkb4ri3WvdW/eqPd/DFX1JirsVdirsVdirsVdirsV&#xA;dir5F/5zF/NKK/1C28g6XNzg09xda06H4TcFf3UFR/vtWLMPEjuuKvmXFX6G/wDOPnkJ/JX5X6Xp&#xA;9zGYtTvQdQ1NCKMs9wAQjDxjiVEPuMVej4q7FXEBgQRUHYg9CMVfn7/zkN+VEv5f+eJhaQlfLmrM&#xA;9zpEgB4ICayW1d94S1B/klTirzfS9U1DStSttT06d7W/s5FmtriM0ZJENVYfTir78/I387dI/MnQ&#xA;gsrJa+Z7JB+lNOGwPb14ASSYmP0qdj2JVenYq7FXYq7FXYq7FXYq8f8A+cgPz30/8vtHk0zS5Y7j&#xA;zhex0tbfZxaow/3omHan7Cn7R/ya4q+ELq6ubu6mu7qVp7m4dpZ5pCWd5HJZmZjuSxNScVex/wDO&#xA;MP5SyedPOiazqEPLy5oEiT3JYfDPcj4oYB47jm/+SKH7QxV92Yq7FXYq7FWLfmV+Xeh+f/KtzoGr&#xA;LxEn7yzu1AMlvcKDwlSvhWjDuKjFX57+fvIPmPyN5jn0HXoPSuIvihmWpiniJIWWJiByVqfMHY0I&#xA;xVKtF1vVtD1S31bSLuSx1G0bnb3MLcXVun3EGhB2I2OKvrn8pv8AnLvQdWjg0rz2F0nVNkXVkB+p&#xA;zHoDIBUwMe/VO9V6Yq+h7K9s761iu7KeO6tJl5Q3ELrJG6nurqSpHyxVWxV2KuxVC6nqumaVYy3+&#xA;qXcNjZQjlNc3EixRqP8AKdyAMVfNv5t/85gafbRTaT+Xg+t3ZBR9enQiGPtW3icVkYfzOOPswxV8&#xA;oajqN/qV9Pf6hcSXd7cuZLi5mYvI7tuWZmqScVZL+WX5Z+Y/zC8yRaNo0dI1o9/fOD6NtDWhdz4n&#xA;9lerH6SFX6EeR/Jeh+S/LFl5d0WL07OzWhkahklkbd5ZGAFXc7n7hsAMVT7FXYq7FXYq7FWI/mX+&#xA;V/lX8w9COla7AfUjq1jfxUFxbSH9qNjXY0+JTsfnQhV8N/mp+SHnX8ur1/0jbm80Vm42utW6kwOC&#xA;fhEnUwuf5W/2JYb4q89xVP8Ayt5985+VJzN5c1m60wsQzxwyEROR/PEaxv8A7JTir1bRv+cx/wA2&#xA;bGNY76LTdWA+1LcW7RSHbxt5IU/4TFU8f/nN3zkYyI/LunLJQUZnnYVrvsGX9eKsd1v/AJzA/N7U&#xA;UZLNrDSFNQr2ltzcD53LTivvxxV5T5k85ea/M9yLnzBq11qkq19P6zK0ipXqI0J4oPZQMVSbFXqH&#xA;5R/kB5y/MO5juUjbTPLgb9/rE6niwHVbdDQyt8vhHc9sVfcHkH8vvK/kXQY9F8vWvoQD4p53o008&#xA;lKGSZ6Dkx+4dAAMVZJirsVdirsVdirsVdiqldWtrd20lrdwpcW0ylJoJVDo6nYqysCCD4HFXhP5h&#xA;f84geRdfkkvfLU7+W79/iMCL61kx6/3JKtHX/IbiP5cVeB+aP+cWPzi0JneHTI9ZtVr+/wBNlWU0&#xA;7fuX9OY/QhxV5zqflDzZpTFNU0W/sGXqLm2mhp1/nVfA4qlSI8jhEUu7GiqoqSfAAYqneleRPO2r&#xA;sF0vy/qN8W6G3tJpB1puVUgDbqcVek+Vf+cTfzd1tke9s4NCtWoTLfyrzp7Qw+q9fZwuKvfvy+/5&#xA;xK/Lvy28V5rZfzLqUe4+tKI7RT7WwLcv+ejMPbFXt0cccUaxxqEjQBURQAqqBQAAdAMVXYq7FXYq&#xA;7FX/2Q==</xmpGImg:image>
-               </rdf:li>
-            </rdf:Alt>
-         </xmp:Thumbnails>
-         <xmpMM:OriginalDocumentID>uuid:9E3E5C9A8C81DB118734DB58FDDE4BA7</xmpMM:OriginalDocumentID>
-         <xmpMM:DocumentID>xmp.did:49477e0f-276a-4cd3-8c1b-cab8815bed51</xmpMM:DocumentID>
-         <xmpMM:InstanceID>uuid:2e5c36ab-b08f-3840-94fd-90b8522b24ab</xmpMM:InstanceID>
-         <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
-         <xmpMM:DerivedFrom rdf:parseType="Resource">
-            <stRef:instanceID>uuid:dab6724e-c618-4184-9b2e-7d44879e5e5f</stRef:instanceID>
-            <stRef:documentID>xmp.did:008add62-65b7-3547-8416-6472cd533b2c</stRef:documentID>
-            <stRef:originalDocumentID>uuid:9E3E5C9A8C81DB118734DB58FDDE4BA7</stRef:originalDocumentID>
-            <stRef:renditionClass>proof:pdf</stRef:renditionClass>
-         </xmpMM:DerivedFrom>
-         <xmpMM:History>
-            <rdf:Seq>
-               <rdf:li rdf:parseType="Resource">
-                  <stEvt:action>saved</stEvt:action>
-                  <stEvt:instanceID>xmp.iid:49477e0f-276a-4cd3-8c1b-cab8815bed51</stEvt:instanceID>
-                  <stEvt:when>2020-07-25T23:40:45+10:00</stEvt:when>
-                  <stEvt:softwareAgent>Adobe Illustrator 24.2 (Macintosh)</stEvt:softwareAgent>
-                  <stEvt:changed>/</stEvt:changed>
-               </rdf:li>
-            </rdf:Seq>
-         </xmpMM:History>
-         <illustrator:StartupProfile>Basic RGB</illustrator:StartupProfile>
-         <illustrator:Type>Document</illustrator:Type>
-         <illustrator:CreatorSubTool>AIRobin</illustrator:CreatorSubTool>
-         <xmpTPg:NPages>1</xmpTPg:NPages>
-         <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
-         <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
-         <xmpTPg:MaxPageSize rdf:parseType="Resource">
-            <stDim:w>1024.000000</stDim:w>
-            <stDim:h>1024.000000</stDim:h>
-            <stDim:unit>Pixels</stDim:unit>
-         </xmpTPg:MaxPageSize>
-         <xmpTPg:PlateNames>
-            <rdf:Seq>
-               <rdf:li>Cyan</rdf:li>
-               <rdf:li>Magenta</rdf:li>
-               <rdf:li>Yellow</rdf:li>
-               <rdf:li>Black</rdf:li>
-            </rdf:Seq>
-         </xmpTPg:PlateNames>
-         <xmpTPg:SwatchGroups>
-            <rdf:Seq>
-               <rdf:li rdf:parseType="Resource">
-                  <xmpG:groupName>Default Swatch Group</xmpG:groupName>
-                  <xmpG:groupType>0</xmpG:groupType>
-                  <xmpG:Colorants>
-                     <rdf:Seq>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>White</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>255</xmpG:red>
-                           <xmpG:green>255</xmpG:green>
-                           <xmpG:blue>255</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>Black</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>0</xmpG:red>
-                           <xmpG:green>0</xmpG:green>
-                           <xmpG:blue>0</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>RGB Red</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>255</xmpG:red>
-                           <xmpG:green>0</xmpG:green>
-                           <xmpG:blue>0</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>RGB Yellow</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>255</xmpG:red>
-                           <xmpG:green>255</xmpG:green>
-                           <xmpG:blue>0</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>RGB Green</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>0</xmpG:red>
-                           <xmpG:green>255</xmpG:green>
-                           <xmpG:blue>0</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>RGB Cyan</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>0</xmpG:red>
-                           <xmpG:green>255</xmpG:green>
-                           <xmpG:blue>255</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>RGB Blue</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>0</xmpG:red>
-                           <xmpG:green>0</xmpG:green>
-                           <xmpG:blue>255</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>RGB Magenta</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>255</xmpG:red>
-                           <xmpG:green>0</xmpG:green>
-                           <xmpG:blue>255</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=193 G=39 B=45</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>193</xmpG:red>
-                           <xmpG:green>39</xmpG:green>
-                           <xmpG:blue>45</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=237 G=28 B=36</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>237</xmpG:red>
-                           <xmpG:green>28</xmpG:green>
-                           <xmpG:blue>36</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=241 G=90 B=36</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>241</xmpG:red>
-                           <xmpG:green>90</xmpG:green>
-                           <xmpG:blue>36</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=247 G=147 B=30</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>247</xmpG:red>
-                           <xmpG:green>147</xmpG:green>
-                           <xmpG:blue>30</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=251 G=176 B=59</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>251</xmpG:red>
-                           <xmpG:green>176</xmpG:green>
-                           <xmpG:blue>59</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=252 G=238 B=33</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>252</xmpG:red>
-                           <xmpG:green>238</xmpG:green>
-                           <xmpG:blue>33</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=217 G=224 B=33</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>217</xmpG:red>
-                           <xmpG:green>224</xmpG:green>
-                           <xmpG:blue>33</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=140 G=198 B=63</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>140</xmpG:red>
-                           <xmpG:green>198</xmpG:green>
-                           <xmpG:blue>63</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=57 G=181 B=74</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>57</xmpG:red>
-                           <xmpG:green>181</xmpG:green>
-                           <xmpG:blue>74</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=0 G=146 B=69</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>0</xmpG:red>
-                           <xmpG:green>146</xmpG:green>
-                           <xmpG:blue>69</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=0 G=104 B=55</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>0</xmpG:red>
-                           <xmpG:green>104</xmpG:green>
-                           <xmpG:blue>55</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=34 G=181 B=115</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>34</xmpG:red>
-                           <xmpG:green>181</xmpG:green>
-                           <xmpG:blue>115</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=0 G=169 B=157</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>0</xmpG:red>
-                           <xmpG:green>169</xmpG:green>
-                           <xmpG:blue>157</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=41 G=171 B=226</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>41</xmpG:red>
-                           <xmpG:green>171</xmpG:green>
-                           <xmpG:blue>226</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=0 G=113 B=188</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>0</xmpG:red>
-                           <xmpG:green>113</xmpG:green>
-                           <xmpG:blue>188</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=46 G=49 B=146</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>46</xmpG:red>
-                           <xmpG:green>49</xmpG:green>
-                           <xmpG:blue>146</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=27 G=20 B=100</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>27</xmpG:red>
-                           <xmpG:green>20</xmpG:green>
-                           <xmpG:blue>100</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=102 G=45 B=145</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>102</xmpG:red>
-                           <xmpG:green>45</xmpG:green>
-                           <xmpG:blue>145</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=147 G=39 B=143</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>147</xmpG:red>
-                           <xmpG:green>39</xmpG:green>
-                           <xmpG:blue>143</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=158 G=0 B=93</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>158</xmpG:red>
-                           <xmpG:green>0</xmpG:green>
-                           <xmpG:blue>93</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=212 G=20 B=90</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>212</xmpG:red>
-                           <xmpG:green>20</xmpG:green>
-                           <xmpG:blue>90</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=237 G=30 B=121</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>237</xmpG:red>
-                           <xmpG:green>30</xmpG:green>
-                           <xmpG:blue>121</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=199 G=178 B=153</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>199</xmpG:red>
-                           <xmpG:green>178</xmpG:green>
-                           <xmpG:blue>153</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=153 G=134 B=117</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>153</xmpG:red>
-                           <xmpG:green>134</xmpG:green>
-                           <xmpG:blue>117</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=115 G=99 B=87</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>115</xmpG:red>
-                           <xmpG:green>99</xmpG:green>
-                           <xmpG:blue>87</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=83 G=71 B=65</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>83</xmpG:red>
-                           <xmpG:green>71</xmpG:green>
-                           <xmpG:blue>65</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=198 G=156 B=109</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>198</xmpG:red>
-                           <xmpG:green>156</xmpG:green>
-                           <xmpG:blue>109</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=166 G=124 B=82</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>166</xmpG:red>
-                           <xmpG:green>124</xmpG:green>
-                           <xmpG:blue>82</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=140 G=98 B=57</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>140</xmpG:red>
-                           <xmpG:green>98</xmpG:green>
-                           <xmpG:blue>57</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=117 G=76 B=36</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>117</xmpG:red>
-                           <xmpG:green>76</xmpG:green>
-                           <xmpG:blue>36</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=96 G=56 B=19</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>96</xmpG:red>
-                           <xmpG:green>56</xmpG:green>
-                           <xmpG:blue>19</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=66 G=33 B=11</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>66</xmpG:red>
-                           <xmpG:green>33</xmpG:green>
-                           <xmpG:blue>11</xmpG:blue>
-                        </rdf:li>
-                     </rdf:Seq>
-                  </xmpG:Colorants>
-               </rdf:li>
-               <rdf:li rdf:parseType="Resource">
-                  <xmpG:groupName>Cold</xmpG:groupName>
-                  <xmpG:groupType>1</xmpG:groupType>
-                  <xmpG:Colorants>
-                     <rdf:Seq>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>C=56 M=0 Y=20 K=0</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>101</xmpG:red>
-                           <xmpG:green>200</xmpG:green>
-                           <xmpG:blue>208</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>C=51 M=43 Y=0 K=0</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>131</xmpG:red>
-                           <xmpG:green>139</xmpG:green>
-                           <xmpG:blue>197</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>C=26 M=41 Y=0 K=0</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>186</xmpG:red>
-                           <xmpG:green>155</xmpG:green>
-                           <xmpG:blue>201</xmpG:blue>
-                        </rdf:li>
-                     </rdf:Seq>
-                  </xmpG:Colorants>
-               </rdf:li>
-               <rdf:li rdf:parseType="Resource">
-                  <xmpG:groupName>Grays</xmpG:groupName>
-                  <xmpG:groupType>1</xmpG:groupType>
-                  <xmpG:Colorants>
-                     <rdf:Seq>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=0 G=0 B=0</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>0</xmpG:red>
-                           <xmpG:green>0</xmpG:green>
-                           <xmpG:blue>0</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=26 G=26 B=26</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>26</xmpG:red>
-                           <xmpG:green>26</xmpG:green>
-                           <xmpG:blue>26</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=51 G=51 B=51</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>51</xmpG:red>
-                           <xmpG:green>51</xmpG:green>
-                           <xmpG:blue>51</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=77 G=77 B=77</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>77</xmpG:red>
-                           <xmpG:green>77</xmpG:green>
-                           <xmpG:blue>77</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=102 G=102 B=102</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>102</xmpG:red>
-                           <xmpG:green>102</xmpG:green>
-                           <xmpG:blue>102</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=128 G=128 B=128</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>128</xmpG:red>
-                           <xmpG:green>128</xmpG:green>
-                           <xmpG:blue>128</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=153 G=153 B=153</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>153</xmpG:red>
-                           <xmpG:green>153</xmpG:green>
-                           <xmpG:blue>153</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=179 G=179 B=179</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>179</xmpG:red>
-                           <xmpG:green>179</xmpG:green>
-                           <xmpG:blue>179</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=204 G=204 B=204</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>204</xmpG:red>
-                           <xmpG:green>204</xmpG:green>
-                           <xmpG:blue>204</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=230 G=230 B=230</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>230</xmpG:red>
-                           <xmpG:green>230</xmpG:green>
-                           <xmpG:blue>230</xmpG:blue>
-                        </rdf:li>
-                        <rdf:li rdf:parseType="Resource">
-                           <xmpG:swatchName>R=242 G=242 B=242</xmpG:swatchName>
-                           <xmpG:mode>RGB</xmpG:mode>
-                           <xmpG:type>PROCESS</xmpG:type>
-                           <xmpG:red>242</xmpG:red>
-                           <xmpG:green>242</xmpG:green>
-                           <xmpG:blue>242</xmpG:blue>
-                        </rdf:li>
-                     </rdf:Seq>
-                  </xmpG:Colorants>
-               </rdf:li>
-            </rdf:Seq>
-         </xmpTPg:SwatchGroups>
-         <pdf:Producer>Adobe PDF library 15.00</pdf:Producer>
-      </rdf:Description>
-   </rdf:RDF>
-</x:xmpmeta>
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                                                                                                    
-                           
-<?xpacket end="w"?>\rendstream\rendobj\r3 0 obj\r<</Count 1/Kids[5 0 R]/Type/Pages>>\rendobj\r5 0 obj\r<</ArtBox[260.012 83.8406 713.5 947.255]/BleedBox[0.0 0.0 1024.0 1024.0]/Contents 23 0 R/CropBox[0.0 0.0 1024.0 1024.0]/LastModified(D:20200725234456+10'00')/MediaBox[0.0 0.0 1024.0 1024.0]/Parent 3 0 R/PieceInfo<</Illustrator 7 0 R>>/Resources<</ColorSpace<</CS0 24 0 R>>/ExtGState<</GS0 25 0 R>>/Properties<</MC0 21 0 R>>>>/Thumb 26 0 R/TrimBox[0.0 0.0 1024.0 1024.0]/Type/Page>>\rendobj\r23 0 obj\r<</Filter/FlateDecode/Length 572>>stream\r
-H\89ÌTË\8eÛ0\f¼ë+ø\ 3a(R¢¨kÒ¢§m\11äÐ\ f\bú8l\17ØæÐßïÈv¼NÚÞ\8b\0\8aI\9bÃÇ\8c¸ÿt¤ýÓQèðîHi\7f<\v]®$\1cÚîNº^^Òþ\ 3^\7f»&\8fÌÖ3E\ 4w    ÚYfU£ÜY\8aÑÏ/éë\fu<\93L?:\1f?¦¢ô\8bÒ+åÉ\95ɽ\92\ 6\12þHÃ1N­ÊjJÏé\9c\15\9e,Zæc7\9d\0ÿL/\e\14ËÊVZ\ 3Tf¯(c\83·ë\8d\9bQCa¡@hÎ\91\95nÿ«ã2ç[AK4î\8e¼\95et¸BÎx²"LÈ\99\1e\81g<a\e\1f\8eÓ\813\8dq3\ 1u®ÔJù­:Ka\8b\8a1\f#*¦ÜgC\ 5pÑ       M\171Ø£{¼TÔµµ/©\82\93ÞÞ<ÏÉ\91lëiý\ro<ß\12]\12,AÀwðxJÙ\1fhû¿\8b\96¥ô\99\80¿ê8ËèÈéU\88 \b5\1fÂ:L¾°2ùf±->¿÷m¦\ 1źA+\90   K\85Æ×\99ì\9c\ebw\19\9a\984}¸Ó\18p¹B0\14\1d\16\7fDþ+°Vô\82\17]\94÷\8aG`Ñ ÃÌb0­A\94\98\16\9aÁæ\88I7\87vîm|ÎV\9d¬ãnÛ\bÒÚoÖ%iæ\0Èb\8f\v\ f\ 2\96ÈÅZ\81o6ôo¸âh¦+j2à©pFªq:¾\1c\8d-\eb\10£õ^jêÂ\92\15Á`<*HX;\1dj\8bV&²\a\8a>,\17\13ã\9c- 2T\93\8dV34c\83\99`\95\82Í\81yöA0·\9bñ¸\11L¡?Ülmà»·»-\93\v\vè\9aÆ    Z\1d%\8fû±<Ï`sw\86ä&È\83Õ\11¨\ f\94\rÕdcGÚI]ï\9f°\8bOé·\0\ 3\0¼%\16}\rendstream\rendobj\r26 0 obj\r<</BitsPerComponent 8/ColorSpace 27 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 106/Length 325/Width 106>>stream\r
-8;Z]b5n\c'%#*ZsM8NlC%==^R8%K72"G.)t9]nQ^%[548!jiY1;/VUTKn49iTS--H
-:D61!;o5\DU2I]V:<Z%U4eYr\o[Zs%pKfJ>Un69cBV(lgd[ZmSZdHu6Bn3#,lHrg3
-#5(qW)EM(MXs_ImMkkW5OYfjN;Le:;<smU_:`h5aMf9q5OsEV^,Y=0u.&E8$qAjXI
-eLD<cGAro`F-<F,e!$\%cq]5)+^BL6PJXbBaP>'pp*td(FB$EU&31tPed@*(WDI8`
-ni_M!9C%2gd.4%pr\9@8lMBA"D:Vq.SLs+6kaQ^Wo8-bp.#N&;49bf4%(e_~>\rendstream\rendobj\r27 0 obj\r[/Indexed/DeviceRGB 255 28 0 R]\rendobj\r28 0 obj\r<</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream\r
-8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
-b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
-E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
-6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
-VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
-PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
-l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>\rendstream\rendobj\r21 0 obj\r<</Intent 29 0 R/Name(Layer 1)/Type/OCG/Usage 30 0 R>>\rendobj\r29 0 obj\r[/View/Design]\rendobj\r30 0 obj\r<</CreatorInfo<</Creator(Adobe Illustrator 24.2)/Subtype/Artwork>>>>\rendobj\r25 0 obj\r<</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>>\rendobj\r24 0 obj\r[/ICCBased 31 0 R]\rendobj\r31 0 obj\r<</Filter/FlateDecode/Length 2574/N 3>>stream\r
-H\89\9c\96yTSw\16Ç\7f\9e\90\95°Ãc\r[\80°\ 6\905la\91\1d\ 4Q\bI\b\ 1\12BHØ\ 5AD\ 5\14ED\84ª\952ÖmtFOE\9d.®c­\ eÖ}êÒ\ 3õ0êè8´\16×\8e\9d\178G\9dNg¦Óï\1fï÷9÷wïïÝß½÷\9dó\0 '¥ªµÕ0\v\0\8dÖ ÏJ\8cÅ\16\15\14b¤    \0\ 3
\ 2\11\02y­.-;!\aà\92ÆK°ZÜ    ü\8b\9e^\a\90i½"LÊÀ0ðÿ\89-×é\r\0@\198\a(\94µr\9c;q®ª7èLö\19\9c\95&\86Q\13ëñ\ 4q¶4±j\9e½ç|æ9ÚÄ
-\8dV\81³)g\9dB£0ñi\9c\19\958#©8wÕ©\95õ8_Å٥ʨQãüÜ\14«QÊj\ 1@é&»A)/ÇÙ\ fgº>'K\82ó\ 2\0ÈtÕ;\ú\ e\e\94\r\ 6Ó¥$ÕºF½ZUnÀÜå\1e\98(4T\8c%)ë«\94\ 6\830C&¯\94é\15\98¤Z£\93i\e\ 1\98¿ó\9c8¦Úbx\91\83E¡ÁÁB\7f\1fÑ;\85ú¯\9b¿P¦ÞÎÓ\93̹\9e\vom?çW=
-\80x\16¯Íú·¶Ò-\0\8c¯\ 4Àòæ[\9bËû\00ñ¾\1d¾øÎ}ø¦y)7\18ta¾¾õõõ>j¥ÜÇTÐ7ú\9f\ e¿@ï¼ÏÇtÜ\9bò`qÊ2\99±Ê\80\99ê&¯®ª6ê±Z\9dL®Ä\84?\1dâ_\1døóyxg)Ë\94\16\8fÈçL­UáíÖ*Ô\ 6\16SkÿS\13\7feØO4?׸¸c¯\ 1¯Ø\a°.ò\0ò·\v\0åÒ\0\rß\81Þô-\95\92\a2ð5ßáÞüÜÏ     ú÷Sá>Ó£V­\9a\8b\93då`r£¾n~ÏôY\ 2\ 2 \ 2\ 1+`\ f\9c\81;\10\ 2\7f\10\ 2ÂA4\88\aÉ \1dä\80\ 2°\14ÈA9Ð\0\a\1dt\81\1e°\1el\ 2Ã`;\18\ 3»Á~p\10\8c\83\8fÁ  ðGp\1e|   ®\81[`\12L\83\87`\ 6<\ 5¯ \b"A\f\88\vYA\ e\90\ 5ùCb(\12\8a\87R¡,¨\0*\81T\90\162B-Ð
\aê\87\86¡\1dÐnè÷ÐQè\ 4t\ eº\ 4}\ 5MA\ f ï \970\ 2Óa\1el\a»Á¾°\18\8e\81\1cx ¬\82kà&¸\13^\a\ fÁ£ð>ø0|\ 2>\ f_\83\87ð,\ 2\10\1aÂG\1c\11!"F$H:R\88\94!z¤\15éF\ 6\91Qd?r\f9\8b\A&\91\v\94\88rQ\f\15¢áh\12\9a\8bÊÑ\1a´\15íE\87Ñ]èaô4z\ 5\9dBgÐ×\ 4\ 6Á\96àE\b#H     \8b\b*B=¡\8b0HØIø\88p\86p\8d0MxJ$\12ùD\ 11\84\98D, V\10\9b\89½Ä­Ä\ 3ÄãÄKÄ»ÄY\12\89dEò"E\90ÒI2\92\81ÔEÚBÚGú\8ct\994MzN¦\91\1dÈþä\ 4r!YKî \ f\92÷\90?%_&ß#¿¢°(®\940J:EAi¤ôQÆ(Ç(\17\94WT6U@\8d æP+¨íÔ!ê~ê\19êmê\13\1a\8dæD\v¥eÒÔ´å´!Úïh\9fÓ¦h/è\1cº']B/¢\eéëè\1fÒ\8fÓ¿¢?a0\18n\8chF!ÃÀXÇØÍ8Åø\9añÜ\8ckæc&5S\98µ\99\8d\98\1d6»lö\98Iaº2c\98K\99MÌAæ!æEæ#\16\85åÆ\92°d¬VÖ\bë(ë\ 6k\96Íe\8bØél\r»\97½\87}\8e}\9fCâ¸qâ9
-N'ç\ 3Î)Î].ÂuæJ¸rî
\18÷\fw\9aGä       xR^\ 5¯\87÷[Þ\ 4\9cc\1eh\9egÞ`>bþ\89ù$\1fá»ñ¥ü*~\1fÿ ÿ:ÿ¥\85\9dE\8c\85Òb\8dÅ~\8bË\16Ï,m,£-\95\96Ý\96\a,¯Y¾´Â¬â­*­6X\8d[ݱF­=­3­ë­·Y\9f±~dó      ·\91ÛtÛ\1c´¹i\vÛzÚfÙ6Û~`{ÁvÖÎÞ.ÑNg·Åî\94Ý#{¾}´}\85ý\80ý§ö\ f\1c¸\ e\91\ ej\87\ 1\87Ï\1cþ\8a\99c1X\156\84\9dÆf\1cm\1d\93\1c\8d\8e;\1c'\1c_9     \9cr\9d:\9c\ e8Ýq¦:\8b\9dË\9c\a\9cO:ϸ8¸¤¹´¸ìu¹éJq\15»\96»nv=ëúÌMà\96ï¶ÊmÜí¾ÀR \154      ö
-n»3Ü£ÜkÜGݯz\10\1e\95\1e[=¾ô\84=\83<Ë=G</zÁ^Á^j¯­^\97¼     Þ¡ÞZïQï\eBº0FX'Ü+\9còáû¤útø\8cû<öuñ-ôÝà{Ö÷µ_\90_\95ß\98ß-\11G\94\10\1d\13}çïé/÷\1fñ¿\1aÀ\bH\bh\v8\12ðm W 2p[à\9f\83¸AiA«\82N\ 6ý#8$X\1f¼?øA\88KHIÈ{!7Ä<q\86¸Wüy(!46´-ôãÐ\17aÁa\86°\83a\7f\ f\17\86W\86ï   ¿¿@°@¹`lÁÝ\b§\b\8e\88ÉH,²$òýÈÉ(Ç(YÔhÔ7ÑÎÑ\8aè\9dÑ÷b<b*böÅ<\8eõ\8bÕÇ~\14ûL\12&Y&9\1e\87Ä%ÆuÇMÄsâsã\87ã¿NpJP%ìM\98I\fJlN<\9eDHJIÚ\90tCj'\95KwKg\92C\92\97%\9fN¡§d§\f§|\93ê\99ªO=\96\ 6§%§mL»½Ðu¡váx:H\97¦oL¿\93!È¨ÉøC&13#s$ó/Y¢¬\96¬³ÙÜìâì=ÙOsbsúrnåºç\1asOæ1ó\8aòvç=Ë\8fËïÏ\9f\ä»hÙ¢ó\ 5Ö\ 5ê\82#\85¤Â¼Â\9d\85³\8bã\17oZ<]\14TÔUt}\89`IÃ\92sK­\97V-ý¤\98Y,+>TB(É/ÙSò\83,]6*\9b-\95\96¾W:#\97È7Ë\1f\15\ 3\8a\aÊ\be¿ò^YDY\7fÙ}U\84j£êAyTù`ù#µD=¬þ¶"©b{ųÊôÊ\ f+\7f¬Ê¯: !kJ4Gµ\1cm¥ötµ}uCõ%\9d\97®K7Y\13V³©fF\9f¢ßY\vÕ.©=bàá?S\17\8cîÆ\95Æ©ºÈº\91ºçõyõ\87\1aØ\rÚ\86\v\8d\9e\8dk\1aï5%4ý¦\19m\967\9flqlio\99Z\16³lG+ÔZÚz²Í¹­³mzyâò]íÔöÊö?uøuôw|¿"\7fűN»Îå\9dwW&®ÜÛe֥ﺱ*|ÕöÕèjõê\895\ 1k¶¬yÝ­èþ¢Ç¯g°ç\87^yï\17kEk\87Öþ¸®lÝD_pß¶õÄõÚõ×7DmØÕÏîoê¿»1mãá\ 1l {àûMÅ\9bÎ\r\ 6\ enßLÝlÜ<9\94úO\0¤\ 1\98¸\99$\99\90\99ü\9ah\9aÕ\9bB\9b¯\9c\1c\9c\89\9c÷\9dd\9dÒ\9e@\9e®\9f\1d\9f\8b\9fú i Ø¡G¡¶¢&¢\96£\ 6£v£æ¤V¤Ç¥8¥©¦\1a¦\8b¦ý§n§à¨R¨Ä©7©©ª\1cª\8f«\ 2«u«é¬\¬Ð­D­¸®-®¡¯\16¯\8b°\0°u°ê±`±Ö²K²Â³8³®´%´\9cµ\13µ\8a\ 1¶y¶ð·h·à¸Y¸Ñ¹J¹Âº;ºµ».»§¼!¼\9b½\15½\8f¾
\84¾ÿ¿z¿õÀpÀìÁgÁãÂ_ÂÛÃXÃÔÄQÄÎÅKÅÈÆFÆÃÇAÇ¿È=ȼÉ:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûÛ\80Ü\ 5Ü\8aÝ\10Ý\96Þ\1cÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäüå\84æ\ræ\96ç\1fç©è2è¼éFéÐê[êåëpëûì\86í\11í\9cî(î´ï@ïÌðXðåñrñÿò\8có\19ó§ô4ôÂõPõÞömöû÷\8aø\19ø¨ù8ùÇúWúçûwü\aü\98ý)ýºþKþÜÿmÿÿ\ 2\f\0÷\84óû\rendstream\rendobj\r7 0 obj\r<</LastModified(D:20200725234456+10'00')/Private 16 0 R>>\rendobj\r16 0 obj\r<</AIMetaData 17 0 R/AIPrivateData1 18 0 R/AIPrivateData2 19 0 R/ContainerVersion 12/CreatorVersion 24/NumBlock 2/RoundtripStreamType 2/RoundtripVersion 24>>\rendobj\r17 0 obj\r<</Length 1128>>stream\r
-%!PS-Adobe-3.0 \r%%Creator: Adobe Illustrator(R) 24.0\r%%AI8_CreatorVersion: 24.2.1\r%%For: (Aaron Wyatt) ()\r%%Title: (Jacktrip.ai)\r%%CreationDate: 25/7/20 23:44\r%%Canvassize: 16383\r%%BoundingBox: 260 -941 714 -76\r%%HiResBoundingBox: 260.012435076958 -940.159420289856 713.5 -76.7445203867428\r%%DocumentProcessColors: Cyan Magenta Yellow Black\r%AI5_FileFormat 14.0\r%AI12_BuildNumber: 496\r%AI3_ColorUsage: Color\r%AI7_ImageSettings: 0\r%%RGBProcessColor: 0 0 0 ([Registration])\r%AI3_Cropmarks: 0 -1024 1024 0\r%AI3_TemplateBox: 512.5 -512.5 512.5 -512.5\r%AI3_TileBox: 232.5 -892 791.5 -109\r%AI3_DocumentPreview: None\r%AI5_ArtSize: 14400 14400\r%AI5_RulerUnits: 6\r%AI24_LargeCanvasScale: 1\r%AI9_ColorModel: 1\r%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0\r%AI5_TargetResolution: 800\r%AI5_NumLayers: 1\r%AI9_OpenToView: -379.499237432242 87.568545097045 0.654974427262942 1428 807 18 0 0 6 43 0 0 0 1 1 0 1 1 0 1\r%AI5_OpenViewLayers: 7\r%%PageOrigin:112 -812\r%AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142\r%AI9_Flatten: 1\r%AI12_CMSettings: 00.MS\r%%EndComments\r\rendstream\rendobj\r18 0 obj\r<</Length 65536>>stream\r
-%AI24_ZStandard_Data(µ/ý\0XÌM\ 5\8eUÆÒ\f'ÐØ°b\ 3\14\13«|<\8b­l\9b¶©k"â\8aM\8aìM;Ë\f\86\rÎ\8cR\ f¸àª\1e\r\10Ñ\vÍ\vRD\1a3\82î-u\92Ï("\1a\13UO\17s¯3\A!U\86zâY¼\9eNs|É~b\99Ï\9c\84åpEejN/ë\86u£*8"\952â+Æj%u+òÃ#\8egY¯!\8d!\8aãePE+6ëuS£dRD\1e\919}:Ã\14CßG7\91\19\9e\19Ga#åÑ+g\83\8aVÃ:¥lÓÑ\89Âá\9a³\8f\94Ã7É\91\8e.%óÎKÓ`ÅuÊG¿ÖÃU6\ fVØÜøèfi¸aè\ 2\b        !¸\0\aDMôýQ\9dX\99\9cµjØDõ|Ç1\8d\9a(\92äúô<Ä\14vSCrªì»hXïÝÅÆKtÆlÝD7w\1eT\82R6cJ\fysF\1dsÓ:s\Óºå>nÈÒ\14]x&Å\92\84½ÐÌø\rIµuâgÜ\14%V}\88u!w\94(N¦]¤\8cÈÌ£&îN\8dÆM\9cèbô«¹ñ\9eÌMô\92ã(cç\ 6\9d¸E¬¬¦?ÎÄðþ\12£°[\8d\96°×w¾ýGYÌÈ\8dH»*þªWgô\9eÙ¨º\8d² mÎÈ,SrFV,Û)Ã,X33zÝðÆj\10\89+\8e+\8a\92>¬Ä\95x\8a\8d\9a\94\8c\9a\18úÔ\1es\14µ\8c2qr\12Ò§ccNAι~þLeÔå]Ý\9dÝpL  ßØÍ/ù\83äJß|Ú\84EÞ*Å#\9e\85s+¯æ\13\8f)afuæ\93jFI\85I;hâuñüá9H*Zw\98       #9Oé´7nÂJnB?ß\86Oa²\8e\9b8_æ>\8f\8a.\8e2a\92¾\88£hXó\85èã¬Djþ\91ÈÔ\8bæß\95ãRçú~ã%|ZÍ]d\88\89âO̯ÙãÂá\10\13C^ÌãRA¿\1a\8cS3\91\94ë|¿:FZ%\14¡[ï\86\9d\82$6|\82\96qRa#3Î\84GÆÈgõ\86Ù\1f\95Oì»ò\9d~C66G3ùtß aMi\93_b\1fÄ\8a:OKhò\8d\97\9bz\  êÉÈ\87Æ\95`\8d\rù½é(V\94|\ 6\9d¨\97\89}¡Í`+\8aj£~æ\92R\14iH'zòá\v;;\91N?\r\9e¢ÆÜ±\98Ы\86\83NºêhD\94«jm\1d\96\85Å8\9d:\92GäÞG]\18\89YÍ.Rß·c\87HÍa\17C³ïwÈ!RQ÷\8d_èU\99áÛøE¥ìÒYw\9c¯¤ä\86>G7z\14¿\14EìæêJ¯\18\8d"ÏæCäÒ\85¤ãÎääCS"׫!\95¨N\86¨ô9\1e½dTºe\8cT¿l\9cH\95HgDzhj­\96o\86\9d\7f¬J·Ï\f;\8aû\87\85bL\92¡\17ù\ 6\1d\85í¡íu7£"4Ýl5xv£oP(ªè%ú±~!rì6õ\15\89\89>U\1ae\14coÅ5[\15ý*4h¥O\194G\ 6\15ÅXõ¬$+Ý»£×\94\8d²ÆìLK/£¢Ón\17\19$\85ËcEíÜi¯åD\97+\ f\11ˬHÌ\9es\95ìéN&6tv<\91JNj§#Ý\88ø\1a,
-\96\19k7\ f\87\90Â*¥£×Îᢨ¯T»\94m\9cPôS9º´8ªÆFÆ>\1c\e%\14e\96\eÝfjTQ\94ülìGdc\84V\14µ\9fl¿2\r\11\8a\12ûèUÒp\15\8d_ÌLU\8d{\11\85ÑÇ/H¼a]h7JwÒö\96M-\13\89Y±N\8aµfb\9b\9cý¬5Ve\91\8bívѨPÜQ\19g\90x,K\99¶[=£b¬\13ÕÜtØÅ¹\83ô\11\1a©ËÐGÑÝ£\17\14b\1d½í\8d)
\9d\8cÔiä0¢ Ý1'\86çÖÉH\9döFª\9fÍÑ\86x\17+\1a\89üª\91×Ì\98\13¾;¶B¥º\9f\1a6w\961'N&¥:QmØPL\11ÇMÔÝÈÔ-\9cQ¦ð\85\83'j´\9e^m\a\8b\17@H`\10V5êD9®Ñ¯Ôñ¢øéq&h4:IQЮ\83L¼\Ôºí8μ\0\aÄÔ\84zT\16â \13UDR\1c4\14ä\92A&æHE2h\86üa\13îI#\83\86\17@HÀ@\ 3\8e\13\9aLÊ,'wâéçªkç¹\1dëÞ\e"\81\ 6A\eÀ\ 5\10\12\10p\ 1\84\ 4\ 2\ 2\11l\90A  >\80ÁÂ\ 5\174@!\0B\ 3\ e8X0\80à\ 5\10\12\ e XÐ\ 1\ 6\ep\90Á\a\1fÈ á\83\ e\14\fp\ 1\84\84\r\1e .\80\90`\ 2q\ 1\84\ 4
-h\0\ 4B:À\ 1\ 1\ 1!\14*\10\14$\10"\1cÀ\ 2\rx  |\ 1\84\ 4\14\\0!!\82\82
-4  ä\ 2\b w\96²_^ÇYAý\88|\10QÐ*S;}j\(\88EÃ,\12\ 4\10!\ 5\19\0â\0¬!Éiä\17ý¨®ºÅj\88\8bhõyª2k·%Ü8ÐA\1c\1e\1a\1c\1a\1a\1a\18\1a\16\1a\14\1aÞp\rÕ@\r       n\98\ 66H\83\ 3C\ 3\ 3\ 3Ã\ 2\83\ 2Ã\19\8c¡\18ÌP\ 6apXhXXXø\82-ÐÂ,páA¡AaAá
-¥`\85*\88\82Ã\19Ê\84S¸">\9c\r
-\r      
-¿zph`XHXPø\15yaa\81\v       \ 2 @\84\ f2\18A\ 6ÈúÆû:ÙLJ\92\9a\eM8DØQ\95\9fk]L\ 5ü5D\98Ë8|#×z\89Ô£\92\98Ó×-Ë]\8a\86tÍæ"ä\f\11c*±\1a\13Y^\r\ f\7fH\90\82Ã\83,$\9c\9cN\ 5.\90\81\r\ 3¥téú*t¡\fm¨C\1f*óà\ 4\85Ûl&\93mqh\98\85Yx9\\90\85\ 4\a\86;\8aÐ\897N¾ák\7f\97Í\9a\f\11C¯!\17gn¥*W\9d]ìåÁá¡á\81áaáAáá\ f÷`\ fõ@\ f~\98\87>ÈÃ\83\83\83C\83\ 3\83Ã\82\83\82Ã\1dÎÁ\1cÊ\81\1c\14D¡á\81ô\820\88\83<\88\90,\87C³h<VUm\86\b\eR\9d\91w\8e4¡Ô¥%#\91ÛkH8\85\85\87\ 4k\18\992ás     \r\r\ 2 ê\10qê¥$\13¢9\1a"ZtGcW\15\86\bÚÕÝ\98ÜÓ©!bJfìZÎø556      7\1f\85\ 61]\8fù|\ 67\90¨È\14\1a\12¤luu\86j(\87JPH¨30$4ÈÔ\1f\14\1e\16\1e\18\1e\1a\1e\1cä\ eÇp       ?;ºa°\9b\19=TC-PM±\1e¨\81¦Á\fVð¹L\ e\93ÐðP\87«Õ\81\r      m`0\12\87'ÌÂT\eLzð\ 3y\9cP3\81\81\f\82$<0|\81á\16îî\12ìªÁ\18nÇP\v¥\90@\ fä°0äà\86:Aa>7f:$,ü*A\16\1e\14\1e\14\1c\14\1c\14\1a\18\16\14\8a\14<lxBÃ\19¾p\ 5>\9cÃ)Ü\9dQ\13\1a\8c¡\84á,å@\r´@
-ttT    m i\18\86Y\98[æa!\81\95\ 6\1c\aa\90\ 5Q0\9b\1f"~ºl­m\88\82$\8féñBÇ\9e\8e\8a\1a\19\1c\1a¤\81n k8\83L)$$ A(\15aèB\15Ìt \ 3\17¨À£I:HB\ 2\12\ 4 \14"\10 \88`\ 2\f6Øà\ 2%DãB®³±\1cIFD|þ\\86B?«!B\12<X ;\88F\86\b¢\96ù¶éb"\14\19½:×Ii\9ax\88¨:O*þ\87.W¤QG5\e"\84Чù±âq\88\98;\93MK"*{ãñßC\84\rÇgR§Ü6D\\87V£¹r%C\ 4\85\15©jÆÛÅ\1a"®Ää\86\8c"d\87$p`êð\863\1cݼ$4üÎç\as0\akX0\ 5³²2ò\98C9\94\839\98Ã9Üá\ e
-\ e
-\ e\v\ e\v\ e\f\ e\r\ e\r\ e\ e\ e\ e\ e\ f\ e      \ f\ eò \ f|àC\1fú0\ fóà\a\ 3=ÔC=Ø\83=ÜÃýAáAa\81¡ÁáAäJ¡\16ª¡\1eJ¬æÛ\82\83ñxst        µàÓ]á
-gxÃ\1dîpQ¨Má
-\f\r
-Gc\91H\1c\96u\10\87\ 4\ 5\93¢P\ 1        B\19\19b0Ã0\94\81\fÂð°à°Ð°À°°° °ð\85\85\ 5/ÌB\17dáAÁA¡A\81AaAAAá
-§`
-¥@
-V\18\85*PA\14\1eîð\84\ 4$\90ÜoH\82\ 2\12\1c\9a\9bÏÂ0\8cÃ<\f]ÛäòYÁ\v\83\85JC¦¢£Ó\ 21\90\ 3=\10«5EUu%\95\a>840,(\9cÇ\84\ 4H\82\ 2\12\1eJ\8cV\e³%\90\95\99\9dÝ\14\18¬Á\1cìÁäx½9\1f]\9dÝÝOá\16\8eá\1aÎá\1eNÎ÷s\9f^·ßÿ\853¼á      \ e\7f¸(P¡
-£`\ 5R(\ 5S8\85+((,(0(4(8(<(È\ 2\17º0\v\85\85\82ÂÂÂ\ 2ÃBÃ\82\ 3\19Ê0\ f\v\ f\v \fd CB\19:\ff0\ 31\10C1\941\1cÃ1\9cá\f
-\f
-\f\v\f\v\f\f\r\f\r\f\ e\f\ e\f\ f\f\ f\fÒÀ\ 66´¡\rÓ0\r   n \ 6\86\ 6»\867¼A¡A¡a¡a¡\81¡\81¡¡Á¡Á¡á¡á¡A\1c\84ã0\ e\ 39\90\ 3É\ay\90\ 4\ai\90\ 6a\10\86\ 5Q\10\85ËÉ\89\89\15y\12JIH@\ 2\13\14\90Ðð\85+ü·×\13èó^þp\ eÇp\v§p?»:º¹\1eOÎÁ\1a\14ìvfFf\e£\89=\94C5ÔB)Ô˪jªÅJx \ 6\ 6R Ó\91\11\91i\88$ô`\a3xÁ
-¾Ïæ²=¦é\87q\18\86a\18\85¹±\99:4!\ 1  
-H¨\ 4\1a\ fyÜép82\1c\99\87>4Á¡\rm(C\19ºÐ\ 5\85÷zÖj\95JuÝv:mËJ¥              °\10\91 \80\ f<@A\83\0\81\ 6\1c,\0\ 4\e84,$x° \84ô`á\ 2\b \15\0\82\10¡\10ª\10B\88è`á\ 2\b      .û\90\84#ýÒô\8eÄnH\ 2ÉÖº"öÓW\95å7rUå\90\ 4I J[êÈ\18\8b\86$p \ 1\ 4\v¢BD\82\0XP\82
-\88\b(Ð`!\0â\0\1fl\10!\ 3\10`ÐÁ\ 26X\10/@\ 1\81Ã\ 5\14!\ 5\19\ 3\10l\10A\83\ 51\82
-\b\ 1D8\ 1\ 6\80\0Á\ 6(àà\ 4\80\a\19  \ 2¢\83\b Ø \83\10\8cà\ 3\f\81\ f"l\80\81\ 6\13ø`\83\f0x@\a\18l\80\81\ 6\13\b\80\10À     8РB
-6p0A\a\1c\84 BC
-2øà\ 3\11NàA\a\11&\10\0!\0\11l\90Á\a0èÀ\ 2"\0B\0\1f\ 2       < \ 1\ 1\82\b-È \ 3\ e>ø@\ 4\f\83\11\9c\0\83\ eD\90\81\ 6\1a\10¡\ 3\f4xø\80 "|à\ 1\v*\10A\83\ fdðA\a\18\ 4\1e\ 1\a\1e0\ 1\v\81\a2xÀ\b\ 1\ 6\80è\80\83\ f2\0\81\83ø \ 3\ 5\ 1\9c \ 3\f\86\ 6\1cp`\81\ f:P\b\80\10\80\10\80\ 6\1cp`\ 11\ 2\ fPÐÁ\82\18Á\a\18L`\ 3   lÐA\84\ f>À`\ 2\ 1Hà \ 4\e\ 4(à \83\ 5l\90\81\bP Á\ 4\b$\88`\83\f>Ø \83\ e\ 1\a\11¸à\ 4(ø B\ 5\81\ 6\1ct0\81\r2\10A\84\ 5\b\10\12<ø`\83\b&0\ 1\a\f ØÀ\ 1\ 2\84\84
-@`\88@\80á\82r\83\b\1f|\80\81\ 6\ f5\8fXö÷Ò\93rãD\r\ 4\19\80ò
- J\1e`\83\fD\90A\a\12\88 \ 2\f&\0\ 1B\82© B\ 6\18ؠ   $À±¨£09q5EýV­¶ÝTC\ 4YìB¦+\1av¢nÇ6ý=nS\0\fp`\81\r"\9c@\ 2\1et\10\81\ 5\18\ 4(\88À}\80\ 2\r8ð \ 2\ 5>\88 \82\ e\01Ðàá\83\ e\14\r"\80\80\ 3\b¼\ 1
-\10\12(\ e\10A\ 3\f>P\81\b\0\83\a\8a\ 3xðA\ 6\e\83\b\1a \80\ 2"v\ 5>è@!Â\ 6\1cD@\1c@\ 5\112HA\84\v\v hð&ú\9bj\90\81\ 5
- h\94\14á\ 3\f48\81     "Xà\82\11®°\0\ 1<(A\a\18\98à\ 4\1c\80\ elÀA\ 6\19\88 \ 2\ 58\10\0\11\aXX\0\ 5 @H\10q\0\ fD°A\ 6\1f|\10¡\ 2\11D\80\81  \1ap\815@\ 1B\828@\ 4\11`àÁ\ 5.\98\ 6(@H¨[\1c \83\b\1e0\ 1
-"\0\ 2\r2@ÁÂ\ 5e\ 3\14(>ÀÀ\ 4\1d\10A\83\f\1e\ 6(@H(Á\a0Ð`A¨\80\ 3\r4\88°\ 1\81Á\a\eD\10\ 1\ 6\10\10\e\ 2\ 6q\0\ f:à@\ 3\ e\18<ð Â\a8è`\ 2\1fl\10Á\ 4\0\a\r\10 $\mu#%ÛFY\ 1\ 4\8d¡\89¢ûUê\13\87ø\ 5\10G/\13\1a\972<\88@\81\f\18\0\ 1BBY\ 1\84i\82~\ 1\84\ 1VÀÁ\82\b\0\ 4\e \80\83\ 5\b\10\12æ¦(\ e\10¡\ 5\19\ 1\ 6\0\ 3\ 6\b\10\12ì\ 3L\85Ô\0f\0ª8@\84\ f0hØ\80\83\f\ 4\90\ 1\ 6ã\ 4\19tðA        >\80\81\ 3\ 2 \ e\10A\83\ f\0\ 4\b        \ 2\b\80\10À\a\1f\82\f\88\r\0\ 3\85\0\88\ 3tÀÁ\ 3\ 4\b     \1c\1d®8À\ 6\1cdàA\a\110pÁ5@\ 1\ 2\84\ 4\19®\10\0\ 5\ 2Ð\ 1\a\1f`ÐÁ\a\1e @\ 3\r\1a Ä\ 1:àà\ 3\f"tÀ\0\ 1B\82\901\ 5\88à\ 1\ e@ P\80
-L\0\0\10\ 26Ì3\9e\67JÆJ(¦öQ\95Ë<#öz=Ì'ç=´¹9s\19\91Èk;©¡Í'dÍ\8e6\ fk"¶ÙD¬UËf\93+{ûÜ0©ÑRñ\ 6\1c\ 1\ 6\1fp@\ 1\13 à\ 3\1fPXX\b\80\10Á\ 6\19tðA\ 5\f \ 40'\9ac
-\10\0a47=\11\12$¤É°i\99m¾öJʾ-£%lâ\8dß\12\8fVG\9d\91ÏhL$>\8d§­q5UªñMHÆ´WÓö^ã;Ú>\19\91Í\9eDQÑ­$üÖ\9d?Ìu² 9jé­û\8d\12\91v©«\96\}øÄ\83Ä\86åùþð   »Ä3I}g\92\99\92gF´Ï\96\9e±þ·t\11´ÿLgOÿEb\1f¸ªò}7*2ÊQ\15ÍrTEfrT6³»\92#*J\89Û7sYñ=¯Ht«2\91àÜ\8e\ 6\91hoäè&á(\eYF\8e\88Êñ]Ï;ú\14Yâs\9f%¨Å\12SV×\921$*V;ú\9dÇèʧ\97kL:²ík¥n\1a\ f#\8e\94¥\8a,u3¡Q4%Eìç5Ï$\1cEet$SR35£Ì\e\87Ç \16v-\r\8d9
-#ߨ\11URc\1ar4f¯s\91 ÕØ×LE5\8f¸\fQ\91QLÕè\11U$\15Õ>8f\14w\11*iè\96Êð\95K,½\16\8f\1f)\97×¹èd$Ã'\1e\ f\9fI<ôÚ\1e¾Îuhøî£\9d¡Û\Ã÷Ñ
-\93;C'\97Í+<Ýì\86\8f¾Î\87\8fâC6ª¢èQGQ*òÐ\91\86üZ%D§
\12     Ñ9XÁ\9bë-î0\11£±k\réelHOX©ø\8dYQ\84\1f
-׬£\95+\v+ìħ_FIePåLR«°LÏRA\12dä#È·\93¹\89X\8e°\9a\91}¾¢Ä¯ÇΫ--Rí×­\86´¥¶¶´?í\8eW¼h´¥­U\ro¨ã#ÈÆsì \8bù]ÄA\9c\99øVûùì³ð±&¶M<C&\9eNM<\172±§¥\1aBÂbWE\164Ñn¤$Hì¦Ê\8a\9f¡¸(5\8a\ 4\87H/!9)ÑD|\9az\88\90\8b¦ÈÜ\88)â1\92í\1dϸÀ\0\18hJ\96\11\8c\9c\95¬êÊb{Ì\8a\89ãÁÖÆÔ\15c"Í\92ÌômLÅ\19\15ívp\ 4M5ò\b³#\12\ e\8e¨»"\1a\1dÁ\12±\921ä¸\8a©Þ\94;\8c4bE¾ibI#\9bmvu\e\8c\86Ya»°læ\83*,õÜïKCÄJö"\92ÙXî>\7fÚ\fó¢uG碪ùÝ/ò\8c;i>/ISá\19Q)#é~\9d\8eh\8c0\191ó#éV\1e³1¢\8e¨ã\ 4Q\95b\1f\13òÏäRúQ\98\89\ 6q\90°ÍÆ$'"Ì+2\r\8aÞP\8a.F\93E\91F36,LÌÄè×\12ûxÑf1\19b\94AÂH>,nuVe\91Q\98\18
\84Ê¢Å+ÛÝ\r\90\8cN=\8e«\19aºäd\94µ*F/Iª)Fbs>²\ e±Úô¢²*MD\9aR\15\12©áut\84±}Ñ\10ã\\91\aÙ¹J^˱JF1Ã\1aµ(¹«è¶Ô ÉI}\1c\854ó­7\96L¯±$L7\8aê¯"¾!³A*{Ül\9cÅÑåNn:ç\1eg&>Ó«eã\8c¢¨ÎvL\1fâ\r9
-*\17ÙC\97º\ e\9f\9c¸Ä³Æ-ÈeSºéÙÓ³\8e[Ôâ)ÝqÜw¼\85U>¥»\13£\e¦\ fñ\8d\e1\95\1asv¬\11C5#É9hó\aIxnÐIjH\9asè7ï ;\12Õ*\9bäæÎ"z\9dÕ ön3c64E5!Á«\9b¢\1a\8b^+\8d\9a\10éQ#aÒrÑË\9eQ\13\eBâD.º¼fÔ(%|\e\87Þ3\91¬%çZó-7b\Î}\97k\88ܰÅ˵ù¤Cbn\88Êä\aʪþ\96\8d*Aò*\7f¨Æ§*²s­ê`\15\15ËhT\89O\1d\95I\12æ\93"\9fNf\90È8\8baKdb/\80\90`\82©±²°.\99fGÏ\99vW\9a\19\e½²\93\89\fÑê\9b1ÅD+é\99\8b\1c\8d©!Ú\87¯Q±gN®°»¢yò¼\95W¬´SÕî\92÷\eå\90\8fLÌgRÍf?\9aÓ\98ðèúZÏ&{%´Õ\b]åb\19\9b¹\ÇæR\13¾f~d\8dÐ\95\89µsÜ!5Ó*É!´\9a±/­ÝNdZTlí­Í|\8cf´*èø1Tá#ú\8c\fsO¦n^ïG]q%ÆWkìNT¶Ó\1d\13\13Õ°<f1MsJÕ¯Ælâ\e\9a\97g\83x\92\9f\9c±\88ìÿCcCd±¡ùÑÜ ªÉ\ 6QÅõf85¥
-\92ÔhÚ\9cî\8d³\8dØíj\88ÖA\17&\95Ñ|Æ:,.¾*ùb¨<-\ e_\;fd¼\91á\v¢ù1\17\1d\1aÞ\98\8bK\95ç¶k\1cUnÌËsTQ\91\9a¾æ®\18\12$·Ê°\89ãÇDGä\9f¢"þ3=\9e\r\91Ýæ÷ª*¹1÷\8f\rÑÐüFF#\1eoI\1as1Ò\9bæô¬2xâĤãÛ¼áö.\17ñ\7f\93\8d1aZ^¿ZQõÏ×F?*¿¾\9b6öÚ vLÆÔ\1aUN\*?;\1ftQÄÖxÚ\9f}×Ñ\eé\86I)O>®\19½0\87|esU\e\8d^\98ñ¬|qÕ\10Ö\8eê"\92þ²òOh½è\89­,¬¸Ü\98\bù¶«\92Y¶÷ÎC\84ã¶#27Jh~,]\90\84B\95\999Óò)©\9f\8c\8a\8d»°YÕ>x\17d\9b\8f#ã§TLy>»óW©\98±\98íb\1e·|ldØ\1a^M(î\93ºG±bxD[¥J[yb\87½Jþ"UÝK&\93q)\92\87\94ÞX\91\ eþgï¸PqZ.\7fZ\17É\86\86o\8d¸ÈG$âýw£X÷ø)̽Ö^§\95Cf³Ðl%e\e\1a\15+¥]ê\1fS:«2\13£\13]       \8bµ\15é\86ú\9aØåu\83x\1e3"&F¤ ª£3Z\89½Èè|KQ\15­Ìt¾\8dÕ\18¹Q\89}\848\8ac¤bn\9f\18ñb>ÍØ~òs\9cÒJ¯r\14\19Æ
\91rªêP\98Ýfü\93áp+c¯Á!½:w584ú\88¬\88\7f:«ºÍ<8B¼\9aA\19\9bY£eZ=\1a2\15\9c\r\19\92úÔÏx+ø2­ng\192õgÎqí¸ÄV/E­£J3v\85¯\93®£5\8do¾³¨CJAU¢zP+8\14«_u3¬\15dWDs\8eúbõÄoM\87§¢×¡ø6\9eþ&'<Ö¶hò.gHÌe\15G\11¡2\19\8aÏé\9d­®Bñ=B×ÌV63KZÅ7z\86M\8bT\11\9fB\ f\9b
-\92±]M)È|~^{\r1)|\8bY\8d\9b^çt\9b¾i68\15õ!bÉ~^v\1aâ
-²Ê^/¹\1a'\ 5Ç\8aN\83L"+K©¤ýIé\8aF\86äæV¬uäæWï wê\84\84#rs1ÍÞ<cGcåPÙÜV7²Û¼¥\1aä\9a%«O\15Ù\90Kå|ÜyÝz3X
-\9fÙX²ùT\85Ϫu\96\ eSÅý£HQó££!UÊ\98C\8a³\8d©ú\14\97\9f|Ã:\88¥è\f\8d5Ltf¼Xª\95£E\1a\16S\1e\19\aÉ·¢l"Eã\14\1c\8bÕLÆ\87ÍNÕõ\9bò \8dÂEr\18\ 5Ñ\1d·\8c4.\96\87yL\1a\1aFi\9dï\86\95êè\9aY_2\9c\1fd\8a·<¦BmMýn\95§d^Ë\97\9d\15Û`Ey\99ª¹Á\8a2eªnúøbÖª³÷\98á°
-+£]wé\86\98ú©WåFo.£\16,ªr\8b\1e4Âv\1c»\83VA¯\11Õ{ë¨aU\fyÌêÕÚ°òEl~v\83#|¡Ï\ 6[\1e×È\1f÷<%c=\89]»Í¥þcÑç¸\94ñÓ\8eWѱf\9e©]X!v_+CF\1c\99t\84\86\8dèk\8e\86CFtêæêTs\90Ì \11gUG#ß*_ù\9aâ\8c«\8dYæµ3Ñ\f3\9d|\9ca\16f\87zRl\99&råG-î\F;]Ù 9Äâu©ØÍý°3²!¾\v\rZ\14\87¢î\19å9G+ìßT4ÅV\8d\9c\98\f¥ÄQ¨ìzucH¢LO\r\97gAÖËUõJGV÷pªÚa\167"¥GH7\99ÇÕèË\9d]\91ÕïlƵNVW©\96Õ[â¸R\Ñ\86Ytè\7f}ÆlÜ=Nâ<&±{¤Fñe\1a.a\9d\12\8f\96b^\ f!Q£\e\9a\1d}u»R̶k}\1cmq\1fÿu*û8\9a\98\87-*R\7f]\86\1fG\93²¿\8e\14\94q\99\88ØÉµqä\f[\94Ñ\88Ø;¬q$\vû\biæ-ì>ó¸\90ÄåæÚG\94\11«ö\11ñ8á\9dÔÅNÒ\87Ù£¡«\9b\10\r\97¢Nn:u\e\1e9ªÓ\8d\99×(\89\8f-®)¦îã$jÛS\17S\94\18~被Æ\17ªÛ\18OZ§®NhèF\8e¤ºÈɸ!\87\11\8fDró\947\19´1Ê        \17\85n(F:\83JÜZ$\8dg\86Îú\98Ô\10ª\a-LÎoý^5Ê$?i½b2\84(\8c\84ÝȱÎ\9f\83D¶Æ\91¸\9a³á\12~)23\%¬â\1a½\ 4\rõG·9\8d\96\90ò£ûW£·kÕgèÎ\8eê7®ÄÜÌÑG\8b¢tVÖ;ª]\8d+a²¹£\ fýÑ#QöÜéB¿\re\94Å©æ§\9b\9cÆ\91GLïtDÂ\19\1e\88oFòGn\13JëèF¹1#Ã#X®£ó/+IÉÕÑÝ¢1%æð\b\8eNeîÏñ\11çù¦qDA-\1aµ\98£\e©»¼Q,\8d«Ð\10[>)\13Ϥ \11«öañU¯\97/\96¯\9f\8e/\96Dözu\e\1fQñÜ£JQí\84C¥Ø\8d\r\877¥Ý¤Í\94Ø\9búu2u\14Û¤j\e\85åÇìÛD¿-b\9fÞPï1\92ð~5ÿvÇlä\95íÂWxç\9ag\8c\8e.IG£Ú      ç<×*³\12\13ÏKl.²¸Ãî\96ïh'IÒPùäÿöÿÿ_â±ù\84lU?³\9dÔÐÂ
-9d¦9Y¾\18Ç\88׺\9c¿ðÊ\92pÆÎFd:FÂûÍNÎê3\85ö߯×ëÿ}\96s\88\rÖ\91Ù\87Q\19\19\19ñ\86\86\11\r#SëU®*\eFV'\e&[\r\93\11Ñ0\91y\98L\96A4TCªê\ 6\91Ù\19éîséÃl¶\9bhÔ7d3j¬º\8d)\99"r\8d)ZlL\9dÒ\1a¯âÕ ã\rÍ0;+3Ñ2;2;{¯\1e½ÔÎfÛF\93Lèä\17]ëó¡Mh¬\7fcÙ°¿>~\99\9b\11\96h¯ÒDZ´\92}\11\8d4\1a"[ÚÍQzò\89\11Y¹£\93QŪúªªôÉ«*o"q\85\96\89\91\15\1a\e×XfF¦\r\89¦M\91iäï\84S\ fÑnn&ýùGÂ\9f,32t\8ffºÉ\9cZ»¡ólLáçäôÓÑ\89)Õù~¿:\1e©&âc\1e\ e\16\1dÍ\akP\9dÍ\89jTÞ`\rVëÊ8Zm\95\8f£U2¬jg£ªÚ\1abb41Zý2h\83fZ¬ê&³\93ë\9d\1c-Dz²³cÝÃ\8eî\ 2\b     \1f ÑG\99Ý\87«ÊtÇá:\12\19®\91\91á²×\aÕ\98µeEGýðm?v\vmLlõ#ÛÝYÅVÿTȪ\ f\9déµ\12Ê]\vm\15\8ḇ%\93\1ekãå¤^Å:ë&ÊyÊæËè®\e\9eUÕáÑÚ+*Ou¡ë5\855D!i¡XX&ò¤\84u\12s\98h^X&z¨\9dzÍ×\rm\84\86jε%³ÕZ¦\99ä+k\999c
-[gì\91jn\86#-!\9a\95±\89\88ôÊ"-!\16Ñu¢¡WÉPäÌ®ú\92Ccõét¼äÅ\86uÇÎ-uWSÒ÷o"*ó(²d-:Õ*5r\84H\16ë\91!ãGÜ^±$Ë®\14ùÅLÖ\18\15É\94\90î*V<y\ f¹È¦íz¡ÉƯ©³\11»\91rÂÚKj;\91$óù|>\9fKËõ˪6w½ÞÜÍÍ\98ãÿñ\18     -­;½N\1ft:½l3uLh#Iä\8c\87¯ÚDääGEa\8dzFÓ\91§\9c~±$ï?ÒhjbDZk±\9fõ¯\93W-é÷*««\90\8cîüm6®ü\8dÌÇê­\15uh\9fÓÌÙ©Cu3\93\9aLUÃ\1aÒP\9dÅz¨lÈ¡RÙ\90ì®áÛ2×\90?×}öqCsêB\9e\8d\88¦q\9a\v $|\80w6\86|6ÌF£\1eô\87733\9dÑaç:nª\1eâ\1a6\9câèP©Ö\93Auu\88\83:¤Ñù\94\87§&\1f3CòÑñ\87õæf\n*6DÌ\10©{þ\10Ê\9c\8c¹ñö:¤D6r£d\8c\fieH\ 1F\86HuHyÈø-§ãfPÙ\9fÞQÆÚÇ\8dC*µ\f©ÌÇ_\1e\ fé8søÃÒ\1ab65DHC\8cn\86tÈ(\8e\91\92!¬Q\17@Hø\0;\8a3ª4hfFMÕÌ\8d÷h\eïyã¥ßxë\91!#Óºê¨É\99q46hË[þ\83|ßÔa\12\9aa2\99\86©Æ\1a&\93Ô0               \11\11\11\11Yj\ 6QM;\88\86\83¨Cè,$çÒQ}\94èæ£ä\e¥Q*QK£tÒq\9bm\1cäûÝ2Ì£T\1fDDd%¢\ f¢¢êq\14u.t£::6v\15iÐ%£!6\15\rñÔ\10_Õn\88i\8fÅÉeÄâ|ØXGÃtÄwÆ\11ÑÑQ\89Æiê<\dä\1a\89íÆÚ\87ýþúÉ£®\7f\9dG\16¹M\84¦ÐnEÊ&ÿý·»\8c\95ðW-\91\8a¯r³Úo¨.dR\9bMé¸ßX\9d»\8d:^ÜÉ¿Áó<\7fº±a;»\89Ý\ 4\95ÝngBÃlìªh\10±\1e&\9a\8e¡\179tÄë\r"£w\1c\99£\88Ô\13ǹ\1dã\19cs\8cÇW\1fõ\98\9eó \9a3\eg;ã\10ÿ´\9bÍx\89$w¼Æ\8e×e\1dïk´\ f\9b\9b»Q\92"ÕùÆÇõGuØ\eÕ3Ú¨N½F\15\ 5\19Ð\80\10@\0ÄCÀÁ\ 5,8\ 1\a\f\17l\90\ 1\ 6\10è@á\ 2\10\0\83\b'\88@\81\v<h\80 \8b±YI\91L)Ë&Y\8d<KèwC.V;±ã«D\8e\16«\95<\1a«\8aU\17E\16+:±\91\7fA<ªÑ\8f76F§*­=¡½Ä<LVêµ\vÍæFh®\14\99\8c#4ÛQ\8cDB\9b¾(e+ªÕªco±\8aF!zLs¬Õlb\95dVy]\8d]é<'"«kÏtVd×\9bé®ì[IJª2ÓË$4sI\95\95õÌwD¶c\89ÌêX£Ç\13#ÚIrVé\92\ féÿÔ\99ÝYµìî\¼;\9f¤¾UU¤?wîVv­ê\99ÕmÞ§\18º\97\15}¾¡\9b\15ÍÊÞ\'dßøg.éü\r¥\1fû\9d(±ÈMqyä¦t\8aä\14Ú\11ÉMqÕÈM¬r&é­\8aÂ\9b1úiçÏxEÒYGRKº\95ÔßNwåM´n%½\9f\9fÝB\9a\9f 1\9f\9a\9aK*\11\99ôhÌvRC§\ fGÚ*3kî\ 4Í\9d\86æz¢Ì\8aæ8'èeÆaW'=IΩÖ\94n24\1cT;\9a\f\1e\r¹\8f%c¢²3++ÕqLX{\93N§8«\93\15\92Þ\9dF÷å3x\82æî\90î\9ft\15ºÿë\7fÛIê'}^Â:¬(Cª¹ )W\11çâ¡3\13t\8bOT=\95{º^õó÷Tt    ²Ì\9c¤H(§\12\9fÚ\\8ads¢ªÆR£È\1d\86 ÄÏ2ö8áIÕ.*§\18\eÕNÆMµ\93\e\ 5ejhCÞ½Þ©\19'Õäg\83Ãq\154"QM\7f¡zM\1c7\1e«ù8\85\19ûb}¥\19¶µ\8b]è:5X»Tk\17NK¡Ø\89WAU\e\1dÑúõ\8aJ\8b_ìÇ$Vd#)Þà\90ØOî\1c))VJ¬(Vä\98\88\9b\¿s\89ñ®¦\94³\90yõ²Ë¨~Ô\88×\9cb36âFBGu#4\866ä"µCûüìå\88©*­d¤\91×Ù©©\1a\8c¤Êc4½Tª~$F§\1a*\8f©|U*»,ÓÏ\8d «²Kl6Ss5\84¬F¢Ê¤:¢9R¡{«Ì¡·\8a\ 4\8dæ­2I\90\8bE\12\12ý\ 2\b        \f4ÓºoÄÝK\96ù<\95"NÝ\94f°FNÈv"3>ÂçñÄÛËxª\8f8¢ñT¾;\9enDÝL3ÂJÚh\98X=[§\19¦FP¥üÌtD\rï×\11\1e³{Ñ\10³P¬#l\84=®¢dîNç\11*!¢ÙÑ]¿}xÊÆè\89é\84højúM}È\89P>äf\94cúÝÜ\90\8d     kÈ\rOñFMFëbàïD<
-\9f&¼z\8bÂ\88¢Ú\1a\18ÖÆèÆèÊv#5\88¢´\8dnUwVS£\14)\13GgF\1dD\9c\9aY%
-\1aR\0ñ\9fQël\92!5$4\99k­ëLÄÝcS\97MR\17\89\98\9e|ê(ª$5ewlTÔØÌ\14\994HX\8dTëÌ»u¾\a)¦Êæ}\b¡ ã\90ê\8e'Q\93\9f9\9a\1aAr=¢aÑ\91°)\9eê÷\11­\99S\rÅ\9d ¸¬\8aC£ðÑ\98\90KÌq
\13\97\8cäV¿\9f\9bë£J\13Q\99\8fNÒÝjF\9c\11E\8a\ 4Y¥(q#ÍÕ[ºèL«Qã«·c\14#²á3\1aY\8a¡\1dù\88F\ f\8b\91Xµîuòâº2\8dUJdt;\13_6»\ f\15K§OOl\92M\91ZE+éV\z¥\95\15Õ:B\16=D\15\9a\11\1aËS\9c\12\9a´X\16iNMÚ­Xô\9cg;\94\8d\8dÐ\86\8e4féuFµd\9a\9dÖ\87\95\13û\rÉtnÊr\bËhÚÉ]\9fjÝÚ\8dêsZݸê\8dóêsV:íÄDsî\97ªñ\13Æù\91fF]\90\88\8bR©1\v=33Èí\8dݱ\12\1eÍP\7fQæò\ 5éÒÌP\854sþ\9d\9a\8a\15Í\8c\96Pj¦Õ¾JGsÎ\bÙ \89k\8cYÚul\171²ñÅ#U\9còØ\99¡\9aªó\90Í|f.­\1aSU\ f}Rã\8e\9e\8bï!U^øÎFó³\99aÿCN\7fN\96\8eÆÏSs²\98¦ãÚ>ó\9bÝ\r]\9a¨\93¹±ÇLNX\8bè8æ\84Ñ©c÷}î\8boNþçf\\91ÏÍøÓ\9a\eÏYgnì\8aÒ\88§N3ÕQ\13\1c¢i\88¬D\89~6n\9f:xÂF~\1a!\19Rj\86ìÄ\99)5v§¹Xï4wÂ$\9dfdz\9a!:£\9e¸!ÖÌ9\9d)+12\9e\99ºý\1e£·¶ùIéÿ¼%2õ\95d̳¬lÐ\84\8dIõ©T\822\1f°ë\84\1aÝÄ'ö\88\9c¥Njxñë¤.3¶\9e IÄ~M5ØVgÈEM(c»qønZ\1ar¢7Ñ2Xé\9d\1em\8fü\97\18\91Ñ\18\9d\8c\96(\93Ð\ZK\90C\93Ê\98\12.Kó+\9dq¹Q\13&.ËsÂg¥ÆÐ\86ö°\8b\9a±1ÿ¤vñO\8dynÆãĪ\1cóÝ¢qR» \9eÕì¢.êÙ8¢Ñ\97Iv§c\8e\17\9f\91R±waSe2ý®vï«Øº\9aô׫\9dD¬,Uö\7fV³9\96Ï*²\97«Ý:eF§2\85ÆNý\r\v\19\ 5bê<æXS¹V\1fE¯;{Mæ*ßTwÿ­ÊùòÒ\8a~5$D\8aÝýµ\92\91¿BÆúRb­\86^~YÓÓò\86ffLÒL½ÎdÖæ\16\97¶'²\ f\ e\87\1eZUæsj©'&íL¥.ùû\11·\8aRFGqM+®)¹âK+þÝ\97\9aÒP\8ad(\94³ºÚ32\9bô\8arz(71\8aM¡ó¾ÔضÊ\99³\17±Ç\1aû#\85Æ\8fÇãPN3\85Æü\84&\ eѤ\93Î#GOªÍÐÔ¤\9ebTs\8b\94}M}»ÔÎes|éxF²\91Nò­J~\94sj:\8e±ÎÎ\95\9a\9e#ºúèbGvD·áQõd\87\8e>»16dõ\12#ÉêZ=³Õµì³\9eÍÊZ\17"ÕKxRåa\8d·ÌÿÕÕÕU\8ee¿ß²sÑü\18ïÌh謵\8b&\9d\99ÝÔ«ìÈ\8fêJ\99>\8fÔfµõLxURë»\9cfV´2«²²*\9aTËL\12ñ¾\95\91\15\8c\8a­²º;\99\fÿbmX\91¤Ü\19ê\14\992&ÇÍa§Ó:SÜrl¢Ô\10EZe?UÏ/v\96\88«¦=%\16s|¶¾X'!\89Ä£7cTRo\15yT\95\1a«\92²[Õ\8e<³ÖQ¯¨×£Þ8G-Ï\15ÕÆ5W­¹º\8cñ\8a*|G+f$éê\9e®Ö*Ç6³\8b5\92ÔH;\1aK\8aë\84ÿÇúª½N²\8d\14\ e±2U$\1c^©¯³Lc\87\8b\95'Fd¯Î-    ýêì\95{GV×\e»]ý\11rTëb}-gÊ(7jê£e*Ò\1aÛúÊ\9a\99\19·Böæj¬ìÙãimNIùv\fegöT!\9bì³$û\96Ò8k\9f­Ê\9d<ìm69Kõ\9fS7ßf\1f$\95\13\87Y\9b\9d\92É\84ã³ô§»Ïç\19éRuz¨¦\f\8dê·Sù¦ÊìüÈ?\99ê\85.t¡\93X¾Üw\9e\94\85ÌjB¿ÓHkvÍ#µj'§]y£'\8bO\9f?\91ãØ\98\90æ¬+\8bé%ùà±CTÆÛr$ÎI\87\1c©Ó*T'UêlY±Vèc\16\11ï\9b©\92\f3\12íE\9b#C\91cíb#]\91\18ïªÄXVóè%Æ*ãÝ\19I¬xcNºÚX\8fTÆ£\92\8b¦\ö_t,¡\93f\96ÎÉ0©ÑH\9d\8d±¨e.óÏýYhvë-RÒ¹H\ eÉç\9d¦Ûê\85l,Iê0V\8e|zÊ<Ê\882£X¿4\19Ö\ e\8b|;\12_\89jª-³\8c\"eÓ\8dm\9fí\8djrgö\18]q\8e4zÑs­cËä\83ZÿÔ\8fn\9bß¾b+\14\93º§Î£ÌÍ\89Oº    OèrÊÐ\91EÆ£"_õ\9b%º]·ÍÌ\19Õ\b  Å\86®æJ\13j;¨8¬¢ª*\1agh\1c+z\19Å2\942¢Ñr4Å"\11âÔÛkÝwd\99¢\99¢û\11\87<ľUæu<e7\9e\9fø^Icój>{¥hÊ&õÈ\9ezM±±Ë¥:\93«\86Uù\12²ù6ròp(Vb,9ó\10«!C±\97_õ)\12\9f\8bw\9a\97>§)F\9aþÔ¨)VÛý\½}×P®wå¶sÝH²éÞ6C7=\9bD\8aÅÒ\88\ f\91Ìl\14©\1f½÷_Þ\12©+/D6e\8fÈÑ9w£\vÇU$ÓhE®\97Ù\1a©ËØ\19³lר\88î\91º\18\1fÒTµÚ\9bß­¬>V\93ÌnnªÞ³b2\9dW¬®NG\19îQ8ä\96\8b,¯idÇ\90ò²b·ý\86\91ÒÖ¥tí¶Ú\10\12\91Ö¡!\85æb\9e\12¡ÔDx\95éÐpk\9b\1a\935Ä)y4Ô9)d\r±\8c4]4gfø\8eצèhCd3Ç×áÍ<Ý\88Å\9f\1e£ßi!\8e\91Dñ0¢\94½e§\97\89Dr;\9d®½Ó\89Ç{\7ff\99\98ös\8aÌ÷\86x\862\8cxgvqæÈÅú\98\11\8b\8c\88îÒ¥xÿÄn¼X%d&\88Ä\19j\9dN×íusaQÌH³î\12Ç&«ÑØQÆ\11\1e\9dÎF×0¢ydÈdóÙÐh+Ô±Û±¿í¸%wÚ!Ö>§7¤í\95\8aevÄæ\8beJ~µ¦Än?<}NÈÚ.Ù¾ùn\9cµ9Û/©"Év$\9aB6V\8eZeëò9ó\8cêãÒªI>ä²\96ØÈЧ´^\89F\9eZgÛË7Hj¢9\9f<å)Í#åÈ\8d\91²LG$u$u\1eéMî\i[ÞU\8d9rk®Tse\11çb<ªYSº\98    \9d·:¿C\1c#½Ï\1eéGº\86æ(VSº×Ðé«M\9dµ¡9Ò¦c\8e3ÇóQJ?\92Ðýó|\8eÑ é\90\9d¥ÿµ.ß\884wB²Ðë%=\9f¤¼×ÈJÌ7lÇ:\1eó\87\1d2ºù®Vä¢\96jlÒò§þ(\87ä\96k:VW\9c\1aÇ\16iö­}Ù?v®ªÆ\97\9b\8c\93\1d\91+\8db©H¶X\8dï[hü²\9eÉLÝ\fjGÆÔÞ¦Eï\r\92lm\\85\9eé\87Înú;ºöóÈÇ\95\9c|\\8a\fºU¾"~^®\96\9f\9eLM\9d\16\9fÎ7h:BÓ\9cöôÛÚÚ\92Ƶ'\1cöF\88EFçÜçæöÂ_Íß\9f\99÷¹\90K\16úÒ\96Ç´SgÇm[ºÏïj\9fW\99ì\1fã\8c\9bÞÔ4\9d\e·VW+bgµº\9d\8e\8dÛzlWûêVýp}³3i'jÕÇxCÊaÕ¯5F\eÖûüVUë[ª\8b\15\ e\8cÃZ½\9a*}/³Ø\95]\15\95kF!oªÌxFVõ»£Á!¯7c\16ëC34ÕpN,wý(\93¨F\86\99½«!=D&K®eæpj®ñao=s\98\8fÍÆ\87s<W-W\1f»\1a\99²Mù$Òúü3\84\86$uò´£\1f½\8e~\16\1a\91h\86W±T\11\94,sDºq8^¬\9fè6öÄ.B¹««°n¢°ä0±BNÉ\89·bõX$\ f\1eiªh:£ÅÓÏX&:\19m\93\1cmÓØc\e2äIä\88~\1c:\9b+\19$ÚW)#Ö5/\12Ý\8cC¢«³\18ñÎ:Û\9dñèrCã\8cE-]Þ\19g\94±Ñ«,Q\91k\8cyUSïycÌ\11\9b©©1&\99±÷iÝÄ7Τ\b\16©\1fQl<75æËª\8b\99\f\ f]Äú\98!«fx¹\92¯ªFs×\r\8bdDæçÄWWS\ e«=«×¼,?\99»ª\9bðĨW³«:\8b3t3ÖSDz\9fÍR\93E¿ó\96Î/wt¦)×\8cênu¢\9aNÂëå\94\96\8e\1f©$µç\98\a\9dSVÆf\88\92ó\8dçÌb®°Î¦77=\r3ò.&\1e\89\8e'6úÑ\14\15\95¦ÊSÅ)úI?j¤kÑ\18¥­ÒmîF\1dmXãÇ\1d\87Xrez  iÜx\16É7\16M\8fGÒç$Ùo¤\*½GÛ)B%³#ô£\11\12¢3\9a\8c5\19\13\19tÖêÌÅû3\9d£ai/ssIy\17©ûØII«cý\ÊÌ\97;\e%=#_t3.5\9b\94SW\16vNÊ?\96\86ή\97øãÕãØ©9\1fkF6;\95±¹¡\92Q¬Û\9b\16Û"ª#\99\1a\12\1dYÚwH˳:»ÞØÒÞÍöÙ³_v3\8e-¶¼\94\88ïfH\91        Ýi\Úº\öS¾MùVÔQ\1aÎ¥\84èò=%kþÝî®w¾ÙÒЧFLÚk½\9b9ædI¯ó>³¹uì2¤³\1dÒG(Sú\19mÈyb¡Óy\97n\96\8c\19§\9f¡_3¿1&\8fÚ£ö¨iÔuM\9bâ\99nHY\rÒÝ8\9fùq®\8cû.\ eS\8d\95\14\r*±!ö;\1abFb3ªÆÙæ.\80\90Àp2'\7féÏç\9f˯·SÍ7ï\89Ç|n\11\9fð|wwòü\88S\ f:º»\91MYçÈf\90Ù\9d'6ö;\19Wb\17@HøÀÙ\8d;\9eç\aÏ\ fÞL?ÖÞ~\1c\91\8b¨ôQ"³G©DçQ¢ZÇyHP8D8¤N:dL<D\ 6¹2(v£(\88Æcz5É\8cy\906c\86Çö\98ãÔ¨Ú\15Íq2NÆÑɸq$\ef~\ 6\19q\90q\10uPÉî¨ÖU­8ªÚñðLÍøØØÐLÆÍM]fÜüãò\i\90i2î1Ä14\9f\8e¡¡¡sÈ4\1dåagÐãaUè\83EÇb\r\93\90ùÃtk\8d*«ÕlÔj5W\91\87\90Ñ?Cʵ\87\94\94PJêþñ£l÷6>#\1e3õuÌÌÌÌÌ\9c\98lÐÜFÍçÈC|SÓº\1a/o4¬%R£:ª¤\7fT«ÕjuTÇ\94Z\8eÏ\98Î8«Ö¸\13\1a\8c£uÜUI\8d²ñ\19Câº\r\9b«\8d²òd_ä/·Ü\88\9cú;\91ýª½Þ¯ZÒÜUý\88½\93¡\98ysä(f5$±\92açò«¶ÂN±úz\19Oäõ*©${;E®¢¢þäìjªîÄD!^j\98XiûË\14\9d·¸¼²\94ie/)¢ÊKHHL\8e3&D,«\JeºêåYÏê.OH+\19»Üªw(fEu\ eYå¹>¼-§\8dìª\8cÌ\8c\8a\86tV&õ\e\9a\86\1eö\9c\19\13»°ÌÇ\96è³^óèèì»\9dÔtnff\8aÌ3_rÑÍ]ÊDâ\ 5®4¨ÔÏg&Ã"Ç)¥\10Í\8c\ 4\ 1\0\0\93\11\0\08$\ e\ 6\ 3B\ 1±\80\a\14\0\bÀ\96@`\16\84\10K´¥2Î\0\0\0\0\0\0\0\0\0\0\0k\13±\8d\a{\8e%\1eäx\9dd#<$âN¬þ\1d\80>jïP\v\9e\18\83\ e\1e\93\ 5Ï w\98\16\ 2àÉèÛ\ e\1e}$í°\9a\v©A²\83\8c$\ 2vxùÅ.pò;9F«\83Ä\14Û²\ 1£:\ 5¹>\8a`$íþE0Ã\95\7fQ\1fuÐñx%)qwÛt\90\91Ò3Ýj\9f\84(\8eÔáú\9b\88í\84ÛÕ!òïÄ"Jß\89-¤·dÕN²rÄwi;1\86âwb\aã\11\ 5|'v\83t&ú\9d\90+u\88o;9\81G\0¼ðB\92©v²Å\89®I\a5Ú ¯¢C±É\ 5:¨FôÎÁÖ;ivsȤñ\84]e\ e½\90â\85'\98p9Ì$>åàÜ?J\ e\e)\ 2r°û\15Ça\94Üüà\89\9b\17\87\94x\9a8Xø\9d4ípH\10\v\85\83kí¤\93\ 5\874c\15p0ÑNú\8aß\10Ó
-\ e¾ß\e\9d\9ccÞàñ\88¶:a×ÝP\94êÄ\8eº\ 1õì$I4\10\r\f¸á\1cÞ\89ÜÛ\86\8dØÉD®\rvÌJ\eD@\ e\ 3v"ÑdÃ:`\8a\r\8b§\13¥i Øà\ f\9fNÞKu^\83{Q(\ e×°¹pÎ\1a>>öj\98O\8cªA\81Ó\89\K\rKa\ 65\1c}NÄã4\8co9\19ÚK\83£Â;\ fcÒpþ¹£aWÉ¥hPYN\ 4]hX¯\9c\f\8b@\83;IÞ\95o9!\9bÏ\90¨\9cü\81g\88×\93s\86\ 2\9e\92Iª7ÃÉsâÅž\8eQDåd\1e3\83à9i¹¿\8bN'RÃ\f+y\9dÌå2¸0\84eÐÇ\9d¤\982\14\14\9eØ\ 6(OV\9eð¢®è\ 1*îà\89\96'<\16êÉà\9f\92xùÄ\9cá>Ñe\8fª\93Áü~Ò=\ 4@\91¤\90@á6e(1\9dR\ 6Í%(äY\10(ãÕFP^\14mPÌL\19ÔH(       H\19º°Plè5\14\ 3­\fº}(I¥\f¥\10
-{ã8¢\ 4\87²Z0¢|\8bñP,áüJI÷;\r\11\8b(ê]\19&)¢¶à\84\87\1aHm\86²Ì¹to\19t ÎËP\96¼L×\95A'Ü­\fÊ\1dJ_uêP\94FÊðÅáË8\9d:\94A[\19¼Û¡ôͼ\88\94¡Æ\ eQ=\19:\14\ 6ú\1a\8f¦ã\10¢hÜÊ00D9\a\15ú\81\Ð¥ö\88\88b\91¤\fPü`Ê·¥¢%âÊ`ðÏ
-\91[\ 6·Lý2¨9Q2\18\81fËpV\7f$L\14\16®\f]C\14ëR\ 6\942Q:GúÚAB\80\19\97\7fz&J{\92\f=\91\150Xâñ½\94N18ÿ¸1,7y\19\83Ç_.\86Ý*Ê\r\86]\14·S\f\81Ì(Ì\94\18J\13\1eÄ @o\14>\1c\86¬<\8aé/\f\90\ 5)QL\18ê\91Å\ e\ 6`\8b\94\98\14\f\8d\94\947\16\18\93\12_\80¡\8eÑü\ 5\94@A¤¯\94gÑr®F\10\97ÒÏ{!-Êê\ 5\11Á\94®å\85\bÉ\14n\v/TMJ)¼\0I\9b²Cî\82F\9c"\12vax\9d2dºà2=¥¿s!¥\9fÂ\90r¡oP1Y\\80XC%\p¡iQù\83·\10×G%/\89*\8aR\91r¶ =¦ÒÍk!\959\15®ª\85Æ\85*vÆD\88k¨K\15\8c\87\16\ 6S\95£ë,\98ܪ\b\15³°h¬2\96Ê\82g­Ò\91\90\85\1cÅX\bc!\90¯\12\97±\10_Xy{X\88ϱ\12Û`!\10\97\95§½â\82Vbí\15\97Z\99Ó®`\15[i'¹B\12n\85Åm\85\12·\15£¤\15\10ûV\82öÊ
-\9d\19æ\9«°\82Áº"\8dü®Ðå*´\17½òÈÉAâ+k§
-óú\95S:T\ 3\96\ 1\ 6\8b\878\85üÿ \8c
-ô+ÐåW\8a\f*¨4±\b\1eó­½XN\0\1eöÆ2\1fï\7f,\eµd °G\161\88¿\ fe¹n¥ }\96%«I¡QÌbN¤\80n\18¥ø» *\19k\16¦úJ®\8d\9d%F\8aÂvùY¦\81(¸;´t»PH\ 5¤\85\96eß9à\962-S\ 5
-U²ñ'\80\8fZ\ 2Î'ôbµ<©'dik\89\ eOH\ 6\83\9d\10\vÉ\96èÏ     í¥-ß\8c\13RÙ¶%\a?í"·\88¦M\10m·ô©MH½·°^MhÝ¿ÅzÑ\ 4È\83K\90Ì\84¾?u!\13Ð\82±\81\1cTÓ¶üù%¤­\\92xÐ\\92Ò%äz.¦×\12\90\8c.Aa        ©?]þ`%Ä\90u       >gÔò\18»\ 4\1d%D\11l\97\ fÇ\a¡»T®I\80óÌ\92ÐDßÅ|$\ 1£ð\12G#!ïxy\1d\91\90Ìå%\1a!!\11ôòõ\8f\10\92z      l\8f\90Göò¤\1d!Aw/5+¤>ñe\936B§æ\8bu4\ 2\ 4ëK\142Bôûòè\17!\1eôK\90-Bkþòª\15!\19ÿ%ª\14¡B\ 1æ\ 3'B\8c\ 3&ä$Bø\ 2óL\11\10Lì@\84\80
\19\ f\f&E\12\ f\r¡©\b\f\ 1W\13&BYV
-+Ì^\15\vc\90      \ 1\ f\r\132\84\90x\1cæÉd\84\1eæö¶F\1eÄ\88\9e $Æ\88yó@ȨÄÄ©@Èyb^1 $Ã)&#¡øÒ¢Ì?(ºÄ¼¿\1f¤\9b0&îü »\8cyà}\10¬\1a\13V}PÇ\eópêÃ\9ccJ\b\1f@\ 4t\95{\0y\8c8ìA .æÇéAÆ\85L\98\9e\a\9d(2\1f+\ fb;2!\18\ fBM2wÇ;Ñ5Kò\92\91­w`È\14w   '\93íì ºPÆÍÊ_ÐÅ¢½\ 5¾ñ,¨ê \96\92é ¤+ã;\\9dT\0V\969aÎ\81\96[F\18æ`ü.³·\1d0ó{r\90\ e\88\99x\ 1ã"3lã?dÍL\85\85\ 3\98ÑL\b\81\83\10kæ)ߠ˵\998\91\iý_}3\10Ï\rú±\ 57\0ÚãL\1c¢J\99<\87\81³ANv\86'\9c\ 1é\89gL\\10h`_\13Ï\14\935\0\84J5(S\9fùþ4\88ôÏdE»Ö\ 3Í~K\83lc\v£\8d\ 6\10\9f\b\rZ04f{\ 6ð\85hbÉ\19\ 4T4Oi\ 6±ïÖÙ\v1£±
-3\0ñ\vˠʣ1üd\0O\91&\88\91AÑIóÌc\90åJ\136c\90ïKó;Å \10\ 21p\8eÓt[\18\84¤§áÈ`\90\1dÔ\98\180\0\ 4ë\17´T©ù\e_\90â©     \88^Ð?Õ¼ú.È:VS\89Æ\96v5Sm\970bÍ\10R"®IÞÚLy/qÁÜEå\8b\v\80ª54¼\ 5ivkÞÍ\16DûibÑ\16\14á¾Z\0ì_¢\ 5ý©f\16hMk\bYÃúæÖT0,°eÙW H\18\ 5þ¬\15<#×\F¦\8f\96ùÚ5Ób\15\98\9c`\1f-õs1*À®      åSÐ(>5\ 50>b)ȯk\8cF
-°L¯\89Ó(¨ôk\1eF\14ä\19lB\11
-\12÷°y\ 1P\10\88±\89µ'\b\ 3Ù|³\13¤4e\93C\93Ùd\1f'\bél\8c´      °<´\89\8b&¨0m\1e"\13äUmB\7f       \12óÚ|
-\9fmL\11à6j$ÊÛðX\ 57\ 3p       |\8b\9bÖÄ(72\8eÎ\r\ fÝæfê\féæ\8b+A\88ë&\81ÿv\93¥&àÍä±òæ­>½1È\85{#Â\ 1©\94À¥|Ó\96Ï}£Mp¿!s\ 2àLq\12H\9eÀé\8a*'¼\82Ö\ fZíàD)fÂ\99?_8\7fr8\1cÓ¯\ 4Ê\828i\8c!\vJ\1ck\10êâ\12l\ 2r%X\95âÈÓÙâPDJ\90Ñâ¼\b.ei\8cÃgaã$\18%è©ãØ2`A\1f'\89!AA!Çë¬\8a7\ 4\1c~ª~;r\8a\1c\12 ^r\82ù\bZ@9ïs\ 4ñ\8dÊiT\8fzÉr¶Ã\b\1cÃX\ 4à}òDP$æ\18\e\11`iæ\84÷\10ä·æü¢!\bð\9b\13¨Õä&:\87a\85 Íx\8e}\b\ 1\8a>' \ 6A\7f óò@\101\86N\8c£¢\93g@Póè\18\8a\95/;éhìgô\ 3:/>¶{ÉÑÏ\v¨\90\v\e±Ù\aZ\17Áj¥\92ùXèA³Í>`ì;p\ 2ÅÀÇÒø@fO\1d\16çóh$áø\0Ýñó'~ ym°ø\80+\8dOq´»\91ø\80ó\19\11\1f\10T\ 4^ܨ\ 5\8cf\ f,Ðr\ e\b±\1fg\10VàÀj\82
-!çã\81à\ 4X\10æãÓ*°\89÷\9fÔ¡¬µ¶\91\a\8c¦ÀÚôU\9d!\ fÄ~d0\9bÓ¥20\90\a^|~¤Ðø¢\82\85<@¼-:\0D\1eà\9a\ 4Ê\9d\81-R\90\aö$\ 2á£\\85¡È\ 3V]0gÞP\ eD\1eÈ\ep\b\10FZ\912\ 3È\ 3\ 6|ã³×Ø$fY\1c\80Á\b¡\10¬´2\8f\a\88X¡3\7f>Û_fÎ>\1eðÂIB9\1eX¤À÷\14v!xØnÕg¨º\14Þ1®@\10¢;»\83j\8dM\8e\b+±ï±yüĶ&Qx{í@}ÖR\15ÀCÑ¢vÀ\1dFU\rA\8a\8a·Ú\ 1s\8fè\95\94ÑÒn¯b\1d(|LOEí@ü\14\ 6ì;`\8b'qDk)¤Sß\81­4Ü£´54E¶\9cbsµ\ 3\93¿ùEÐлÕ\ ep`å\84\94ìO%\ fë@9%±Ñ\81ÂOúrÂ\90\1f¥Is ½Êá,pï+r`¹\8c|Y\96×\1edË"\a8:¶\97"\a6'{\18U7÷R8à½68\ 2N\85ØÂ\ 1ÕQ[ª\9cªP²p\0¤\98G=\9aR\8d\84åï\96FxÅqÀ\ 5/°òu\1cÈ)\81¥ÑâÔ|¢l8\ e` Z0¥1;\ e\84ü\1cØh×Mp\1c8<T\86w\e»\14\ e0nõE\94Ô\17E\ 2ßÀù\15$F!¡Ë²\8fÜ\80\ e^\1cè¬OÝL\e@w/\94U\ 4cï9eÙ=`\ 3:ëº\8bÖ\v\ 6FáXg¥\8dºt5`«6]Lj\83\89Êi\80» çí\81\9bÊ¢\ 1øø\13òB\ 5\9cy]ð\f|µÕdL51/´\ 3µÔ<\ 3\99'\ 2\b5<\ 3\eº\1fî\8a\ 5\10\84Ú¶\v\f\11Q\9d\90\1e\11¤\fì\ 6ï\97\14\fø
-Ûé¼#Å)7~\f\83g@Sr\8c&\vhF\87o1pI/\18)a?ü8\ 5l\18pZ[¶Ü¼\97\102\14\fØ
-<Oº\9f\82~\ 1(9È\81®§:e\0þ##Ò¶\ 3\8e\89Öº@\89_Oý\94Çu\81n8¹\12C\11\17Xýï¬yô/\8e¸²\ 5pf©q\ fÙ·\93\0Z\0%ÿ߯%¦\8d\8e\ 5ÖÎ"A ¯@±H\93ÁZ\ 1\0}ºË\97¬\ 2÷^\9f\ 5o\a×G\ 5¨Í¹%é¦;'\93¤\1c\93\14\85üßH
-èP\rn]\ 2\85¥\14(
-$@\887\966\ 3\ 5P\86\1f1\o%&\eO\0\8b\183®!9¥\ 2+Li\88x\93b\9c\ 6,\9c Ü\12F®©¦`$\8a\80C\ 4ì\ 2Æøeþ¢'\93\80\8f^\8bøÂ~Ê!\ 1IX5i )}ë\b´§:Í\96ñ¹®Ä\b\88\8a\99-k \b(©ÝÍ÷KY\1f\ 2\801úúÉK\9f·\10Àã\8a`ód\97q\1e\19\ 4¨\96d\0\99¡ß\95V\199.¤^oFRú\ 1䣢£ÚQDß@ºeØØU\10\9a\8dÿ\99\84\ 6>\80Â×Ì\17\ fdðy@\7fØYFyá\99\b°\82w\80Ð:7¡\ 5êò\ e\88\0?(\9b×v7T\a\8c[âA\1e\1c` Èï\9f\9e
-\aH"ßH
-"\8eeÒÜ\80\ræ ?¹`ôP5pØ\07eؼÞCGê§\ 1ô=6­ Å'å\19Pyð©×¡Ë{e@>\\ 3\10\81¥\ f\85\9fî\18\ 3øÜÏÀÇ1êä\15YW½þÓû\83\ 1
-&Ý\7f\fÜ\83Õ\vHbæ\9b?\r\88b_°Ç\ 5x³®±ª\95láÐ\ 2æó û\0>¬2¿\ 2N±N©ç\85zZ\ 5\1c\8a\1d\ e;sS\80µ×i*\94í|(@\9f\19:ùÖ    àF\88£ÏÞÿµ­Né*;hñrè¾ùçT   (.bÈ\82\11\10\ f        ØlÈ\17Äõ\r \90\10Sâ¶þ/ #\807»¦b³x>\ 4\14Ççt\94\84\ f\ 1Í\0)L\99e\9f\82Õ `Π \9dI6Õ\9a¼~\80z\11Ehµ7\13H$z\80h9\11ht\1açu\9e\1d \ 3C6\&oç5T\7f\19\831\ e`õÓL¨ü¤Þ¤¥\r\10Å\aÊÈ;\ 2m\80        ×@z\ 4åR!\1a`\ 40>þ\86â4\f\ 5/\1d7\85í?\ 4\9b\81\ 1¸L¸X\ f\Þw\v°ÂU\83¸¢Ê\94®\0·Ôó\96,\8f\16\92\ 2xÖ7X\91Ù\ 4 Ô$Xe\14óo\19\92\0û\82 Äô}×\89\0bÜ­±ðS\1a)\b0/«me\9a¥õò\0r!\8bw\83×uÃ\ 1àË[\13ø¸âng\0[å~"*DÔ¦¡\9f\17Àjº\81uÅ>\b\1aò¾\9b\99*\0H9ÖAM\887\820\ 1èe@²I,®p\b@Â>\8eL\a`ÄÓgkÐ>à\b^\f\80ñùNþ\1eíx¬E\81\19(\0\1a=\0\80|&Õ\7f\08\ 6êC>¤ 
\91§Ë\ 2ÀrIa\9cÆ>\93\ 1\80æ2\8a¦Á;\0 è=r\f¤ô\14\80Dÿ_[\88Bûÿ£ZM\ 4³O°\93ÿk${º;\89\ f\7f®8\0¦ô\95w S¤\86÷Z¼û_²Ùæ\9bÌ®ÿ¢\9ca_ÙÌWsþ\af&äù\8fNñ®\ 6­\88©¸øO\12\ 3Î$¤"Â\9fwÞ?m`^ü\8bÃÝ\87Åì\1f¢ë\84Ü\w\85 QýO÷ÿ¨U\ezOè\7ft×0vùGÎ\88k»g\96é\88ã_\97åço\ 3´Æ=(ü\eã°,\15øþhÖvÓDX\88¶_æþ\fiEö\10
-aTûC\9bÒ\14\88Ò\85\1dìß±\9a\139¯þMñÐ\81-R×\9dþ\995>\f¥\90\ 5\16\1aý\r¸\14MRTôü\95S¥6\9b\9aÿCq]þ6öÀ^,ÿøÐ\83éÈ\85Ì\8eüÁµyùû\13áð\94Æÿo \89vGäùUÄ?4kÕ\ 3Q\11ÿ\aë.\10O{Ä?\82\8f\8f\9cÖ«I\a\7f\1d\ fþ`/¬Ü~%ò{\7fÿ\10|³9ð;V~ºxÅaµ\90\0í½Pl÷Ó{¤#M\aC\81\93û#\90Ýýð\8aÊ\11àA\16DóãÒE_\1ag        \1aç`\14¾\ e\1awãð\10¼$ûuìIÝ7Õ\17Àþgz´Ë\95£QfÙû\94È­?Õ\90cç¥\96Ö®~e¥i2Ûõ\89<1\95ú\85\80ª\8aûS·Ñô*§¿\11;'÷\9fô+\ 4é*>\18]x²Qô\87+\9c\94úáùÙA\ 2èw\88     \ f´\835ªR¡\89áù/\ 1\18\1fãE\94?VJ§\95òäö\99gf~aãr\90â[ù^|\97¿¤*@ù¬dΧòWVY­PùG\e3NåQù\19~Ln\ e\ 5\9d\fçÊ\ò\a:\8f\91D©nüò\85ü\1d<\9e\8b¦.ç\1cäø¿}5º\ 5\89±s;ùâ§\98    AØ\83µÍ:É ëMl\11`âè\ 5îðãêJøÞ\fÀ\89\8b\85\1f\88ï·\1c\147\1aüÔJÀQ\94-+\ 2?ø¡\ 5j)Æa¿ß«ÿ]\ 6nÀõ'ßç\90?P¤÷ýÜ\98ÑóGLÁûUPM\ eeŸë>ä \9e=,\90{îËÌÁ S\81¬\8cûåÊ_r½ýÑq\ 2:¦Yl\7füÐQ<\81/£mj\9cÛSû}
-IÖ\9cë\ 1ç\ f\1aÓ¶\81@X\ eJ\12Ï0û`\8eDG½BR0w\98Ù?íó3BÌÎvwUd\7f\1a1Ù+ö3­ÊMÁG{¸`_¬w\vá\eöíóúI#q&õAÓçNo\eÃõ)öÉ\99#^¤·³¾\8e\15\95(Q4\97Ø¢«\9fi7p\8e{s\9fS\17\80ª_ÌZBÔ@\96\97ú¹hõA   [6\84ú\ 6À\12\0Ò:ýÆÜ°_¦_Û¢ò3ý\r\85      T\80Ï\9d÷G¢ÒoÅ@\1aDzn\fé;\1f'\90\90º@Q \8eÑ'B{²\1dxk²>ô\85ñ\1cVùcÐw\86
-\83óN?\1fSLÛ4Ì®\ e­\9fO\96úñ'B·º¹z~ÆÄ()w\9d\9fRÇÛ¡\14¡â|\\bï7ίCé95:ÖG\8b褥w1\14\18´<°bõ²\ 6{\ f2_»´Î~ù<\82\829n\10w©±å¿­\8c¾îo¼Â°G!jåWþ\01§ÐRÓ´#å\7f\15\19\7f¦=b\rÞäç+X2!d~\95äÿ¬Ó¶h'öÂ\9a\13ùlTï¹B\19zÿ|è\1a\14\90\7f\9eÝ.¹ãw·{/\16È27~'YØC¶M#\1a\95æÒU\19ÿ´hì\11\99=M@E¶\19\9f¡\95vpS¸'f|j°\88\aL"þ#©ò.>ecƨԨøT+¶\9b_äNðCK|1«$*Âñ½Ä7\18«\ f{é p\95'+ñÉ]ºJÃ\88\92\95øòå6¬\0\85\87\12\1f#\92   ÕåÃ"¤Ä×Ìý\99ã\ 3È\85î\95ETd\98@PâÇð&HÆ\80)\80Íl\19¦¢Ä·LT7W;óÅéÞ\8b\ 5îJ%$\10âÈ\84Õ ~¡\î#z\8dø >¿$\ eJSÜ\83\1c8\88\7fûÚrK+º\99\1f}r£c±Fnø78²,0phnø\11\97ø \87\9fþ\15E{Ô  ®\ fg\91ð©\9c®ësð\aÝ$|y4­ô§hý\81>        _Å\b\vRßý\92ðÉ¿\8e)ÊÓÉ\13G-ºÙ³\93ðe\b¯´þÈàãFøÍ\91¡$#|Á{ã¿áÕÞ\ 4\18\93R-\e7)\82Ï4\vZàá\99\83À?\ 5D\b\8f\b\r"ðÕÆâ\ 5\1c\97J\ 4>¶T\10ÞD=¦é\ 4\81\7fÖò\8b;í§¨wÐ\7f\8fT\10\82ݸ®¯~\8f\91ñɵú=\89Ë+QpÐW(\92Æ\9bÒÆ÷²Í\1d[Njï5J´dĺa\9b\aîÐ{é÷&VK¬\1e3áx?\r\89Ì\94þÚã};µ\7f\ 4Ø»\97Ù\80*Úf-Ð\86\7fGËîqøíaOã\aÙýÅÛ´mè\9a\1f
-\b©{ò\12­\94\88\ 5m\82¼áÒ¢\9alÊrÿ\90ƼWMÀ1\14÷I\8f\18\1a\ 2\9b\rà::p?)ï\ 4÷\16\1dÆÐS\11\91·\17'C\93e2ôæ'¸½·s¦h\ 2ñz¶g¾ý"\14âCÕkß\ 6ã>º0£WP©öãÞ.Vàü\8fiß³ñ\11Q\rñ    ¤\84V·Jê4T'SÇþ\89.\97G\16Á`ª    c/X*GÙßI©S¢?ö\1fekwýÏPm±7Z^       Z ï\92X@÷u\ 5\9aíf¤\80ësö9!:VÍ~MS©DB_¤Ó¶»\ 4\98×\1f\82ö\83.Ç­\9a\90\8d\ 1éZêúVðýî\81]Â<*\\7fh\9aSÈW\b;\86­\1fÆé£\12\a¶~Ì\87û`QEÎüYß%KL&½5¿±^:\88õ¹W\1f\0\? Ç÷2«/5ç\18\8e\9fµUõ¢9ÅUÕs\b\8f\91QÍ´+à5T?nâ¤\81©'\81ç²ÌÝ\99GýW½X\906oÙª\15ÒP\8f\93 2éNy9Õ§ßæ¡©ÿÙ¦b:ý«\12òÿÛ)âÖô'Û6ÜCem\f\98øt!\83ç+ÛXÃÒ\1fº\81ݯWTi\8c'}\81\8aòE\80û\1aéña\86\ 2\82u\8f~¼B\8aFϧ\rË(£\91¬è;­=ËîAêDôü#Îõ\93ñN\8b\91¡Ï\83\13\b=þ5M\19\ 3Áâlâ\81¾zÔjFÜØôÏÃã\9f±ñv\ 5\18\18èóÝ\9c\8c'(<úü\9fð&v\16\ 4´\9eß,Ñe\19¯ø\8cx¾¤R
-mÌÓ½ìü (l°\8fÓÆ@çÁð9Ѩ$o¼(\87\95 4è\9b·]ûÙ\19c\95òAÛÕÚü1·µêÞ\95Æ\9açîê\8f\93\ 2¨>\8dæS£ÊË\ 1\8af\81¸ËÍ|X9\8d\7f\8e\8e1ɼ ±\15ÐàÏ\19Hb\1e^<QOfY9\8a\ 2æ\1d ¹¢\9c¾Ë«\11\82\9ednk\80¸å\95TñE÷jôY\96\9f
-\1f\13\17«\97å'Gè\ 4m³Ö\8bl®|/A×õ|\11W>\9eþaýù\11±©|eºÄÓõЬ\94/zV\9bXÔöãÓ\1e\94ß·»\93+$;\8dáä¥Å?\ 4Oe\85æKÞç\b-   s\93\ 6ËMZ_9Ñ\1eùK'âÕ       \ 1¥"\8föu\87W\8fð\eª#C\1e\bÇ×à¡=\90\97®\ 4Sqh\19È·\97\e\88\84I0   Ç3þ oÝ+\83ÇWNÊ\0gñmøø¢ÎñFÖé/H¨t9¨\ráã'J\9bY\86Ï\f\80(\8f\17\1fo\95.\9aü\8e/g6eî\8fkÞñ`[á\e98å;^¥ß$*ò!Y!\80\80¾ãqÂ\ 3\9fª\1f¬\90Ó¨\rAfï\ 2±ª*\18\93äGÐ\ eÌñééÊl6ÇÿEìN¦VÄË)kæxå½Ô\ 6¡9¾:Ï b\96©Ñ\1c?Å­\ f\8e\8a¯½\0æx\17ñ\¢<i9^\9c\89XS\ 5±\1cßëÖ\a\94ã3¹q\86h<"»v\a}9IæÆ7,²ä\a\8dØ¡ÑkË@8k\ 6ð\10±2>\ e\16\0cUê\12XC0~ \«M&\85߸øYO\1f\16]Ø+~Ó\16[ü¿À#Mñ\1d\93\14}J'\9eáR\88è@m\97s\16\83\9a"Ô"¾*ØQÖ\9a   \ 1Cd
-U\10\ f.6\8a<Q '{øÐ\8a¼\ 4Y6yY\ 4Þ2\f\85\9c3mKÃ#$x[^\98û\96½\8b\ 1\86g9ÐØÎ\124aù¼ÂÃ\\85æ9áE°\1c+õßL\8a´w[\13á\85úZ4§N|Ì\13vðà\92÷#«\1cÝ@¯\86(*\99\9bZ\86¹\vb:\88IÁ§4Ñ\1e\rÆCüz \9ac\17XSÖ\v<\92\8aʳ]\17Ê0Í\1e\0Ä\1c\82]\9d·E¶\ 1Þ\87{\9dô>\9eèûï­\ e\91ûyÂ\7fS_\90çï+\90'¯­»{¢mP¿»\8böÈz1\1aÄïmÙùá\19Õâ÷\9c=\9eåÞÜJöýA\f\1eñb) }ç 9/Gõ\84¾SQéQ$ò ÇwÜ\9aA\86\ fxj\8d\91ïÝ\92¿U»À\11yÒÔÞß×Zò\vÖ;\1cJ\r \0\88Þ?\92\90Tiç\j2ï÷4\ fðáá\95gÈ{\9fU¹SEG\98õ« \17\17Î\84Y\81\büî¨\fÁ f,\ª\15uwåºVñ{\1c=&c»\v\89n`kL\80C\8fÝ\91\9cÓFìÃÍé£uÿ$£\8e\83±,3ê>\1f¯Êùëc\8duUV\0énûµß\9f»;ã\88ék| ³NÅ6wj¹\7fzÎIáSÛ\96{\89\83AU¹µLrÇ];\97¡TÄh¹\8d;Lî\1eô\8cU\17&î QS=        \8cÖ°ÂÝòn\9cç\86r     ¸Ë\ 5ú2[U\99\19\9eضðí%é¦\84<?ñ\ 5ôn\17¿V¡\91ZL\9dÛË\98 FªÉ&\86ÅÛ\ eºÀô\ 2Xµ}Õ=¤o\ féäÎlÏÔ\97"DÚbÀ\1e¶_\13b6\80\85°³ØòÎ=,ÖÎ\9a´$Ó¦¯R\vß\9aGµK\98]¨Ü´ùi·Ê®6\8dJx\89ÎÒ\ ek-\98yX\8fz\19G;)=9¦iw5´ã\98\15eí]\96!ÛÏN\1f¤A\86a¨h¸:»Q\v\8c\90\81Í®éX´\8eùÿ\95\99\13³³ú\1f²p\92p\91e§dF7ñÆ­\ 2\11\a¸¯\8doàf£\9f¿"%\1f;4\ 3Íf\e;^Ç¿\89îΰ+µØWÌ&hüë¹ØÙ\vj\ 3Ø«¬ÄN\92x\98e0Èô¯Ãþ(ëMÐPù`\9a\14ö«©vW\9cì\15J\vv\82\17\ eÑ\ 1j\10ò\81B\ 3ìÜË%cR.ÀÎ\95õM\ 3\90Ñ\12\96_ÿ:U»yà±ã\ f_?u\86k2à¨s^·HÂw7\14o-?¾ë\9c¹¦B\95s
-ëú{Î\88F\ 6å\88r.k®cGì\99Äõò\8d è\8aÈ­aÁn=¶\|ȪvëQî)\17\b0q\1f[7ÈÜ4°´Ø­Xj=×TÑ\1f« \ 2\ 5´¾Ì\r\10\90ø#\8b~0ë ¯\9c\13¢3Ó<\88=~\9d°hæäþذ\ e6vçüV~uô×ÄÀ\8duu\96 \12GüKuuÚ¢é\81gOlnÆVgùñkeiaxÆX\1d\90¿²\8e\89ó\94V]\e¸\9dì!#ä&T=È\8b\19\19ßÒ?ª\aYv¬Ø\1d\9fO}\17\e µâ\97ûlê¶\r­³p`\81üÔR\87¶:&sPR\f\9f¤þ\1a ï\8e8碵Qw\13¥!ßl \ 4\89zÛ5¤_\a2\9f\ 6\15w        õÔu\17j\vD_¹\14\97\ 4¹U\92lMÔmrÑàÀ\87 ÐôBAubÂ^NNÇ\89\85÷\17kæÇ!äqÀ­íÊ6·à5\9aL4=,\846\\9db\87\81#Î9\8c\97
-L'¿}\ 1É\87oé½-G>¾#®t\96\0t/\¤Ç\94®\vÓ\87Cw*\f\19%ÊI·:Ñ71Ù\80m\92\8e¢#ëú\f\v\14éh\86MB\8b\88ëéí\ 2éË/ÝC=õ1\9e\8a\9b\1aÑ9\10¿~£s\ 6±;l\83\1ek\93\19Ý\8e
-\9f\13OnÍvÑU\1e\84\ 2±qÝM*º\12ÊÍó\12}Ãñ¹\85è\bîðý\buw\95C\7fáKÃèrÈB0t0ºã¯\v*4/I\93á     ÝQ\18\83¾bÙ\9aCb¿Và}·
-:EÇÄ[\fj®WüĨ!\ 3ý¼}æ\ f(\ 6ú\ 6Ô\13BzF\8d\ 1ú-\82a,\1ci\12\86ýùùA\eÈ2?Çé\1d\8d|!H¯Ï\17\90ï2aÁX|âs©ç¶\9aöÄ\95|çÔ7ä[\9cÔGÏ¡\ 2  ªD\9e\ 3\92\89>\151\ 1ú\9d7_\87øAÑ\80çbc\95?BÉÇ     ?Üy5Üna\15ÅäsìÂ`hoûu.-Ú:.a1\9d÷H\11Zð+âA\ 5¬¦\ 68>\8dq\0\8f&çT³i\88Ϭ\152|-N¥â¼ðl¨XÒE_Ó}ï\ 3çÝÛ[$ñæÙàã²\96oó;\v%0\92$
-âHTܳq\ 2´c>4·rÖ!­\97ü\84cj®1\1d\1195\ f}\9c(ÍM\vÀÞw\88\f}uAs\11:\1a\ 1¹°\13B¶ã»Ò5CØV\f\95nÕ):Q=\99óó\13\95\90zE¶c\9e:ñ,\140\80\8eyÐm¿e\8ay7\12i,ÌI_Ú\ 5æ\8f\92¢\98ý?_îÐϪIþHC\8a]ÞʤsZµ,Ô\ e.Nh¹÷,\14\9e\1eËG\80¿÷Ëþ\8emP\8a$\r\ 2.jåÌ\18*\89Úö}È*ï8\81[\ 4¨À*7U§+\ 6ü-\9d£òÏ T{fI9ÕÕ\94ÿ \16\970\85¢©\87úO\8e<R\8eF.1«(\8f"wÕÎÉ@\8b\81r\8b¢å\88\11ÈÎ34\80\âÉc\10\8e­y\1a\b\8e\93G­%\13Ù/aB\93ßk\17cfRÕÏÖ¨/9½\8aL\9aرT°M%¿I&©ä¡_hÀaq^I\9e\ 6´Eï\92°AòªBÞ¯6þÂ\91#\10§8jdøÝ\86\8b<®ÑFQ2æ3%rú\99¡\a\1d`(ä\90§uÈËäÓJj>\¸\94\14r{JK¬r\97\vr*=\9b³+°\vÈ_\17»\15\124äÇÇ.Ri\9b:@?\90\97"U\ 4âWsçñâDc0Q!ÌïxÇÉ\86"\18ùw9áêøÊÙð«_uHu|{þpS~ç\99ãV\ 2%y*'\rÇAUh=N\93µéÆ¡è=>Ò$3Ù8-Ü3kG_\ 2J\8d\ fÈ\91\84\9b\95\18Ðø\9dËý\ 1®\Æc\18\80\16\14%\1eo\ epòüVa\\81¥Tʨ¡VXøâR\10A|\ e\ fR\9c\14äEÏS¡íXh©Z|Ù\12Wâë\17û\8b\17\ 2b?\8bñ°ø+9m\9f@C¡Ì\15\93@lIú¾,+GM|¸\ 6Î\14Å9csÌ#\15\bH,¢÷ñfâÌÈ*\9a\ 1¡x \97æ\ 3Î\r7ÄQÜ[±B\9f>\1f=\\96ô¿!.R\8a¹PÊ\87q\8dW¬ÎèkÃ|¸\9a\ eíÊbÀ\16\1eNK%\1aÀ\ 1\1e ÐáÔ/ñÜ\e>ïú\8dSy5üõjsÅøy\7f}\19NÀ}±à\8c\97ba0\1cÀ\rzN;\8b¹\85¯\9d£³¢p\18µ\89ºÂ\e"L\ 2Ôg2)|ª4¶     ×Í}óÂX\12>\84¤zZfë\f l*0\8b\ e\80ðu\83íµ\1dmº¤\1d¼3èmc\18°\r\8eU)T\\80X\90\eþ@'\83\91\ 6Mh,m[p\0ºÒ¤`ÁÏO\15-Rð1\aYQ\12<'\9d帽?ÿ\f\ 4\7fÆ\19\v®øk4l*ÒAá\rüŪH.Öoà\885\80\1cþ¥\9fr\81ÏÈ\89A~Í>y\vS\9c\95Í4\9e\86Ñ\ 6\\ f"Oé°\ 4\9c­¢Ö°\13¹"àÐ\Ûâ\85\ e\ 1\10ÿ\bx*>\87\90´³IM<     pï¡ÊH¡%\ 1>\96°íe\ 5\94¡        ð\ 3ö[ÆW(\ 1\87\1e\9d(\92¢¥ê\12ð;¨\86Õ\11Ê1Ï_\ 2n4\10\1119àÑý³\v\aüR°[V´\88\99\80+\ 3q\vÏx<\99\13ð\92´1é\ 4|\1d3F    «¢\9bì\ 4<\19lr½Ð&àü;\86\86t98ýOÀwëZá\99\ 4\1c\81\92 ç\ 4Ü\87þ\16²x \9c\80Ó©³*ä   8[\v\97\9e\80Ë\vp¥G\86A¡(À\91\fÐ\ 6*\12\0?¬©G
-\80#Óc\9fþ\93\80\ 4À/c¥ÀHÌ\9e\17\0¯'\ 6rÔMøo¦¢¼syý\8fïo:ª\11\9e´ÈÏê   Koù»±Ð\8fS\ f÷ûÉAü\ 4\8f9!À5ýÎÝïG5\13å7\16\9dôë=B°à7©*îÌ8\84\9f\a¸o1\vt\a±ï^v}¯\92é\85W»Øô­\8b~i\96)ýà9gu*\r t¾\91\90O\882¹Fùn\1f'G5®\1d\9föºø>]øö\12lp¿à[C\8a\ 3\0\89,².ïÝ4f^\8bäu!\ 5÷\ eÒ \9e\99½OæÐ-Ålx¥c]o\\19Ë\89\eT\1a+\1eS-\84J\9b±ôö̦\8e|¿ôN >±,.\18·Bo¢\f\ eP>}óÖ!\83\9eê.ï&W\164Òá\84\a\e¡Ê®|Ùâx_ìÖdu\17ÂÄÛ@\94\81\17¤ð^\10ÔøÊ}"à\8d\ 1\0\82ãç8|74\10¸£ç\99\11¼[Ù\17\97CÇ×nâ\9c»\13Éi@k\99\9f\1dÖ}µ\9b¹\81\13ÀìFXKf%Ê=Âî6Ån/ã3ÌòH¹nl!\1a÷ÕM\14ͯw\9c^S7FP\1e\9fít;¿3ÞÙ\8f\18\94n\ 2ì3¼\ 2U}ØYtsöN6\e\8bó     ºS{QN9P\bç<÷x¦1©¤ë\86áܦ\7f¥\81m\82tsæö¹ È3wÅ~¨\1a\89ðr\8fb\1e®mQK\ 1Âf\1a\ 6U¹%¬\86æLî/\8c\8diR\13ç!\93Û\9d¢¨\ 3\10\19N&÷à[ZÚ\rø\ eáw\1c]% \86¦9:îD\94¬\14^XMÇ=\88[sA\86     2AÅ9Æ­Æ}\91\93õ¢Ù\9c¸}\9fð}1V?PÇøÃ\e\92Eá¶c\97\8e\1dDÝM¼_\99ÌxÁ]\r\12´Î-¸EÝîÒ o¿\ fº`òW-/û˲\ 57÷é\b\7f¯Ù>\17Ü-Ö§\\91ûÔaÁÝbýØNQµà¶\ 1|«3\89Hãé\vîI|wÕÀ\ 3²à\ 6\9f§ï\90\10ýr\1cåAIzÁ}¶\1dóbÖB\e\96ÝÀñW\83Â\1d\vJ\9e pK\e\ 37/\v\80SJJ¡p[â®ä\9fpßë\ fh\8f\84¤3 Bs\ 5T\v·6\85»á½\ 5¹¨T±Q¸\13TF\95FÌO)è )Üî\9bxt\9b\82\94%ÜMÒdù\8e\8e\8b\r·\96µèóÀ1m¸½¦¨\92'ܱ\89¼C£9ÜÙ¿\17r\11\b8E8ܲ\vçj(Ñ VY×À\86W²ã\1c\ 3°Äb\ e÷]\9eä\ 4\87[¾ã\89Ë\14'\1f\87\80=Í9Üé^¬\8d\10\87Û(\7f\14ÓéÛ­A=\ e÷I\96¸c¦\13×\127sö4¶\91I\0s»:Ö­ÖóÖó\ 1¨Äí\80ª7\WÍ%n~d½H2\15\94¸\81^\ e·Íö0æp3µÖw\89|e\8eÃ\r\1dS @\97yµá&ÜC¢\rzb$Ü¥vP»\ 3éo\9b¿\84»Þæî½áæ\93Ô»ØZm¸·!nÂϳ9    7õ\1a\f¦\84»-©kÃ\r\ f86+\98\86Û\08\1aÊ\1c ©ê\86ûÓ6^Úøßp\17müZ\8dÛ¦sÃ}ìÁܳán*½\85(Þ¾\84»ÇµI±×¤/á\86\ 6½5ñÀ\0«\84;!\f&nFk\17 ÷Nö\14¹\12/.á\86æs³b/Ø\91\95\9bÕÛ \97W\90C\8fÃí+§¦Ä=\ fc\10l%î2&Iw\8bÛM\9b
-âö°V\8a\9b\82a\84Ä=L»ap\12w/£\87þä\ e\849ÜL\9beÙÚ\16B\0Ôp\ ew\ 3\8aAâ¾¢
\84\e_H\b\8c¸N©0(\9eJEpj\0\11\ 6à\96r{?YpC¹>J\8b\10\98òª"÷6e\90\83Ûæ\0F¹Ûä2Ñt;¤Mèz\ 1T¬Ü\ 6\a»rFh\15U:¸í\12\8b\9a\15Ç ypÛ7ÖÖï¯íz\1e×       \15\ 1\9b\ f\9díýágo:Û\1d
-3óYa¨\8a\9b²½B\aÊ\10ô/ê\ 3ìb[ÂX½\81Í®`\e\90\1c\r;\10@yí\0v\93n'\82&\[iÜ        Å\97"#¸³öÑa\17½²\83¿×.\87\83<A\aç\0©jwg\80u\88ßÒÈÔæ\10ú#äm\19gÿ&ñ\84^\91z\88\v\92Ëi\1f\ʦ\9fm}@\11»\81iïO \1aC Ó6\10¢ZØ\97\b2aª\81/\9c´\81ëv4\92¸_£G;}\17\845\97§\17\13\160\1eYh\13ÚR|{7{\14h#\80\ 1\1d\8d¤nä³\87.?ÆbÈAù'\86gÓî9w\8açð\81º9;Þ6\9f^\8akrÎ\9bmàó¤g\1c0\10³U³\ 1\ 2ï \9bS\0ÏÌ.CÃ\ 6_³|~\98Ý\1aµü4\943x\90ê²SnÁ9\95\18ÛcÙØ\7f\1cv\1a\ e\18\95\r¼¬.IU\95\1d\1c¬\9c\1c\8eh\b\8e\1eÙ\10å<\12¾Ü\87!û       ¶¦\1e²ßqUU©^!¾\8fýF#¾\88\8eí6$ì\1eר#\ 1­\ 3¨dìl\98=ºè\93£m\8b\rw\89¶Ë̼¾>5µ´\14\9béÓX\8b\b\83\17@ ~Ð.\fL=\ 4£/ 6\9f¡\ 4ª\11Üæ\ 6
-\87íÍ\809\87-\95®\aùVV\81\12\86}bâÈ\98ºÀ«\7f?aw   \ 4P{\1eí'ì\vP\18 Æ\ 4¢sáÑë¬\82Íë²\84Å\fòÈÀÎi2f¼¯éºd`M¨\88\ 3\9dú\1agÈA\7f\1d\7fb\r¦iÙð\8d\ 1¹!J§ÍsfèëÆ=\b}\9e\7f\8efæH \9e<8\ 1f¾õ\ 1\ 5a«]§®\1dYóº$5~ º±¢|\11¯]\1aos6\9c5Õµî®\93F\16\1e\91\ 4ÄWvÝÒa­^¦®ÕyoàZ\12tý¯\99\15¿¨\81\97ë·éßê\1d»¢S\1d×HFû\94\v\12\9a\93\eªÈùÖ\82\17ñÆ\17±\95\97\85\1eZOê\9fÿt\14`ïµâGÑ\8cB#ÃÖ©\90\96\16OØò\ 2Öú·v6Õ\90Ø\9fÖÐØ¾ßÞ|Ð\ 12Z_Ëæ\16Oæbö¬A\8aÿò­\ 2v\97²4ë\0öob÷\eã\ 6¬¬A;\ 4\9bÔ KCd\1dYòÒ\91uáØ\90\14¨x}äV\9f\1a\ 13E¢\ 1zúX\f±\9eÛÆ\84 Ù~\ e·\aëZ\93\17þê\14\15\8bõj£s"?\8dÉøìêÓ÷\ 2\8c\99ùTh\82\808Gqµö\ 5$\b%\12³Õ°Ð3ñj"Ú³\1a*èô(0[#Ù\15Ë\82Æêüô\8bÀ\81ú»W}ó¶hevhCeµj¦ó[´6(ÚdU{+"¨wP'\f\8fª\rákàü\ 6;Jy\ 4a\9fãÇ}e\83óHuI]¦þ­2B\10Õ\83\8b\95ÜÿS÷\11X¬¨¦\9e3íÔº\ 4ÉÆmjø\92F.IÙAI¦vÂî¸\14ó@5\ 5¶Ôvhë~Ò{±\94\9aN\85}®Âé\18vHêC¯?UL¦é\8f\9a\15á\88\94\ 56j\11E\9a3R\80§\8c\16õ){\9bi\ 41zC¢^\8d${þ\86:ð`k\8c\91à      uê¡`uóp­ ¶\96\1døµ\18\88\ eP+y2K[ØÃñÓ]\90 þÕ"\8dݽ§µ\1d"\ 3;x±yz$z¸¦;ýàb\97®5ºÓ\93 \10²´%'DÕiZ\96\80§R/\83\1e\15\ f\84újü$«±³Ãéâ\90ÆÓ\91nºÃ¤n`lzp9n¬_D\ 5pºÂ\e«5kÙiÃt\15¸ü\b
-ìV\99\1ej\0\12\8a3¦ù\91\aÓØ\96=\ 1³\12¤\97V\14^_\1aÂ\8a*.͵\85ô:Kó\97 N\ f]i\85µ&½\80ëý\12\176ªJwQÛW3*\fß(SºQÒìx(}\ eûd\ fÓI´æ¤\95\1a,Èw0ip¤\1e\9d¤¯V\8c\15\1eé\86Þ\13\8d¾"½ù\1fE\0\86ôüVÚ\b\1aªºA\ 3é|\ fK\91\8b\86>z\9d ÉÌ \99\8dG\876y¯Êxó\1c\1d\9d$C\ f8\93\eí\95\97Q\19¦\14\1cªÑ\7f\9d\9b   3Ú\1c\16®O\9e×FT\12\86ÚÃu\8c¬uÑ\90qÂ?ïá\8a,`ÑÆ
-\86\87\aj\ 49f\7f\8a.\10Ì\ 6{ÓlOô)\84\ 1\0°\95èÑꫯD³¥\eÕ3f»X&î/»\88®iw­Ù\0\84\v3\17ø=\v¢ë\ 1&W\0²        Õ<ô¢]\88)*\0phàôöì\92Á3tZÑ1\95\ 4\96G/´ªé§#\89\0?\14T¡Çif>P\b^\0â\85X\95¼xyXäEè\r\1dçeèOWóåA\ fù\88\ 3\9a-\84\fz´çq\ 1\90ÀÎ%\ 5-»bs       \b\1a\1eE­£A¿³{\81\ eÉN¢\¤\ 1½2ø-5 \v\90^"¨\81\17 ÐLÉ\8aâÅ®ûgÿÜ)\b­BÙ¼ÅJ¶æ 69çO³égKc@÷\9fWf\17øÙê\9e\ 2x}¶\15­¦<Ù\0\80\b%¬ñ|Î\00M@="hUù\1c\ 3\9e.\90\99ÕCï¹u\83\1a\9fg\9c\93öÜ]\10\15\ f2\99Tõ|¹cö¤¼ëQp\17z.±áãVöíQ\ f¿Ëó­ãßW\19\7fïxÞø¤FÂó\9fh\9dÇç\92¼|gzçèÝ\83þ\0y\83"î\±\82`\ 1hg\89\17\9e\87\ 3\18¸¯s\f\1fW\1aÝ0cku®¤iy±é\8crÈëÕÊøyV\ 1\f\82\89ÎÆ\82á\1d´sNÁva\18ÑDæ|ÃÙéÌÙà\8d`ÁØ\8e\8e³Ê9Ó̰ê\94]\9cÓ\90óZ¡ÅËà\9e\90%ó+p\83\19,\93¦ëx\+Ä9ïÓ\86\9f#ÆÁ9\94-üyOÞýÍ\16ãB]¨\94e<½Ù©¤H\9b­\9b\a£=ýâæ7\11@źâ\98bu²ÍM÷\92ÇXÔÊÄ Í\9fÀ\9d­c£\9f\8dÍ\vÅCiÙvnø8½f?þ\8d)\15\13­Ùµâ\ 2ñôÞ¬æÑ©\16\12\9e\r\a½4jV\ 3UiN5Í3\92ÿK\8aG\9aáSih:Õ\18 \9a\8bÈR­ôÛ\1dû3[«O-væ\18Å\15&\ fÿ\8a\97\9b¹B\9fHl\91&¿$rdæÏFæ\1dIÖȸOË\Þ\ 2­\83IµÌ\924ñ!M\949\9c\9cä&\92¹`\ 3t\14ù1\8f©\8bñ\1a/7\f\1e\81?\10É\r¦Åü\jÞ\0\9d£\ 241Ë)\94+MÌ\1c¸¹W\rÆ\13±\98\98%nËVNæ\97Í\14M̶6¥¬\12db>\81ÙÕb\7f\ e\88L$¬±\96\82\1cf^At§\1e ?\87Y\8cÂêb\90q\98µr6     ¾\9c*BÑ8Ì\87ÿw¢/Í\84Ù\ fv\8aU\121\1f\13fÂß\ 5󬯱9avÂÈ |ÅÏ:a¾!\80
-Ö·¦    3£\81B\1cN2}Â<U^z}Ç\1c\8e©\vI¶>×¥\9cU0\8b\91a\86S\85\86\82\99æ\ 5*\15"U¬`îñ6¯H5j\8b\82¹C.¸\19JbÅ\849Du\98Çç3¥v\98ï£\1a½\19\<%;Ì\8d\1d¨LhÈLa´Ã,
-AODf\rÁ&æ¤
-æ¬\0W>\eµ\bváÌÄìg\9d\85\86\9e\ 4\8d \ 2ïß"\98\94\80Ér\98EWèå$Ä\1a ó9¾?\13\ 4\84Ù³r\9665Ô`\ e=Â|\1d»¼ôÌútúî[Q\8b0\e\13±2?æQ_\11f\8cfCh(Ãr2ÿ³17¸Ø\9b¯\1f9ÄLb/{Çê\8a\eèT(vØ ÷Ôð_N<6\99(`\1dÿ$õeáì\98eð\©\97©8\95ÍJÀðò½4ݽ$Ô\ 1N\99À.Û7fÛ\8cLü+«ù\^v\ 6\96\1dC®q\99\96\fRl¡gB\19³zË\r\8b«\a3\1fÚ²}¯\87æj\19F\8aeæã\ f ÑrL_ã\9c\ 6+Ê-\87¬Ìr=Ü'\9f\f\90ãc\19{IÆø6,?Éï\9a¥\1fÊé+\9byl\18\8d\98xf$ºr°4Ñ\95ï]\86ty%ñ¿q\96µrß\0Û\83P'9ëL\å\83>{ul\ 2i©·¹\17\1a\16ÚL[¥½]\9b\9a\17þ´ÎÞ\19tÇpº  ^4\1a\19Ñ\83\19åMË)kÕ¾\99«#&\\14%Á)ô\18Lp2`¼c°á´\81ÖNÜp\ 6fq¦U\1f¸\1f'eJ-ã(gI8¸\91 É\f/æTýÔI\91Îé(\14jëeEt^sQ\9f¦³\95Ì\98\bµ\ 4¬Nr~Ð\85\8aÖLÞuê®\a´\95\9d    .«ÅíÔ@×\7fÛÉ6Ï`;M\86\ 3¯®ß@M°vú³§7ÝÉLhæ\81¾ó\ 4Ãó9&4\r\8f§~Kn\98§Ô:aUè\99B\0\976\r\8aéÌ»´Vû\947\9eY\81\9br^\13ZËýÎ=a¤¸+0i«\8d\8fK!öß\13Äíöp\8fZt\b»ÖÏ\90ëi;ýÉÝË\r|¦üÏÅ®v\ 6¨­æY= °¼\8c>` ÎÊ\92ð\1fh7¯¥QÐ\f\9f\fª%%å1×ÛA{CÃ\84\bÍ~\1e.nB³DÎ\97\15z­Ôó¾P[\v(ACcr¨}\8dCM\ f\95®KÃ\8d7\88úêjFd[æúmÀ^²Â>{¢9¥´ø\14½íd~XTÿo5\93\8b>pÆJ\18M\14#ò¿\8c~\95\ 3ñ4Êì8\ 5áë¶C#årr£ñ®V\95)GíÉmî(D&v\8b_`j¤GÓhþÑ>\82å\91\11\ 6©Úµ©èCúÅ¥õú\8fjdÒNhD÷!\1c3ÜIº:»H\83£\9b\8c\80\89\93J2P}\83ÒS\7f\90tJ©lRã©ô\86ã\9b+\8dÅüeé5Ãõ\vw_ÊìÈ        S°\1f\9fèJ©\ 6¹Ù\ eÓ0\ f\vdJä4÷Ì\94Ý-=6\9c8Wd|ÊÕ´ìÓ;
-a\8a'Úô
-!8tpóµ\eÆi\ 5\8a¡øsjWf°ØéÚMD#\ 6\8b=:<\r'+sÛ,T\ 1ÕÇ\ 2\94¢ P\9b\96\ 6\18â9͸ÕéñG¢-ÔQ85?T\87ÃÑBQõ¹ÂXŨ·0\80\eªÒ7a\87í\ f©§\95\8a
-\93jX\1fj\95zü²J^*\88uÒu¦ö|\8358µ¬Ï²=O\95"¨B\86q:?©'æÒzÁ\4Z%
-Í]Hª·ò*\1c\9ajÔ¡hÓ¹FJ\1e÷AU/ÚZ?ªZ,è8`Uµ\ 1[KÝ\1f-Z=GXe³yçXV½¥\15Õj\15\13\96¨±. \ 6ç1îçªÜ»Xãw\15ì´ØðÕÕCý\ 6\1fÓ\19LÕ¸D\16\10
-«d\1e= Å\8a6u¬\8cí¼h²&\1dªö_Öà\ 5E40qÖi\19\16\15AëW%ác¥u@äz\93j\8dðZk\12     î³Õ@K\v\87\r\eå­ÜkkCpÍô\9c\18\f®Â\1fó\85qE\99]]S¹ª
-UÞs\ 5%EÚ\7fº®ê\1a\1d\8f\ 3°«í«è\80(RåðâàU\82\1fJTy\95¤%{z½\a\19÷Z\16\e6ùÊ£9.í+cí2\84ýÊ?I\ 6ã¿Rìª1\8b¿à"?`çÜ"Í®\8f·;"ý2\80\95Ý=À\b«§÷\96,,_zT\86\0\9eJ\11\82\ f«\9e´\1c\9c\ 6o
-=\93¨}b]\80KP,¶\9aQ\ 4>\1fTÙÁX½¿\8a\92 iìv<  \ 4äØ"õX5\ eø\1dd\ 5%'+\14ÙDÁ\89?É®Ë\1cd\92NVLYï¸>_YP\r®\19\97Å\83\b\85:\98\15£ÌêרÕ4;Ý\9fþ\84\9b\8d\95R\86rÖ?\¹êÎ"\90{6nè«\97+@k?I¶\94Ðö{oJ¢í\97\ 1\84\e-±kùA\926²-­È:äÕ\18<µwØ\f\7fZÓká9©\15%rMò¼]Eª\15Ô\vH»Õ¿ý£\aÔJ¸µ¯l­\8fºV\97\vå¸@º\8e[\11\ 5é×v\9b´\1c\88í#ï@êF¶Ìζ÷ {1m\8b¾\93\1a¯-\8bK1Ámé^Ì\8eàÖ´¼³Y\89N!#\ 1\92\9fna\82ö\19¹[3Ú\80Ä/\QªøíÞ*Ý·A¿1\ 2¸H\85¢ÕaãµH\ 4õ\84ëfó£6ÜTG(`ò,\127?}ùªÅE\81âx5\84\0|\ØHîòÝ:\ 6Y\8drׯ@\80f¹9\90Âêæ\ 5\1a\16s\9d¨ '^sC\99JÈç[\eì\80öN]ÿ\86\fùÊB×\réªLÃÏÌtå\1du\15Ù\1c\8aÕQ\1cz¬®>\ e\82{µ®Âf2_wú±«¯\18\1d´{Å\ 4DÉv»\90     \82¸\9bb\ fTÙÝçÆ#¡zW¯$Jñw\9fz2\ 4ò\fèØÁk\85\8fÈ\84gÚ=âs\94\14í,âÀGÆ\eÑ\1cÂ\9bvJ²¼GeÍËæî\7fÏ­Ó£×Sï\11\ 4õV\95|~òÐw:ÆÓ\16\8a½¹+}.ko\8dgPÒ½6\b\0\ 5úÞ\7f<è75(UÐzáð¾\ 2_ùÎñ%_ ¯Ë\97\8aL\1côm\ 4À§\ 5:<X«ªü\eÐþ\1e\99\11ÄU6ß\v\0\8bI©Ò\1dCþ²oжÀò\87ñ¡Iʾ­g2L\9a¡Â\r*úGp\9a\80ÙU\17©/È¥\ 2\83øÚÑv¨¾?ò}|¸A0/ª¾-Snu8""¡/B\81,\a+¤ýMè»sË]ß\1fôUY«!\ 2÷è\87\8cP\rÐMè|\99\7f:\8c\93_Õù\92WÜá±ê·Y\86Zb\8f`çË\85\9e\85î\1aù\96µ;_»¶©õUÊrâF
-i{À;¾õ}\93çË"¬\93§¯\1aL\ 3@VgÑ\18§¯\0PJ8ùȳ¦/º/   +;óE\9eé\vÄ\9f5ç)/\eÓwmekXÎábú¦\ 2\15\8a\88ÈXD¦ï\9eg8òx\ eK\18\97¶÷η\9aÌêV\9dïEJ\8fÁóÝ!&ö¿4m)\ fð|±¾\1957ö\80ë\1cÏ·p`¦ì\1d©(Ô´gÓÄO\14        0zç\e\848s¹;_â\18ðd=kæ£u¾o-3\a(_¯ü\13\10sƪ|ñÙÇ\88|\ 1bå[Ìá¨äù\82%¬½Å\12åKÕ/s\\9e?c\8e§½¬¥¹ÒtùÓG\10\8a÷æ\9b\1aØ8*_mså17NÔNå\ea\ 3Ùÿû\15\93o5g#´\89ß½\17¿\9e\ 5±&\ 2{->í\ 4bEñ\ 5/\8c\8bç\a\13\9f\ 4EI\bS|õ]¢\b>¢nµâk\8a`\0
->M¾]Í\91\81ì\98rK\17\rúúOzL}i\v\9cÍ*!9õý\80\97¦ú~Îâ\93Õ\97¬\14`Ðä×<\11­\95H\ 4?¾éïØ­ÃúÖ\1arÊê\9bëàCôýz¦kæK\8fü[\90/\ 4^\116\8aðÃw\ 5»¬\í\0        \10_°r\19\18A!¾x\99Ĥ\9bøºê\1e\8c)\11ß¼\9dö's,\18ñ\95/>¬\81\8e\11_àÂ\1d¡T=\ 4C\11F|#Þ\bÞ\80\11¡\96«\rq`Û0\15Ä·\ 3KÒ©î\88¯^FEa:C|%\0cM!¾á\ 3\1d\ 1\8bøâR.\ f?ñýÛ\9c5ܦ&¾.M>r\85d\16$¾7\e\8e\ 2\9fPN|Í-\91e\88Ô#\1eºâkù×0Ì:ZE\8cjɽ4\81Q\rVU#t$b\87-\a¾\83e\9e\1c\aø\ eK\14f\80o´Ñ:¤Ýµ\87\ e>PI¾½çGyÆiMUÐg\10_.\88à)ÄWÂá¯kä\ 3ñurÒ\9c\ 41iî±zØ\83î\ 5ë%¾\\11ºÊý¤q\7f\17Xs`ò\85Û\94\99É\8atò=ÏE\8cMGM¾\93¯#\ 4Õ±ÔÌÛFô\88\16¸tk\9bÉ\1c\9e\8b\14åÛ\99Ò#E  îʯøF0\94\8aP|×nÒR\18A,Øf=Ú^ÕM*U|õ+Ó\1f²XÅ·ê¼tò­1kpÁ¢ïrzÉä+P/@\88¨R|×}+eòw÷.á¼R@Ià\v+¾M¦\16Ù\8aâ\9bËy@%\85¼°\8aï\99"ÖY\0f\17\98M\895I+¾\ 2¢~\ñÕÓ7\98Ñäû1´Ê*Å\97J4=ðä\8bÝy*¦\9d|ù½@- áq\93¹¸æ:\9c¯\93÷X³}\8cìη\8cÕ-òÎwÛr\95Æ\89\9f¬`
-\ 5ÿ\98mH\ 5Ü\8e\1diÎ×Y\17Û=ÎWÅëVÛ\82\9c/xÅi\892$Éù\1eRf|§ýA\80n\84Éw\94ó\82î/B¯¾\r,+ê<ùB\14\9aèÕKØíìÖ}Ôå\88Îù:nbÐ\85\9cj\9copïíào-¥o¡àwZ_ ù\0   ¤/#\99£Dð\0Æ#      ¥\8fíùhÙ½ÊI\8c­\ 4\1cc¡z5ï¼;Øù\86\ fC\84éÛ2
-\13z}\89$ÌÊ\86ûÒ\1d\8bÁ\82__Í«ªür\86ü£é\97\98¢\93àî÷Nµ\f%\ eÔ×\9aÝ\9a¿e¤âÅ\ 4¤¹_\aó\87\8fa¹ßÇ\10ÁÕ\8aÄöûcð\16Ô¾Iö§\99s]ÆÚ/ùyC^]´§Ú¯\1cÆÆ\87\9c½·_q¹Æ\ f\ 2C\»\95ü\91I¿\17²)\14²\ 3Ü\15~7°r\ 6¾/­¢_QÚ¬§KÑ\aÿÜU\95Êné¼½\15{OÛÚ.\19Ý߯\0\ fùEßçµe÷$Ý\9dAàâ      ùÕ\8b\7fü^åê\ 4 _\98\18\9e\97ñì\17e\82\87Å_z8+àõ÷\7f\88«|\ fâ<îúëÐÄ1ýÛÀdyÛÿf\ e\ 1<yº =Àño3<¼9è8\18°\8c1a
-\81+\bmQ«ÀÙÑÊ`ÏÀ9\ f¼¬Q\85\14Á\12;12\90\85\85QF\80tjÊW°\1fs\f\ 4\83\93\ 2­ÆÌ$\1a|½o\ 4*\ e>:ýÀzðÖ¨Ç\aa*fñlF8TWX©\841\88ÍÏío}\9e5©mnç\1c¶iéÂ\83e\18.Y̰0j82M,ãn8bS­k\18êÆÃ\95`#<?ì1\ egT\10+ó)lu\88\ 5shà­æ¿J\7fÄzRÈ\96w\8b\12\ 5Q\8e\89#\ 3\14_'®\12ÈÝPìð\11l\ 4¦Xú\8fæWÅʶ«\98W\f\9f[\ 2e­Øxõæ,Næ\9c\90.¸xÙ^¬o\vÑ\84ñUý«%\8eq\89ùÉËø\1dh_Ñ\91\82Æ?¥Æç\1d¥Q\95\8d\83Ù\8d\ 5º\bøÄ±²\ 5D\fæ\98\91p?fÝé:1Þ±-EJ\1f\1fÜyÌÓ\87à𱰹Š?ö\92"\14\93\11\1añ\80¬\9c
-ÕÁA\96÷CãBþ\13\8ek(AMJ³d\8aü#úÃÿ\92¶£æ\ e\86\13\9a\10N\8e"'\89®\9d;Sõ!_Vü§Ö Åx\1f2\aô¶XÑ\f\13\ f(\8f,É©×B~rÌ\ fyf$°þð!GL\10ØÖ`I\90Ra\ 6ϧ³\90\11#*\ 3ó!\9bD\915M\v;\19Yh÷ÓéÈ!\97«\9f\1cYqè\95¹UfÊ\91é½\8dtD¾³ãÄ\91½ö\ e:\7fàx\95Ej­;\8eì\0ócâ¢+\12G\1e8\93ºâÈ"\b\8dÂ5ìK\13\0·J´ÉgÁ¾ëðIó 9²2îÎÂ2\9b\a\18
-ÉÏ\9e\92û\8a\0\bÉ+^\1f1ÜÜ\17\92ÓÍæ\8c\vÉé\16\ fù\11E\8a¬j?¿%9\96\14º\19»\ 5,ÉC»§\18a\85xY-{
\ 6Õ²¿\ 5sR\92Inp¨é£9Jrqîyj*\85lqI®\85Q\18X\92uÚ*%Tòå\1d¾X\1fª®\98Ðö5ÙR\88\80ãt\9eI\14n>S\9c\92ϰ'ÒCJîÂËî\ eN\ 4CHÉ\8fíi\1dÁî\89þaL¡×\16»\94\fÏÄiî\\152$%\93Ï&\17^)yDî)\br*))â\ 3l?\1cFx\8b´ö»\90\btJ¾+\83\96Úkèi)Yrh#ø¤äëquù\86ýH(\95\92+-\98Ù\ 2ÉR2\8fÛàqo±ªØRrÆy¡jK¾\8a¶ü\8bÒÅÄ'\12Zg\r\7fF&?Åßj9\99,T5h\8d\9fz®´\90É÷v\b¼;Éäó\ 3ná/I&ã©D´6\99\ 1\97î7\99lr\bh\86+utd²÷\0Òvdrç~Sh\93CÚf¿\93Á\19ID\80òÛmI¢|ø\ 1\94L\99´)[ëÏhIå&
-\8cÐ*gà¥\12ºÍ\14iNj+k©¯¶¥iÕõWF\8biTdù\ 45JEË"\91\92\9f[oàûq\99\ f{MAme;\19\ 3Ò\1e6ê/\9f\99å[\eî\ fÄ\9c4uâÎ\98§ð0´È,\8b\85¼Væð*ħ\99\ 1Ý´EÏ\9cáQù0\9a·\1a\8a?ÍDGs\12kf\aùhP\v:\91ÉE\10ùÓfºàmrs{-`\87_¼»&\83\8f\97\1f\9cS\0\rë\9brΠ\ 2Ñî\9c\ 1¼ýyLç\0YÂ1²B¸3}SÇ\v\82çT@N-|\8aMÏûRÿªWª£)÷¬K/¸ò9õG»ûìü\1a ´\9f]$\r\85ý\9c#\b\bþgM\949\\11è$"hNó¹\93\ 6\1d8m\1d¡±_¼\92\85.\eìù¬¡ó\8f ÅH/~\98#\1dÑyÏ£\85¢µV\ f8gÑ\17Ã\93\7f\16­RËQbôÙù_Ð5\9aNëÅ×h\r@[¬£3SÜS\1d]ª\þ£¿(P"ÍR\81/s\92\9f\8bF\ e©\91M\1aõW9_b~\v\e)}\bÃ\vÏñ<\92Þ÷¤i®ÑS~éÜ¿¤\1f2ýx©Ð75H\12Ц·n\7f\86¤+½a§×\17\85ÿJÔÙÌ\9f\1e.\83ºå½\8f\87\8fbÔiF \f\92\86â\ fþB\10\ 2\81ÃcFGí`ÅÏdRÇVd^^jd(ÃÜK\8dm\ 1\8f\e/5û
-Ãø\ 4\9e\1cºÔ$¾ð\9dB«¥þ@5\89ÚRs\vÇâ¦å\ 1O@©^³IK «\96\9a¿öÄÍ\96Z\90×\90|®Ý8)]\10Æ\ 2Öu}¶Ô|h\\82#0ã\0?\8d\14\\ 1&«Ij:¶,Ø+hIj@DÖ¤·\17|JRÿÀ\875GÿÑ\87¤Î:sá?\ 5Z\99e\8c¤þáÅ&­É0Û\84¤\16Ï©º$u
-ö=æ<i\90ÔtY·Ç5\91æ\v\92Z\9d-n'©µ\85\16ÇÙCw!©wÆË]-µ\12 á\9d¥n¼\82â\12FG\96q¤æVJ=ò      á\8dÔ:G\94LVO$µb\8b©+âº\0\13\92\1a£ÔÂ\8c-µÚ\ 2\88(Ë7KýN\ 3±ç·fI\ 2èËR£ùÔæ\85\96Z\b\1cÁ½¥>Fî.;&%I\9d\9eF÷H­æoNç\9d){\z¤ÞÁ4=;ÆñH=ÉÕ\r@\80«_\97N"µ\97xu¿Ö'XcÔ\92z¿\ 2ZVjpxDf\a宬Ô\16\97'\93¦{[©ÝIuªÓÔôýÛ\13Lm@At\8aéå¥V\98ÓËA\86      \9eï¥~ñ3¨±\1cú±\19o'þÇK\1d\12\82\80%\13%\vd/µ\99[\83l\1a\90-\97\9f\18F\8fV
-m©a\89\ 38\bÒRó\12H&iû²\ 5\8eÔ/\ 5:X:Þ3yè\1aä|\9c\f\8aÔ\12\10?õ7\15\vÜâN'ò\81ì(¹W/p\83ÈìÎr\16©%îRmÍk £vú¡1Ë˨ÿü[\91ßÌ`Ôr\8f\1d°\7f^H\9d\11¥Ö°ËÖ©¥R;Á1\161àG­\9cJû_\92æu<ê\8fÞl´*xÔ>À að¨\832\82µ\13ÕRQw\81!8\9dgÑG¦\f\15u\96\ 4_6TÔO\80\84î>\ 1\18\15õ\12\8cú>\9a=VÔ~ÂV\9a(RQ\87Éjß\81¿®¨¯ßç\8d*\19¦\12ð\ruu>RÙ\eê\9aAy`\ 5V\9f .\9bì»&¨M«Å`\12Ôf@T4aPKP\87~Fí:Ï)Am\13\83ñá34P£B\1e\$¨\aK^\95\17æqIPC1\ 5Î÷P\1e3Pÿ¿zå¼ù\92¡®ó¸q5\19jDÜ{Â\ 4\1f\vø\fuÚy#Æ\9dì½íe¨ÉO
-4¬±\18j\ 5kuW|"á^\9b\ 3u\97üèk \8e\vq\95¡¾ÅÝ\97\8a\1aO\9b\81¶£Þö8;\93\8b\81\7f=\a-¢-L­\8f\15\13pj\ e\88\8f\8eWC\0J\10N\rÈ£¦\ 5b©;c\7f©\1dbdlòRÓ\90YZ\9fó¼h\14/uæÄÈ\96SëVë\81P]¼b\11+Õæí\897\99ªó¹\18ì¹jq\99\97©²øLmeõ/Å»r«#£\0ß»º2ÌÖ)`\1d¦÷eÊ\85k\12°\ e\e¶´Ý\vYL»º`úèý_­\8b$¨H¬ÙË\92r\ f\91¬\8f\ 1\ 1M\9aµù" c´&\95ý\ e¬u¬º v¶\eíøÚº2¬5áµp$:µuZòy2>EF¬5\18\13qÁ©\ 1mýø¥¸Ö
-\83j]¤\\12®fk´\94Þý4[ßà\816·A\85½ÙÚ\1c1\93(ûëö6[³¬Â\94IªõN¬\ 1rX¹&ªõ\19\11Ñ8B\14\ 5ÇP­u`\1f
-\1cZc\8b\ 1I\86Ö\96\99¿L« \1dк\91\18¤\1e\ fÃ\16\94\93d\19´V\9e\0«¦Ö\87ôÛ\95²¦§Ö\80cÅÖWÜ\9fZGX¥Ê;Âh¨µ(Sw\8bõ\ 1ÄÅ¡Ö(Fl\9f83äÇ¢Ö%
-x­Õ`w\91¹Ë2£[`;\aµ¾\8c;ÏZ\86N8ÖPkR\9dü  É\86Z'#@9\1aÛìm¢Ö<]Ì\86aëT\ 1\98ñ\9bäd\v[S¢:ÐÖ9\ 5¶6úà\1a\92Ë©Øú\1cÒ\8aP8þ\87lm\18)1º\19C\97\95ËïrÙºDÖ@¶å\8e\85ÊÖ\16þ!\ 52QV)n¼Û\18oW[ZLfk\ 4ܪ0\e\e6[kÇP\8f·Ö»Äh\ 6}\99îO¢:o\9d®ÚùJ\18\85ç­ëÿ¸àz\ 1BPÞ\1a!\89\98>\98
-ÞÚ¹?ÎÎ\11\8dÁºu\88¤Ã\98qm\r_êÖ¡Î\93¸Á%jl­¯;¤¯[\ f/ZÅÐì£ÐÛò»V-ݺ\15%Ìòñ\11æéX2\?L2k<Dî\8e,\99­èg­}¯{\ 4î\85å:ìfËR×¾] uwÍëzÊîZïÌc<¯IÈtÀ×D-$¬-\19\99!¿Æ0É\1a¿lÁ½èK¶\7fJ«OaÚ-û|)l\19¯©Ãæ%\1fh,#råÌ\81f|±\17í5å\e»\83   ÷~l\92/`íÒ\9f\vq\e\ae/!(5˶ö$)\16\93\87?\9d½4{¶Î\bm­CX\97ýqÄ,míO\9b\8e\99»Ö\0¬JEµrü`m%\14iε#V¸0é\1eìrÈ\9clÛMg@!0¾ÑvëͶ£sB*«Ù\8f TݾÈ|Ó\9c·{Ío+\ 3úº\ 5wÒá\9e\97¶I]ܬÊâù¸í¨yk&·Z{EnÉý4\84\e\96[Z-{hn}\ eÇ
-ÏýÛ¾\18\10Ýæ\ 1\1d\8aMw¦2\ 5\a\1dõ¥Õt|ÝüÍP´\eÙ\ e\ÜM¸\13\10õnö\vÞ(Ð\90ñ\16ë\1c<awmO\ 1uÞv\1cO¥w$³£Zï\7fµ÷WHn\8c\f£_\1eÅàβî:**P\12hu1ë1-\99ì;\91ßXwo3ì·¨\9f\98Ëêo9ÿ»#Å\94~\80Ãàfc\15¼xFà82}A\ 3×R\9dK\82ÃríB¸àüopé\9f½\ e\80puV\12\8e@
-\17Ö|k}ÏmÁô»\f\ 18kÃé\f°­ÃíçÒ¯òYÜ>\94wýûÝù\91M{]ý¶h\bQ<¤SäVq\9c0<ç\96\9c®\ 4#Â8?6`p\8cÓ\9e\88ÆÙáâ«lÚxÓ\14Ç\róÒuüö\9e\9eôy\9cù×vòã­º \9f¿\13ÂÌÍ<¿Èï¨Ú\0H\9e\99çðHɽ2yXÛ`{;y$ÊQ¶uÞ\94\13o\98\ 5Zåx\16\96/¬Ibv5«NÝ\0\1d\80øò¹lC´0oÈ\84\9a\8fùßMè`æ        2\19\81Ð\1cü3WsûI\8bW\ 1^\8d0\9bãènn ÎÕ\91æ¤d@\eC'h\9dËÔ\eÐùÎ\ 5\97²\85\ 6l*欽ãsç±}Y?׫1\b/\ 3úâ\18ô<\15ºêcZïÐ_¼Ìé\83\1e#V\ 4l\18=29úì\90\ eB\96×;\93\9eÐ*\1dD$µÏM}¦ë\87=ôpºåî0\97§\1f\1a\93¯\ 4uãÿ¶ç¢\8e
-       C©\83kûoon;u±W\a\96>\19³\9bêVx   LX\1dò\9e\9c`¹~~1JX\8f%QK/ëØÿ\aß§u ·¾7$xåºX=&r×ñÍu|´×\87\7f½\89\0ëx\84\9dJ#ö\7fýc\86Ò¨\eÙ\13øÝþ\1eá\fé5;\rð\98¨f'é<\9c®>²«S­aÖLRëªDÚ       j\7f»}_åAA\92Ót2¶ë\96\96«ÙvmL\92êvNcÚ5~»ã|à\ 1Äh¸7\1eÇÊÇ=ß>BÀÜ\7fÐ\0±Cw\1eÎÅ\17º\97\82ø\84\1f3©î#ÍîýÁ\ 10ïî[j]¼sQî\13\91!\88øYï6°\15×1²\ f%\vúþð£±ÿáz\ 3rýÝ»ñÏ\1aàiB\8d4\ 3ïNà¿\15\98*4úàm)|÷.Y#Ã\83\82ȯc\87OÑßÞ\ 3UuPÃ]\96Ú\8d\ 5Et\89OdÕ¢\82LO\88\ f8ü!;\8f7\88Ï\94N\88»Ë\aÚ\83xb%\a\8b³´\89Z\ 6ñ\898)\15¢Ø¡TÅü\0*ñòH\a¥\85n4\18\ 4ÝG#R<yd\1d\1cQ\8a\7f        30\8e÷»THj)X³µxÑ\8b\95}
-'>\8b|5\94¡\16\9f\9bÝr\1c²²x²üx
-yM;\²x¼\81¤M -·Ü,þÜ\a6@\8cÏ»\86\86w\8d÷\ 3S\13«ZaõñתþqãÑ\ f\130êÈ_¸äã)\86\ 4ÊÛ_\99\14*ß®e&\1aË7\0hÔº|[\ 3Ôv\98ÿ\18¹üÌ|º\80\92\9fêcØÞ|qô\95ö9¯\82¯SC±óð|H\1e\10<Ù¬R\90,Ð{Ô4b¥'\8f¦\92á¥0¡7ÙycT¢Ï!Ô»\9d£×-é\11\92¡´»ô>\86?\ 5Nßs¡\94&\85 ~$·9©ÔÓPz«©^\8c×Û lá\7f\94\16W¿º_¿¢¬\97\1eßËsëëF\99Ñ\vÞõÿ\ f+
\7fía&(Fûb\7f\88\0 ì¹\1e+vö\8aªCËn\800íåZª¢_{eÌ\93\ 4·\8f¬"á\97k\81ÛKe\ e\84\aÜ¿\15È z\0÷_¯±3¹\1f\12r5È}\90Ä7^í°\7f±èÞü\ 1N¡Ý'\ 4\1d¸ã=Å\ 3Sa½G@\11"1­óûó}\18Çß÷´À_k\aß\10,|A\9açê\81ÿÈTPäݱwmÉø\v¼ã\8bFäãg\90Gmò#ÚÊÇãËWÒßÊÐüIJÙ<Î\87Fôü\ 53è§\8cÑ·\8f*ý(|\0r\b\1eý§q~¨\fìÂ\88ü\82\8d\86\1f¼\9a>\ 5¶ìµ,\1f»b>âfÁÿ\ 5Ó/ûZ\1a\10pÖ¡×\7f¯u\90ë4W²\80\_ß\92\12«3\18&\ 5ɸYc¦ ãº¢Abâ\118\ eÆ)`'N\ f4Pç¢\11ÃWë\9fÚyÆl
-\9b\95\8aÐ\9dÆÉË>ÃöT¸\v\9eX½jÖùª>\82ºzF\7fz\84µ\eÁ´9>®\81i\9aè£õê\89}nF\85\84Éì\86ë3\80f\8d±àÍÚ?§¬p¨\96khY\8fg\a\184\84\9bÿæ©~ñ\9e\17/¥\Âߦò¯~´÷zü\82\83Þ\19º\9bâ\88gYáé\94õ\16@;Ý®\9c1ôí\15\ f\85û]kOýmu\89Zµ\MÎá§uÖ9¹ÓN['ÈzCoõáV\87ìq÷ù\0Ýè2RÅ.±\a\12P½¦õP:\81Ò\ 6Õ»×&BûI¯\80\1eXLÛö\1aL\1c\85\1ccE¨v\83
-Û·"9°\O©S?\f\80Ûà\8fÓ\ e'»'ë\9b\9f\19]¾xß{\12¸å«åÚ\1fkC\9e)\90\8d\ 4¹°¹E\95\19ÿ@Cö½\93L\1fºälÖ\ 6§ä
\ e\11\ 2îÊàÑwv2á\8bG\84\17\9a\86à.çB\8eìBb±a\94Óµ\88n\ 1À\ fR\84\ 1#µëFÂ{ y\1fý\ 6ø\8a\91\83ÿ\b
-9ÓXÔåITßd\rÙ\9eO\10Wà{\ e\9a;\8c\16\90EÍé\9f\1e\1e\84¾&¸ª©¢hê$¤L|$\ 33gboY6\\95ÆÀì§¢xF¤ ,+Ïq$6Â=Ö       é¸\86FëôÌÌ\\17iæÈá\f4+¬YX\ 6K\95ôؤYhO+ê¥sN®\92àÄ"\8dÕÈíØºA\8eÀà\ 3EHu¦xì\13\16\7f>å*k\8a£/Ê£\90psY¥\13\9c^ÖÜ\1d\82uÛ°¨ã\7f±u\ 5¾jÄe7\f!qîZC\0\a\99\b\85\v\9b\19 ¼ñ|DxÒØ\r­¸\ 6\8aÃ#a´xý\19Üa½w\8cÝ\1cSx\viSh¶\1f½lÿ4q\94ŲX¦k\12B+'bLÆSÍ-ù\16æª93ü2ï\ 5|®,\15µ/\9fÅß\vÐ\7f7ç©æ´c\94}\9aðIã\93\1e\16lëm\1a\8aø\eV\90\12õ\145#õ\11Äô§ÜÅJGÓmã¡\ 4ºº5·ß'ßehÔÈ\1eéØÍÅ\ 2\r\7f¢k5\99\8eB×þ­t^Ú\ 6]\fà$Ä#½{8»\7fú´k\97\ 4¥Z4JH5\8b@\9c3ÝRrʳ?âP3\8f @\11\81\ e2\87}ç¼\ 6\18r\1f{eDÓª\89çÕ\99rîÑ$+Ñ¿G\81\98 4Ük\86ÀéÓ\95âÒM \ 1DYDV\88ÜsJvÏÿ\ 5;\ 3<\13é'0\8138hæ(ð\87qh­\18Çl\ùGj\14ºy¹  ¡\99\9b\87ªf;XvfrLɪ¨\81ÏÏËç\1cÀô\1fû?[X\80Á0MC6+çd^Ä\11'\17EÃqÌ\85à®{\8aÜ"   "×ãÓàÉ\81\14cÎs\18\ 3\81T,\ 5²*XóìÐÝëÝ\19ìh§\ f\9b·@ôÞê\19!R\95Ð1t®¨^Í1×\83m\8b4k\82\82À\8aÜ\8e\16è0\8a\19umr-\bå÷FØ«\eX\95\ f\ 1\12êzÆêÁ£z\82\98á¼TRÐý\18qs\90\1d¼â\r`\8cÁ÷Î`Ãé\18¬ßwʰLxm«gç8Ôú\17ÁçØâ*\90\96]\0aw\ 6¿×]%ü{È*TÞ\7f\95\1fëL\e\16m ÜN^ç\98Ê®_êÍ\a§\09¡wÿL:yJ\1ahO­çhiT\ 3­Yj˾\8a¤$½·\e\14ÞL´¹Þ\84\10ÕÄ \7f\93ch\7f°zìY\8a\ 3R\85_\ó¡gA\bEq\92l¨6|+Y¥\82\8aº¦\81ÛÜï òi\18î\a\12¾)(;û±të\¦Ï7g¾á¹\87f=J
\92\7f¡®\ f\99\bÆ\14\82æ\82à±ÐX\8c\83\91º£\11ªBvú\1d'`×)\98\a\9bS\86jû+áQ\11§\92\94fû¹Ñó©ÿee®ç×\91#\84\96\13°æa?t\13\9e\ 5û       æÑö\ f\11<=!8|\13\0ð\15\9doÅO\18óàeS\98×\88Mÿ\0"=ã\95\890DzÆ\82¾®\bÛqò\aKÕ¢[Bmï%\956\8d4\90mâ¸\16\ 2ï\9e\9bØ(¸\1dm\7f¡\94\0\ 4³\1a\au`\r\8f.\eS\8fèâW\82Ò6]Jq \88\9aǦ0ctç\95³²(æü`\94âà´Î\9fÃd§ Z\9d\18\ 2¡÷\93¨\85\a\e[B\80«Q³ìD\96     \0\17䪲u\8f\92\9c\8f\18zwïJ\89W£n\ 5¼rç\19\86Q\er\80²×®çaî5ÝØËSøÍ    ¹\9bX)ñ\avQ1¯Ö\90\e!\7fë§Å~YXñ|DL\ 5      \945\91°ì\8d\1a8\7fC§ûü\98\81\ 2*¹¨a\a\88È\10\8b´Ì\ f\ 5\1fO9¤\99Iu\7f6\96QõSó\90¥,eüçèl?\9cúK     '\8cÆ\1f:\r\82\9e\17±u¿wjÌÔÇ\ 2èÁï\86ÕåÓÇ<Ö\eDH\r9\ 5\ 3;3ZRæ\80ôEágGPy\84$tÔà\9a!\12º\ 6f$vb\anþ|p3Ä\9d\0ÅÞ÷Úo¶2+yC\96º\90\8bÓ\8e§U6\bÃ\11¡\17Ñk\8f¤\1d\17Ç\ 3¸\ 1«Ç\96»ªà\87°ÿǤüºB\98Fô·\94\11¿¼\9a³úo\veÞdg$\86\92¥Ì{ñ\9fÀ[]\ 2\9aåp9Úºb,ݹèó.\ 3n\84\1eËMthÏ*\ e\15\v\13x0lu¼º64˪®9åô\ f\8aÀBºäÈ*EÌ+\84w'FY#U¢TT\95È!É6¿\ 5H\0\93YTvÀA\9e\1dó?¦¡½
-û4®\0ö£V\ e[õÈ\96[\1a\r\8c~#°K«|%Ä5Ã6c# Ð\81õòù\91\ 2X.\7föOä\b\ 3#        9Ic\8cè+\ 4ʼ~wÕ\88ê\e\83Ö|HÎ{×\ 5¹'ù]qQ`ÿûr?IÉ\16eÿ\14\9f¯\91\1cø\87\15<\85\7fF\10ð8P½í²ìm5\86$cü\\93M\99_\0\11ÿx\97\v\85°\85lwQ9S\9fþ¼¨\f¥\ 45ÄZÏ/@¨u\8ehÚÝÜq3\0\ 1â\ 5\ f»\8eÙ¥q\85¼!\12h,ܧô\9b"þhè2¨\14ˬ\12ê\ 2é¾0ÖjK\95<þÂ3Øk\92ð(\97\b\977\8evÊ\\9atZÖ`ö        \ 6ú¾½\82\85>Âaë\99MÞT\ 2\93°é\98r\87\9fÑ2© ¹¥0TÖÄã4\96J\8e\93\9a\1fð¾ÁÍw7ÕWXÕ3[\0
-
-öÙ^Aê\19\eý¢.b\8c2×ÝãåÈ\a%¡×aÈzÍ\91\90\1c\9e\12h\85\ 1q\19E]!áò\ 1¿Áò\ 6\ 6r\8eø\8aQàjrj·\15*u2Æ\8cA.\ea\18*]A*\ 3\18T2\ 6Å9Ôi\91"tC{\80\90\ 1\95Û\ 3w"\84ñ\96ê!¹ô\ 4¥X\10\8c!|\17fVP\18\89N\18°+¿ÏÎÎ\11z×È>A\92ê*^:ük<>³mYü< VÞ\8e§hÔ#+y\1câLáØSwªøka\82=\89\9f\ et\8e\12¾,O\14á\eD\94OÍjCÇ\898qn c|}\9dZu\1f\97Ò@Ã\15ÒA;´\13Öy\0ÖÚÀú9±\1d|\94\12eQ\96!@\ 6\99ö%î½wµÙã\9cY\19;%[²S.»éL0Æq^î\8b¡æ\8c}ÆÌ\96|F(HÏA\11q5´ó\ 4­f\11ṬÂ\83GçSÂ\18Üñ51\88ÞKµ¨ôþÜ\9e;Ü@h\83Wt\86©o±\1c0r±.;}æè\9b¬±ÔÍ\15±\fz±*\85\ft\99@Dîª%\1a]÷Ä\92Ö\98\ 6Òñ\7fÙÎìT:=L\88Gâ=L4n¯á«\92{¶yzªÿ\18\ f\94ð*%\7f\94¥óäÌðº\ f¦9ixô\97üHr\8dJË@Ï|\b£1\89ðR\1dÆA¬I·\ f ´½D&×ãË\96S  Å:­$ÊAÆÄI¨\8f\8eý¬ú°wPÀÅ\1f\ 1«è\fÚ1!wµÃ]¤eH\19H2x±4^"g¤\ fI\9bë#â=±èÍ*vD³\91_Ø<ê¶^þE        \5øSZP\96wͬ`8\7fð\130ÞÁ*$Ü\8aå²Ä5ù¸\10±G\95\9eÃräTþ\1f\91w5#Þ¨\94,M\ 2\1cÕ\8cþ\8b³\8aè³ÆþiéBÅ\96^Nò¹¾cH8±I8Æ\9cw\e\1c rD\11¡\91q\13\92­ÜÅBïsé\17aÁÒê\eXB,*ìyl\11I\84ظâc8x6æ´C²·ËêÌ\96ù\19´\13#\10ÉùB\ eä\e-M&Hb\8df%\98ê@s\89)\82µ\fô]ÜùZJ\9f¾\17Ö!Û\15Üí\ fR\9eçH\ 2\87ÔH\fº=       l\8d\80ÚM\91ÏlC1Ð\80*\823²±£ªÁ1\80AF\9b½bfÃd\øð\90¾\e¬t±ÁC£\892T¿Ë\87t`Á\7f\0\7fq\81»\9f\10\8e  Æ§\ e N²|¤\12\8d\11D0s·\91p4P_ZVÉ\17å*zF6&v\ fÚ\84dÒ¢³IÅE¥?Þ\81v\ 2Ê(Mz\84ó\85l_\f\80ê7\85Éí0\12\9b\89µ\90YÚZ\ 6#d#æy\92\b\98.\90\9c¹&ÌÊÝ.y\81TÌE=²1%ûÈXFX\0éO(uj\85o»XwQs&ï÷QüËëj\98>\83\9bpH8\11ØV©\9eº"ínëÊ\ 6';\b\91«\90Ú%\84úó\0©JÅAs\8e¢e}£«Ñ˨,\90·6QGÑ\ 5\8eÎp\86¯\1aý\8dGÑß\8e\88\1fo\1142A\16Y*´ ù\9aE>5æ¼a\8c\80çʳeèÜ\989\88Í=\80ò&y\10ò\18\92\85\e\9cÃ:\19¤K©¶F/§×\17\vV\ f½órñÜæm\88\13Gò¤±(\8b^\96¬êÎÓ:bV"\88\88\87ÔÞêIF1\1fÎ\18\89|íb\9cÁ\ 5\13´¡¹E¢B0_sVm6÷ª%Dùý\r¸\83\14-['D¯=òB\bî[\84V4½Ý\82øôP·#u\ 6àZ\a×Ðwi§Ü\ e¸\aÖ\9ed`Ä\8b\15äkw{ùÇè\8f#yà\1aæ2×\1da\vä]\ 26H\85Æ #\9a(uD\ 5\82ç\ 3\1f\ 3á\80Øa\14\83\94)\ 3c\9f\1d¸ ±YæóF\ 2%1\ 2^\ eþÃ\8eü\80\v&k\fF£¸Ü/\9aU\11ð¤±/q¤s]T¢#T4\98\92\17\12\8eS\93\13\91,\83ñ\r\9d$1\aÍ\1e\9b
-©$\1eól\8bXÂUÚ8@\v\9e\1c\9e(\13\94\14Û¬A9ÀröiØì´±&\99\r\80\ 3\19ÍÅ"Ç×õ½I\93\ e\bçj\13_KÕe&\1c\86òñuN Ò\1cFÉoIÆ\15ÁL\ 6úWÂ\bã\14ØöÔà\7fHôò\17¤ÔE"è\8bu#Cüþí²ÞÌ¢U\1a\13[a\93M\1aòy\16\86-ª¿\88~\1a®ò²í¢ë\rnG\1aó$ÂJ0²ä\9e`t\8c(âË\15fh4n\ 39­ß\ 59/\82ènz~¸«¢\02.ü\96õ¬\9d*òªÊPÂh\7f\8d\9d\19~t\ 1\11Q\14\17"CuúÇ\ 2\92»u\8b­Û\89\8dII\9aô\8f\1d£Daìs¥\8e\r\81Ùõ\80\11Ý\9deQ徺\98\ 5ÕÞC\98à°Ézx\1a%ìmt\84¸Á@×Í\0ã¦Z+C£d7@\e\Ïâ@«P}¬ûÖ¥\1eS\13\85¾<\9d\\r´\87?\13Ƕ\87\8aÆ÷"\85\ 3<{õ\ e\ve\1e¸ñµ7Y~ü­ì\19Ìë¾¹7À°   \18ýe¹Eä# ÝÜB3ÎÙ\96fpïW\9b\84@àR\9b{Eg#Ó&G\94\10S5\r\ 1\986\aj\1cwWPìØgÈ`\rB|¶"\90µþ\1d\8dæÍ¹Æ@I\88D.ÂT
-R½^1¡\-\bÉ\e\ eºv\ 3¦\93ül\9cÿ/w\fR\1eÁpEB³ \aÊ\94"I¤àA¢õÕ4Ç\9d!\99å}H\8e\91\ 2%\1a!#8\80'1±ø\9f\ 2ý:7/Æ\8fÄVìJWr8\99ÒH\r¾üÞp°¢\¹ÉVÕ\b/ö~\ 3K]AÒßðz\ f a#\87\17Ç$!\80ê\9b\9a=6â\ 1     Î\ 1#\e 2ä# \93J-ñÅ7G\80F$'\82\v\12°r\91!$T{¦òW+dÇ\11ñ;(~Ü$\93¾LÂ\1f!Ƽ\83TÉÅe­\93cR,\86æ\8a\b"us¿­4£Ê
-\13\ 6qùa6Rf¢\0\9eö\7f\92È\84\9aW<ó\8dd\89°À^
-%¼\19\18ãÙ
-\8a"ÂED\88®\ 4¯¬Âaæ\e\98øQ\16¦\9ao\1e%Wä\90\v5¿p\8e\82iBo\r\ eª\9e)\ eg­â\8b'\1d\1fË\v\81\ eb\7f\f\ 3sâ<¼gNß­]n\1e-Öµ\ 4\eµRú\v\12>7»\ 5ÄFêb\9d½\10 µYOÕ\ 1É\9c\18\85Û)ü\0(zydÙµ-ûÀ0\12£\14¡ýФB¾;÷Åôè\ 5Ôå\f÷\93Ê_õÍ%\87ä@\126ÃÊ\9fx*\eèc²\fc\a\81H\14ê,î\1d\ 3¢Ú¹\a òBªf\94ùîÊ\19å\ e\8cÊþÊ/\\ 3\88\86Ré©þ|q\1cÔ°Z\15y\1fRyü\83\90´Ðm\87¿s\12WäÆt0\82\9b\94ìcP\ f\ 6!=
-¢ZǨ7Ð\7f+§Ñë²1(p0Öô\12M\85o¹cª÷-¼\8e)\19¬}N¡\11J=û]d\7fP\ 2\9fOøAÛT\12¤ð+¿Ñ¼Ì*¨\98\98T\vJ\1a\97\84\0gé½;\f\b\ f\81.\9fÀ\ 1F{\b^ïMÏ\92ß\87\83e\fí³1iÛ-¶,¢\ 3Ñ\1fC\91@\13\e?\1aÿn\v¦æiÑY8Ø\19GjØ\11\9b@ZTX\\v/È^W\ 4î\9a\82u\8c=\v×\aŦ'G!K\8eÈÄ.jøn{\14
-c\95\14\7f¢\ 3Òh#\14\97ÙÓ¡Á\14¤Å\ f\8aR\96DèXsdÐ_-;}!:~·ö¯\98±\b\ 1e\88²7b\ 2\84¾\98K³îû=»ï.\84Ì\9d\8eë&#{¨Ñ\ÑAYõ§ñ/·\1c¥:g\99\9fÊû\93\7fa\ 5³\8f\ 4wD\1c\14./G\ 6\9e\9fª\16ýfQ\91ñûJ\r \97Lºû}O\92I,¨Ï4çÊ`Sf\86\ f\b6\92&\83Gg\9f\16ó¦vn\81ùÅeúô\90ú[\9eé_Á¨-\1d\rÄÃû\17:X¯\15p`ë)°6
-Ý@Ôì^eÍÎôw \87þ\84\8f'\r\9d8\ 5\foï_\8f|Óß\96
-n*ð{a²R\14\94ØÊ\8a¸øý¿8øÉ\8e='\ 4\89*}\f"\81qÞYQ³\92¦à\13\88¼r~ô ÷0ÍÑÉ3SÇ\92ÙÃ7
-\1e\18Á2\82\ 4í}ÇN\94ª*kì0Ýï±È 5?0I\9a\ 5
-\89É+Ç*<Ú½,\8a\13\1cT¯l,¿Æí¡vs:â\93ØÃ#zÑ¡ªU'\8c¸´{¤Ö\92\13\1e¦\85\ 1\8c\12×cä\9bêýÀÂ#&\81\80ñ÷RÍ\ 2BÔ¸ì2â«\v\1d\9c©TèÎ(ãRfK\b\ e\99}q?ÎS}\11S-(r\aÁ
\a¿£¼JM\8a?Uie>\87-:ãìéb¶\b7\ 6ÍË\8aCÏ}'\8d\aÁ¶Ì&¹VÝ\16    \81°¼í`\ 4\ 4Æ8ÞB\8bÁ\1dC\ 4}\1dT\92>\13_\ f\ 2\82\ e\9apÇl\1f\99F\90g\0\13ä\11\96zªÎ\9f\8fä\18\80[·0bZ²\1aõú\18­\89äp\98\9e\98¼E.%«×\953]%9\86êé\rI¨8\8d¾5ô).äLuÍü¦³\9c\rX\f­ù7\8fÑÆº©Ì½_ÊÆ&KoydßAµAUJðq\9b©w ¯\ fÁÌ«RN\99ÀÁð­A\88s\82°ºÃ`\8fc\89ü fõp\97y:ÿì\8f\1em
\ 4æ-JDNì$Û7\ 4@\e$\19\ 2\19ÅÃýÂ\89ÂwÁ\92TD­»5Ð\97L?Ú\ e\14\b  v\17Ìé\98\97¶¿ÝFNe+\96Ú¦À\ 59ïàV4\vss«ý¹½\0\9b¦Ïn¢\84;
\93¹-q9yZ¶lÏc\95ì\96\84\94/\ 3\94-ÌfU\85\9a\84§U;\ayp1±m\90j%hÝM\8d\86ðÑ\9dO(\8b\12\86\12\vt\0ØzWýëÿw-.\14âÚy\8b»-qR\93V {\80\ 3$säÌ\92GÄ÷BO.Q\96u<7\7f 1Y\ fü©dUv|×me\9bG\ 5ðÝ?Ü­OÓì-ôbÔV\9f(0Ñ׸i¤Ìe®xÛO\9b̪ÃìG\ 3\17\99±~\g©:\894sÚÍ«\aeV üw\8aGY5!âV\97\ e´\avaS\86~Eô\r\0\99½@\12µÆØ|%\ryÃ÷zPÁêºóéþD6O-eä~\91Ù\ 6¸\e\89^þ­zª¥4õq\e\9el\r\ e!eg\80årß8ÙÉ+\f\1au²®³}k\ 1\9d\17S\15=Ac]·+²5GÏ\86Ô¢RÃÿ2hø\11f\16é\f\Àñ·â¥tpòÕ£èå5Tϵ\18z*û\ 67tÃ\rxÕs0\83»\83LQ]É5\ 4\0\91\15ù\12\ 5I\11îÕm\ 5}\8fáê\8a\ 1Ëv\99ë)\8c³GUðÙ_Q®¥Àd&Ai
- Õ/ùóF\89¢ª\12.ËL\86:\84¶Æ\12h\8fE·¸ÑZ¸\16\103«Vú\95\ f§ÁX¦#\95\81Ó1[¬h,\83Nh\7fITØÕŸÕ\ 2ç©\84\rÙë7ÑüÜÝNGѶ©Ïvh\rfnâªgæþ`½\92¼þ\95éþBo\80g\11Æn«      b\ 4ª÷*\94\85\97²Ó`XÖv\17\87«J\14\8d¤«þ\1a6FÁG\ 4É9Þ¿\e×H\1a¡Ì\8d8ÀD\95!Õí²úVÂ\90ÍÀ\95RLÌ^VXÍc\fã~\12Û¢\84\93\18\10l\8c4ëp+}nÙÍæ¥§TZå\bå\87¯Äl\v_4\894>¼\96ò<­\98ô\99P\90O©ÃN¹i \98\ 2c¤)É\1fhª0\88>cô|Ú¬z͵\87ºônU©$q\1eH\10cT {ß,É\ 21ôÉ-%ä8\88¡ðbÁ\9440kç"\ 6\83Y\94\17\85Ʋ·»\9aõú'j5½\8eê{\ 6q"r\84Çt0\88}\97õS    \9a X»\83µ\8a\16L\a­\86£N\vO5\93Æ\84\12\9f½/å\13l|­lOX\92Aðt¥¦ã\14>°¶$\9d´õíy\ 1 \10HgÐ\99(ãqç]://y]Y§Ð\18Y\17[\89­¢\8d\8fÕóA\9d\aÿ¢^¬v
\97â­ÃÄé\86d\95øGAæÅ¥ÔË\88¹¬5\89\9e*çÝN4\97´äKÈÜ\ 20{\99\rÆ\13ºªt¬Zâç¬Àa\ 6ºÕ®ÚÝH   XI²¢\92\89×Þ¤Q\e\vû   \85&¬ÔSQQãA\97!½¿Èol¦xðJ9\92\8d\19\1fij&\ 4CT's/a\1a\aj\93Ñ\9eR\9bh\9e\bI-¦3+
-ëà\8dqONQøÿÈrÓí\búå»ÄÀ9\9f\88­éÄî\ 4ô\93S¦ÅÍ\18x;\84x3\19±\99`Þ9W%O,AéÛ)º¹\18\98ml\16)\12ô/\9dßñ\ 2\b\10¢ñ\13µµÎ¯\18Èî\1a!\\ví´­\0V\9eï§\ 5hÕÄtW\1d·\8e:ÂR÷ñI_\rºÔ&\93º\8c\ e¹F« Ù\10F\814t8ÑÚ ªÈ\1f¬àù\9d¬\ 6Fóç@\11fÂ%\85\1f\84V4\10"\fÚdöÆ\9d0b/ª V-§r9¤ ¸[·¹6:®\97\84\88<D\16«ïÌÙ¡¾¦v\8d\11÷k\f]8\ 4ù\90îêǤRæV2O\97åLÉÍ®f\1dê\1cÎCÌlß«\95æ\81\11(ª|ª¢¥hðE«\11T·Ø_êÆ\ 4H\91d\99!\ 3\118÷ÏEÔ\8f^GÜ&öäs:Tu\ 4Ö*ë=t\1dÛ}fÉ\9e\ 4é\86j¾«E!\14rx\ 4ì7e)\988?4´/¿êª¬\80H²Ê\82IÊ÷\82\bb\ 1\80.ù¨å èKØÏº\86\13\89I\80\18\98\91\v\847\ 6Ó\80ðÌ,\ 4d¨JF\rà¯\ 6}+\1aò\90gT*bË*\97qóµ~Oë_\92¡\93\9e§\9f©­þ\15\16&æRnÂ\9a4\84ÅåüÒ¡.G\89l©Ve&\14\90ê°N\0L¬G\7f(\12­úÇfñËyÛ¥p¤Ò³I\ 2vþk\füO²AòÕ\95b\92
-\92u\8bt?1Ë"þ\9fmÊ;`¡ß/\8b°(\ fUâР      ö\v- êÕ\99\7fN\bÏô\12#\95®@âËÀ\a¼\84\ 3 F\98¬oBzåÖ«þ74¸"¶\12ô\88sy¯u\f\9d\r0\8ew\13ø\9d\84*~-ÊÒc\e\87\rN§VZ;EkÀT\8fnIÊ\16ÖÄß\85ÀA%8\17C´H?w\18 +\ 1\ e\16EHÔ\88\9c(\1c\80x\85jëòN]c½øz\ 2 ~Y©\eº%8Â\8a\9bÚéÃ}¨\95\ 2\0Khü\15\ 6í\9bOz\94øiÓ\1a<OgôÎ\8e\8bðû\86Ïg¹\82kã_@\ 4\9dh¥é=\1f\9dù\1f\8aäÖ¹A\15$P2è¹÷@ÓÅ\92*\aÊ¡\8b8\93ÑN IVå\8fS\vâ¶2!^R%KÑÙ   ÆÐæ\82oÖØKدÎ\93\92)Æ~\90\0%\r\0ƹ\82?úbZ\82g\08!¼\18©ëKô®vìbsjd®Ùdé\\aj¡}»ÉNa\1f,\ f\9e·A\9d®O¸-\84jçñ3 \8f\80q\bÜ4-\96f¥×z%gÁAJ¥|>ÙUQw\91Hª°\ 5ToUè~\ 3?fdÝÿÒ7\94\1d@rýÐo©ðË\9a\92ù|v\98´Ñ\82\15O+òÝLÊ·¥oÎ.\90nx*ä\97\19,3FÁ \ 4Ñ\b³ã\12\17à=\eæ£Lé V<µCJSÚC'ÈD3\9c^\94\rþ\9cl2e82Ñ\95n\8c\82\0±EV\10ÈÔ5Þ\b\11U\93{¾è,αvÂl\9f\9bòG'ùÀ´¨$\9d\³ø-_\99q/e'è\82slf?¡\96$\ 5\92\83\ 11ê%5cÕ\84\93Ù\1d\9d®-|ßÉÿ\85ÏêÙ§Þ«ZàÓGhÆqKî\1dN;ù²\87vE       ç\84\8d×    »Þ\1aìÞ\8b,FÖ:E\98D¤:NÜ$A\16\98JDÛRcõ\87ìôf\ e¨oï\16sz°ÀTüÛÌþC]@\8b~÷t
-Ï[Æ\85\1aXU;$²\92Ö\97\91\1a\8e\aM.­ÞåÓ.Ã\98\94­D\a\0è\ 6\17²ÿÑ#\83\b¸»\1eVJq[Sò±w\8fR6\9a4ãLx\ 3\15ûËÄþ\8bo·íô.Þ\17ëcWn\r¢¿ù¾ñPÊ\11\01\11D4\91\9aó0<Øa£59Ê¥`×M:!Q\8e5Ê{\1cÞ&\17ð ã.NÑLùóÅ÷§¤*¥FôÓ&c\b\fë]2\9b·®²G\ e³qÿ­Èe¤?^"bK¡[\ 4\9f\89Boîé\15Øh\92Ù\ 3IÝ0O\8aè8\0f3ÇÑ1oë\1cb5Ä\141°Íÿ4¾b\7fCKkcx*\a6-ü\r½\7fS·HDÒÍ\81È\97p=åv"ãò\b\ 2\f@ï}þ\e\0Ñ\a!Û»\19©ÝÛÀaµn\9c.\6Q{Í\92Ç\8aV\84)\85 \89ÑÚB\a{\92L£¦±gãÞ7©Y\85\rxJ_\ 4Øð\8bô
-\9b
-¤BÑÄ\ 2t\8e\ 4aÖWï\fݲY\ f\94tHñ)\93;\87\11t­úïy~\eO\9aÃý\0gU &ÙÂ%\ 6µì\831´F\ 5!\983ë      \86\85tô^DÎuJRí2\9c¯Î»5íÍN\9dW\89°ëÝ0õÜ\87Åá\r\92Lqe_?ó¡\10·c&?Ç\82Ç\87ÿY\8fЩü»³\93Y\8b\0v\ 5^3ò\85g)#:§4q\8d\1a5È+8\10¡fxA÷\936A\11Hüÿ1¬nH´
-#ù\92-³×¹\16Õ^b16KÐ\87\91G^Ý\80 \9a{\a\11ÓNÕ$5rß    Ìb;\16\ 59\vrÀbF\1c&\12\ 1¡k´      ­+ðz\7f\8b*|ùf\17<Îßoþq\9eé¦\rX\83ï\8aÆ©­\8f¢*#I\±Ê[\ 5õ\e5?\0î\19HBä\8c"I?\14S3ºÚ¿T\80\8e«\90\83\a\1d©â\87TóÎÚnÚ8T7Æ\ví"s\ f½\16¥RùùïÈ\8e\80à\bp\8b&ZêñU\94´v\94¥\v\86\80eXÈ\1d[½"\92T¢Áÿê\83ÑF\1aô\9f\80!E\95ì\ 5ì§ÅÔ\rÃzi\12ý2ûÓ\ e\82\azU£øSG\85\97»æ#È\7f\ 3¬`\e\0;í;5\99\95C-\0Ý\84¶Ô\ fÖÅJ9¤J8       á\8f÷?§\96\96vÒ+ØDµh\92q\9c6\ 1ZÙ}?$Óq'\16ç%\11Q\12\8cH{\92®NXÌCX\16ðáe\8d{&lb\9bø+{\93N\94=\96ú9]µ£\88§À½b"Vøê\8dWoy±ò\9dn8;\13æ§?\1f&y¬x¤þ$ý½\1e-\902Á>\97\80÷\7f´R­\16íÒcJ;ë§\f-\ 2$T\89ìþR=;\9b¥4<­¤M\9a\1fhME,¹\ 52Û2æ\8fE¥þá1|Ê\11lr\17\91&7\7fU\ ez\ f\ 2\13\8a¿\9fÄ!Ê\15\f\80I\97Òcñ!Z³ïÖd\85\13Ç'£$×\9d9\vôÿõD;³>=ò\95É\10ÿ\\9ab¸Ær\9f\91«0©|\95 ¤\ e\e\94x\ e\v¾Q\b\18\82A3üÑe\83\94ä\1f\82Ìóå\8c¨\99#Üf]\a#\8eÁ;0oåÚ@\9f\1d\95\ñ¼\8c¡\12\ 2\1d^\f\1d\rJcú\8fL`h\9a\90¥\82rà¦\rK¼wÄZa\9d\a´\92$µa\1a\8a\0)±nâª=pH¦Ø"Q\15ëûv(Ò0õ\v\92}\9cºSù\93Z<ÿ\e>
-òå#ì7¾ (\88(^ض÷\8bôªzV®\9aøu\12¼\10\86OB+Ù\12áf¾ÅðA\93Ò\88ü~Aõ\ eÈ<Çìxõ\93kýÜ¡ç1Ô_L\84þªPÊ¥u  \8cç\95&¿7'\134Ê÷9\1eE\17\94\ 5t©<©ñÏj/j?ø£þu\ e:^4   ?ØÅ\10sô¼³{;ØDÉý\ 2\ eSU{A\19NÑììÏ×ÙÍ\18Ð~\r\ 1uTõ[\1dÖqeñiR\a.¾¶\1cmt§\89Úé¡\84À9j½ç\ f\10î\89^\92\b¡S\10zWJ\89g#&\9b]ëO\ 2®=ªí¹Ô¦õüÆ\88·\8bX\b-^í\11N5¨]\81_îw¬÷ölè|\11Î÷âö\16`*Ë1ãÉ1AMæ\81ª\16\86æW>¨ÔÞmt\ 1mmzoTã55­\ 5\9d\14õC\9e\16\16\15M\82¨Ó¯Uî\97¬\92\8f²bc\92:\8cÛ\95/¥'¦*Cå\16\18>\12\17[a]öi\94zÕ¦}=\9f9äÛ<#®\rpçífÏ´(«výYî=R¦\1cÌÜX\8f\99\1a÷\9e@ë<\a\84\ 1ÐÄq=ö_
-º¡Àü7¿zä5wo\12\0µÉ\rÖ],\ 4\17Æà2× åÕî\81\9c\81\ 5ÿ\8eÑÁaiSuK\10{Ü,\ 2ppr?%\84\8a²`¾^§uØ\93r{ë\v\88¡%\18\88(Í lAçZ?õ\91e/\12z1$w\90\b1Ä4\9c Û\1eÎ\83_?TưÛoàg'    ¹m\8dÜ\94\99\88g0\89÷¢\19\91j\8dRE\16½èÐ\ 2«Ùß\85ý;K¶@ô\89pzjQ¸i\8e©o½\12áeYWã¤>Ä:ÛM\Ó\83\98+\14\13\0+x\b_ã´ ç \85Ë\91\9fXJ¼Ø³ÒÕCC¸\8f    !HÉLïö\83ôÑ\83Mpg\18êÂ_MM5\7f4\b\8aPëÖiÇMã3\rãL0\v@ÊÂΣ\95¶Ñ\92Ó\ 4Ö0¿hìO©\1f]¹µ\r\90\81åra       `¶·M\r\12ÿÏ\ 4\17s=U'À\13Á~\8e\92\83ûïXÑMÕÓá<KnÖ±R?¿¤3Ò\ f÷7°\ 25q\1fh\9d\84ý\ 1þ\e¥Ë'@1\0\15ÕE\95£\92ª\90\ fûéA\16èé\9b\82ÀIQ&\9cXz\17\96\15\82±­¬\19Z)\87\95¼«\94Å*\1fRE\8dS©ú   Òö\97¿/\90\8fúRS\1ex¾Ðü\87/¿DF\17e\8aì\ 6a}\ 5\11Þ\ 6¢V\11qsÎà HÇ\14§:íÁð\87»\ 2\82Ñ@[|\82
-\fÊüÿ%ñH¹Ñvù¶¤î\84pe\0\v¼ð\ 3î­º)\1d\ e\85J`\8d\82ëN\90ê*H
-x[6ò$U"aê)ñom\ 1\89\14ðòH\9cÅ\9d±¼\1afy¤LKþ\ eS¾u¹M1\82ðÅ\91ry¯\r \9a\ 4\,õ/ùtUí>\16»H\92\84srX¡        ôa\18̯\97\1c.\9d\1e5ñªêµè\94cXë¿\9bC        FöÜ\95ý\8aþ×ÌÇú¨yrÎc¯\15æ¨À\ 2\ 4³\91w\1cÕJ\v´ï@
-\ 6ÑØ9RóvúÏèy\9f\ 3U<\90*\1c\7f\80ëÆÿ6àä\91Ãl"`\97¿SéµÛ\92|\t    ]N¸\9f¨cy­6i¢\ 5\90VÉë\8e¶Ã×Ëżª7\ f\86_zy1×\17ª¯ãH\15ÇUÃ\89®\92\ e¿\85é-¡÷áÐíø\86È\e\86r_(\94Ô>p\17òá1Ü\0Ê\ðá\ 2]ðçöB·Ò\9e+\98ç¾;\93È×\99\85v\96D\9d5%¨Î^W7gy\8c³Î\9b\83b;ÕÜð\12\9dø§²¨=í·b6é\aON~\8a\\8ajùÏÚ­LÅ\eýPß\16{4ùë1!,¶9EEþ\17½®
-\8e¢ÿ}\14\91\95«âw=þpñìˤo\ eZ\85ÐÜÄ}7\94ÓÇ\85Ã>\16Èr^ºE-Éc{ñú\ fÞ3ï\80\90»T#Z¼\88.GüD\92ê$}-\ 5-¦L4Á X`\18­\fð\b\16,\96¾µ?å%\ 4\97\9b?\88\ 1<G;pZ\93\91\9c~\87\8cNæ6\9aë\ 6K>#\9a\9e\7fO±XßöñHÁ¼Ø¢¯B\87v#\95h{F\90´\11þ\ 5¬Õ6\92ó\ 1sÏÂ\7f\81\87­Ü\8d\94Xª¦4u5Ä\82í9v¸rÊ¥\v\8aõ!G\81b*\974¤Q\8bqÐê\8bÙR\92Ã\1eP).tþ\1fLÛ·CÂ\19®uÊ[á_\98ßO3H­?²ÝǦéøÚ7\ 2ª\19\13¼¨Ë\16\19\94¥aÄ\87\ f\11p\86©²?­\92#\95ß©j\8fªý«üæ¡î2iÈo\90\ 5ÑØr!2æ\12e\8dv\f\93\99à\92>+¼\19G\8d°¿\87+\84\15\ 5¥Eðêø¨ÑÄíjã\ 5ÍÔÿ¦\b¢^Ú-¸¤÷ý>Y²\ 3Ëh\ 3    bÊye\rþíϯڬô\98øL§\84\ 5@4ü51¡­[Iµ÷\95Ï\b2\0FTI ÏÆ7¿Tr#éöJO\94*7GÚ\8fð;'k¼\88\a\9aè\8fÆÕÈKR±þ\15]1*°þÿG<Å/2\8a\1f\7f±?\9føßûzF\1e^\9fF\15\7f6?@ô#\11\13\15\1ey¯?©¦`¼»\8f\1cM)W¡YW\ 6\96ª\94¯ÂÒª:¬Ô7ÚW©Z½M FnßÍðÒoø\ºÇ¾;        ëãÿCêö·o\7fÁ"\85\8fõRsÚèw\ fC\ 4ä\92¿ªì`é-S[ÏI\eè\86\92TÅ­°\9eÙJ\95ÐýÁÔ\1a\93g\97Ùåß\9bò.»¶,\ 4\7fG\96\18\9e\90ë\86\84ÜÑ"¡\9632£ø\9a>\18ùõ«áJ\8c¡¹C\ eÿ\a   3d¾\82ìKø¼\7fΩn¾6z\95£L\98\92+Ñ£ñgY\ 6\9d\9aR\98\ fL¤ìL´çu\rí«0íK3ý\ 3\9c\95\7fÚ\83s\8e\86S¦ï\98¶ë®\900R\98t\86×Ã\1a£k"ÙÛïq?    \98ÿ§°zM=\b©\ 6¯ï\80ûn\9aG\ 2þ!ïíüË83\99\97ãå×$YH      ¿tH\ 4ü\17?(&\10\ 2U\ fÑÊ\0Òñ2Ìá\10k~qÖ\83JwIÿþwT¬(\92x¤ãß\90\13\15á)í\ eh\85\17Íÿ÷\1e\8eÇøÆÆ9\b\10\¹òÁqÌ\8ag\rt\82\12Ö\7fò\8d*å@\b\9e
-þjMºW­·ß·\86\ 2òþþ.[²\7f\1eÇ\9aü\12ê?¿ÓÛõÏFÿçÈ;ÿ\ 1tf\ 2J8é,-ð¨f$\ 6\11ªFk¡;¥\84\11¿´]Ï\ 1â\8eq\ efF*Æ( ¤¤$é.¡, Gô0,z&ò\12°\ 2T\ 2g\ 2\87\85v9µ\1f<ZÅÁZÐ)=Í£­5[Ý_¨ô"«ñÇvY\89\86Ä\82\9aÔ|Kc÷$\97\95bÚlKI\9d\8b\8b\93\95\88z\858YTDµ\98Du{\93DNÅ!òÖ(*)N\96ÚM¥aæ\7fÏI¬DC\82Á¾Ñ»ÚÍÝѤRC\1cŲ\8d\9a^¢!±`\9f\86<«¨cÛ\86\g³ãi®eN-Õb¢3qG+¿°\97fÇÞ³ÙÚYM4$\16ènÐk{°\ 6\11÷öi\98FC÷¤Á##\1e7¿©´\93\96zfû3ó\7fèuÎêªg\rqVí{\96í\1a¼   ñvm\9bnÐG\1fæ^q÷\97\8bÎï\a1O\98\9b\83k;v;$»ßÝÒiåÍ~*\1dkÐîæ\8aG¶]Êß®×r\8fhÍZs¹[§·\95¥E7òU]%â«æ*¿ÀD5ª<£9*\9a³´Å?ó÷¤Y&Þlna¥)Õ~\aKG¿8XùÅ`Ý\99Ùà=/\8brÎFf\9fûiÓîª\8cvi¬Òyec\91<Þv^ù»¨Ðð¬ò\8b2û!NåN\9dZÎêÒ\18oSU·\86ª²Rͧ7TI6ÂSJ\9bÉZõ4»«ëºKt\17ÝX\9f_\94\7f×ø÷Úã¼íTÙ/·ÆÅ°`´ÿi(Ò\90X0º\9c¶¥\1eÕñ\85ßóÝåM\95j%!î®ýèTÜÌTó\99\9a®£¾ÓT\99g\r\buÖÈò\8b\86\ 4\ 3C\91Ò(e¥îP-æ$å\17\89\86ÄÂÕo[PÜZÎ*Òò\8a½y\88NzÅ\19\14(ªHñ\1a2óâ\90\ 25«PohtOÝ£Yª)ɺ8\94\12?\19(¿HD\147HúE"\ 2
-\14d\11\89\b\14((±@A    \ 4Ð\ 1"\82¢\80äñ`Q@BY*\15\ 6\ 4\ eÉ\ 2\v4&\f\vÄ\ 1£òp,`\15ÉÒ ,\104\88<\18ÐE\98DPqxðX\fð0\99@2¡\10 \81äÑ Ò°0LX\ eÐ\0by<L\16\1aD\1e\f  \93\85\ 6\11\96\a\84\85\ 2AEÂ@\ 2\8as¨8\1e\vh°@\1e\130\96\b\12PØê\1f¥´Úcfå¤\19¡Úús¬}:ós\ 1CäS¢)O\95\8fÊ\9f²Óå#\9d²mÓø&\9cÛFûÓ\83&2Ú7>\9b®sváøÈÆçSÒ1ÓÙjиåoîÓ£v¦ª\vo\9cÛêêUE¼- \8eú£V³uÖùü¢¦þ¯ÞN=¿¸\95uÇGÚ\1d[Ú)ÿ\9bÿöç\17þ¿\9e"µ§\1aÇnw·\e3\1d;\91ÑÜ\1dUqîé±Ê[\e+4«Á¯ÿÁ§\9d~\f\r¿\93¿é/¿c\87k\1eÅ<}~\91\83¿©,\9bükô¨ó{ö\87®\1fíì\19\8cÌ\8alhoÈÊ6e¿)Ž2\e¡\95úc¶3Ûìæfs»\1c3ßÜæfù\85\99}\fOhE\93h¸ó\9bÆpN8i´iOË/NÕÊ.E_Ëò\v\9a5¯)\96\8c\8ct_óë³s§i\9e_X­Çw·«Ç\10Çw_¢<\9dãÚ·{\8bóÕBÏ­l|ßiìó+×\87¨S\1f\1fy¼zÿÝÎniÇÎÆìÔw?{\fÓ\ 6Ï\90|9y\999V:8\96\93G\9eÓKº:\9b»\1dÛÓ»\1fÍíç\8cpì:v\9eÂ,KLý \92\1ak
-ÍsfS\98\99Ò\11\9a\95±\8cV\13á\1a))ÚÝ\98\99Íáî\1cz\ eí\87÷9ÏQÎáa\12~0¿\18L\9c\9bK?\11\11\80\86\ 4Ãâçºh·1Ë\1d³µ¬zå\9e\91\9aÑ\98͵Ô\9fëë\9f\15ý5çë¾òó¿\91ýz[×í\93È47mÕÜä¹Oïª;3Çõë\13o|½±Ó>N-T\ 3k\8c´²ÆH+ÓH\8d»\8b4§G\89\8b\98«öÚhÖë­ûÎ\117o\88Ô\90\8ej5\9dié6j\8fújól*M×îc\88ç1ÒßoÌg{úÔ©9Þ³åø\96Ôª³Ç\9d=y¯¯ûQïvìh:Fz4\BÄ¢9d¸µEû\90+\87\8c\9b¸\89\18¶M7¾ò}sn:ë\9c\u\e\19ó¦Ê\11OÙdZ·Cúh%¾¬E~º¶lkëã\9fy\191­Õ\18éø\12\10\80DCbAO÷Gæ\1có\96ÉÿmÎ÷¡úÕNùòtê\8e\85õOY1P\14Ú\93\89jå9E3ÅT\Ä\9cc¸»KÕ¼ú\åÙT&ú~c\89zOËL#K³LWÍåÙ©\8ee~q\97ù˳Õ\9cK\1d»´´\9cËËËÌÃ<˳ÌÌLô¤iÖ(ý4­ôò6/ÓH5m\93\94ÖWJ\9a\88s¥ÊPjUªFcM«¹ôôj%B\1d«âÎõ\9a;¿æÕ\94~cµc?3\9dÓÓ£âÜ\93z;GÍÓ\1cÔÕKÿtRóZ£z\1cÕ¯\9a\19ѦÑZí\10êËì¾·XUs·{\87»_8ĵҵmîmÕ»¿Ùe¸\12ÙF:v_\94\13Iï¥VvÄ¡\93ÖÉ\vZ×äæîÐ7¿ØõmQîÜÒm~ak:äµ3ZÓñ\9e\8d7¿X[»ü\82hi\9c6þ=´ùEi\95\96&\1a§ù\ 5j~a§f:§ZGsº:¦tZô,S³\ f\rYÎ5çê\85+*C\95\925¿¨-ÍÌËÌ\1d¬\1dÌDÓ\1cÌ"Ìü"ç2¿¨|êÐ3¿¨¬üP΢!M­\17kÑvQQ1\87²Ôu¸&«94*C;ÔÛG¨F\7f\b\vÑFC$Â\9d=ôî\11î¹ô\16önô2)s2ï\ e\13\vïêSwu\97_hÍ-îU\9a÷hªNu\85Xj4Þ³V\rÕ½.¿¨û­ákͶÔlKugiVcVw\85§Î¹\1dNÝÖL     m?e+[\8d­\8cÊÌSd6%ËE\1d²ííhO\9e%×M{ýRîËöz[\16ÖTÒ  O:\97_¨û\91tïô\ fý¾\87~§¡Ú¡ôe\19ñ;ç³C\9bÌf¾ÕZ×éÌ4uÇhs'¦j\1dU\8eo4vVjÖØ´\ 1å***\88\17Ê]1x0¨\88È£\ 1\f-\b\v\930(\13\ 5ÇBQ¨,\90É\ 3\82ÂäÁÃ!y(,\11\10\a
-\92e¡<P\98°@D44<\1cV +È
-.WÃåp¸ L"\vå\ 1y\80`@\91<\1a\16\87ä¡(E)(\14\88¬ ²Â\95\82¬P\8ar\ 4§ \9bÀ\80@\0Y$< ¨\ 3\9c\r\1a R\16Ç\84²\0\r\184``A¹Ñh4ªÑh4\1aÚ¨FC\17\8dÈCÂ\88\88D4\1a\fÉD\12\99P\1a\1c\a\81<\1a\1a\1ah@\18\rÆ"y@*\ f\87c¡<X\1c\90\ 3\93ʤBaT \16Ê\ 4F\ 4\bÃ\1a(\ 59xP*\8c\88\1f\18\rT$Kdi0 \ f\10\ f\ 6\ e $H\88 ±@\16    \8bDÂpX\98°\80\1c,\1cøÁ\ 42qx LÊ\11\ f\a\832\f\ 6äá¨\92 aa\rX\16\8a\ 2\90Éd¡\1c\13\a\96\a\94¥\ 1W\1e\103ú+¨
-*¨,\11\87Ê\83Âp\ 5\15¸ü@ò\90 \18*\92Ç\ 4\ 2        \12\84Z4 \ 1DäÅ\ 1\8ex ±<@L¨8D\18\0e\ 2\994\16\ f$\8f\8aÃ\83\adi0\1a(\11Ǩ@H&\v\92E2y\90°\0\85\ 1\89h,\ f\10T\ fLp8*\vDCÃÄá°\ 2\12Æ\ 3\ 2"\82Q\80¢D@\1c< ,\f\1c\15\b \12¼°\b\13\aÃA\ 2È\ 2aQ \ 1\ 3\v\fâ1q\0¨4\18\94\ 6SP4,\f\12\80\98<D&\v\96<$\8fÆÃá\81A)ÀÒ DL$X\1e&\92Ç\ 4KCA`T\1a\ fD"$®@" \16\8a\ 3JD\ 5b\81<&\80phT\1e\15    &\92\86d\89`ÀB!À\ 2Ápp4´4$\v\ 1\12!\82\ 4    \13&8\0\80¨\1c\ fÇ£\1a0\1c\1e \v\1a0°@\0
-\85\b\10\ 1a@X\1c\93ÆC\92\80\ 4\14\bL\ eH\b@\81Àò0¡²8&\12'\ 4 @@²P\1c\90\87C\83A¡,H`©D8xP*\15ÆbqL$\90\88\84\ 3\14
-\8b\0C\ 3\14$\90\18\80"\81\ 4e©@\1e\ 4(\80\ 2\82D\1e¹×J\98\94\f\11ÅB\8e\98\84ªWté\8e\9a§ãÍ:kb¥ë¸c\8aªS@¶po4Q}µg\9aÕ¤Ú·Èx\8be\8c  !I, á\0\81¨Ó§*ª­Ô\8c\18&CíÚ\19b\92\8f\f\91\1f"\ 36b\8a\ 6?¢K\84«È3Ò\9b®ö¤K5t»Ó«Âèl«\9e\91%Ñ2ø¤\96\8a\1e3(@J\eR\f)(]K\97\89¤§IT5ô;ûÝmÞF³#zL§»»Û\80ÂpH¡¸\11-MDKG\96äS¼è\1f²Ê[\r%\1eðêaV\96\92Ýhb\96\rO6u\98\ f\v\14Ua@ pH\16H$ Ñ\90X@õ âÝ\92a\12Î}\b\ fÓ4T»Þò é\9e·ô¾·\88Õø<Úí÷\86y½}3 þ\88fãôeÚN§mÅ1ÖØþÙvÙ\98l\a\9a>¨´\95i\92Z*\b\0\0\0     ã\11\b\80@( \vGdRÁDÜ~\14\80\ 4brFÂP$\8e\84¡`P¨\f\81`\84\ 1\14P\0\18\ 2\80\ 1Ä@d\ 6Dn\a\15Ü\83\9e]OÿîO
-Ãy\906\83¦D\10I¼¶\89\ 5\ 1ô«-RùE®¬ðÁ\91£4í_^\e©DO¢    =ZÄ\86&\875@kn¦dÜ:¬\1eêé%6J¯?°ZÈÕueìÌ"F\rÿ©ë\18\8bé\11±®û\14tF_\8f\19ý\ få÷jU\81x\8eÛW\f=PÆ\9fº\9b.ofvÀm^qit\84úM$<»\18\ 6ÅH³øß\fÛÆ]j\Äl\Ä2·\9fÐ\8b¬SØ{~ýé« \18\15'Q¢*t¤_Ç´;ú¡¾\81\96V\81\8e=\1cløÍ(z\88}9\±N\ fDG¿ý-SrÏ\ 1`n .m&>ÜAj\93~,\89Á\92ÊÅ\ f¢\10\95(\997B\87qQÝ õK\9b      ®55\85\ 2V,\11Íü$r.w\1a¨án\89q®» 7 \1eNdð"\10Ô\e­?L8\9e\81kû;ÖIº\19U:\b\1d³ \ 1VÏã\1f\97ëî90+\94×\95\93ë\17Üi\1dÇà}\8aH\87ïί$)5̨\9c\1cWÝÐ\88òvxÊfiQ,DTY\90»\ eºçÔ0XlÕ@\ e½Ù¹\80æ\84ó7'TN\86î´¦ûrÉ\8flp:z¦³8vòVXÔÌOc¿Ñ¤]­·´$\90\12\ f3;`Ì\0\12\e¼
-H\1a     ã-'þéÎlr\v2cvK\8f³\aS\9d©;õ¨ \96\9eÈ3\90t\f\9c¾oºì®\f&ÝÞ;\97\eXüDb§A²\86õ^²B\87\ f\9b\ðaô\ 3Cäë\13Ûë\83\9e\9b\119\7\7fh\13\rµ\89.·8è\10Ý£\14\12]\19ÿ\1f\9d
-Æ9Q­C¦\1d\ f       Þ/+^ ¥¢\f\ 4\Ö÷j)x3ÄÑì±\7fó~\9bJ§»ÙJ\eи&\93¥\9aþX\1d4J¿\18bà]Bµ¹COºIR\1føBÄøû\1eø\1aÿAA§a\89\ f\f'«ge\ 2w\ 2ÁÇæ~RE\a\9dBo\ eø¨@\8c¸±"\16¯\ 3\ 6>\94å£\92APê\97u\8a\12\83\ 2A©g}Ap\b\19¡ ÏÇf\8b[)ßL¹d\80u\ e|wªÃ
-\r>\98\8bôÈYõÇ\9a%\8bÅ\9aK²sB0\e¥\7f2\ fC/¼bf\bó°{+¶ëjAý\f»\ 4\9e\1d=ÞUD¿ÝxX«C\1c?\1f\95\90\88ö»¹\81SÖ²\bûf¬R?b\14\9dêKl#\18\aR\95åâÎf\17bB\8anÃ^ò_ÖK\ 3K\17á\88Ô\14©|\91+V¸<\90óù%¯þ\16ä¥\98ü <Vk¿'\ 2=#¸­yYÕ­\14Òëºi'7<1ÿ£;-\8b³\11Mél\88\10\8bÑ禠      ý\13\91\1e\80¼\9d¿ü=)\1eçÊ\14|³X£Y0J\e,s\bô\87\ 2·8¶\92#\8b²$y\8c\9bæè\ 6\8cã\1f#\84\ f\8eüfpâAZA\16\9dDõMt±x w%«4¯4\0|C\v\aîW\ 6¶î¢\85\92\14¹ÿSwá8\91üàD$£\1e®lf6MÞ}9_]¤m;\v\ 2MßøÂñ\r¦\98ûB\ 5wè8yC0\fzv\f\14Â1\14uæÉðWc§\828ö%¤Ü ¿\0Âh<±Ø\95¾xUbe\12Ó]Â;B+«üj¯<ð°fÎ*S\ 3P\869²¦ÿÈÎvA\9e7ÚH\1fÛ\1fØ\9c¡Â¦\v\93\86M«X\ eG\8bëc\1c\8f\95 Ð`\90Ôå4ùÆÁBq\ 3,B\ 1   ´ß\14¦\8c \8a\ 4e\15S\19\18\ 2\v\97õ½Z
-Þlüpö\16ls¢i1Q¢ooY\81¹g\84\9bGÑûIô\94Oïê\95cZ\ f\97ÖC\16-£Ü_Â\8d\11¥\ 6ñ\8c¼ß){Eü¶Ä_\ 3DUääb\96K\99\9aß`¹\970L|\7frséQtGbV¿÷2û\90¤\9f§ôîÒ\19ÓK«Ò1G<ѬlÆ{\87\88w\eð­%D0\13¨xx\13\88P\999<\81çnÞ©\94F
-"Û!è©kô(f4«\15Xú¾w{E\94QuÅY¼¨\83\9a\83bjOb)Ë\8eîiòÉ\0ÄõÌLÐÞ´¦éª.Ã\15¼Ùx\9f\96¬}×¥<Ž\ 4!è^×\bº\87Á¨ó¢GY$é¿9åbè\87çã\ 6Ëê\96I\9a\8a\9b"\8bü:\18¬í¢èd®m¾Y\18\13\13¦S\7fjA~U\12ü\82\99\ f\99ã³w\11ÖÒ9É\1c|æ¦\8fo=\80;¨sä\9eQ|\80³¨\83\87\fÍ ÿ\85È\89\v\1cô&\99\9d\82ÐeÚËz\92\ 2\ 4Ú03-ö½\13 \8b*¿)ê]¢Otcx¿`2=oË\1f \1f£\8c\ 3KA¶+½ôï°D_bÉtú\1fÀ\7f\ 46*W\a\9a¹c\v´\ eu8]HcvB¨\9e¨SSE\8fg|\9d"\97Ý\ 3\1eþF\97LHA\8e©ËA%Mî^;\8f\99Yûü\11+\7f\8e\18v½©¥] {\11Í.2}¿äb¦HDÇ5\18\9d?+T\ e\88ö®Ë!\9eä»V\10ñs\9b
-´xnéäz\9fqY²ûÉú\86&\1dHñÁ\ 4¾\esÉQrC\ 2Öw7HÚi#gæ50\r\80\14\ 6n°f7í,\13´=³LÕx ¸\9dù_þ¥ã]Â+ûѼ\9d<#EYf÷Q\0,Ñ'˦\99\1dÿv3AÊòô\7f\1afd\1e©zp×\84N\e\91ßÌT¬ÚØ#\90³26\1cÆ:¿\ 6»Ê<¹\7f\89x@T6\91§\90·\7f¿\v\1f?§Jçä{\Z\86Ó\9f®\aÅ\ap\9b8%\13Eê¤Ïâ\9e@1;°Ã/WtÂ\19ñ§³\ fî\8eѼɳ\82\94=\86î/\11¨S´ú¡ôq÷\ea¬H\ f¤\8f \86i¶³TH'Wàþ\9cûb\b\88K\19\99\ 5+Z@ù½þÁ\r\1an\13ò\0\101ëUê¿ö\13 \rÇZºÛÜ\96è\ 3ûÕd\11ù\9a\1eVXC\f\8bû¡[Ä£\87Åûº2\85o\ 6í\9e5*UhtGzU\9cóf\94^\8cc\e\e"¨@4ªìSôÐC§\12\82È$LA\1d¼    s\e\ 2Ô¬­ËQ\11¢\0çß¶\87`6&Ò
-½KÇ\96ÞRè\94K¡ *¶áÎ\12ù̾?\11&w\91¿ñ\80\r\9f\90|auì \aBA\ 4¾Ó|þ¼¤×\0Ðeq~ä4\ 5X\9f[ñÏ0±\10dG\89g\94£àì\85\b\r\81ìgÄÊgÐM¦;cÐQ;§Wþú-<ñ2á\99Q3\81\13\eãC/5\0 \8a\8a¢\10¬q£KÑÂ\ e\9bw\89\91%[\ 1|\ 1\ eêáä®øÌ¹)z\8a}0¼2{x\93î­¨KEðǰTß\17¤°Íð\7fV÷ø\90~4Gï7ôco7VP\8cºØô\91\99'\Ù\89A6Æ^~úÉQëæÀ\88\8b9i5\82pH\92µ R\16\8f\9c\97f\b%¡-0¥\rJ ýp\8e\13Ìþ\90¼$\7fÞ\9c\83Ùÿ¡Xás\ 1ñ\8d\bºæ)8\0\9eº\ 5LIÇÞ\98\9ce\ 5p^£\9c\8aQ\8cï¡\88îáÛh\94ߨÙý'Ðâ¥Ä GXèä[ªä\}f\89kù÷DLß_\8dJÔ¨«\81PúÎÖîêeÇu\94àÂK\9ct@\0Øû\8b\\9dÖ¥(\99;FÕÝ®BÑþ\81T\12áMÙ¾µÆ»à3æ¦\9a²\8f\8c¦×&W&j?©4\18,YÑ\8bZeoöÀ wÞ\11\7fFÒýmÍèÂÃÄT\1e!¸b\12üX#}6*_\18{î¡\81QOÃà\99y\86\86\96Æ\99FPµîÌ\85Ýyc -\ 6]4\9fw¢ú |\80Xä¼\7f¯\ 3mäÑ\8cC\9be&;ÐòñSÇÏ\0ÂÜ,¨óNZ³Ý¾\85\ 3TÊ7>Íâ\9b{X\bò\97\1a)"\98ëØ\eð$ýÅ\10OeqX\bÈ-\16?LlùTBÐDNw¥H\rõ\e-zwL¹Î5\vW\1e\99ë]`"k[ÿ\91©N\9e.PW6V\96\84Ù\9c*Â:©\83e\95\92õ²Jxãm\97\ 5Ä\ f\a¢&MN*áªàúKQ2Ì\ e­Yë\8f\90<z&\13A\1a\9e¹t¦ûà3gf4KuP]\1fæ\8eU¨Ýõ\1a¹lÊ\ f\89j2k^wD\ e\88 sìuø\14ê¯VU\8e\9d\99¿+\8d\1dD77LfÉAàß»\89ªDbqSεÂ\8a\rÜ\e6Û®'*zÊ\89\8e\1e»epýÁ.\9d\19æ5õâ¡7\96\89\85¬åT\86:JâåüýÀT\97´\84¾¢N¬0x\9eq\8c\93e\83`m$Õoäd\9bÈ*Æ+Ê^\8a\91vÞÓ@\83ò%\v\93ÔÆ¥c\bÛ\9c6Éãð\aXz&{Zz¨k\7fçyÂkå©è\19røaÝAûqx`pÀ\9aðL\7f\14\9cúfÞxRãþ|\1c%\aÃß\7fÊ­õ¦ë;Y\86\94Ï2Õ\13\91èu\19A\0#\ÿ\9cëBº<WÞ\9c\82\1erÑ®,ñJq.1µ8\8aæ¤ó'^Èá\ 2p\8a\18\0\1fÈ\92¤ø\1fÓîUÏ\13\ f\9b$\ f÷\11Þ®Ó®7r|ú\93êMoñ   ½AF$\92à\90è0äLâälF\7f\13\1dr\1c\84Utq\9b=#óý#ç\ 5àk\1f¨qZ¹5HÃÙêò;ëAV±åú\19³\10ã\97º÷ßj-Íí\9e\92«!81Öè¶Z\1aÄ¡XtúåÙ\83°ö\94ð0ÄÉU\1a\ 4Q\11@\1f\12\1c\9d\83¸©öçâ|òë ûqÿ/ \18vÓ}õï\8d²u¿¯:>\12N#|ɲª\ 3î\f\189á       û\12\8fþ08Ø< cÈ¢íìÖj\bÅ\98\ 3:Qw@Y¨oGu¯Í¸mº\89Ã\ 5^,4\13\8ffCXCV<?ÂEÄ\99¡$hP¦þtI¦\1a0p² Å«S|Í\92\ 4ìÛ        BÇ\90Ðe$?ó\ 3ü\8f:·Õ)`Ü\bæ4¼(0]¼U<a2,?\86\\ fð\9a\13Ä\19\9dÇ^;Ç\11\86«\rðt\eÎï}n¼{ÎC\ 6|\1e\9f\192B\98Þ}\85='\90±ÞD9%´\98ã\ 4þTì¯\\ 6^@Çð\1e\17\ 6\84ËÃS=¿ÞS\8b\14\ 3\96v¹k\f\9a#·xI\12ÇIÒ¸5    ÊA\a'Ïg!T4¤ðs>ªÊ<Ø\85\80"\ 3>\ 4º4;\1cYÖ¯\ e:'\13\95*½ð¤g2\8dÞ\97d7ÿO\0\95\13\95¥1AÐ]9¨\by\r\14²t¨;§x
-\8a9A\8f\8e\83W0\94«Û\18Â;\r7\7fºnßÍè¡\b\82#J~µÍ\10­y°<Ë:M\ 2î·9i\96K\88\rð\bBU\13À\7f-ÄÆÝªçëê\b\1a!Üiº.ÊÍär|\91];ÀC\1d\1c
-\84ð\9bû\1fRX¢û\1fë2F§\88\99A"UBeäê\14%­`«P\12\87\ 2Wrºôà<S\85\1e(`\v\9a\83\171\9aí\8e\8cϧÐG¢æÕ­\ 3{¥J\ 4Ü'\ f£¾9\11\81FÉD\80\1c\9cË\v\81ï\8b\1e\ 3\98µ}QZ\ 2))\94þ\7f\17ûÝÍ\ 4\aÙ\88§\18¦\1cå\15\93ë\ 1%\ 6®òó \81\v`\87°\83ÂS\e3A0'fsì\\9fè\90ÅË"\935\91íR\9f.Ìï¡éqÿè\87ýï!ßÀI¬ìõ\1eª\90õ7IZ6]\96+8\1d¥1\ e\\9d)\86Ø«\1fV\85Ýø´\84ÌH2j\89}\96\8fûiÔ\0)8ëó[l\84»\89È\8f¸J¼/\86
-9f,Þø\rëM\83cbLt}}º·i\1e\99\10d\84$ÿ
-ß,\ez6Ës7       'Ñ·mT\1f{\11\'\rÙÆkeÝX\ 11Á®¶á\1d\14ÌÕn4Ø\ f%\95¾´Ôn½n\1f}È@Qû\ 2°ÑT×6\9b0°Ò\8aº¢à\10ãú\0+[\9ex\1d"¥À}Á©è\13\10\988ÿêýx\f˾\19þ`R[åkÀpV\1c¢E\86\1a\ 2\ e­\fJ\ e9\eG¬ú«\rÍéH£-\1aà\ 5$ß@zG"XÔ_\86Nßq7\96!"cäìFRÏ\9e¼m*º³\b\83\8d\82\14°ÂتÝ)Q²0"õ"æÅ\1aX|/¯\92èS\17·ðrüh\JF(\14\96on\0\7fÖòh\ e\ 1\1d#>B\fI\1d5\90ÚL\80\8d½§\ 1U\ eYºÅ%Ëáx$j\9cì\94¡Û\18gcã­¦2ò¥Ê\12¨\1e\81\1eã\9b\83b#mi\9fwg\10÷\18\89P0',£«å¬:cÇ\1a\19ì4\ fñL[\9a1Z=Å\1eÏÓj_\1c9ÌL\18ζÆzm¤ó$à\1f¼\96»È\eª_¥ÕzrÀ\12' y8©\86\18\ f\ 5\bÉ5\97ôõð¸é_ÉÂ\1d»,ÝÈ®¦ökO³\123ØNà\10\1e\aH\ 1\94]\8af\fn\94Ïc·\13(g\90ã¸b!¼<Á=\92 º¨\ e'Oº¾ãß\ 6\15{ê°Êå¦5\9e\96!\8a\ 5ó-\85Ùob8nH;Þ­7À\97¿\17 \93\ 5\e \13¨·$,\ f\84\
-\v\97³\999\10\vÅÿîÿ2CU×äñ_ºî\80\82\94¤ ®à!Üì¼¶\1cÍ.L\ f\9ff\85îzíÿ\96\14¬LT<­&\ f7I\82ñ[i·vòe\12£ô\7f\1e\9b\914ãuή÷fíF®\12ÕÂ8`¸.¯ÅuY6¥@\f~²c\826è{¡\89®Á×è\7f6)n\13\92\8cÈ\9fï7C¶?ô\86Æ!\8bí×\81&1Æ\9aB[\99X\86\8b\10\12\r\84\8e?9$\87rÂtÍ=et\8bcÕiõ\12Ë{$¶mGQ³Ë\ e°\91 \ föNî`Uf\89\8eµDËkN\0\\ eÚ^i\b\15^éè\93C Lþ¹­\ f\ 6Q\98\eðø
-AË\0P\92üAd\ 6AÞ±\0ïrŷij)\86%\f`¹(wsW\ 3Çn\ 5\84\b­¼ºz\9f\85&8ó:Í@ü²\ 4²´\80;b\9f\98{­üeÿ:A\87Ïv+\1e\ e+¬"¾t\8d\8bÆ1ô\18\19y>m´=\88\9a\16@\0\15î\ eÏ8kÿI\19Äñð*\9amÙ$ñ\15\93ä¿Æð$\10ë$\8d\18ëô$\8e\ 1\98
-5\81\80LO½s¿=\11¥\9e$\0¿V»ñ\8f=Ãø\ eê\15.¼4âT\ 1\99Ûx!ò\11\13úQGþZpº÷º¥Q7\ 1µ)\18\föî8\9cÏÞ»<Hgy\1cA\98\ 6\19\ 4Ù¢I\9d\10*\ 1\87øUáÏ#Ð\90a\95Iq\862Cäe+» Hë¦Ðx\ 2©¤>c¤$o\93ª\r(3ê\b&\99\9c\133*m\ f|ô>¢^ó¹_ñÈW>"T\19Ä»\10ZGÚ\90)Z\14mB\19\1f (\v\98#3üÙî½õ$\8a1^Aî¡]#\b¨\r\93tüå=hdPp#8[\80\99\83\0¤\14 f\ e/$¶»>Ì-=
-Üf¡C¦¯Q\894F³\«õõ'2\97òñ´\88ò¾.\13\11\b¤Ü\7f ý\8bSRÊk\ZµÛR\ 5¥ÌyÇ#b\8fL\ 1\8bqt­ñ³ý \15gj<¶
-³p\18\87\ 4g$¿ÛD\86H¤Æ\92ÖV5\87W`\11n\82öx\18X³¡\84\ 2}\ eR\99ÄϪÁ\ f\90\80B&\7f\82\ e\8dD»À>\8bV\a_\12\8dþÆ\99y' ò@MÙ[Âëðih·É\15§\93Ú\16zÊ0\90ÿºú15©\ 3TáÚ{\a\8aä90\ 5ݨ\157gS.Mâ3\98Ö;\80\fÄ¡P\ 1\12Þ\ e\ 4JÙ1ø¼§G,\1c\9e:Cña\8f7Ü 1\9c:ó¬        Ô\7f\8an    Ò©ËY$öâ#ìÌ&ð¤\8dhº^¢ÜÖ¦N\9ctsöã÷    Þê\k\96\88Ö_)\9d\87\82\93u\11G\843\880K\ 2ä=\ 6\9a\15\ 5·hU#°ßùér-nÍãYÑ\9d\82aå{?êN>êÛb\8eË\12\1f«"^À\ 5\9eÄ85\ 3\ 5Æ'¹\80\ 4\ 6~¥´\8aj\90\81r_g\1c.\ 1\bÓ@KÚ®Ù\95\1cµº)¨Õ\9b1/,)5$Ù'r\1d\8e¾Ü\88 *IKÈp\84pqê\96}sÑp?M\101e#ºh5é÷pjÁ \7f'¥Æ-Bõ\1fiÕM?·$ÉÁV­µ/ab@âLµ*äu·\9a\175ídB» c\88²§;]¿¡SV_²Â\13¥ë\97e©i\99\93Q.}³ë\13Øç\80\89N-·ø~Ir3s\9c§\8c\9b\94\80«Ë\81ÉÜ$`]/\86Úzü\9f\1c\ 5̰lÑI\8fwFH$\8eE&¥\ 6\96ÌF\1dá\ 1\9aÙOü;^ôY¾a2,Ø\1a
-©æäÿi¸øéY©T¨_xα,Þ,ãÚø\ 3Cê46\95\16k°/²°LÄy£\r+!Ï~j§¦rE\8cy\8bÆõXÓ\1dÂ?ó
-)\8b\81\18×EÀ\0<\97\b\1d\ f\99F\17ND¥|ÜúÐ1\a«e\8aïÃÂ(Ês\8c)%\vêìIg©\9b¼\ 1ý ³\11u\12«v\82¿\12FÜ9;vÙ@\12u_w³-Qºv'\86_¶»- R/\84ú%Ð
-êð ÎÄ\9c¶)\9a\9c¡\9apZéܶQ\0\ 5â47¡a!SäQQ»¢\1cü)\14\12]áwþé¥0é[åMåâÁ®¬W-øÿ\8ay·4\ eþ#\12ùgãC\0æqdȲ\19ä³m©µH¿à-\ 3ÑÑ·nïVÕ0ÿ9\13±Ø\90]¶*üÐ5Ãyòó3RÉ2)a'\9dÀBð1«6\93ÌÌò'\etvhÐ\90$\89_Ës\93j"÷r°aÐ;\92éÊ\128ü)Ú\80j\81Ê\1e\89\ 5Y0$Ä\9bZ%ìFæ\19r\1a0¹ÆO\eøái Nzb­÷.H\99Z\ 5^.\8a\83\7f±\842s¤¿Î\87\ f×\ f\9d¥\99«ËòGçO\82íc6
-\16è\v\ fïçÈL4 ¶\93+i\12÷©\ 4`\8f½õ ¦\ 33A\9a1Õþ!sѧi\ 4úW\98%´Ö\16C\9a\99`µ-.\ 39\9b\ 1VYJõ\ 2f×*ï>\16\\ 5Ä\8d\93M       úQäÅqè\86ð\9a       ¤ÿ\14Þ{¡µ\94x\12:]*%\f¼ ù|q¦\1c£\81\94ñ¬Æa\ e~\ 1\14\14Y\15\r^  l6\90¢8 ¸&_®kU6>+©\86ÝÐÜ\8d¢\18\1eóJÉk\0ÍIª¾\f\97².\97¥\90!Ô?\8a\eð\aĤ¤^=-ã  Ã\ 6Õ a¹M=H       ­\86uD\8dL}®ªÈª¤ï~\12ËUÆ,£²N\vÃ\8ah\ 2¦ïíàÙäî\8d\11íÚñµò¼vò\8dø¦gpË{¿Ì@Ú\1d»a§\12\a\1dPÉ÷H \9eÚ\85]\8d.#\99®5¼ÄÛÊ_\95È© õ5\98\89ãqø<\ eë¥.\85á5aÀ©\168\87^"Ë-\81^\94¥~¡\8d¹Ãéw>À\9f\8c*x2\18\10~\85\ f\8fµ\98¶OfO÷wOI\8eÉ\9f(zD¾{r\82&Aö\ e%Óø]{+@´þÈ^\ 5ÕÃL\b\90òAÁhh/©-\89\8f\0f+ت<¥qøPNä\9e\Hñì\ 3Ðm&s0J\87à\0\ f
-\1a\ 3·b·`bê\81\87\1e\8e\84\94\a\8f¦)#xàMâüWr%q'\ 5a\ 5`Á»\8as¿'\8eChd\19®aeíï\9bîþv]aéÃ\8an¯²H¸`íÍTR\10ô=XM´{Á¶\85r×¶\1dd?,\92úê\1dfÊ9^c\88µ\9cx0lM\1d\9dø£²µ\1f\8a:\17U%\9a©\v\9e\bcúÁû´xÈB¸B6Ý%<¿\81Ùv%ûðI&\9di ß\15-\12\13\ 1{ÑÖZ#íx\89\96\81Âæ.m[eƤMf>jù\9b\8dØYðLÙï\a¿\81b9)Ò\8b¾û-\96¡\9a\8c   \14M\98\86¸x\0p°ÝrÔ\88   ÙÌ´¾ \8có¹\933Ý+¢d_"ï"=(W¨B\ 1#Ô©hD´;â \fKp\ 3Ã\86Üý@´´º¾\84Lr\0¤ç0\16,s\8bT\9c\85\b³çÆ{\8fç0\91\93VÃ8\16X¾1D\8cc\14®\86¢rC¿3\12\%¾PãD\8fxÆ+Ò¶\1fOY\87RUP    \97\95ÝÏó\94dÏx"»IX3-\17­\ eÙ\93ôÞôù=3\81`\1a\10W\ 5%áÒ $â.\91|\87\9eA3\1a0þD\89GHí\90\80\ 3h\rÄ÷i\81\1a#k±bn\ç©Ú¶\8diAÅ\ 2Úê¹f\15\9f\89ýö\0\a\ 5'jÅ\ 5ÅõÅ@sp¡7ºÃ\10Bdw\8d¹r?þ\93ïKäp&9Ù\94Ü¡\82\b^¹ÃW'\8c\8eAké\82ùþô\18¥º\V¾Zl6>ñôT,uM,\1dÍø\88êbzãÆ\ 6oR\8ab\1fU!\96\98[\12\14·\1e7e¡\8dVúõ)T\97\04ãöWÚ\85`ÅsôÙ'\9e \9fNâA\9e\89\ fÊÁ\87\16\fß{YÔ        Çbø\9aHlBÄþ%\14&§¥~Ã\NÝOør\9c1ì`\9f\95­$\84B¿IôoXI\90à©õb{¡\14÷ú÷\rpºHM®HÅ8\U\97\92)#»*\123"´Å\9c·\8a\96\93c}\ 1\85IP\98t¡ì¸¡\ 4\9a\ 4E'ÐY¶ë9×>\ 1Éì\ 4a¿JGy\9cä\1dõ»#Ú\96ä*»\9bX7Ï¿Ä\9e\ 5\14Þ7äj|/wòÛ\83[Ãê\12\92tÿ\85\94#³Î\\99\ fDÃ(=\18Î,ÙÔC-g¼éÉ®\1cÎ
-dÊ3ë|VE\11\rM\9b\10\rw¼Ö<Z\96\9e¥*\ 4Léj1Ö
-)P[?1\10k;ú\8b§¶\84B¾)ϬF31Ïpå\98\ 3ÖkÞ9[\9fb<QuÎLþO£\1föD>~ b\0±V\14~\AI\9cÛ/9\83î:Î\91í\10¾0ì!v\15/"õ#fz\7fz×å±Ú­O¥\ 3\14\ 1\1aPto+¾K\12W=WD°)\85\f7\90/£Á|wØ"=ìL\9b¾\8e!\80³\86\86¥Â'\86äÔ\85´T[6¡ÚðßKßÎ+b\eE¥-­KÞ)5ßw$b:7\8f#\8dé#O¥ý^ÍÉ\ e¯,-{ãe¢\8569\12\88Ûâ¸P(y\96É=­¨Å\80\9b/\8d\81ô\8cúÅjÁ\9c[\r\96\8bû5\19\9b\80\10:\9b\94wvqè\a\95"\8b÷ø"×e\9e>öxð½\98\92+\rLBÓ\8e"húk+\94±è\17\19¹à¹\11ZÁ#¾>\13}Ë«´k\94ö¤T»È\85ò\82>\94\91\93Ê£m\1f³\1c\10½ì\88g\1e\95\eØ-\1c\8fB3NÛ"ݾZ\v}Ìצ0 Ù=\90ÄÒ;ïæ[Ýa\90/ùdÇs±Õ\1dÜ!qñ\82ÎWògÜ#\9a\87G*zÙó³Ó¹ãL\94¾)6Y}\94*dµ\94YÄé[¼ÁØ»9û-û\1dÞ¯5AF\ 4¥\ 1\194G¯qË^XK\87Î\rÂ\80Àjì ;Ða\ 5¶1H0Ö\89áÝÍ9¤R|Ot\89\r\84\8f\vÊè\ 3\8cvÆK¼¹FïcÞ©\9b©ó\15\8d\8eàGjº`Ñf ê\89\ fn\a\9eQ\99ü\1a\16\ f¾=àj[&?%\1e\ fÃÑF,å\8aI;·®¡F°ð.åî+\83\18xEÈ\1e!´C\12\0kd^A3Ä\99Q&E\91Kþ'ýËÜù>tÎ\ e¸X©r\88y>\9cÓ+TÆê\82oK(Éx®ÄÉZ%.7âºÀ¹Y|ô6\86Üç©z\84\82(>áè'\92\80J\84oëUBõÇejG×
-3\80\82íôDûñ¯\7f\89ì¦çø\8cØÓ±\11\eióÅbce\17\1e¢:0¾\f,;(N\vdòGÂ\{\rKÄìl\r_\8d*óÿèÆvÀw,/e\8b\aéÀ¨\190\1a}\8bâYqÜ^ËÔÍ\18?´#qÅî|$\ e®u\18,ýb\19\17ÐÅd\8d\9e\85L­æg:\8dÌl\84AD©7ëc`ÜB¼g\92ʽuÐ[ã¸\ 2d\ 6·V\9b\1d$_&"\17ý\ 5';6I" \92²¥\13IJ^\93ö\87Í,sH<\eÕ\0\ eÀoÔÿ\9d\ 4\1e\v      %?¨HIôc"Æ*ªô°N-Î\89\ 1°D\8fÅ_\ 5çO,\96\95\90ÉJ&Ii·rfi(ÏÚÀGÙ¾iy\eC\eÇ\18·Æ\9b\ 1z\1ax\8cO¢©\98\f¨éDäóÏcE´{f°#U¸%}\93\1e¯\1fÀt\1c×i+xd\921\17y\ 3­ïÏà\98©\14\88 ±Ð\18\1d±À\11ì×\8d\8cJ|-A\rÏè\81­A\87È×rêYÏ\9fâË_¡\98(YÖ\13f|qÕ\9c'c\9e\18ùÄ+n¨\r²
-\96HðlÅhWm\ 2§ë8\aéÍÒ9ü4ÕÐ\13d-k¢Ü\81\0\86¬\8b\8f\ 1¤+\91ó\81\9a/\7fù`\7f\ fv­äÄ.ÿúSA"a\7f+«¹ýµH6ì¢\8a¾\9eê\8b¾­¤¶\ 6\88på®ñ\10wtXM,\8f\8at:\86<³"\14¬÷à\ 1X;l¤%~\a\81½\ 3)\16­töî×\8aÌ1\15(ÕGC8ñ}Ó\ 2|Q\15»G\19ÆWU\7f%FßV\86D\1e½-ZÜ\85\17+\14X\88\99< hí®\8eT±ö*5Þ7x;\89Æðåîb¦Ø#\ 5\15$j\15>D3À\vÛaD¥Zd\9b\8c3² 8n-ÛZ\18s{îíW\93c\9f\16²ØÊ°è\8a\ 1©Õ8z
-(?Ä\83\82\8b\ 1\bdf5±\8fE0¡\ 52D¼ã¸kcKâñ®¤uà\e\ 5\v ß>Âs °\8a\93\8fæ\e¬ÿ)Äæ¦\9cKÂGPôߥ\83Q26\85ÒÔ\8e\81Ë"\85%4³¼\8c?\82\b\12¶l3=¢\v×\r¦¶·óh\ e\a<= \198EBÇ'øgÀ>CØ\18]Ö[à+å\14\8d5{ìû-ð3\12\9b\ 5\86\14xl3väh¢1\12hlö\8f\0\ 1@¿w t°%:úF\98|l6L\9eº\8e@©2®#ñUg\82ÿ\98µîÈ·Î\bê/×ßû\7fq#yÀ\87qàñ ØÂF¥¸J\vð|Π¯\17ÝæÁ¯\98Ç/\11*ïiâ^\ 1\9e7Om\90#ÚaÔ\8eo\87â5\918\e\b\80»ITC\8b\12\9aOê!ò]\ e[y\869\bÛ.¨Ç\19Èȱ\10ì\9e\ 4ËpÞeÛâW6ÝV1\87\8d\ 2k\10\87¶Vû<ªvX\bl2§@v3v\0I\83Ñ\8aÝ\83ê3!s\1eï¼"´/\ 6\88¤=÷ý\83öh\87%àOz®ñNq1n\ 6g\8b$ 5\13ÿþ|¹#É7Â\b\eUþ¥5\9aósû\94÷»YæÇ\88ò. ã\9a2ÐD5\9f\ ey0¾¸Í#Nª\9a$½ÚÄ\83\88ý\8a\1ariÄêè\99\96é\ ef\81Xëãzkû$qì[8\8e®Uþ\9e ï\1c\80Æ}%¾ÙÎ|Îá- mWgPP9¹\17T^7N81£Föy´¹jÿÞg'\14\93øÀ\93,\99\15\1ceCÊ7'X¥7½NRÕ}\97\7f ¸áP\82!Û'aRByh(mk.Ïú\97´h©é­R"¦\96¢\15\1cîÈÏs\f\ 5'\91ÿ\ 3 ^°Uè0Ù$\98\80#\1az:\15\9c\11ç\91\80#¢¯ïX70\16\91\vw\ 3\916\12ð   \9c´znÖîÍhÓ\14ÚÈ?\bµ\82ºº\9c\86\91\8bÏ\81\ 2 Â\10\18¶.ʾ^\8dÆÄY\ 6Â\82`íñ5Ã]c\913×y¸Ú$>}#îKL¯$ÎO<·s\12\rä\0\ 5Ãü´ßT]QX&ér¢ù;\11'*\95ë\1cÌM¨Ü\O\18tÐB¸+Ü7\8ec\92ìúCýÄ%sO\94¾N\88\bÌ\90î«{vX|\ 5\9er*\82%\12Ý.\ edl\1cI¤Æ\97­U\15(QV\1eÎ\·\9cÈkÄ®då\95DM\93\9c\9a¾pä«Þ¢\85åö\19ÿZKGº¸ºq\12~<D\9fpÓÓA\8bóFì\89Q¹Ïe\ fyÉe§;Îýü\ 3\9b\98\esZ\88H.M\ 6\9cÿø#/ñîÔ}s\14\11c´ET\91\7f4zó\¦A¡xUW5Ò÷ÔÏØ"\9bñ\bYñQc"fCê>\18»Òã7Î\116,¹Sg\ 1çO°â\15ÓS7Ó\r\ 6\87èU1­æ\ 5¡\15BlB\1f\8d\ 3\95O^x\856´;áÉ¡àÐñ\bcò¶\88WPÐ\8bÖ\81UP}f\0\r\84è\82\87Ûq\ 4§\9cLoð}\ fW\1cñ\r\ 1[\0e1|\83\1a×»\ 4\80ãO/Ä\bY(¤\93Æ5úav¬ÓA0jò\9c\17æ/¤U\eÙ¿CÝ\89'\1cãzZ\v®I{\8aªÏL\15\89Ìb\96¯lÆ\9c{\ 1ÿÌØYüØø©g\9a0\ 3¿¥h\ 4¦\12;ó1~%ú"Z]Þ\84²\ e+º?³ÜÎuþI8iñ\82\9f\80z\1c\930ÄsË-TÈúØ´\15\ 6¶p\1c\r    Ü ×eº\8c¤ùn ½\ 6ï9ºÃËÊ\18æ\ 5ø)\7fM W;mBßæ\9b\ 3WL0®hE%Lè\ fï\8bdônïBÁ\9e\8bK\f\aè`\84ÎIx|ùp      NÇ\88E\8fFS¦¹ìHh\808.\97Á"o\91\17VW3\ 6Ãaά¶®ÈáôK\82õ\8c½ío\1eÒe'\15ð¾N94F.@\9c\87\8b\18'\ 1¨\87ã¬\12\82[9§Yúßså\ 5\1dÊ\91²3ÌX«\v(åjsê¿\92ߨ.ýð{Åúqî\rΣb\15¡iâÄDyK4 Õÿô`\ 2ª\0z4Òe®\97é3&\ 6\81²±å0§\ 5O\1a1ñã    ø Ìqéu\aàªbÿ
-):\ 4wÞù«_vAêØÈu6\1a\v\17´<\ 5\8eݲCÄNÇxû·¢\12Ø!ý\15ÓfËkllB\0Á\10ÖG\87Éë\rê \88Â#±¥1\16Å®Y|\15\83Ï]ðs,$ç¯D¡3\6\88å!$\9cȪ\ 2\8dïÜ×\rä\ 4âv`S\94\12ùgdûÉ\84Ö#\f®>\90¦«\87%êìÎÐ)é\93Û%\9b\14ÙzÞÓm\e\7fPݾà\8d\15x0
-"/ÿe\94¢\8c6Vu\ fßßÇFj\15Ó=\1e¢j³,Yó\94 \18\f\91\9aÒ`Ê\ 1Ú\18\1aì\b\aÅ\e_½ø0@37òùºH\\85Ó:\18\9d[h\ e°\18\1eü¾Þ¹þîý£G¨¸xÂUH¦k\9dó\1eK       f\88E)|%\94LR!ú\90fSaD=Çn\10©A\86Eê¢L«¯§Ày¡Û\12?
-ÍGYÆc\87<¹ûW\ 4í²«:µCù\1eHw¦\1fÛo\1a%H\9f\87\9cïênÏ¿cËp\$4Ñͺv@,\9d\8d\923«ê\82V\ 3R\8b\88[íJÀ¾}×Õbå*rÅ\80\9a\82\88"eg4¢½Ðd\1e¤áY+ãûÇ  Ädôrå3¢¾àÎU÷(\eæð\9dP±°8Dø¦ÊÂ\84øL   ë"Ý-w]Å\98H×X\19È\8d\8ep'}C04o\1cW|Õ,\81U\8b\88¼õR\1e~'¨Æ\\8bØ\1dS\99G[bLÍ \v\93MKpò       \91:ÀÍ    a\e\17¡\8b+u¬Rc\8d\ fF\9dµ \8e\ 4
-p\eÌßQ\96©LµÌ°_i(\aà\võx@è\97eºrs\11¬Û\bpOAl=qhß
-Àí\rêv×on\90\12K\8c½ Ü\8e\11¬4\9c0\fõoh6¾rÑ©Tm\1dô'\80CZ¦\ 5u|v\ 6\8d\12\94I\ 6øóC\1eÊ\93ÿW²ã\8d\1c\ f\12ã0\13åMÈ»À\82`˳²Lð\8aþT½Z«Err`\16yV\18}xeH¥âh¬\13)\aÃ\ eù\ e\9bË[`Zº\1a\9d\ 3\83bC\8f Ç\ 64®²,        ï\ 50,n­¯\94\19W
-)`ö\ 3þ\97\8c¼e\b\84ÆúÓ×\18\8bÖX{\97\86\1eÊY£LΨÌ\aDr©±7?ÎSnàX<\14ZwÆ\9a\82\85\*\86\ ev\ fö \ e\8eR°ª\8eY`Ò«\ f\fDO\8c«mµ\84n\fÇ\15àà\88¯ï#Ù×c\ÿ `«<¹Ó\85\87Ù´OäÌϺJ/\9fJ¶0§]g¾{ÑèÇ\9c*@Ƽa\8c¸Â%¤M¢ÖfHÇY\1cåaÜïi\ 5\94J1k°Z]3þ\86\1e¼\8f[\19;8\86ó\84v¶µ\8bÁ4WÐ\8dW\aáºÝî/ê¤/\e\ 5\8cË"d\92 ·Éϳ8$Ø\b0ÃZÙ`\v\1a1ÿÂ\1aÒ´\148ïÊûymÕcHO\ 6¿q\83pªìmÑR\ f¡\8b\96®\ e\95)4\85\r/1+h|#M6O\810\14ìu\1e}g,øzÌÜÉY\7fa]=JèÕ\7fy\98\85\ 4çú¬E\952¤ô)Çq(9\ 4ê\7f¸¾¹æÀGì
-\90;\8e:!\9f%J:\81\ 3ø\fqe\8c\ 1h×F¿\8b³æóùo@\ 3åvBl X\83)\ e⿪Ë\b\9bÄV\87¥\1eX\ 6®NCέ&K0K\fX,±Å\12\ 3
-\95û~\19\12êO\9b\96v²Ì\18\80&©qN\91V8¶KÐ\89Ów3Çäp$5\12óëÄÆ\94_¨ÒófÙpw©G˨ØÐ\9a\ f6d\8e|[ä\ 1ë:\16\rê\1f\9f\12Z,'þ¤\1d\84åñÝ\8e\19~ÍøqbKó\9bË\1c\142\1aúÛqX\ eÕrWc¡\9büG \8fJBc\9fC\9d@º"\ f 
-\rÆ¿ÉWOð\7fd¶3Ó\b¸Ñ7fJ\85\87¿\93aXY\8b£/\ 3³ã¥\ 4¯+\19v\90\ 1\ e\11ägG]×ÁE\89\9f@\e:3dªÌ-¾ä\92\8a[\18\98xG\86_[G\7fCµRÀØ2E¹ ò\90³\89¿¼´³ðßSÁ\97ØËl\1fz\89Ô©(\98Ü~\83¯vª¬P\86\8a\8eðYøI\96~
-\f\ 6,\1elÒp~d\16\ 4\ 6Í\8f´\14izËC\8eR\ 4ft;\fÎ\v\0\vâ=\17
-ΤL\85¡Ô¯,íÿæý\v#\11j@âÂ[O\16²z×ï«X\ 6\83B¸Z0çx/Døî²Ï¢ïã\1d\9e\9cA\14T@ð\ 5\a\ e\16ò>G`2ÑÆô¹"©äZÅ\8f\7f\1d|Ûy\11Õôò«â\88A\86×\9de!`g,`\12,þó\83Z\ 3\9f\ 3V\8bO\1aÎ\v®ÔÝÀxUj\a7\ew\15ÁR\9b!ÏÏÊ<(
\bZ¼Í\87\91C¨Ê\9fúÌ\1fÇ ;Y±ªüèÓÊÛß3È'|çh\840G\95\91Z|=0BßÂ\7fØ\9fR2TøòëVC]Ó§C\14VZÖÁô\17\80'\b\ 2\10§¤
-Ú4$Çóå\06\a\7fçBFH\rÆqð\86§P> ÌÈ\83i\f   \9ecʲ\84ö+$\ 6\10ôQHh¾|æ\9cF\arZ\13M4ry¥£HJ¶\ fz\87\ 6Q\f¯²i<ì\a\88¿bZë\87lUЧñìf\ 4È{q\9e\98Y\92ú\80¤º\98«{\89\9bö23pÛ¿G\9bï6Hë§å\85Õ§o0¯â\8e$S\18\b*½­¢\ eÕé"TÝN\15íg±6\9aÌ2qUò\8d\17õC >\80­©\18Ø\9d Kn¹\e\90~Wâ\91êkÇM\17\0)\97\89ü \9e¯èesq\11DiuCØ6vâ@\9c \9aÙø\96Ü?ðW\8ab\8d\ f\84mJkIvrnä\10×\8c7\89\11ªa\1c\e\9cn\85Ã;\12²«À*$.¾F¾U\96ÄG\1dü{£¼¥Çóá\82ô~Dê\11\11¯\10\83\10r\b\19ÉÏ\1dC'ú8Ù\1e\84ý¿'§\86t-r\10(²Óáò\8d\ enkú\1cq»WÇrt\ 2eÓ×´´1µT\ e£ìLëøe\14\9eó>\97\´Ï\81OtÇ\9c\88PlýØHÝ\84i\84q|îá\84½kÓк§Û\1f\13©2ù\87\ 3ª\9f\bfóÁ_ MÝ_ûNI¯\834\få­zÏíÖÆØ\8c\8a]\07¡?\eêØ_bôä~é\pN#Ð\ 25ò©ÎÿJä\8dgt Ì¸\12ñ>ÐSó õÌÖ\8b4V      Ï\96k¿) \1aÒ
-ئ1ä¿G¸þ¤«\89eøcô#}¶\15\85àE\1fµ%(f\85\81ï½Ô\eí$3+©Âhü\1a\8eÃ^ø\9b\10:\9aþ«0NA\81\ 25¥xw\10FÐÏ\163B\rÁÆ¢]ußúë,µ×\15·m¬\12,õ&Ù\8fÍ.}\81\83¡iy
-o*¿AÛd}]2ôÎxM²¨`]B@\94ÛJ÷[樬@gár\7fu\ 6+\87¸ð\87l\0\98ç\94bQ\1cÖ\14Ó\µ\98\9fn\ e´\12(3H\85Äékgf»öÉÝ?½ì\83ñ/\86i6\91\88\8f\18Zz)¼#çÃøq³\19÷\v\8a\8c\fì\r\ 6oï7å\Á
-üM
\84·\13bOÙËXbm¹mV\97­M\17¿î2\87 §X\89\18\17Рé\16G\ e)\91\18°á\86î6f\8c\96aäï!np¼n¨¿\80Ó\96ÌN@Ä\90å\8c\8dísÐ\16\80ã\\95\13waÌ.åçï\ 1BwLtQÑÙJ\99\90b+\86B\99ÿßJ\94\96\8e\93t/_\1d`\ 2Ão\11ã\fù!\6\88Ùö)=¢]ù}\rb\f\9c@¸·Dg\v\91f\7fR\95^³s\rçF\96"eF+\86\10\1d\ 4\91¸ð8t\873ÿ©\8c¹,Z,¸a;\1e\136d+\ 5v\96\96\r
-Ät\88ÖÍ\14P4!\ 4     G)\0P£ùÖ &ÔÚ\ 6áö\ 1}B ÛÝ\1c¾\1e\92Âu\96bNæ¼¶È¥\9a\r\ 6Ez_N¹»\18\12\96ÓÌ\ e\12\0*\8c0,zEU#3ây[éÍfR¡!äÉÌÂáN\17\9a'l\ 2\ 5       Þ\8dï­ÎæAÞô³âÛ\f|}ù\8a=\1e¢ý\8d\ 2¡Së\82£ûP\8c^@-%qqèqÓ[T"\9dÚ_\8fbN\\r\12s[ò\ 1dB\19\8d-#\9aø*Ô«¬ã>AóÚá\8aá\8b¢ì/ã*Êâ    á/?<\9f^Qɬ(k4\vU)Y\fð I\8b£\1c\b¡9Ù\17\1d\ 6M\80;O0\87\87{\ f\99Ð\83o\89\ 4@\9d\Î~JYAt\85¯ïv\7fÓ©\19\86\88ôJ\r\vöá\97\8f²ÝïxqoΡ#\8bÉùêß~Ð\ 3ð\8a¾\19¤/ê\14y³ÕP\12¹ãÒJÐÐmc 0ÝBàñÆ\18*\955t\17\9c\1c\11n²èÃë\10ÅSK\82p\80q\vÖãæÓ@\ 1Ö¹ä­\1d\88Æ\ e\14\85·9.ïäí³<ô\82°Ô?L\97GnsxÌÝ\8bpZ\9a\94gÿ\81r  ø\9bd«ÈÁ\1a Ê\96\r\8e\e5\ f\1e\15NO^7\a¢Û\ 3Ùø"\88jÏ´\94\11\82¤\ 3\12hêê\89~Gá=ïæë\120°Öóp½Üܧ\97S\8b\13Z\196Hcì\82þû±\8aµu^\ 6Lo\P\8a!\84K\87Hc\18\12\17µ±  ôs\96ehDi·|â\9e/
-Ñþ1\10] k1\8dos\ eâO¼'£wí\8dY¹30 Ê>²\11,\98\8dΠRë`v.\ðDÚ\1fæð}ì áu¼URqÆ|)1\88ßðº­\8b\9aÙÀ$C\19\97\r\8e\87\b\81\8fµßa\8c
-9\10¾\1fÃ\14ù̹C\ 1\9bÙ\1dQ§0îö\Ú~â\ f\92~®"ŧÎÀöÍE»e\18ê¸] '\86Érê\86\16\85Ù÷0g%M[pn\88\87x\b*@-¼\92\99\19T\aLáé\87øåiÛxà'¾E+Ã\1a/\8eâ{\82G\99\17\99@\e¥o\90\ 3\8b;\8c\f¡{ðÙ7\83´}\8f\19ÊÐ1åm\ 4#H\vWL¤wët¶÷]?3x\16`\18htq+  ßX        ã+ª·yl\ 1+2Õ\fãdOg8ñ\17¿\9a\81\97\r\87!\ 4½9©ãÉ\92Æ\90EG\ 6\ eícB¼'m\81ôÛ\84ÜR(
-6E\91À\95þ©\b\16Ú\aÕ\10\9aåN0t
-\14\7f<ή6z¥ÇT¢^øÂ%\9cÀß3|]\84\92£jt8\15u\91C.%¼B\87»Ýn \14\ e\92Õç\83Ä\18\ f¸mÁ°bQÁ\vÖ\87\rUnÀ ¾fö¿\98-\e\83\10LOmð­Zß\ 4/Ññ\88Õ\80Ø)+ÇÎAç× ú¦Ù/\vk|\ e¿9±\18ç\9b*F&ã\9axàñÜô-Î\1c\8eí\ 2ø.@êìe"í'À\r!9ªx\14Ìxø\v
->û\91¯Éú­;WHæ|,öRW5¾\1fP:Kt\8b>\8bùÇ\85ñ\1dBá#4çÔ\8bßÎ\199ÛÄiö5[e\93\19b\0(8\17ÿP*
-äm\7f%\0`ðo\elÑ&ËÃ~K\91±Ý\92\16³& ÿ«12?w\12C\1cä×*3»Þ\1a¢éC Æ»ª®ê#0`ïäû\197\7f2T^A\ 3nÈòÕ\ 2\rÔÔ=²\ f:3Ö½»\a-å{ø0\e\11t\ 1Û¡\83Â*oò       a\84ÒúñDÞ©\9c\87,G<Y\ 6|X\96êg T,)µþÉ\ÛP\87f_|#5mÇnÆå\98¸\968©GH%Y\8a&\ 4âÿ,\80Ê}&÷¸8}7e\91K²ëD&è\lÀK5\97\85ÃÀ\94s(¸e\19#E©±\1aÕ3üTnOKð~­\9d²¿\ 41ªÇ~\92«¼]ÐÙ\84ñ\86V\85ð¼\19\9aE<õÏa\88p`&\1fjkre¾âåKÌ   ¾Ræé\e\9d\ 1\0å>ÍU\ 4Öf§iT< [ò,\ 4½\84
-(ôØÍÅ\8965Ñz¦A¸\11\8f¢\1cT|³àÆÒxJ^\18C\944MXÏ\8e¶@C\95Ü:]U³«\ 4\8f\82ù\961["O\85#ö0£\9b\a\7fÊ1\91\14#\1d,
-)\89Ïê\8bùDì\1fã®áÍH\8bã\9e_ݧ>¤«[ ñYLAw¥:¥¨\83zá}\ fþ$\ 5 8\83\85\83àÄZ\9a}\ fý¹©d\ 2\ 2»\ 3\9a\85%e×ü\18ís\95ølý~|EòÅq\84\87\90ù)g\9dG\9aM\7f¬cðºq\8d\1f+,uçKîj¦\96\94xB¬\82q=Rèf§fúd\aÆ÷S\e®\93)\8e\84«\eWÝÐÿjY [\\160«Wl\9f\0X _!ñ ôIZ\83nÝ¢8\8cI\17Âl¤\e\14BDº¶eAѯhya\82;ÿ\95Q\ 5\16\rà&É\87\ 2G\1a&"@Þ\91q\ahmäû%Óð\8faïw\ 4í(fÿûã³Ï\10P\97\ e\85»ßAðcGéâçý%\10pú¿°¾\90&ö¿"\89ñÿÊå"ä¬\ 2IAýD\10\88\15ä:\91ëÒ
\8ep\10´u"\84ö
-¹Ñ5\12\16Êt"B\8d\85Ú\9aÈä\12\13©X\16Ì,\11*iLÄç³\10\9bQ\v5£Ø\82B©[\90\9dn\8báB\9fÀ\X¹X\17ÌRß\85^KD\ e½ÐÈ\9a\17ÖKï\ 5_ß6hY"2\ 40T\ 3p÷_@-þ\85\8e'\87¼¿ ô\18\18\83A>\12y\84a |DÒ\10C=\12\91«\18*"g\f\13\92Ç\90ô\ eP\1cÃe>\b\ 3\1d\89\ 4\r3\8cû\88\Ã}f#\91\f\ e\8bÈ=\9d!vÞgpV\86\86Ú\88\88䣡K\v\ eÁ4¼\95¡\86r!2\95ª¡s\8d5\84S]\83Q-±¡¾j6P "!Ö\86y!rêÛ\90;\88Ü \e\1a\81ÈÁxCï\87\¤o\88ÿ\81\83+\1fÂd8ØÒC\18+\ e\10æ\1e\aÓË\81\8d\86¬\9f\1c*ßa\ eÁ=ç`;\87\10\13:8r\97{\96\ eL\92êpwCîu\1d*6ä\88e\87x3~·CC\réõîÐ|\86H\0\97!2\11\ fÅc\88ÜÈCi\18¢|<´,Ì\83¶/ä7\9a=ct!\vÄ\83¹\16B\80=øb!\94Ë=\18\11%s\85\ f6T\bIù`;
-a\9c>\18}B\18î\83­&\84QùÁ\19ø/÷C¼+\1a\ 2\ 6\869Bòçb"\84ª|è\15B\1a\19\88\8274\11\84~x³\82ðÌ \91ä§ç  ¹@¤O\8e\87ª\ 6¹aÌ +\e!ú0ÈvùÕ\ 5\99a!\1acAÄ·5\ 3ñPAdÔ\10Í\13DÕ­\ 41ñ9D\17\16\1f"f~ÀX\8d\13\85\93\82 cP\11Í<\906\16Ñgº\b\11\ eäö0\82;\ 3\893#Z/\10ÙjD£\ 2\eÑ\97@êÎ\11M\bD\16\1eÑr@TÊGô0 r\81Du±\9e-$X\ f\90\94\14\89n\8b\85\8c?\10Æ)\aj\94\0ÊçHT1\80\ 4E\92\18\e\0¹+K"]ÿãì\95D"þã"2\89*úÇQÔI4¾?î"\94\1f§^JtÌ\1f¯\95\97øcK\95hy?f]\89\ 6¶Î\12}öã
-.\11U?\8e\92\97È¡\1f7Y`" æ5+&¸1?\ 4L&ê\1f\ 6g¢ú´Ò\843\81e\13q\98&غ\8f\ 6¼&Ò[K¿Ðù\8c\9b\0\82õN\a'À±\8ffW_\ 6Ê£\9c°&\94\13±¬\19úÉ\9dÈ×\91¹y\82dó¡\0\9f(-\1fkç'*ÉG\8d\80¢l|ÈyAQS|H\80(\14uïÁ^¡ \13ø\88ÜCÑ\95ï!ðDQtÌáæ0\8a\1cE9÷xJx{Ì\85\14uµÇ"1f3{ô>¥\88a\8fv\\8aÔõ\bT¦ØX\8f»»)\ 2Õã\1cì\14±|vö§p*=d"**F\ f\19HEÕè!±   =¼e*Â=\8fæ£\8a\94ó\88êXi\1e×U«È\94ÈÛ\ 1\rV\8c0\ fÖc\85»ò   Za8y0³\15N\91\a+\áðx\90TW\983\1eL\93âá\ 5yE\9eüë\ 2¿ð ì+ª\83G#Á"\16x\ 4Â°Øø;N\15\8bJ¾ã\84c\11Ò;NK\16mkõ\85\18\8cåe\11°;Úq\16å¹#\f\83\16ï¸ã^iQ};\8e¦\16¥¶ã\f\\8bfí8W¶H7·\85iõnÑ\8e\0\17½Ì\8e5qQ\83ì¨t\1cvX#¹\bpÛëµ¹øø\96y\9f ý$]ää!Åú|¡u\ 1("öm\17ÿV\87²ßECªC\1aò¢5\9a£\92.\11£\17Â`«ËÛ\và¦Ãy\:ªÈ\17´¤#ÈöÅàè¸\¿(\89\8e+ú/Z¡ã\15\1aÐ1sÀ(ø\1có\10\8câ;G\8d\1a\8c\86\8e0´ô\vÃ0ç\88\8eÃ8»9®A\8c\8e\9aãZ\89\91\979Nv\8a\91\ 6s\9c\91\8b\91p9NUÆè^9®ìÆÈ£rÜpÇ\b}rÜ\ 1d´,9N$\91\11Sm~%\19\17!GU\9b\8cÞãèê¥\8cF\8e#¬VÆ4\8dã\ 6\8cú0\8eã\7f\19\15\8bã\8aÅ÷Ä\91\83fh\ fq\1cÖf0;\1c©~\86#5ΨU8*_g´\15\ e%\7f\84Ã\17=£rp´ÙÏ\88\14\1cá\ 5\8d½Àq\98C#øç\8b\86#ÀA\13i\98ù\e\9c\95\86é}\83\8ak\1a\1eó\rZ\92î\r\1fø4ê©7\82ßQãcÞ8ma\13\1c\12\16o@8«q¼\e\97|vcG¬ÑU7&_k´Ð\8dJºF\aæ\86âר3<l(\8f\e\18ìáFÌâ¾\8d\1c\99\8d\86n£*Ú¨ë6ôecÛ0¡ßØF­¯6Ð\93Z\e~0º¢6\92\91\87´ÑõãF\9b\8c\11C\ 5ÝÀm6b\9dÝ\18*Ì<P¼\ 1O²á]o\94\8d\8d\eMb#¼¿qNØ8gàh\ 1l\9cèÁ\11èÑgó\96¢EA©)\1aÃH3\84¯A/\88#$à \14G£yÊ8\84T\ 4{\ e\bv\0\7f×pÔ\9bkøkÐ\89\1cGº5j§²\9dÈÁµ\1cràeÜq\94 I\16ÌãÐ;\\86Î8J22\8e\11·Æ\rÆ\91\7faç÷Lk´3\1eék_Â\8bã\91¬ñÅ\aÖØ\fã((á\ 19\8eS\1dSY D±ÕHPB"¬ÕÈ\87ã(¬\1a/SF5¶/\8eúé (°NL55\9c0\8e\16R£}"\98\1dj\18yqð~\1a15qL\89ö:\r\93\8cM\ 3ùÄ¡Å4\1eÁ8ÈóY\96FzÐ\93\86\86\89£áÅ\88H\ 3\7fâPîh¼,qPÊhdê(\1a\81&\87F\1drBùB¡\ 1(ZÐ\98s8*¦{²'\e£ò32/q´ýÄ\85e\1c\15ÅPóÞ\19\8cv\1c]P\99åqÌ{¢õ8Þ|Ì`%Aèf8_ð±\19\1eû\86\e5\83È=\ e\97$ù]\1aG\1c`±âø\a˨D\1c\15\1a3z\80\fÇtaF²'1Ëj80ø2³á\98s\19·\848G-#;1,CiÁÊ\bX\9f2J)\8b2|ä Ä\93a\88:\93\81«áP¤\92q¥     É`²ÇÈè;\ f\19Þ\e\8e\90\ 6\19\11øý\18\b\1c\ e\8d\1eã_\9e:\ 6\85  G1\1c£RÂÑac\b\9b®g\8c5¸X\1fÞ7²UR\91ôöb´Å´\18>\18«\18H\r\87JQ\8c\17J&\ 6wÃÑþ²ù\93\19r)7Ä\18ÎíÃØuÐa\98K\1c½Ö0\1akÅ0\80&\ eM\16Æ\9b\18
-\83Ãñ\b£aù`8T5\18 ÆáÐ-\18ÿ\f\12\f\92%\8e\92\r\8cf\1c\8e\ 4\86Î!\ 1Ã\ 4\88\ 3?Hð2ß_\18r8B;6\1cåº_ô¬å\17.\ eGá¾è²Ä\91m8\1cÕô\85¬CùÂ#\96\vK\817T\10Ü\vÖ.\8e¼°\17\8dµ§\17@/\ eÍóâ\8dXyÁ\91M±OÌ]\88ú\ 5/\92\eÝ.\8eâ]\1e\ 4ü\7f\89£+^(X¦Xº»8t\9a\e\87\ex\11àÇ1ÿ·qx[£B"à#\968>\8d\17G\8d\0ÇQ\vwÔí \ad¦ä(¤N94ÞÅ\1d\97\83\8a-s\18î.bçæb¦A(_A7\0\1d\9eã¯ìBsçº0âæ¨§.ú\18J\17à6\87>èâ\19\1fç\82\91ÍÑñrÑí6GÑ\15É=\eP\T sx6\\10\1fs¸       .x\8c}\vg-G/y\8b\81\8b\v"Yp\v\19-Gµó,\a²¶\b\98f\8bkNl±xÍQÛµØè\1c½Ç¦Ð¤Z\98M\ fµÀ÷9TL\8b\13C\a\88ᣣq<o\ 6\141\1d\9eÏ\82±P\87­§ÒY¤«:Ê\9aEݬ£`Ëë\90\88Y\\8a\1dD\96EÔÙÑCY(^;jG\16;a\80çcQ\0îh\1a\8b\8eÒ\1dyÅ"VÞñD,\ e¸\f\8bE}G\rÂb\ext\ e,
-\f\8fÞ¿B±âQ«¯Ðx<:ö
-\81\93G\1f¯P\80y\94#µ+r(\1aDW\18\19z rE`\98\1eó[qnÝ\91\15\87½\1eÙZq7Ì\1e­´âþíQpVÜè=ÚdÅE\83\8fX±âÚñ\11\ 2+Nuùȼ\8aó\80>
-®âDê£Ï*îÆ>Ú«â2¦ªb¢ûè\98*vÃ\8fn¨¢2ó£Õ©\90T?º\98
-\1dïGG©\90Üù£\0©Ð\ 2ÿè0*´´\10\15öä?ÊAE\v\ 2\90\büáõ§ 5@lz
-ÊZ@,l~b\81@Lq
-¾Í¦pb
-$¡)Â\8e\91)02\10ý\97âë\ e\84\ 2\11AÊ[
-QM\90ú+Ŧ\15¤aJÑzAú\9d\14ê\19¤F9\1cDMR<\99\aa\8b\141\82\90&H¡Â"¤\94G1 \8d£è¿\12b¥cÀ\ 4
-q|Q°©\10\9f\15\ 5+\v±WÞ\854M\14ÊÞ\10žº\90\9e\1d
-ɸ\0¿$C!­ªB\91\e\vi\84P\94@\854\18\14*L\10\14α\90Ì>ó\ 3\8a
-*Ä÷\9f`ÄBÌú      B«.Äß\96Ñ\11C¢øÄ\r3$fO\1c¥AO\f·\fi"O\8c\r~'*´\8e®¾do\9dHzH'jS\86\98Í        :%9á5Â`Ò}\8aM8\9b\86\ 4²\9b\88\10\92A\0J\1a\9b \19kMt¸¤&üg\93&p¨!
-hâ¤n\b\ fg"­"\19\8a\&"Ý\90NÉDÍÂ1á\99\e\92tb¢CI\\ f\88  \98\eRñ%j³¿KXÍ!Qæ\12½(O·Dú0$@-qÒ-K,Ú
-K\fOy9®\\89\ 5\13V¯y*Q6\88\91C~ñ\94h(\87ô*%:0\1a%ÀË\17JLnÕ'1²ÓI8²l\12å!\87Ð\98DÈvÈkIüp¢$æ=#%±ÕCJ\12\8e\1f¶k\\90\84\90\10\8f\7fH[\17\89\88\ 3X"\81UsH\fÙCº       \89Eÿ\902\ 5\89"!R\v\90\10/\11),¨¥\8dÈ\1c##\89<\97#*Ò\12 ÜÚ´\1fÁØD8wDÜO¤MGÈ8å\88\95F\8a\b}77Â\14\15\11mhE\1a\ 2\ 51c\91m\1aqyÀwFhÓG\ 5¶PF$m"\8dò¤i\1cFÈ/"\8a\86\8cÌ\99\86if\ 4\89EØ,\1a     ³"úW#é+\92i#ê("¸72\9c2\8ex}"¸ç\88+\1e\82\80\1d1Y"\88\86\91\bêÔ#\1eG\ 4U>âNDPÞ\8fØ\15"¨'\90\18\ e\f\12\9f>\ 4W\85Ä\19\ fAyHì\95\89¤\98C\88û"©Ü\1038\922\rQç I]\ 2À°\92\84\0C\84LIö-Ä \97¤r\85¸Q& _!\8e¤)ÄÈMRvBì½\93t\94\10õ\80\92\b\ 4!\B\94t\1eDûHIÁA\84Ñ\94¬/G%Þ3\b\8eUâò\82 j%¦*\b"_\89\9d  \82ú±ÄËì\11\15Zâî@PÎ\96Ø2\10\14q\89+\ 5\82"A \­K²\v\88\18½äq\808H\19@ÌÛ/iù\1f\96\1fZ\a\13W\7fË\88Iu{oL\826³¢*M
-\a \14ÄíÃ\96óCò]R\15?\L\r0Áp8f3ñ\r\1fÄ\82\9b\9f\ f\831\ù0F\9a\98\8b\ f¤¨\89!øÀW­\89§÷À>£p\ f\89Óg\ f|-\13Óõ@å7ñS\ f\f\87\13\93ô@(äÄ\ 1=P`N|\9b\av\0»åÁ<q\9de\ ewv\ 2\ 2ú#+\9c,\90\0À´\a\0Ð}¿uk\18\84\81¾ÐÑaà\87\9a\8b¤Ã\88þV\92ÝäMrT\1cKÍ"\0\0\0\ 1\0\0@\9f\b:        \94
-\1dÚwÆ\1dç\9b¯Þû~k³·vóþ³¶\17ÿû3çºó\8aGý¿\95\ eµúÞ^½µVï\9dïµùwnûå×Zk·Æ÷ÚÍÿ¾ÿî\8c;ÞÝû[sÆ\95\ eÅùWK5Çx{8ã\9b¯þ»âQÞïö¿âÎ\7fç\98ó½q·¿oÍw¶¹âÑ®¯þxçj\7fí×ZooÇØrÿ«¥ÿb»«µ\17[k«ý\95\ e½:W»õÝýân1¾\1c\7f_íýþvËïÿ\9dç\8aG=®thϸ²3¾\17gl·÷Öv\8fïÎ\19ÿÛ\7fµvwÞ}µØn»uÅ£?W:4ÿ[!=ª¥;{\8c?îØw¼;æ½_­5§<÷û=¿|\7fÞ¹å·s̯Æ\97ÛÛ18\13½ïoÖ<ÿm±õÝgï¿\02\9aßë³í\e_\8fóþÞú»e Xv0þ÷úÍ1¯\r¸o¬w×6×Ï\7fï{ï\8fýå¶²@\12õ:¤\87ö¡¼¶]ç\f[}¢÷Ð>Ôj¤i\ 3\11x\9e ø\8dX²Mê\7f0ÜÅ\90¬HÆÂRÄ)ξ\16¨yÀö$é¦\0\18Å\ e-Ás&ºÞW^¿å\19{¾­¿¾sÛ½ö_oﯶ9W\92F|Üý¥ÜæL-íºÞ\8eÚ\aj©¨ÔI\81\ 1Â\ 3Xù±À\0\91\1e¨4\ 2ÍÙ\80r|õ\8f\1c\1fT\\99\1fJ\13MX2Qµµ\ 1
-Y\95æÊ,Á\13\ 5˱\ 5z\94%ûH\ 1\eÊ/9\96\1aJ\8e¥ÆblW \80ÍD\9b\88bÈa\89d`\80\rh.XQ\f9g8cÉÆÌY~£    Õ\bh\0\8f\92F/¥LBSö\19 ¥HÄgh\9a´Z\e1äL(\84\f¿ú¸\14\84\8dåYZ\85æçÁVßY\12\19\9e&ôj\ 3tBe!\85\0á¹\ 2c_Â\84B4
-\95\ 1`\94!L4óÛLóÖô¡A.µÔÒKédb©¥\13:¡ø¡A\1e\1aä\94ÍD/õÐ:\9aÂ\96îR&\15@ù©B\10(\9efXz©\ f\86fzéî»WK5µ\ f\ròРø¾L»/Ý\97ÒL³ø\ 5\10Y{é}h\90\87V)dR\82\ 1İD'"I\86g\89U\82¯ó\ 39´£â7®Êï\95y\99¯Õl4\89_\0\11­'I³½tòÐ:
-\99°d³\91DëIÒL'\14R\82¬RDKÐõɾ\10}\99³Ró\98jL±ç\9cÛ{ïµ3Rö¹\9fþO¹íÛZl\82:P§Å|×\0@57A\1d¨öîwÆ è¥8W»¹Ç?w\9boþÞ{ëýŤ\ f,1§\0Ðdï­ûn\8bµåYç|¯¾Úîëý\8b¯¿\9dwÏuõ\7fëÎñÕuw¿w\fõuå\9dwÚsö¼wyß\7f¿ßÞÞ|\7fí>û\9ewÍ9×Kóýuo\8có¥Øj|ëïô¾9_þ3ßõ~Þ)î\16ë_óö¼Öýw»½Í\e\7fË1Æ\99k1\14½þâÞiç¹ß\9f{æÝfmûÕ{W~;Í;ï8wößϵ½½âýñÆÝ_\8fy½¹^ì1õýöÌõõ]×ûÿÚñ{»\8aïÆÕ^mÅñ¥øã_/÷6güëö¼S|óöVÞÅÿwªùß\9b[\9dq¯ßß\8eíßWÛ¿±ý?[\7fsÕ¸÷\?çÝoÞsß~Û}kÎ\9dÍ\16ï®ûý|ÿNõÞ5ón÷ì5í¹»üÞÎ×{»\8b;»ñõ\9d\7fL/îþ½\9eßî^Ü«¾Ú\8a~ÜÝmµÕÇ^wÜi+|»ÏwÖuwÚ\8aWÜÑk;ÚQ~;ʹͺj\9e?¶¶n¾;º;\9a¯Ç\98wßóÜíÎk+þõÕbùþ\8bi\8aKq)nã\185WÔZ\9dõµxëî«õÜóh¿;óëoÏ\9dÞίþ\1e÷¯³ÏZ\fE7ö\9ewÜÿ÷_Wÿùõ8÷¯o¶ÝæÌ{Ö\98s̳­º~ÝQëkî(D\83>×@üg:ݼ£¹ÓÛ;õ\9dv¯¡v\865\95\16óèÅ\9eß}·æ\9bßz;ï\9dþ\9com¯Ïþç¬w·¶ZPÆ\7f\r¤eîÖ¶£\k\99Îo\8fkï(ßZFwÿâ«e2å¼×Lï×2ùæ\8f=ß¶Ú\8a;-ã+î(ïwï\9a»Ý\7fÕ\9dí·î®ëÎß\ e{-f½¼/ƶóÛQ¼;ï;\8a\9fú­eèÝ[ßú©¿6×\8bµ\f½:ß®ÃXËhÜåK7îîÝøz\¿\16Û¸Óµk.j1$j»6\8bÈF\19æA¯&ÛÙV\7f\7fÍ÷Þ_Å\14§­R\9c\16ó)\8e\85Z\0alëï4Ю½z\9a;ê)ÿ[k¼kö9o®o§;Æ\9d\ 6Âõ_\8f¿ý\9d\83\1d®1|¯ÆÑ2·ÃÙÞÍ÷θ£ûf_­¯\19ãNËôνç\9agÜ;Ý5\ 6]ýoŽêmë§\19g~Õ\9fWÝѼµî¼Wý;Ê=¯¿Ë\9dr\8a¯Ï9gû­÷Øö\9f?Ö¹ZÌûõÜ{Üï÷Ù_\ùç½ë2î[çìíÕ\\1eµ¶£\90}3]þ Ü3¼~úéåÝãª;Z?ý¸ÓV¿zÿ¯æÕÓ¬;º½ç¹z\9a9θj\7f7í¸£\98jÛ}Ý3¯¿ÓVù×ßí\8a鶸zª/½\19Ûj¯Õ¹bÌëÎ\97ö¼qÕ¸«üV\8d3æ>ãúogë¿]¯þúÛá«\91\1c³PôR\9b\ 2Å\0ÎÿÁ¤\bR\9c6\10\96©óÁdX «\1cW é\1c\13&4æÑþy¶Û請\9c\9dsûïÖ\9cîÞ/®\95¿<\95§­l¿ôïU×ýN[Y®\89^«ò\ 3KýR\v\12)¦»Z-F¿Þ¹Z\8e9®öoìýýw_½ïö\9f{þ¹öúb^-Þ\98cOïí´\fí»Òê\7f÷»{o¿¶âÛwݵó«ñÏP{»]ÿ®\7f×O­çöv\1a(Fy\17Q;\130z£*6fXá¬\ 3\8aªOv\96#)`Ã
\8eK\16\86bé§8\8dúK-§:Å\99òý\9cãÛ3îèý\9ewÊ9卑wEííDj/ÈcпÚBDó<jµ\96çÜ[ytß¾qGq\fEíç½£ÚzÞQ\8c;z«Õ\\1e½¿£\96^Måi \fµ·Ó@Ôv\9d½\1díøæîþ_?Å}óú­½ö~ìéÍZ\8cvz³¦¡¶¥eè½\9d\ 6¢½£8k\19ê?½\97n\ f¢\1ewôÒk)Î\14ãú;\8as×i \8f;º­æ¢V\13Qk¯l<Ï\99÷ÐÄQ\15\v@_\96l\93²÷\83á0dlÌ´LÙW\9aN\19(ónÇÒ^ñJ6ã\9cð\ 3\97\ 4[(26fê5\953Ñ#cc¦\13       \10p\ 3øÊ\8e½2\19¾Øæ{3&\1eG\91C     à\fW\1f9R\ 2Øê\13U¬q\14[#\8b%@ÀíöýJ\17k\1c\19tµû\14 àV»Ú«ïô\9e\v\10°o\97/¾ø\ 6\10\0\v,1¦\ 10o\82Cx\9d\bjll*0\8bF"Qáª\ fN\e0@3&\e¯qa\910$\87\ 6¯sk\ 2\97\92\82×I\1fǶ¥DÛ¶\11P\16!lÛ6    \ 4Ƕ\95\a\ 2Û6\80ÓR\92mÛD\vƶåRÀ\ 1\16i-@¶mÀ\80\ 1\ 3\ 6p\9aÄ\12{M¼nÛ`\87\86ÎÄ]á\ 1ç\ 6¥\0Ù\180\80tO\13\96ò  Á¡ü\rendstream\rendobj\r19 0 obj\r<</Length 32300>>stream\r
-ÑàׯÀH8-Kä\19\82\86ó8Z\9a\a\8a\80j\13ñ\10Q\fpÄÛp8³Â\84\19u\13/G. \13M\ 1gaMªÍ\8bä\ e|@%¢\95áÄ67\19ì_ª^ØÛ\7fÛ¶ïQa\99Øt\v\15%\98áln·m\9bÙ\91ªf\97\13\93\19f6Û¶m \ 3Û¶å\ 4\18×!-¶m##Û¶\r`ª£Ãi¦
-dÛ¶\16ÅÈc
-\16Û¶-\1eÛ¶\91YÁcV\94\95\83É@t!ðÙ#8ø¬&6\ eǶm\90\8a\88\93ÁÞ¶m{5: \81×ñ\8b\14¸mÛDWDÇ\98¶mÛJ\81mÛîG¡4ÀÛ¶m\ 3D\eÐö\9c¶8xlÛÂ\11Ù6Í\ 4\ 6\f\18@\82:\rÎkÖ ò\ 3 B\9cð\9f\ 6"\8a\ 1É£\e\9be(·-\81 \83\18¡VÉ«\94ÜÇ!ø\1eÑD\93-\96\86\1d\8cþl³m\e§\rP\905®@Íö\9f\84\99P
-\r üd¡71ÝK?\18Ê­G'¥Ñ\86D\ 5\80"\19\8a\19ó\vE\f\rO\19\86~0\94ß\ f\86b*\vé(£\7fß\ f\ 6\14Éð\14g!0ÀWú`B\ f\0Æ\17\10Da²\ f½wUOS\84ÉB+ûHò\93\952'G3zP\82\8cCòËlî
-\14ÅqE\1f\1e°ò\v\95`øÉT±ÙË\ 4\9e_   ÊÀÎ5]14\81æB\0_Ù±ú\ 6ð\95\1dP\fM\eÏÄ\95ìÓ:e\9fóS\8då
-\ 3ÆÆòµ\1aecHc\\82a+<e ë\13ÀWvdcxù\19"ÜQ\85\91\ 1\8c²1´5\ 3®!K6fdái\82\9a\0\1e°r\ 4ÀYbbcÉY\85â8
\e38\16\96¦±%û\80®oD\8e&Xù\85\ é\92.\19\96+\13Ôà*\ 3À(\83ÉfÔ\f[#\ 5Í\19\15?\99Ì\15\9a Fö¡æG_«\99¹
-E\92üè9\e\ 3øDúQYHÏ\90Òñ¤,\10\94ÑÙ\18@9Ò\81\90ÊÂÏå\92\85\ 2©l¤²O$él\f\0\ 5Z9\9a\91ì£æGA1lQÙG]²0ÀgR\19ø\ 2\05)\8b\82¯\93\82åGA\13|\99\1e\0\0Ã\93
-d8Í\8f\ 3\93\85 k\96\9fwIò+M«Q£[ è²Ê\8f%ûÎR\8a£\19áûÁL&å\a\92$F\14g\1c°\14\0\b+A\8b] ù:?2å\92\85\ 1Æ\10\0¾R\ 3\8aá\8b\81üd¥    % Ç\11\ 5]ßÌ%û@ç\8c<g"ú?\98\97    \86èÿ`.=K\90Ò{?\1146\vY`èáñ\81%\86\1cËL\8a\váîk>\v\v¶{\90\e\9a#i4\89   c~.9\9aX (zâ\8c\ 4Iâ§\1aÅÎþ`²ÏüÒS\0h\1aÑ{ï\rMZ\82äGÒÿÁ¨J\8a=Öx»è¥\94U~£ê,?úAQEÁó\13G34)+,]4\80\95\f,?Ò\94}åIÿ\aã¢çl\84­F\19\8cÒK¢ã9ÃÐ\ fæ#yNqãê\1cI3\14¿\1a\92¬\ e3¿\98y\82¦\89\ 1EÕ79W¡æA    Ê\0áù\89 iwÔ\8e¡\v\0P$Cq%~*\1a +ÁÓüÊ\9eµ\1f)\18 \ 4M°$ÇðüHæ)\e9'hªf%{o'GÓïã
-,\89"\98á÷÷Ó,C\8e\0\90%û¸dáË\f\89ÞÎýY:[ ¨û­[ ¨\ 5\82.æ-\10t\86²\85Sk¿rÉB\0\80áI\9f<\16\b\8a^érð\14°9[ È¿Vá\8b!6f@1l\8då\88\ 5ªb\e1T\85çGÆÆ\fG32Kð\ 4c_ù\8d>\18\18(ºd\18põqÎ\97+$\9d#YJáûÁ\b\0O\v\ e\b\b\17\8a\1f\rOÙÇÏ\92(Î8\1f\fÌV[õ}\84\1aPT}&0ö%\88ßj\ 4\99\9aO  \9e²ÏjÔ\9c\9fG\ 4K\ fJ`RP\16\8açl¤%Ø¢V\ 4\ 3\80 \1aÀ\19\8aßL\81ºd!ý¢Ù\98\11E0seã\80°\1c=\98\ 5\92Êq\149\1e+,;þû\1d\96d    \ 6\10\f_\fÔ4Á\92$g%Úï\0\8bñ¿óc}'\18\ 3@˼6ã¯ùîZ\80\80\0\ 2øÿ{}uÍÜ\9f-\10\14\eÏsT­BѼ\0h\99÷\ 4K'XúÎO\ 3\8adì3)\ 1nl<ÍÙ*\0\85å\17à\82°Õ(\ e\9c`©ü\ 2ÜPe¦8\ 2³ü\ 2¤LYã\91âRÜ$Åißùi>>Í\10ä\8d°Æ\1aë_-õùÿm=æ\1a[«ÿ¿úwÛ³­¸âQk«÷ûîíïö\98ó\8dû¶\97Ûû»¾»ãÿµ·^\87j\8b¿Î|ßn³¿\1eÿ~í¾ÚþËõ¿¿ÿþûæöwîÿî½o˽¿\1aû­ûïÚîÏmÎ\9bo\7f}Ö>÷«»î\ek|ñÝÕ~ëï½]ïn·ÖÝ⬽ÇÞbî·å¿cÌïÆØ^m{ηoë¯Ï¾w¿õ½·÷¿{¯x´÷J\87öþýæ\99Û\8c=ßöZ¿{þ×úݱç}ó]ñèÝ\15\8fr\8c·ÎØ÷\8a\7fÿÿc\8d÷Çÿöíýõ\9cs\8c-öÜÿÏ-ÇÝ£\96Þ«+!Êq%£1ÆûÚþ1Æ\99ãJ\ 3ͺ\12¢\97oü»¾¿sÛ³íöÞ]A \16W\1a¨­\84\95L®Ö~üq×þÿ\7f¹ÿøj®\11½\14Â\12ÇÌ\83¤\11«\91F±¦òòîY_Ï1·Ø÷}{î:wίÍ]W:\94\7f\9c±ÎvûÞ·ÍXßÜyç·ï«ë½¸Ú­sÎWã½±å\1eç\7f±öÛf{³å\1cãíqþ?{«»Õ\9ckÌ3ö·Ò¡\9cß\9f­æ¼{{­íß\7f[í·|g½íÕ½Zoy·ùëûußßz~óçûV:Ôÿ¾uµ4sþíõyóÌ«í\97û¬¹å¼âÑÛ+\1d\9a=ÎÕz\9b¯Æ_oÜóö\9ck­-Ï\7fç\8d\96w_ñèÿ\95\ eÝ·ë\½Õ\9bcËsþþgÜmÞÕÒßí¾·âQ\9do¥Có¾{[Ï­ßÚî\8d·¶7\7f\8fuµ|oÿsöÿsî1÷\1a_\8cõþ?W\9b»÷ßþ\9f;®vóî±ÆÞc|q¶y_ì·Ï\16W\9byÞ}{oûÿøzk/çÿúj)ï|ÿ\7f\7fÅ£¶Ò¡~soõÍÝçl½íùs|/ö\97S­ý½voíuÖ·ï½o¾\9e[\9fõÅùZ­½ç\98ëËñÿÕónuηâÑ­+\1d\8aíý¹Z]-Åý{ï1ιoß÷Öþ\7fmõÞº[{+\1eµ¸BzTKy¿×Ú\7fµÆ\1cç͵®t(×ûöûµÝVçûuç¸Û\8bõõý÷¼5ÿÕfïoÅ£ù^\9b³×\96s¼«åöëÎ1®xôöËoÍßzï\7fïúnÍû¾\15\8f~Î;Õ7Ûß¹öwã¾uµøú|mîöÛ\9b÷½Úß«³çØâ¯{ý\1dgÌûÞ\15\8fjk­®\96v¬wÿVk˱ÆÜï\9f±½Þê\9c·õÚfïq¶ÿs}±ïys{\7fÆôr¯qÎÙ[Ìq·\9a{Ý+\1e½þV\ 2.rl\95¤Èª§¬\ 5\9e²°ÆVXT}2pÆ"ÇJ
-\18W+Ù¬\15\8a.RÀ\95É>R@5¿ð\94}\95\14`\82²ó\13['h\9aäX\96\95\14`VR\06KVyÊÆU        ²¾\97YM2¶\82\ 5\10\92¬±\8a»ÌæC½\ eÉ|¬®XMòs\81²j\92ªj\92ä'\96`\80S¶Z\99\95U®Dre\ 6\0Åoe\ 6xUWe\95+2\14[20,ÇÊ*GÒ<Wµ\14\14\91"v\86*óS©F
-VU\8d\14/\0¬\ 2\84¥\86\ 6 ¢,P\16¶@ÍCu­/û>Å
-º¾XxkI\92¾\96$ùwI\92%I²H\11d\8d1\16YÅÓ¬âi\964\14ß\ fæA   R\9cf     Àoq\10³Ó#©ò\14Q\rJ°æ­\|\1f\86\8am\99ð\15\9cv°IFr"U\1a\91\f\91Åd\81\1a\19²ç`<k\1f\18+v²\92A\ÇFæø\ f\87ì\80\83%b±R\81\12C-bà\9d5\88^aS ~$\85        ë\18Í     Æ\12\e\1fVù¸H\8a\98\ 4¢DñY\8d8\ 5§9@   ²ð\81² \10\12@ tX\960ñu\8aMF/\ 2\99B~m£       s¥\1a%\91ë\93qve\83\16¬5C1\88
-On\91\b2"è9TFà¶\a\1a\84<\9cb¬Ò®\14X\14®\ 1Îú>\bãêá\9a¥\15§\9dÎ\ 4¿"©"¥jtb\9d\11\89@¥0ú̾ÒÈÀác8\19\>\bÕGà[\9d\ f\12\13°+ËLÌ>\1a2!y¡V©~\1f\9fÔfa¡¦\16"=\94h9l"     \ 6ÿ´D\17Mc\ 4¨¤°\10¡¢$\10DpZ£Fl\11\16R\ 5\ 1á\10r\19\88mU\81@XT\12¬\a       WFx\88\98­û\0\82lb\ e#eÀäp\ 1½(\ e­ðÛ\1c<~\88hP-Dh\1aºÀ\84¤a\15\82¹P\ 4\ f\89\bE\11áá¨\8d¥U2,8ïÀ°Ðra\188M\97<\b\ 3ŦÑ:\85,¯ÐéV$ö     F`*\17\14\fJ\ e\v\14\84\ao\81qZE\16T­Óe\12=(#SÁÅäM\12\88Åf"!"\89\92\8a\94\16\1aà¤t°\90\10#]&þDê\14ùB²£É\83\ 4á\92\96\ 2§q\8f/RX\8c\1c¯0kEl
-§Ä\99\1aÍ .\9f\11ã{á\91\ 3¶©\10\rÌ\16\ f"l%4"\ 2\8a4\10\ 5±\84\ 4ÆfHxØpLÂËÕ%        \e\81G\11Âá\82)\94ñBKè´]H\88âáô\ 2E0\8e\12\88Ó<\9cª\80\1aJÿ\0\9d¡À\vá\7f       á$áPA0\1fD\ f\ 4\vxz\1dD¼L¥\ 3     \ 3´\1c\19ä ì|\8aOfõ°ð¡\80@0\1f\v\82iàã\12#1\8feóBy`åHãÉ |ë)!\92\8aNhÅEt8M\92\0ùt$|·;\15\b\98§HÅY\80\81        \9cÿ\9a\10pL
-\ 6\a§!\16  7\98\rba\ 3\89xo\13Z\1a\93M)4Aj0/\86\bM­¢\ 3\8d\99 ê\1aÖ\f% 9uT­ÌÁy\962\16\10Ædr$¡f8M²*I\8fÑñ$¼Ò\92\b^l¦ð=
-X\81Ã{}\ e
-L\8bÁÅ\80q5°6\98ðáË\18X\84Ä\86!a1\96ÁÆ=J\ 6\8eÜ1\ 6\93\8ehbð?²¼h\ 68ße\ 4"E\97\882Ár\81eºîÒ CÒÂi=ä\90²|"\b  \96\b\95¦b)\11:\ 3\96¼\ fÈ
-\82À)UY½¾\84
-\84\15±T2\r\97®2áЪ(\80@ø¯à³z\8d
-B\8a\8cAÁf<l\ 1\83ýN\ 2Ç\ 1\ 3\8b\0\14¡1\11\98\ e\8d\86\80ÓÉh\82QD\10 à4MÅ\14\17Ø@é\\16\a\94mÁ¡P\14\1aÂ\be À\93?B\0\9cø\ 5¯\8dÂ'O\rï\8f\10@ü±\81\88ñ)\f\10B\9f@`qðÚË xÒã)ð\f¢Pç1*\96Ù#cÉê0l9u\14\82D§s\1a\87\ 5ù\9dk\88Ho4ü
-.>D\15O\95H&^\9ax\1cî\99¸\9e_¼H\84÷È@Ŷ®nµ!¢ÉÂæ2\99Î^t\86¿Ï\bL²M\81ljS \ 1Ô§@\ 4¥\17\92\86\ 3Ýè\ 5\15\9c\13ÍiVİÐÞ\ 5¢È\ 6\ 2?"\1fx}\94\17&v&O@4ϲ\92\ 6\92\1d\fP\ 5î%\90\85;5\82Â\r\12\19\ 4,nF\v\968*\18
-\ e\9fF\1eÙ\1d3Wuq\1f\17nÈ~\9fû\82\94*w\ 2\97Ó@\8f\ fwa]HfwVPY\ 6\8dëd\19£óÀr¾}±0ÆB¶\ 5\98Çê$F\15\93í\10hM$\ e\16\1c&ù¤\88&\12\9eYf²\19,?Q\91Hݤ \1f,&¢ì@¬\9e\ 5\84¯
-\14\80N\95áqB¨\9cÖÉ\97A\15U\r^C\ f\9e¤Z\a׬{\91\v1@Lt\19b\9fº±%"t\f\15   \98\ eÓQz'±p]\a\16\1d\ 3L\15\eØä\89Õ@\1eE4\f\95h ä\98\9b\81\87±+\18Høpð\80ÇH=\ 6\93\16§¤ú\10\85\843\17\9f¤D\85\18$¢f AÒ²\13\1a\89já!\90¤F\8f%\11.\b\90\1aÏÈCD\b\8b@|¢*"\ 1\8e\r\91ol(D@\81ì\89À´ç\12©ÐDð\bã¡Q#\92
-\r\17Ù^¬\80pÚÅd     !\bÛ8\ 1\1c  ,X\1dALME\aRM\89\vÄ\ 2\ 2uÈH\92\99@V ç\80,\10¼óÁ­'>@ä\ 1ë±ú  \1e\8d\92Ìô°h$¡\a\8a\80³y\9c\9e¢ò ðÏ\1f¨ßª\8f­bq<8íb\0;\1d©\ f\90\96\9aI8ÈGÈà¸X F\ eVIôqè\11Ás@\10(\108jÄI;P\13°st\ffÃÁ\0éf\8dÊ \915\1e6èjèÐ~\rUGÁ¡Q\19h\98\1a2\18*Ô@8ñN\83Ó\1e\98РñpG\94\ 6Á¢ë\ 6\19\86\ 2\væhè\8fµ5b«\16É\8d&R\14\1c\ f)X\\ 5L\94àPç¢\813¨½ÄA*\b!î¥ðêp¥\96õ8K#¡\80\93`NÎɾ\84ËA8f\12\ e\94\80jp\9cV\99\11l\í\9c¤ÀÌ\9c\80     ¼\10B-\81\a\ 6å\13\18\9d&\10\ 2\1dJe\10¨\98\ 3$\81Í                t\98ì\11p\MF`#\11,\ 2\15)\88/\10[ض\0\ 5\ 2\81\15xu$$\ 2®Ì\80C u\11-\ 4\\98\86ÉxeH2\ 6§Q `
-F¬ä\ 2\19å7ú\18\vòG0\1c\10F\ 3£«P\98\18Z\ 1bĨÀ\18@\f\8e-y\18¢\83\ 4\rÃ\81\82dÀh\11L\140Ì/æ\19\92ÜØ\fß\90/ÃÃK\1d\83A\15B\18¯\8bn0\ 4ÊÒ\82Á\17\1cç\82Ó>~D."HFlQѰ\10\87 µðà\98j\91ÚJ©ÅBÄ@,\b>Û°0\9dÎ\85\85LA$-t\88%Z\88<\10 \85ø\89ø,4\82\ 4gQ"½2\8b\8a\86Ò`Qð9,\v\b\19\85`ñp$øÅ\ 1\85b/8-\16ºyAð\85ìb\82\85½d$\8b\ 5Ôë±h0¼Æ"ä\91\8cÅìûl\v\ f\1e
-\86UÅÖ©¢q«h Ä6\8fmÀ¶ó\e_\eÈÂjm\ 2$\8aµ\95H'Õ6°M\13\e\84¨ ±õ\ 5\14ÄÆi¯JÊaÛ\f\8c¨mA1;m\v(»°éЧ´\85\18\95Âöá\8dÑ\ 6\91\\12\14÷\816̬CØ\18¤è³A\90\9cg3¨\18q6\81²±ÙR\8c\87̦\89P¼Mre\ 6\9b«rºl¢\ 3\8b\f\8dÊÆiçjE°Il\v\94Í£9\7fË!\ 3¿\95©Û7      Æ\0ß\ e
-\1a\v³¼ \9c\8c¼\81ݼ\9bÂ(f·Jè\9al\90NU7\8a\r\9d$N\ 3\9b·P\90l\95\0\8d¥\rd{\10/\8f­c)\8e\8dÓ¶¨ÒضWç6\95\ 4\vl  \9a\ 1ÆF\89h,¶Æ¶m\e×mÛ6À» ¦\81\18ø\0ëÇ\a\87±mÛ\16ñØ\ 6,¶-ò)\91­\ 2\95\0Ù\16\11\11ÈbÛ¶í<¸l[¦Ül\9bfÐl\e\85\87µØb«      cë.\84±\r\18`        \85<M\86èZ\9aEí<FåÈ\18Hºòb:-¼ñ$¯mVÂ\8c \81\12æ@a±m\ 3\ 6D|\98ä~V%&·ÌIï*n\8b^\16\rD\8fÓ\1c\1fÖGó ð;OBQa´\18\r\b\98Ù\80UmD\1eóC\10\ f±®%-\84  \8c"\81bàqZ\ e\9b~1AMµ@Ä:§\9d,W\98\91\19\f\940\94\ 3Y/O\8bdC8\80M\ 6\f\ 42Oà\806\92¾ºT\18\Ph#¡x*aæ´Bà\ôá\14pf®1\86©\805X\9c&\1a0`\80\176T\18\f°(\ 1\17\89\89õ -Ü\89òpf\ 1Cy8Ó 1U\1d\8b)\81òp×\80ò°ãò2u\1f\942\959\8d¡\ 2¢\ 2¢s:\9dN¨Î·8Z\15\ e[áh\91\rd\ 6b\13±\10`"7³\80j\940\91\8ba&\b3A;\81\99ã©CÁDn\ 6²1\91ë\98p&\13Ê\84\82\84Ç\ eD\1e\90      \8fÍÄF\1dK  \85À)P2\ 299\88\1dTüÙÁ½\1cÄ\1e\9a"\90óAìàA\11È\a±Èìà^Î
-§}pHrj\1e\971ô¡\8046\8fË\87bÀñùP\9c.3\ 2\97\9aÇE§P\1eæ´\14ê\ 4R\80\96Ó<®Æåä.§\ 5{\\17{\\ 3\19ß\13LsêN\15\aæ~\a¬8pD¢âÀ§\87á\ e«30ª8phñq\9a\ 1g\91Z|w\86U\15 ÅwG¬ÚHh 67\93\ 3\r\e\89\ 6\ 3\ 2bs7\12\9b\8d\ 49Ð0VN#;C\835æèI*\1a#²ãÇØ\18Yd\12\ 3qƱp\10\1eA4\bB\13\ 1
-C!E\90e\ 2\1eßyHØ \14\12<Èz\81 \ 6\83\9bL#ÇâØC\83\86\98ñ
-\ 6)FP ©wbV>8\8d\0ôBiSB1Ëßu\16æÄ\17
-E\1c\83+x&\8e\9d°8\vs³@\8d[\ 1\17\90hE0¢(ø\87­ÀãE\8e,m\8bD\820ñ2\99Uõ2\1c{N\fjÁÆAcjà8h\1aúÅÄÉ8Î\89Áfd1q$\f\ 4>g3c14©ï$v^"KYVø­e;¤DË"$øÒ\84Ó\1e¯pÁÀ#ñÁ\98\19E\13b(@\12\ f¼À\ 2
-\ 6±WÁØÉBÛ2\86R\r5\85òzÍ´@\b\ 4\ 2ÙTuLUÇTuj\86Óf,\94\87'5Óêj¦uª8p}PZeª\ 3B¸(\14Jòð\ 6r\99ê<(­2Õ±H\14ÊT\ 5\ 4î\16·Õ-n«[ÜV\ 5\ 4\ 3\8a\81\ 1e\92\16ßÍt\8bÛ\92,nË\92"]\86\e:'Ôv\82ØÜS\ 4±¹\99
-GËf²¡C6t,\92ÉÃÃ\9c&\81\99\12\98)\81\99ã©cYX@- \f0\91\9b\91ÀL\bÌ\8c\80\14 ­¸Á²\99L\83e3\95\ 6Ëf\1e\ 3\r\96up\9aæq\b|\19\92úÀ\1c\eu,%T  UBÕ     \8fÍp\1a\816óà`YGê\ 3-\ 2)É%½¹\85\14(\bd\ 3\ 1¢@A0GOÂ9úÂ%s
-\94\v¦@¹Ì\fx\9e\1dÜ\86ÅmÙ\83\18®ø\ 2\ eîE\12R \òAìq\80p/\a \13Ø\17È\1f\8aη@òË\8cÀ¸cFl.§\9d\9aÇ\85\ 1f\82öCÁi\8e\ fé\8cà4ÆæqÉpÚgÛ<.\9b­c\91|ÌÑ«*3\ 2+d\1ej¦e=®Î·H4lZN\8b\84Ó<¦Ek,\1a@\b÷"á4\8f@\ 5Ê[\Îí\85ò°Ç\1c=Ór\96}\82,S\r\1dY©c\91ÄF\9cLàÃ:,\92èàrZ$\1dsô$\9c6\86\ 6\87'«,\92ÎùPq`ÓÃp\87%\99,\9c 50U\1dKç\|\97Ó\14D\9c\8fk l\1e\17        çá.\fÜ\81»0p\193Ôâ»\1eéS\10È\9c/r!YU\91\8c¯    §y¤Ïc=\ e\81ï\92\ 3\r\16   §iP\9fÇ6 \13¨
-GË\8e§\8eE²iÔ\11h5\89\86\14é2\92\ 6B'd:]2§5@lº\86\81Í\80E2°É\e\89η(\904àkÒ(?\10\9b«å\8d\ 4äà;xxl8<(-Ëi\8c
-\88NGÀ¡ð"w\1c\17R\1fh#\9cÆX\946\a·± x³\bü±\17\a\1e\bU\1cØ1K}>\8cAU     '\9cÆqûÀ6F\16\89\82Bd\96òX®1á±£\85ηtº\ 6\8bD#â4àkâa²\82\89\\8fôy\1e]\83E2\86\ 6¸\8dÅ"Q\bI&ùs°¬æ¡ó-\ fN3±\1e¤e\80Â\b'\ 6¥\ 6Ëf"]FRÎ8\16\89Bì1\81\81ÀD®G\1aЯ-Bm$*\18\\16\9bIÄX\ e\19È\a}h\ 2Ó\98º\b\83\8dÁ-\vfÉi\ e
-^ý\ 1:\18\9cÓN\13\ 3\1dmr\16fD\83\16;\128F\12à4\ 6\9fcqebV6@4§\89\9d\87\98@\85Åã3        |1LF£Á*y        Þ\14(iÖ*up\e¥\84\16Ç^
-ÎÂä4\87\ 6ý \92\v\f\ 6Wpá\ 2É¢ìêĬÜ,0\91\vQU #TÐ\ 2åÚX\14\94å\fU\99X\87Ì\87&\9f\82\17ÚãÍIud\86\85»fÙ\8d*\ eÌi\8b2%v¶Eà\83re i\ 6\fI3°q`\16ÉV)^\ 3\9b\89â5°5ü\83nËÀ,\92MàÄ\90\85\85\96%·<²\10Ð$t9\8d \93\f©\93\f&¯;ÖU\bs\90\91}0É"p\80\17È\83\8a\84Ox¤O\16Ú\16      Y\0!-\8d\10©¤'\964 M­\10ÓX¼\99*\98%$°\95©\9d\914¶ÔH6(\ 4\94
\1d³%ájý½»Ðª\95ûu'}-\16\82\12.        \94~H\88\1e°\bÉÃvм<\ f\b.0\12`\98e\§
-\88\8a¾p"\e\ eðÀY\8aF\92ÉÛ¼Jÿ\9fJ\96\ 26\13U\ 1í\12·Ðj\82\952\91@öôà1\0ÙRg\80U°±ec$\8e\15\8b¤û¬ò\16\euZ\9f\8f·Ø¨c\91H6eYn\a\r\96\8d\14hP\14\10ùämIOìêÌà\8dÓd'\ 6\81\16.Ùt`Zx:\84{aè&\15É\8cÓ`Ù\86þ\0\1d\e71+9­r\166\e«p@9#°*%`9\8f\97\NK&lL\83\ 6Ë\92\88ã´\89\ f\91"\19A<\ f\8b\ 3\97±\9eª`ðÈ\87\9ddwÆi\15\94\ 6Ë®
-üBb\80E^\ 2\eqÊrÛ
-&\11\89\86\ 5§=Py\82\8a\90\v\89Hc$$ì\ 5âÀ!R`\f\1eZ¨"\1e\91ÕF\ 1~\12$*\ 3\ e6|`\10<0\f\8dSÇpIØ\1e\aY\1c\12'ûyÐ\9cö\9a$\80¦ð´§þÐ\ 1\95Î\19§AJ\1f\93Õ\ f\1aAw@=\87JåX+\82\83\ 3aÁi%\91\12*\89\83­\18Èr\9a¾xºWÀ<\91ü? kqàÀ 6¤\12¬b3ø£kÈ©\8eÃä4²7X¶t\9aÀ8Ë\90à\1d\18
-\1d\vv@Q¨Áà\9cv\10\8e\1c« IÐÜ\8fq\16æ¨\0\81c\1f\1atw\98U0\18Ü\9cTNã\90\b
-$\11\ f\97\a\84»\13³²lt\87ùX\14pÚØð0jO\8eÀ\98\99;d|Å\81\94ôÄ\9e¸\86\99\ 4eÉiçB$nN\81Ĩ\e,+É\84*ú¡r\1a\0G\94\r&ÁF\85\89\\96x\12d\87cÄ?
-\bTU}\1c\ 6]garÚ\82\ 3£c'0\98Ò\88cp\r\83\89c9-\ 1\ 2\9cÅY\84"\96cQ\r:¤/\ 2\91×.Ð+\ 2    §\1d<d(\16GEaÔpb\98\ f[\81ÃD%2<\9c6rà\12\96\8c\89\95\8a(%d%Ò¨9-dbS7¶\8eE2ó \\r"\99\88òÅI\15Ñm°ìã¡`\90Q\Ç[&D\17ý(é\89Eð"Dy2 ÊÒ\ 4q\9a¦¡Á²bg[$\12\1eÆ\ 5w<\85\80ç[4\v\8b\ 3k\1c\11\9b\99\ 1S\1eÛ\80\8d\12X\ 1\83^÷<+\8d¬ÑH\90&&\87\84FN(}:\ 6\13ó@ðåª$\97Aa¥ðµÄd\1d§qóa\13ÌÑ\93`\8aB\81Ö\r\95\89%3£        \8f\8d\1dl\8b¤[I.\9a\81\8b\ 1B/á\84       ïá%¹h8Êö`<\9b㠩بÄÍi3½\0í\ 3bid\86\ 3\12  3NjÂ\84Ä ·\ 1Et\82ö\0\7f\11âB\98\11\98kb2\81ljNS\80d¶-ë\98Èý$\13\ f\e\8dø\89È\94\1a1\88Wý½\10¼.\1a\aÍ\ f\8d"(\ 5.sb@\ 2=\86M¥c\9aø\9emN*L³-\92ËÁ\84Ç.\842\17\ 6RQ\92\ 6\9bW\10\r@¶'LP\16®`\80@a `Ài\a>\16Ã$p+m`í\rÝNf\8f\1d7\1fÖZ\1alKóUH\f\ f¬ó[\1aï4]2\81B¦(\14h\1c\92Ll>_\17É$$\99Ø\89êt\91ô\89m\91ÜûÁL´S\0hº÷\83!  k\fQ*\vA,ÙGOó\ 3é\9bÇ\96ì£\1a\ f®(\8e«ª\1a)FÐ,Á\0`YU#\ 5èúDñ»\9f¨"C\98\89¡ 9«ª\91Â\8aÕ$_ç¨\9a\99õ\94µl\0Õª\9a¤=ÃS5R\84 ë#AY(¶@VY®T­ÖÈ\ 2AQÕj\8d\15\16\v\94\99¨4R\88\94¹(E\9dR
-\91È\0\0\0\90\0c\12\00((\18\91\92\91$\84\98í\ 1\14\0\ 4vV&D:>.&\10Gc¡@\18\12\85\81\14Ia\14\83Q\10\ 3a\fc\f1¤Ìé \0\e\fû8Âô[¾\12£\ eû]Þæx&SuÙôLOé+(và ]®\82&Á¥òal1\ 5\9e\94=KmpÞh3q?\91ó\16­\85\ 6\879ÄM\99hk(Å
-êÝYÐØ\99Z\ eEÃC¸\13g\1aúf]\17\92\ 3ôÄ$ú\96-»í\9f\r\0ù.\9dP÷£¾u\19<QÇ\1aØUs¿VÑ}5x\ f\91\ 5·¿\8c¼\10º9\19\ 2\14@iÂD1\1a¥É\12\9e\1e<|FP¥}Öc+Fõ\81\89\97¢+С\14ç\r{ÈÕHO\19]vʯè\86[]º\11øG\17yLÏ\96Pùè"\8aU"o\14bÒëT\88Ð\1c]\f$\88òèÚìû\90ñ*#P]£[\1an\1d0Y¤Md9º\b¾L;\14ÝÚ\v\9b\16\16¬\8a\ 3<ݮĢúNèÂA\8a\92\eþÑM=rY\ 6\1f÷&¡\ 4ÎèYZìQÅ\11¡\128Ù9\88¯Ý5QÜ2̳Ç\92+ò-¦ø³\9cü>\8aéÃxRÌ\e½\81\91d\aÏ\r\ 4p\rçcÆ\83\960?ÖH^\91û/nX\98\87\8a;ôÖ\0Ä¥{*Â\ eS,Qò\8ef'W\9f\88\eÊ`GÅ\8b\b1.ó\1aB.L\ 6\80×E>ÓP\8f4\81þpöt\9a5\ 4\85V\7f&\1f¾PÙÄcj\10¤\1fG\ 33C\94a*¾\À÷(%å"+IÐIJgÉ6©VÑ*â$«<¤ü 1\ 1Ç(\9bkgh\89§\erË©\ 5©¦\10üß\84\16]w\b}r}1\16à-\16\v)ù=¥>\v\ fæ¼\1cÄ\86À\11Öíoy³\97\93\ 6û\88ËÁþ\89mfÞ6ß¡¼(kü¸Dp@\93ö\ 5ÕCV\11,ÖöÆ\83,̸Êkê!\94­p:2\f±M2Ý\94\9fá\83ü_YsH\ 5\8d{é4\9c¬?\9d\83G\13å\a\a)~\1a1¸ð\a\ 5ñä¢lX\98¿rØ\\81Z\15Ú\ e\9e¡\aV\85\19«\1fÙ\12\B\9cñ^\9a\ 25¿          \98TÜâ-\83\88è\0\1f\ 4öâYb}ÃÚÆÿf\97Úfº\92ç}¥;µ`ºÛ.hà»t tE\8e\9dseÅ\9b\12ßÈ\98Ç©\sLéÂx®ð2Ý[8rÍ\85ê\8f$ø`ºï\ 2UöO×^¼\19û\89eºß\9b\91®\8fÆ\ 6\97ß\99®àq+Cp\1c\e\e\98®Þ{vx!\0so9H¹òÌt\8dfmC 3ëÈ\85ÂLÈ*\9f°*t\8cúòJ¥q^ "\18ý¡Ì\0¥X\98\1f\19bST\86F§Zß]dV\ 6Ê=\9e\92\96X\rª\93\8eäÍqÔ+Ca\a-=·Ê×Xe´!Q\1a6\ 3ѧ¥ã¹:q¨\1f\ eÀ\8e[ätú\1fW\80\a\90\ 3Û\UÃÒ¿Ôìt\ 3ª\8c\92KtÆÍëÞp¿q\ 5OYeÄaÁV\98 ^Æ(¥Qr9\ 6\96\1c\ 4ìt3\97\a\19*ÊÂ\v\98:\1eëK=õ\ 4{K96\1a\8a»²v%\9f\19xáÄ\83[]¾K±¤r.5k\ 6·\93\97\1f8\v\b|2åóÙ£Ñ\9f¬_Òäã#\12ã.ò'ÀÿR\16\ 3\0[W\1e:e~\80ð\18,\9fZ\92\98-w\90¤ñ$\91ªÍÌúq\vÑ>\94þM\824\82\ÿ\86ÐÇ\94\9d\ f:\8c­Ø\8c\8cI!\91Ý\92R<\ 4\8e\18Á¬é¬ÁOÑ\9cË¥\v¯ÂpqWf8v\890û³i}\15ðer\e\88Öé\87\ 1È%¦Ñ¡\8c\19\85\fÏHp\9bré\11ðQUí\1eÓ)Â^\88\91tt,~\14\1c½¤\18\81aïÌ÷Û«éZ§À!%¸éhóÒheôl\13\10§\1a°.B¨7|7Mó\9bÏ\b\84TQ\15·æ(Ã\9bà_|_«~\90¯j4ͧ\82Ü^ì¦\9f°ã'\80Å(\eNc^t\ 1Í\8c\19\91ú\ 1@\85xÖ¿À\8aÜFÒÝä~¬EY_\95\a\84\83ãÒÒ\8bµ]Úe!\19¾T\fò_\18±\1aÅ
\19ÑS%Pøe)pÇa\85þ¦\80Lc\ 1x\r\11H\8a\18Ü\v>.\95ë\8e)\10\eò®h±Ç\ eÜ\8fA\ 1dYX¹aN\963\a\97­#Bxqâ\ fÀ#$( .E\8b\a\89ûU\bÔ#í\80\8b\13úÁ\vGÓMá¹Ë]Q?ü«jh\ f±\90þmi¦!ëQƸǠ    y%õ\9e\9cbl¿.,\9fobÒ \7fßîf\8e÷1Öt\8f.\11\9a¥¦è\80ºD\92\8d;ÿ¶2Þ)ÕqpuÏ\19¤CÓ\9c\7fº\fJÃÿûõ´®°xö>òmX\9e\90\98  I@«dá:\1eø~\8b\f(\9ccÚ±EdNÊ+uÜiù£TM5F\80\90\ 5â/¨Odº\8bÄøW¡\8b8bS\9eú·Ãó\9f0coÈO\1d\ 2úR\9e 5#\84\1da\90ß»rU·PBÞ\8d£\1d×9áäè\1atf\1cì#¡670#\92Ý&Í\9d\ f0\8d¥V\ 4ÞOI`\80E=ófÊo\õ\95ÊËL«¯Ibø\f\17ývÿì·Ã\16\83¼ÖwØ÷\8c®\10q_n 8D±µo\18\f\1fø0\90&ÙøãÈ×jP7\83\ 3äTSÌÖÿ\99Í\r¢\93\ 3\ 5\97¶6\a»y}\92\eááÑ ðÁ\98icxÄÑ\12§ÐÈ\9a[·6ÝEPÒíT³*d¯Û<\09\18ï#ÿlT\ 2»A4\1e\8d      _þg·\14\82\16\83éßZ\98\17Èp!9HG\e\eÁn\8fÈÉ\96\9fn»L\8dsÝ¢
-JAë.Üô\18\16¢Á.\92×\8cÝO\13;Í)ô\9a?\8b\;\16X ¨Ä`ÍúÙe\15È_\85!\17³íBJ\87å\82_
-J\88<'ÄC\934³©\ 3-\ 1\85K\ 2¢
-jDÅ%QÊq,l,=Q½ÛöQÉ\9b\96õ\9b>\17·\90ä\14\80Ãhc«ì\7f   Ç\80ÅÐ$ ã,\1f\\84     ÞkzáPC-\83-\ 3l³_^\7f{=Á+\ 6:î·Â}\17Æ¥Ë
-S\16(í<\94XA\11ù\99®¾]\ 5u\9e,\16\98&\15}ëÆªf,³¼Ø¹øè[x! \e\ fs\0\1c\1a\9bQÂÃ\1d´ï\92\80\97\16øÎ\b\1a\9e2/B"°µ\16\ 1Û\87Â\8bgI\ f\9a\8a\ 1{ ¢[Ä\87ù»g±èP8w6\8f\98@Xä\86\0\98\1f>|\ 4ßrÄ×-#á\ f\93Wô~2¾¼ùqH\ 6AB\18\8fOoá§>PÄ    \ 1¨·ù\9aÉ"æa6²n\1cÇw¯\16\89X&\95\87§¯e\87¯\8f¯_4=¬ÑÆìúJ/|I«Dv||Ò÷Àæ`Ë\9f}´ÝÏ­\8a«\1c\89§ã#\97+Äs-iÜÏ*Õ§Q\9c·\ 6¡V\vi\18´\95\82:ï¹sQ\83\1dg]\86^\83Mþò\0ݤð\bQ\1fÿ\9fö?Ðí\ 1\81
-p\97JqJ´\90T-ÒÒ_x\19\93\bZ¾N!\92ý\8aPzWøï\94³\13\8ej\11ó~\1cØÃ\ 6M¤b-× ðHñ\98\ f\93/\aär¡§ÕS\82ü\0ûi\1fèr\9aËPTX5\9aä\eû×|ia¯gqy\85{ëH(HZ5\16²ÿ\11\90\1að·$aÊ5ÕHaHÚ\14í«Éöð@Í\0\96l\8c\9c»×º¹\1cÛú\86 Âã»r\13Ê\9bäª&Ðèa~!Z\83Ó\16¤\ 3·õ½©æ7eFÖ\16\9cÁTG'´+\1a£6\eÜ\82Ñ\94Þ3PîKv`NCVãªT\8d\83\9e\1aéa)a\97Éeß/\92ö%ï\82¬I>Cu\15ÇpùDøÖñ\14ÇÂ
-\9d±\94\1af\93³`P\99ÜÎê\fø\86\1c·\9aM\9dgëiI.»o£bW\97­úx\19\1c\ 1\ 2xËÍ\95Æ\99x\8a+/\99+{â={ÞÀäY\97ár¼: \ 2If
-\93\88½¢ò\9eñì*÷¶Ýµß\8e¡À#Í\9f?ð!o\9e]ôaÃsq7\1dÕ3\88\87\839»}5(aÂÑíÌ8¼<{WL\80ï[\8aõóLu\93û¢\8f$\ 4|\93E[\81e\9bÑke\1döÌdîMR(,\\86¯?RAÎ\ 5\88 E½l:\ 4\16<\ 5¡\96bkØçeH[!c&J%¿\8a­\f6\ 5YÌ!)OqQ\12í\88ÛR;\8dÄ6(¶\13í\9a\81\9cý\11\19¿\96W\1fã,lÇ\9c\1f¹È\98·\eßø~\14ß\ f\ 3\8c¨!§<¤ÿÌ\15\879a(4¯\19ä [&@\ 3X^»{Jä4UyÜ¥?PÒè^ïrâ×ÅkäÏDQÞ\98Éfdå[Vû>\81\8584´×ä\92zG\8ec\84Þ®\92\88y
-vÖ¤\9e\11\ f\98ziægPFS«özò.\16¬\86ùp\96â]\8bvWQ\11äl}]~\9e\9f0hÌ\ 1ß\19\19X²4\90ñõ\82ZB­°ÙçåUD¨
-\15Þ\16Ì xnykQ\95ç\98â\8b\80ùË![\86ÕÁDD"nhí^ò\1f\90ñÜqe\b\ 1\13Õx`ÿêºÉ\96\15Ï\15bµÏ\ fÝz(\98ä   !Æ\1aÜõ1ìÂ\ 6\11\ fA
-\9d6ùÃ\97\ 6\a\12>gyÞ\15Lå·ñÃ\95­`ð¨\7f\84\8c\7f\18ª\93\80b\1dN\1cÒw1Y¨æeP\86G5\1a\84\9bÉM\ e\915\ fè/Û\8eæ\17-d¤\1fýõ¹\10þ\93ò-\ 5¿j\96úF\94Ì9³n&×Ñ\93\8d\ e
-\16\97     \8ar¶÷BH\ e®\1fõi\bßËJRcJd°\19jÚ-°\8e\88ÝÁ+¼þ\14\83Bmz5(:Ú\9f¢¶#¨q\87M\ 5\81L\8d+Èráø¤\ 6yCF¥³Ð%\80!\94Íþ~§$\81´%aÐÅé\93aWE-ÎÁý\18 \1fÅ\ 5}=?\90M\81   ¼L\1f¨3ÞN¤ÖYÑè\0\97¦Ö\896?`\85¶9u\10k+ãc \9aW\18ª\822?Ô©(6Ç\89³\8eW\7fA\82¿\15\91\88¬\8a}ÃZÌ))"rc²Ëù\11+/8\9c\e[v[Ó?\1c\1aIÌ,\1d½N4r:eZtJüA\89\1fX÷&G\80U.M\rùJ\ e\92á[\83Áo0Úâ\ 3Ebïg\97®ë¯¶ï\aD3Öí\95¯\}\9db  )[¤\95*íÛÓ\91×b±|Àà\90Á\1cú!ÆK" ±*ï%2\15\1fG\87Ù¨£\89=ÿô$Óvo«\9c\ 1\10Ô8VÒLx\96¦\91\ 1fÛÞÓ qðix]B£-ë4\8a±\8c\ 3y\90Y å$oþ\1d\19É¡#÷    YÁN\99Ñ)ô\eÊfö\892ÌQ#Ù\v\b\ e|\ 4µ\97\8aû!âÀÑ\9b\18àöA M\97\vü\ fCõ H_\83.#ó\9e¬»'$]ø9ùµå|÷®g#\ 2­5Ì\vä\19\f©ú\14^\f\10Î\839\9b\95²*n\82ý\9c\87éq0\ 5\1d\ fðËåp£Øá-Åü\86tìAù©Éºç8\91â\97Çþ¾:Þ\86Z*vÉ\ 3\8cl\w\8b70ß\11\8bÔH\89Ú{ \88\ 2!\84Ä)Ýà,ä7\88À̹\91\9b\85\a\99\9f\ e\86µÇ\1f\0\86¸\99{\81Úh|h\89ó\16ù[H<7©P¸%Ui$[C\ 1ù~^d(S\b\v\8d*\19t?ªo@ûÁ\96ï3µt@e\bÈ\1e*F÷WÖýl#_¢ÿ\9a\18\99YU×h\ 3\93&\ 3D±7É\18Å9\bnÛo}b\85¿ãkö\86\9fì\ e\9cåd¤ÿ·NfT\1a\1d>\8b\ f   ø\91ÌzÓüß²X#(\17~åô)\8f\ 6Ä\ 3§aý~ò^|~«¦PÖ\96\82     °ê×\91x×ÛÀËo¤gi\eÙr\1fµó,M\87or\98צ®Ör\ f$&I>\rø¸¬¢­pRS
-\f\9e\8añ\93 ¯Oºê±ø>b&×T\8fIuö\föh\0\98\9a\12\a\90`0ø×\8b¬       ¡ÅszÂw$VRÍ\9aàF\ fÿ\ 3\11Ã\1a6Ëì\0cæ>ô\1e\v+\(qvLh\9c\7f\86}D"Ð7#Ry!u\b\16\9c\84$\93\80\9e\a="Ø\85ׯ\9f\10H5i\92Ìõã¶¾<;Ú\8c\øt¬W¯­\91põê³þ\ 6¡ð8Éó6YòêQx¶e\v\8fxQåÈté£\18¤zíìU¼,\14h\9eÖ²Þ   <~\16Ù\9d\94\14ín³Õ\19%-´G~\9c"\87\9c\0¿V4\13ÂõÓêic9X\8e\96\ 1éL\95\ 4Ùp\9fôZN`l\8fì¨N5Ã\1f\8b\83K\16»ÔcÞ+}fûF\9f\97\ 5í\81ª1¨fè÷ýÌ2+'G\v\18\96b\É|\ 4\bµÙiKW-p:¦ëÉV   $âÛ/\8e\ e¢Á³þ\ÆÑ<:\1f\13ûS5\8bQ\9fþÓ\ 48\ 1\81î{.®ÓÄ\8a§\99^³/>ÍÃz¨Î>c\97\87÷
-þ¼]\90Éê&\87êàø5Y\86÷îsce÷Í\r]ãË×õ>£\ 4Ìl\e+"!`Hù\fä¡\1e\18\8a¾|¦\97\bê&GÏÎ\1fC\97}'üË2·×\\99Ðàlë6\15Û\1av·C¾VÆ!\1aô,Qx½ôD+N\ e¬d´\8fbçë\14¦c\8aÜ=2\0dF\17´¥\f\7f78ÚW\ 3I5Bê#ö\821W/vÌó\87Dr\81=¡u¿\15K{©+gíU\8bÐ&éG1c\83d©å)\12n\ 1p\13 \8fãÃÖ\12tN~oro÷×ë37*¶<FJÆ\aÓ-w\8a\Ûõ=\b\bðd\10Ò?\11Fu\99ª\85\rZ\ 6¢\96ÏÁÛ\1d\8aÊ×Í?ÄþÓVp\ 1l\9eb¶ÀÞMC\ 3ý¿-nhÞ<\vk\14*%\80\b\8d6\ 5\ 3ew×\\920·       Æ%\93~(Hx%â{V\8fÒF\e\1f\9btubwâ)r"\99HǼÕMÞ\86þ\98Ò\ 5ÏÅ^¹&*C3\8f\vQÅU\8a\0&\1fTÐÀìÝ2\8c"\9dà\ 27:\8að*\b|Y\1e\97mÐË\8fø\83\1c\11X°Ó\ 5-Ð\ã'(iz(3\9dº\8a\1a\8f;û¼Ëï1ÔØ.ï\ 1\e\ 6ê z¦_'\9aþ íàÙO\13Á¡æ,Èû$ßz}ý:\ 4»\8aäN\ fC\8cÃx\86\9cê\e¥\90\ 3\15]8ÑðTËi µ'zÿq;º8]\96d;.\85\8e\9eü#¨\13¤«Q\1aT\eu«c´ÛÑ?°\9d§\9a\ 41à9\87ý5\11Ç\ 3&ô°\86\96ëà«¿®n\97\98Ç\8b\97ÍxÔí\13É\1fcdí¶\1ah\vuDÖn\10Ð\90k\9fEé¥\83ZL!!G¤XU(íðýê5ö\8f\84\ 5Á\12ô\1c\8b¯cF5Ë3iÈ~5Ö\8fÈèn\867~¤\93\83õ\ 2\83\95Üü°mdÚüÃFsuu+ò\ 4\99(pã`ds\ fWàP\9a­7\8d\8dêZ<:o¯îi;÷e ½°«\12\10\89 g\92ê¿\96L~º©\ 1\96ù\93E(.\ eì\9c\92ò¬\94\16^\86\90X-¼!U!\8b)\1cF"@§YGD¦îiBøÏUµ×2-\ 6Wæ?C<¦    p\9e\80: g£erIwiÕE-\85*\b¯\15\0\vHU[àUW4ðv\89\11ùa°ÝAKaì)|#øþ\12Ì@\9bÓ\17O.
-B[y\ 5R\ 3E=n±n-Zè[0(ýÄÌ\8f\95\0ÚÏK\14D0!¦³é9ÎO¯.6\9c\12Lú÷!Ò\b\952æfúþ\ 3)Îï1AZ\ 3 \9aºÙïÛ\1e¿t?ñJÏ1'\86ÑSf;x÷ÎÑKã`«uâöüç\9c:=¾ê:\96óùCØÔ:ðýF\9eæÇ\92-\ 2Üy+ÑL÷åî\bbì~Ç\82ºÑì\7ftB[ÂZ 0Å\9b×9øä\99\ 1O¨¸JÛ\b\81\ fàSõ³[\18\ e\83(A\1c\88\8f`ÇÐ\1fá¯o\10jr=¡\1aLeï\85É\81åÇùíªDe´\bÞ0ø¿VÒ¿\8dÿÖàú\ 2\ 1\85?\v\8a¯&ÌícG?\81TÍ4*\aàú\ e\10nÀ)h²^\r\88Ôû^\15¹õC±\1c\ 3´  _!xõ\91U­&\1fC"fK\10\99¿\83¿ð°¬íQñsn\95#\16|°¼ñè;º\8f\15\13°UÀ\7f×y\9b0\92\84È\8c\8aÔàõt?Y\ 6¯\17¤\12zâ^QH+Àn\ 1Àߪ\0ùu8\ 2éFDÆ\9bHûiu\8dæ\8b\87¼V\94h=ÆR\10\ 4s\95MåCʬ\ 4Ú\vþù\ 6pkén©»A\82\ 3é¼Ö\f¥Ð\99\83\ 1\81Á<¶¶-1!ü\9f\8eZD»ã}\fÓ\1c
-g\90f\ 2\84\1fÀ¶ <ÊÅ\r­ éD\99¿J\189\91\fw\v\86Z\9a8JìîÇé%ifm\9c×ÿ?&2D±ð/ò,\98/Â4¢¡\895İ}\8c\bV\1e\84\14ð\14\vù°.\12\1aán.ÄL ]\vÂî,@MÿÐ/m²ôÑ·4\16\91      `Å6?uÅq~ç²\98³\ 2w\85Ãä\99o\86A@|¢Äð\91\1cK)=¿¨·Z¤¸´VÊï\85û\f\1eùª¶ÙmÑ´\ f\8c>FSpiÝ\19Ñ\9còRuS&Kø\95\ 1VcC)ÛD@\ 3»¨F \96\11ï\91\10ÁÅ@\ e`$¨e)³®DLK\r\8béåëÜ?\ 6Á\8a\8a
-PIc¦³´ºì(ií\ 1\80\91\9a\f,N\eçKñ\b\179ãûQþ?'þ&õTanÜÂܯ7\193]\ eÄ­dÜl\96©s½+\84údp8Â\ 6
-\8d)òR\8e\b\ f\88²x\86+\99¡ñ©ÔjÎ\81?\8c\18Ò=n\96#
\93\9b\9bZ®?x÷©L8öI!f\973íB¹\99U\8e\r\8f\85×Z\83ÊLNº\ 4ÊÜjÛ\8f§T\ f\9a\85¯¾Îií\81K8#E\1câ³\b¸bÜ\adcµ¸\18D;\15\b\9dÑ\89º\86T¾n´ðe\ 4\86bmV\94J¯Ø&ý\ f)"µ(ݰ_K\14µþ_\ f\91Óz©Ùoe\96-\ f¸éD\15Ñå3u7@X\10íÅ*Õ\bÞÔ!;ãhEÝy\bìõ\11\ 3¨\18\ 6\0\16ôÁ\98Y\95Ñ@ÛÀåÊØ?\rÈf&]\e¥o«;\15}R\v²³é\ 2bL\8f\7f4ÄYÞÑ&N\19\1a.§ÔÄ^ z\1c\11ð\95:p\1af\88\82ó·2Â\ 2R\90²&âM¸É{U\19ud\98\80\19º\ 2HêT\16ý7\90ÌR ó¤þê\8c\88q£0ß-á\8a^f\8c\7fÃ\98ÔQÞA+\88cNÂR\945âµìÖÔ·\9aȲd\86oèðtÇÑk\800!' ISM2ýs\ e\82üna\ 6_\92¯ÑRÑ\1a°Ç³¿\19§er\88t\11í\10\9cQ\81¥\84á\ 1ý\80Ì                à\96ä\8b\9e1"l\9d\8els\18\88!´ÈÃ\1a\b´9[\87ª\8eË\15åqó0Áº\9fo&vr騫p\1cÑ\en0ëÌ\14P¾HòFÇ1P \ fi\90\14Þ\15{\1eàk\92Ô\9c>ó£þ"\§ÛÚÌu\86!\13\92\1f\15\95\88\8c"\1a\8c\14°¶Çn¸5ûóK&pJ´\9dB\83ë\ 5Æ9\8f\17F\89u\bÚÂ\87Ü\95ÞOS7?·\16OÓ]\9fs\90*\ 3/\1e\91Rç(á)\97µ\13Õ.\f\e\13\8f¹|¹OqôÒr\80u'\f¹{~e\99ä[]"¬Ä\1d½ê2JöC\b¼VÉ\8e£¤øáÏ#nìvCTL%Óv\9c¯ëªDç\15Z\9b# ­»\1a·\80\1fîw\ 2±<8ZÝ\91(¾TÏqør{u÷¹µ\94\ 2Cc\9d\90\86\9fW\85,Ö2l\86Ñ\16úú=\0ÂÐ"ëÔN2Üý?gÿI#\1e\14Âåi\vp\96Vçé,ôöÃ\ fMéd\F \14\9c\9b\ 6\18<éz\ 5\17ÊU5Ux\83Û\1c=\1eê«é¶(â³B\12¨Ë¬\e\97¤Ý®ëä\19û\9ek£p6\ 1Áï0B\9cÂgÏf\9b¶QGF*<2c\85
-¿åC4S
-FEN\10\15\84õ$PK\9d¦/rxû\82-SÆ75\1a\1d\b\ f\8fjGx\89¿       Æùæ\9e\88,\vîy«\1e£\11»$îä/ \80\95\8c\9fbu%;\88  @é\ 4=
-ÁÐ\ 5*\8cÃû'©®ûõÅ\17\0ãÿüOãê J\9bð\14²f\ 5f:˧\1c+Dp\17_\9bî\8e°­ä.Lñ¦\96ñ\13\98L\vR¥Ý¸Q»è\v<lb\8b®¸Ä¿ú\v\13fF\17\93ñ\11\149N\8f
-xO\9c\17%\r\ 5o\97\f\90\8e\14\13é\a{\16í\9e\8aجÝY@½;Mn.%N\v\8cÁ\80½fðɪCcÿ\91Ò¬W\a[OV@PúfæÈÚ\13D\97\9e_\85\1e¼©a
-õ³N\89\1aÜÕ±×A\10\ 4l\10¨ Ë\9f§\11X\17óá¼j! :án\12­\ 6FôÖ\8ddË¢      ôÈ(k\89»=\85\9a\8apI\91¨ìÛ-ÃD{:\86\ 3\89áÁ0ybóTܪ\8b×-\aèèqwÕ3\92'\81w+E[ï\ 6+G;7\1c\81\ 3y=QsH\9c\894>*2¦ór\90 \ 6çu.¿\ 3Îv'Ã\e\9aU\80¿\9c¬A×þËä<%\87Û%N§¿Çg\9aa´U.@\ 1²ÉBßû0Ö$M\ 5=㮬~îõ\92§aÁhò\99\1ajGÀ\ 1¤õ©÷X¬È³B\10\9d\ 3ÑÐ>\86̤\8cTªI\ 5D\94ñ\8a AnZ\91'\11·\1e,Mxcö\80\83Ì\8a\9c\8d¿ã&TÎ-ig¶`á¾C27»\99}ºL\18St\rì,U*ÿÀ\1d\802|Ée¿#v\96Ð\9aÿhGñ;\aó\81Pu¿4X\14Ð\94\1e;~Ï#C\10\1a¶0À¼ë\A\7f\18KÃ&\ 5ÙÇ [ Ò\1cT\98\88$K²Ì7Ë|Åï |\90u\8dO\8e¯KÞã\10\98,\99`iE\1a×MCZ÷\9cT^§µþó»÷¸C\92\18Ú\13ë\87=¨CZû·gF©É3q\ 4\8cKL\8c«\13\ 2\11\99à?:ô!²²/ú\8cAüi\b0VR\96lB\9e\1a~U:"II\0\8eX¥G*õ-0½_>\90\88c\15°{©\92U\9e\18ç\14>h$\87ÑRÃG×ç<      ºÌ¼Í{Öpü¦WÙ\95\80\10\ e?\1f q\1cê¤\ 6Ë\1eIô×}Ò\8d)í¢']\ 1â\10\8e\91yÙmQ5O\99\16C\1d\bÇeWÐu\8aûg\8f¬u×ýÃ\1cûG\18Í÷Ë"\86/ÐtKòF\ 1%ª´å\8f\1a!rÃ_ÿ×\82D¦èÑ´\e\86\ 6\91ÝÌ\8f\r\1c\84û \ 4$\1f<\ 6¡\8a\89?\855Vñ\ e¯ò%Íà5ZdÆØPý\9e3\83{é*ÁTÜ#\18?b\8cÉ_M\92\15âQ\xJfZqñ\92ìi:äë\84BÍþ\85*ûVåöÐûIà7/ùºw±L\89!4Å\17µeL·GsR,äã!\94dCà_\87\10\ e´í>ªpX¢MPÔ\8c÷¹\9ej½nþB©\97RYÞ4Y\ eöÚX§ !± ) ÆÇ\95«\89R|F9<Ppóa9\16\16\ 1É\98\v>2qÅìéþÉ\13 -*ûí\83\¡Ú_¶a\84Y\e#¢%ò~}ð*hZÉscó\ f\12\91-\fð\r\9b\9eòê        !¼^AxGÜ*1\8a8\85E!¹~/# l¨\93\81
-¥h\1a\8dº\aó>"Õ\97ØÁ.\1c+\r÷(§<\84\1cµ\f\1fr\14é\86.%\1fF\16\12\vt\r\84ä\13+ºéÎÆ\1c\8eàü\9a\8fGj?½³ò"\a{\9e\8e\8b3j\93"\89\10äO'5\f\1fS>¸zR´:\f\88\ 1!T¦\ 6pFÑ\ 5ë¶q#þ\1fq\91\85#¶aøÑZK¥%1\17\8c\1cÔv\10j\v\7f
-\88\96o¬.\ 5 P\85T\aòF\r\90v\1f2\18¬Á7¸GC>fS4½\97Z70_!fÆààþ¨>Ò\92§-ü$\92\12¾\v\91F\ 3¦ír\19\19ã\r¢Ý¤Û
\97o\85øÄNE¢»\93fj(Î\84\ 2èd\ 4'WYÊ£ÇD\ 6¾Óèqu?K²+ü\0\ 5X\18\ 6ìf«ÁC®a¹:í{hÍ2M>\89:\96Ü)\97\7f
-o9\8e/\9f\99\\fÆÆ(þ«\98\ e\ f\v\ e\18׸ÐË0´´XUKþìmvÝXÀÎbâÂÒÞ¿\80\e\94\1f\f{âL`¼(\eß½jf[püòLJT\ 3Y\9a!\ 6v¶¯ì$ì\vÍ\r\10Ç\10êD{£÷ï»ÌFÀ\85ÑrÇKî\898l`\87¨,3O\rAISó\r\90³óÇ\ f\7f¹\85Éëb¤xÛ»9®\13#L¦\eµ\13¯;\ f¥L\82\12þ²m\16_¼5BÖ\v\1d\84OLl \ 3îwõ½õ\ 6C.ö\93(a\8cƪ7\163£S\92¯Vëâ^\9b-\9b\a\ 6þ{Ð+q\b\80ûÒÝ\109OBf¨Ô\a!\8e\92ÛÈ\95z\9d-\ 2©\9eFE\16åáÅG0ì¼\9b°\80e4'\94\12.\13É|\8c5\89{«­µW\eT$\18?ÒLôØÐÁ\ 3\94ÎñÖ®\8c\1f6\98\16èµ\vðå¥Dw\992ôeÃik\1e\10e\r'\13ç\90\Dj¸ïI\94Øl5¯ÛþbÝ9,z^éôáúê}ó\ 3\88£\ 5Ù¯«Gbø9¾ô\16f\8f#^s\8dúJü|.CN\ 2\8bæZ    \ 5G\92\1aê\88Öʵ¤\15\14d\eÿr°¿ÉMz>\13\86 ï?\11\ fæÂ\ fÛjϹËðµq{V¦\ 5\90\ e\83\99\1a\80\1a\e%@¬\99Q)\82\bzu×\81{VÄ\9bÌ\13¡Üá@xRÁqlÉò`\ro\1aa\17üá\eZ\9cn%'\83Õùå\a\f¦m\86,Þ±:}ä\8cØUR\9dq\0Wkq\9d\8d\96ìi\12¢\92\9aâvÇ}"l¸\8dð׿_¶µÑÊy!@\ 6¹\17q¿&!¼1Û\99#¹°Û_\8f©Ýýéñ\ 6\16ëà<\8c\v/j\92\88\9c;RÞ\8eI\8d\10µÜ³Ñ Õ&\ 3JºÇÈ\87Æÿ
-ÿJâm\1eer&
\89\8bìzA¡Èr8\f(\ f\ 5ò=a² H"änT?\11Òq|%^;\1f\a$ÙØÚlÒ\15¡\ 3ò7\ 6\85H7\ 5õ©\1a.T\12\116Ña"\18Z%\86zZ\ 5\ 4É\19\ 2»\8b\97\8b]r\b=d\84Êõ\91H\t\9e\95­'V\965¬ÐÆ\81v\1e®iåK\10\88E\bË©B\96®²\9cÎÙuf\ e¨¡pàÖ$\86Y©²"¥Ç\7f
-Ò|m(À\ 2r\9dfÈT\80/ëklxÛùî<=\1am{\19\8c{N\80\væ\ eäü\r¯E¶dè\93¨G\8a\85Ó ¿»G¸«\ eËÛÐG´ý´ël\14\150\9d°#oÑ\ 4xb\17\85\ 6ëêrWkKE\83\ 5V\9a\ 5Õ|\9eI=H\9f
\88\9eã\f\930\90SÕÈZº%O<\1fÃÞ\ 3!|,²\1e2§I3Ç\90\8bSC8\8e\12\98HáV\96uþK\92,\97\84\10Ê\14-\\1cÔ\12æ5\8f\8cÙ\ eßÍF*\15)\9bx\82ø\9dÿ\0eaXÄr\8b\9b¢\1f\95ÂØ©Ñ\ 5îÊÜí\8eOI\\aÈ\86\8f\17Màò\91u0 FS/ \ 5oݱ©\95\8cP\ f÷ÇOß2JÑ>ZÉ\89\13>n>ýQ\ 4\99z`\9dG\17£¥\15åå?ãYQð
-ï+dò=¢U\ 2F\140L(ÉððM\ eùR\15¢nþ3\8eI)~KQS%\ 2p\v#8Oë\7fÚ\eIÊ8\15¯\0Y\95ºq\9bÓä\97\91ó¤Ë\83çN\ 3jÒ¥®$4¸×\v\8aïù\f\ 4¡V\85ý\16\87\82\ 5¬­\85GßZ\ 1¡¿+h&ð¯¡c\9b33øC3Q­²»Û\87Cî!Æ\15_97~\99á;\9añW¯¡\9dÄ\80Ùcç\94\9eeåíAßï¨Ú«*\86[èª-¤]y©á\9eÄj)ÖÚ\1a1RXÂôSâ"­¥\9c®{ZDÉ\88\18I=\8d}0\1f±\8d\1d+ù/\1dIhX\ 2ù\19Ö©á¥E\82QhÆBÉe\f\1a«ð¨!\rZ$Wë\r&*ûýÌs\f~ùà\80\888ýPN\0\9aì+j ¡\9f\ f¬nbÆ\88\1f\7fq\13~\18\8c\13Ð;X»¿\94ÐF\ f ëaܽÍY\ 1¢Ì\akÉÛÒ\ 2Ú<p,/\vb¡]ÜåÐFȨ\92\8açj\90³nâÃð[L/Þ-b¾ü­\8f/\1dðsL²Ì\12#óI\83 \95\1e4P\95\8dcº°\85þ<·\8a¯ +r\8ei\13\93o÷H\1aú³Û\ e\8cÑãT\fUz¸\r4V­$x]\839ô8À \aÃÇ)dpÕ\8e/\13\94\87\95«´1\10¾\18\9f\11Çôä·rP\8aü«Ã\12jÃݲ\e5\ 6\86ýl';ØCÁó\ 5*ÃnÒy1FEîÿ\85.\8d^=\8fy\99\97\ 6\8dKÂ~ï¿n(®Ì\0ñ\81\82"?×q\ 4 ({\8aDa@gjìwwO§   \8bÁÌ]\9d\1e7\91)^\16H\a­ôÙÀ ïLzüë°\8d©÷\92_H{ýyäǦVÊ*?Å\0\13ÐÕ;Ø7CÛ^Xõ?\9cl\8b\ 2h#\1dS-Z\b\10Ð\ 5ð©»\90\11~âEr¹\ 2\9a\8a\1cÚÇç)JW©åKg­\13\86ì\95\8bb»Û-$\9c\ e\83áV\83û\91\8d\b®\ 6\1e)HZê'À³îì(=4I8¿m.\ 1(Ö c B»\r©¶z\97ü«#]\87H°Ìãv\8e©Î\9aª^ØAC%\9d\e\9a3Ï«\a\1c©ZìB¼\\§
-\17L0\f `ÐC\91³Ï'\82¢íW\99{Úørïøö\90ä´\87¸t\10ú\9aH?0\9eb=QgüüµlÖ¾\ 4\1dð\99\10
-\ fÑÏ\11¿#é6 Tä·»\84j\9a&]*ãëS\12\97\1c\87\8f\1eCÙWì`ßi¦\89\17Xz\9a\94ÿ¹û\ 6\85â%¢s\1d\ 2ôHãø]°\12¾\9b\88\99µî\15ÆÁ¸\82üçÜÑÕ\9ez\ 2\ 6m\85&-\99öÙΩøàÒØ]Àj\9ed\97¥^4*Bk'+\88|:\ e*ɼs®Í1Sg\1c\1e\asçÇßýB8\8c±â\88ø\1d\8e±ÿa.\1c\14°1\ 1ZRÀÝ9Ò¨Í2³Jr*\ìÏ\ e\1eö\arC\80Ce8zø#¨öÂÊþ`ðµwÀ\19\atu}/-$e\9aÜú\8b\a\ 6¥)\19«SÓ\91Û1XÛ\99\9aë\8b´\ 3¢*Ͻ\1fÄÓ\ 6\0Å×ðµ\85%k\1d66==ÒD\8a\13\86n¥p\8b±à\99*7\ e9\ 3\0\92²\ 1\fwPñÁ0UZ8Z¡\ 6\8eA>±'«F-\84Sð7       \v       hÄ5`] 6¼q¿¨±\18H6F\9bË\16ÜàS×\8dñ'\17Z=¬ÀZ{KØ9\ f\94\8dúÕQëCZÖ\80\8c\ 6j}Ö ú¾í(\ eø"<Ò:\88±®\ f«\1a\1c\8b/\8e\15h¶¤\0úq`\a\vÚ
-b\ 4}\8f+Oßì_è\e\1a\18r,Óè}ýýrYÕhÓ¯×o\1ð\85u/c!\89edíxu},
\83,\14\12:à[l¸§ã\98q\8dJ\14\1awòC\9fyªBø\8bQÆüu8\10\9b\87\1e½Áb\8eeL\ f_\9dÔ\84    +ÞBê\8cx¨o?ÖT\14`\1cÍÖ¹X$bzVv8\açD³\97uÄàXxÝ+ÅÜ\15\87\8eb\94P8e¼\87êr¡AÞë\87î\13\94C\88,\amå¨ß    \1dé\8ca³RZý¿\89óØ1&Røms§\ fF\87Þ¹}U\1f{>îr\9b[\86h\vºW3eë\rÕߣh\vÐæ\12¤m\f\1c\88äàã\86\84ÎB\13tåx\97kóÝ\10\9f"×˦b"/TÜ\90/\9fü¹\ 2zïf\1c~7¹ÔôÛ¤\88Á¥Ê2Ðú\r_*µë\90\9c\fñ\rKËôM\96µÂÅEZ\95\8ej,ÿâ>\ 3\94)ÑN¶óFKøµÔ²Í¿\14ïîhGôE>¼<RÝü\ fò\95è 0\92O'\e$\99\fG lÔÛ7cÔ«ôgGDEP,-\14fXÞÖýØ_\ fóG\a\89\eXPWA\¹¯g\0ò/¬C¦z\r("p\10ã
-P\b\1c\ 2\8dO=Oª[¹\97\88+^ø_öë®C7\9c\0\1cPuw5\89Ò?\97Ï\80<ÏL%÷¬
-:\88ð[Ç\ fðÓÌ.)¹   \9b:\8a:mYX=\ 4²\920±«\87æÉ]q<ð\87VÍ\ÃJÿ"\92.$w\1f{>d\82°b²î Óü\95\1dØ,Ôõmª\r\11db\ 2ù\ fê&\89t\9bSÀê\½i ¹Â\82aÚ£äÜ\1f\95)\b\9c'%ÑÆÐ¦ªÝYV4\89X\ f&i\12,´mæ6Uj\15Ãð<âÀ\8d.P"\9aÚ¢ÃqÉ(W\92É)v\1d\9bqq
-\ 1,@\8e\ 2\17³\ fé7\ 1\1cL|ëú\84j\14;2@\84\8aøB[÷C¯îÅlé¾¶EöD{W½U\112¥<\ 3ð\ 6;\1cè\ f\11\987ø¨/&<\1dò\14_^q|A        \95D\8a?ÀfÔh;\1en\ 4÷\112!\85\88\937Hõë\87Ok\84©ÏneÁä%à}0Ö¬mj\e\e J\80Ý\b½#á)D$ab\83½58À\11\84;\ 5r\12\80ùTLá'yϯ¨Ô.þ'ú¡ÿF\ 5\9b\ e\82t\86\14u\99
-\94}-\98TãÆE\91\17*\fiÙ³\88\81\84[Iò×â\a#\9eÈVN\ 6ð9¿\ 1G¡TÚÇFßw]Ð\16jæ¢Kâ]ü®Öø\ 4nt|\16ßÁWc²VI n~ÙoJäÔ\ fp´6»\86¼\ eclL@z~I\18|­'\r£B\94ë ü7ôä\ ez\11\9dô?©´oEu~6\9c~¾(\1d°?wÏyY\8ey\9d\98â\ 1\ 3\v\17}þNëº]\81º¢sÞ\ 1MC\9dî×òmaØÛ³\8eÔÍ\18M\18GHÈ
-               \94R\14ÃiÚgg\94\0\14æ&4P\8cïWã\9f±¢ÌÌ\13\1eñ\17\ 6\18°w&iU2È\9cÌÂñ\93d\86ì!Û90;akW½î¬\8a¯\8a·»h\8dJÎIò?Ö_^èÞ\9aÇæy¹\93g¯2J{\85\91~>¼8ü¼o\98hN\7fÁ0\9c#ïÖ^%Áo\9d\1f%2p÷\ 20Ù`ïñUE\12\89X:\83\91aù¥\[Õ\93bÛ¬uj2F´\ 2Jeywk\83\82\82)\99I6UX¨\9a#D!¶NxÞ+2K.\90\17³ÅQ\1a¯t¿°WÔKÎ\9aýUí©\82ÀÂþC#\17\90~¹ !W²#x\96\8c\b/ZØzXȦ\91\8bñ\ 1Þæ\ 5´\7fJV½\13®P\81 \14®¿\9czûúz«Ñ\vfëm8\94\ f\19Nk\82áÖIÏav\nB\81ËF\fdWTQ§\96\ 6\97\ 6\13\81\18_É ÅG÷\0Ã>¼\9f\9d\9b$Óó³«:ö¹'×W ³9&\13¦oº(lE÷Ë\92é\85w\93\ 1áÆà¤ÄÊ.ó\11\81\r\9fÏ\95½_èk²\9a^.¨ï>`ÈÃB?çN/É\ 2\88RîþÒ\8bPU¢\13%¿ñG¦\97W\9bû7*(h\85Ç)L\90\ 4\12\vp\ e\82\81SgÎ\ 4\96%Ô      \12®Þó²Ów\19+æCÛ\9b\8d\97@ïã\82\9c\89\8b\1aV&±Ö²êØ=6nÏÀ\8e\18Ü.QÆ\ 3ÎãÞ\ 4*\88\8aÚÇ%÷¯
-Ûß\80¶¢\9b"\8a#9c;\147\80Û\14¡¥×÷Ý[Ó.N*`¡\98ó\18t2Çú\\82ç+\815\86\båüÐ\9eY\13^ h|Pv{\1f\12\98\99­.ýR ü\b;0\ 1\9dóHC~¥Ì\82 #0CS£"gts¡\1csc£)26Á\91\8d\9c}:£     B\1cà@\89`ØK\10\ 1¡C\9byÔ'\fÌÕ¥\8b4\ 2>]õ=Óz\1eiBºQ\8cG$=¸,Ç\89\ 5áv\1f\92fª¦\18Ý\913tpNÐ7À\1dQå8~/H\97nýºÜ\17eíT\8b`\14\ 4¡\ 3QlLÃ'wVÅ\95^ :l)ÐæAYí\8dÕZÁL\86ͧ$\0ì\17è´\ 3ñÂ\9dÑ\806Í£ÅA.ZÑ·!Ø?Ë\1e<Vc\12/Wÿ\bç\18\9fð~\85ME~s'¤?\ 6|\12\10\ 5¼ª\99õ\94\84VuåfT¡È²:Íl\ 1\9fØ)ã14Ìî\86ÑÇ\0Ä[á\14\búM\bâéÍ3
-`EìD\8f%~\ 4\94Ç\81\a\1f¤+¢\8bTe\10Þ·¹Ñ\aIN´\9fϯù{¨?3«w\ 6£þ?8\91ò§\9a\ 1Ïj5\0þ×ÔL\9e&<4\82\8d\83ðM\98¡\81\eêâ,_hs××\f\ 66\94\aõ\1d|^ôëu\8dèé>Ã=­­ï¤ôVÂ\9f;¡{­ñ\9c´\90\94äû`    ©öQ\1fû\ 1/¬Ù\9e\10NYû¡Î\8d0\85ãø\1cåâ\apV\99TëA\19î)ÒÎ$,³¶e{\ f\84\13\1d8îõ¿k¨ß|8)@Ðv\8c\vD\88\92ºÿ\f\16\84/ò¤§rCëÉNÜ"Ä=\8eë§\11§°\11©<ô\9fø\13\1dNÓdÌGýªõn   \9b\1f³\\94ã«`iÕ?D\88\15\1f\9b\81«qns\9f\9d\a$R_`\1d\93\8cç\17ïÚ¿ð¹êè\95\80\10°VÑy\84\ 3\13iLqá@Ì¢<«\97ËD¿"Ä]üËÈ\ e\19à!ÒÄoyWj\85®x³\ 15\83\88+\18¹xu-X.7\ 5Áy\1a\98kB:KßFô3»-,ZP,Ô\fdÙLîߺÿH\10:¢ê·¥«~ÏËså\15þÚ¸¨\96b1ù´b&o9p\17ßzÊf¥ôÆ Y¾\1e'J\bÃÚ×\94r\16\17ÿ\8b\f[å´Æ>æi]]è¥d\f»þ\9aÇ\9a\86£\0ÎóÒ|µãý#4\87A¿ø¸å\80AD¾O«÷\8cbÚ«8JR«lÍÇ¡·¸k}ñÌ\12¹m\eÖT\89¦úLX¹µyÞ>OäüøÕi\9e\16(\ 5\ 2bh0ÇKö\8cçk£ÐÇ_\ 2\8bA[\ e®\ eÇU/\96\91ÍGSäÔ°[\9dÙE:\ 3\HJdtÅÛ\8cÑ\96\11\10\83§´vë/¸\8f{òg\1fÐþ\82\85ÝÀ-C\94ßT¤¨×*MøiÞV\8dî\ 6x}\11\9bO É\e\ 6\a\ 5d^(\95\19_Ð2\a\98Pe`Þ'ø     Ù¥®m¼9(\93\a\r1¨r¿E\8bÇ\82hU¾\r':s\19´\921ûBHZÒhõ\15W\17\eÝB\15ôò\9d¹\14*y(¤\11\15yéWhæs0ät¨¦¿[¤hÂD\16Súxà8L1­\7fT\81oð¸êÑ\9b\ 6Ó?\9d×X´þYÃ\17\¢å¦&\ 5Î\12bpþiQ0f3%sy¯\8eM\95\1ewM\15¡3ÕáîÍ1\15#`d­\8bÈ\87\1c       \81\15m¯|\85Çka\16z\8fýaNb¤ôÕ\18é\87\80\88ó½\83ê¢\95óK¡\a\9bã¶oY\9d\90\ 2Á¿çüçµ-³as\ fÛ9\v½ú6\9bÁ)ë<¼\90ÌBJ|«r´oEï\98Il\11        ­?Ôì7\10C.\9aò\8cØ?\e\85^T«¹ªQÕ£·¼sâ\89\94V¦É\ 6ðªi*[OözI\f\0h|Qg\ 1\ e      \1c\ 2\9e\bíI'\80À|nûVÅ\90ï¬àuÄë\98(Oè¸\ 6o_X\89Ò\85õZ\88ÕD\85è}\1aîn\ 1¿ú=¢\85â|öæ?\15\ e6 ¤¨æBÓâ+ûF\93\9c( Á\81ÐB}\14<\81KÉñÝQ´Qù\9c\15l4cu^¤P\9c\9a>\ 6w@¦-¸5\8c\96\85¬Ñ(æ\97\19Î\ 2ZVËJ/ìu-OEç
-vJ{äF¸(\19\ 3Ý­ËÁ\12ýµ\82tFÒ\v\995\ 5P(á¥[ÿ7\ e¯\85j\12î6¥^f\88¨\90sYÙè©\ 3\92ë\v\ 4\8agsÝbÃ\18E9\96S=\91»k;{N\1c\1eà\8aJ\9aU»ÒO\93ÿ·Ì?\17¯e\17/\83S7\ 4z¯ådæÚõ¥mºâ}\9c\86ú\8cÐï    §1\ 1¤·#\8b\91
\91
-M«X\85&Ú~ѹ\vm|ÍWòÏT\15æK\14Cá±»¾A\1f:\8bÒçhe\16\9b=\8dÒR\99\1d¶ñç\8e!\8e³Ôºí
-·;µJ\þ\81íx¾\r@\89í¿1      \1a\10:aGê¯D´,{Í3ï15Ð\ eÎX¼`-ËÓ\aîóê-\b\96\94\92f¨ÂE\851ît\\97ú\8bã'\99Ý4Öu\18$ý!9\16¬¬P'\rYl,g1e-ó\ 3:\10\90\18+M\aò\IéewVÄ\95[TS\1aÀ/ÓK£è;\19\9c\88\8aX\97³ÄbHµê9\9e\1f¤\19ðå\8a\v
-î¡M\8a¿½¾Ü¥+´úòG\1f\93\9e6¡QÝ\97w\91\93ÔE\1aâù¿Ä¥\ ezª{8ü\17¼Hzáþkû#Ï\ 23°(*^\95¢\98ï\ 2R\9a\8c{q?Ì\14ó°Ñ°o½C2°\8fhîU±\13/Múö\99ê\91#2¯Ù\a\rX?ÚÃÁ¾f\ f~[¤],ßP\10¬3\r\93l¢ÝuÍv»\18\11h\8fã¿NzÇ\9bW\1fÆkAø\982kµT\9a\83hk±\ e\83\84H\90zF^Wþt3z\9a½\9b\1f\1av\15ê¸t)#\88+\eÌ;ï\93¸3½K:8    çN%\936\/jÄ\19òÑ\1cïO\ 6\94\98ÞÃ÷\98@ëJO\10EoP\ 6z\ 4'F\9a\ 2±ë¹ ï\18O\19ÖÅ\89Dr4«Ü©«\ f-1l\8c\8d>\13æ¶\ 30\1cc\8b\1dô\94²1ÓÛD\83\ 4å\a¤blϰ\9fð4uXI¥ÀÀå¨.`\16{¦º\14ì&_Í ®ªì´¾p\e\88Ø'Ó\84,\81Y\11\9cõò/§\fD\ 1ÛÔ9Ú5Ñy\95æx=-&¥ATåì\8c\97wu`ÑÎÌþ=\13Æ^>&\ 4k\aß\80½!\7f$6Ë'\7f}\80e\9aШq\eY>ú\\röt8\9b\82À\84¹eÏßþMéñ2Ý/V0Ê­\14-ÀÚíIþ3\18Y\17óH£È/GGî.ØØ6\8aF5×a\95(z \9a\89}\1c§\1e\91jfÙZAé\15Ö\1c£+¥¿\ f\ e®\bÙü2\88\94r<\11PnD¨â\92$b7wÜd\92©ô\ f\9cW\801IÉ:\92\ 44Ò¤\7fú\90\8c"½Ä±ñô5äìÞ6{\1a-Ô·\ 4Aÿh5\18øý!ëÁ\1dÅ\8d\b\96\97³\ e:E§Þ\bþJkN\1d:c#XÓÔæ\81QâVt×4eöi©fï5ئf\7fX7ÐZ3Ò\8f>¦§\98£\83låý\92\82\ 3½a\15í·\15\81\97\88?_Ç\92-`\ 1^t\9d\ 2½¨
-\18Òû\võox\82í?¥\90\ 6¤\98\92ôÌH\91,¹H\ 5ÚìÒ\\12\95Ý\92Ö¸\0\9eç:.§\r\89wFFå(Án×I\1f\1arC\12Ä.Ñ\84Ñ\97óò¼dÕ\99R\85Ï@\b\úb³h\82
-îj#­ÛE\9dÁEîehAþG\89²\9f'?\84¶kM¯\e\8b\96ä§^k8ë[@
-'\85²\16\1a±\1f\ 5O\90\9b\86\80q\1c\18\1d\1c2µ÷0à\84tÔ,S\14©\91\ 40\f\86¹µ¤­\94\ 4üÓýã&¦I>iÍÊDP\9aúÇjL!ZÕ¤4j\ 2ÕÙùg<9\19\1aîtÒ§6zz Ìb\15j\vwÌÝ¿)õµ¼ 2\83@
-  h:CÏÞú"w¥*Þx*\8f×7¸\1c-bØ%À\ 6 \ eܯúK\ 2\ 1ôq\99Ý\9f\9fá¿Û\16¡úÀ}÷\b4\19\rÙ\89·OQ\84@,à®øI\102\83\b\9f|ÝÁ[°5\ eå'@®\8c£\eWãýÃ\8f*8älM«®uóÞ«)>Í+N«Ý\8f×2\82\ e\vÂÂPèK%\82Ò\18ÚøÀb±µ×"a\ 4]\e|XcÙï\1dÄ[2\96¥°Êx\84×ò\10·Ô5\8bLO&\f\94Å2Ǭ\93ót{\877Þt#\93º\8ab5\15¢°\1eÚrå\86à2ÓÌæ©¼Çn\91 R\16H½(̧R@Ô\e¸èâº0\¦Dd²L%]|ñâõhl2Çä\ e\85R\ 1Ê5Ý<) \0`X\aÜ¿Ë3\ 2\94\ 4×uÅuG]·zÝì°'ef¦dÖ5\83¡À{j\9e\b^\8b¯\vô\ 3ã\ 3Û\ 3 \8e«pµÅ\ 3f#   $4f\19\10\81\ 1\81\92ÃÈ\b\11\83-D8Í\81\11\18\8cöfàõ\bÍ@\92UN5ú[ËLI²lNW.5/(Íp\1a\84ël\12jÀ©AÈj\87\17ëômÉ\ ew\0½\bG¦Z     N¢\b\82\11útT\ 2\18¬8ß
-\æW[Øò\82à\14\88\1fÆ \aºVC\b6&\vÎ\9d\95ô\116Ô 2 ¥\1c\13ôVÚ­õ\9dS\98bNGÄ\\91u*¯H\91q\88{eóh4ÜÜ\ 4p5±\9c*/) ¥\1dµ\10Ð\9bäZ墱ªRÒÌ¡¸àÁÀ¡¸\93\96CA«*\r9\14\18\8d\100\ 3ë'\86\8faÃÇp§\14\9dà\14±\11§\88á[I\14\8a&Ø&J`\91(EÅÚ\0\f\ 1fa\b\80!À,Í\93Ò<4O\8a\ e\90t\8e\95j'`®±Rí$¯T;Q±`v\80´à`èñ}\1a\ fïVJÁÐ\ 3ãïÓÈ|\1a\ fÑ\96\96ù4\1e\1f\18z`\9d§ñ\0=\f®#0Þaþ\81¡ap\1d\81¿\81À\99\7f`\fÍÐ@`̽è(÷¢£,\1e
-Qw0àr¨Ë½ ¨H\92«"IT\99JU\9fä90\9fäyèP\1dèáP]zH\17¹s\86\8a \87A¯R\eK¡Î)kb\96R\10`PxPÑ\13a¼BáIx(\ 5´\84\87\86\ 1gªÝú9:\ 6Ø¡óÚqNòCã\eV\95\9a¸X\fã'\10Ú\87ÓwÀÈrkæ¬\96È\9c\81*Êb­ÌbÈ\95JùÆ\18A\18\ 6\9a\13J\b\10A\90Ï\89ú\ 4Ô\13\97Ö4Õ_\9a*\1dvgK,\96LY\f§0Ï@\88ÖÂ@Û\10Öô\9c\8bO`fs |F2-èiUÆóR\8dß\8e\100>\82\97\ 6R¢ñ\e\81(ã÷\ 1\19Ƨ³ ×'0\97\13\10,øð\87Z\ 4\19D 9\13\88UEÉ1¿TÇ\82I\b\ 6Ì5\15              \ 6=Re¹\95v9\89Ùr\82ËIÌ\96@\8fDZ,H$î4:´\f¬W\19X?1|Ì\8e\8f,åT1)§Ê\84rªüD\11³·\12¾\95n%\11N\11³\f\9c"f¯Y\ 60¼YÎ&²\89Ò\10        ô\ 6h\1e\9a'³ÁÐ\ 3gn\190ôÀ\8dÐ\ 3+>\8d\968\88¡\aÎX\1dÁ\ 3ch\98\8cë\88\1dæ14Ì"ó\98DÙ@ 2ÿÀ`\f­\84¥¨xAuê\ 5=ÄCG0¢â\13¨2U¦ÊR\8b\98\1aX·±t\eKh%U¡\9c*\8foc©b K¸\92ª\8c%Ы\8d%ÔF¡\[ÂCÑ$<ë\84òxBRD\1a\8c\95½v\82w+è]ÓÁØ­$âZB\95\8a\15e8'¨d:|Ò\8dH\rª\15\85\93ÁÃ.Y\16\ 3*Ì    \ 5\8fEh ¯ö\9c¹ð\13\90\95­\8b"d:¤øf1äN¥¼® \87
-A\1cqØßXíVRX*\984Põ\ 4=8g\ eô\14\87\95j_\96\13É\93\8a\ fÊ\16W6\aÁ\80ø \f``\aÊ\bcJ&?£\108T\8eÔZÑHt&d@d1Q@\8fÇ
-b\Õ\93Xç?B2\12X=\99:V­]\8få¸P\1fÑ%p\e\93aAk\11\fª²º\9e\17O\80\88\9b\1cê\ 6äZ%Q\94\1aø²´\88\9aË\94\91\85îË\9c®DîêT\ 5ñqÄ\95j\19\87\95jo("\v@àð°R­í¤¦µ6\ 1\fÅ\84 ÔçhT,³,åhTìÈ>\ 2ù\\84Ò?¹ææòfÕyä°\91Jn¢\a~Ef«\89*â¨h30\9e\1aßR3$Hf­\1cê.&¨io\17\ 3ëE\a\1a\8f0@/äh赸¡\19\8eè\811\95\0\ 4\16\eãA©#\1d\98\17\81\1dê\8e¨\ f¢¸¶\12*\8a8EÌ\86ªFE\11\86\0S¨:\95FÅr¡3í"{`v-iT$q¬Û\80fDN\95EÉaöÒ%~§O\8düÐ\84\83ð#x\84ã§6vâ\87Q\98ä·0qÂ\8f\8c_%%\1a?\12\82Áø\81ÞÎ\822Àf\18;¨"\ 6!\ 5\94»[Õ.7³Þn\10\b\v\13ËÈ1¿L"¼\1f\e\8c"\ 1o\ eÔ´\e-\98Õ4\9diOѦb±\84§H\99\94D+Ë'£²ls\1f¥Qq1*¡¢EiT´\9d0\81K\94F\11"\e\0I\85\80\ 3      ×\9e\88p\9b\f1£`ÓAê®ÞdM¦É¥2iTÜ´\80JÆ#\8d\8a\91þ\91\10ÕBE;Ò¨92'\1fÊ%G.þ d\ 2\8d\8açæV,8U\82¤v¨»z\ 2\8d\8aÖó2U\ e\10»\81\88ì4¡R\18£ӠçÐ|Â+\11°¨á\95\80\93\81ï\92¡hb.O\84!+\13\0È#¼$\81FE2\93áE¬âa¥Ú\83À\ 1\15ñG£"\ e}\\1f\8d\8açåázZÂ\83\8aæG£â;H×K6#Úà\b×\8f\1f\8d\8a¥(k}4è¡þs4*b\v©¾\85 Ô/_Y6rZ\8bPÊàhTdà$)èýä6¾
-\7f©Ò\82j\1e\8a;BÐ\9cÆF\8b0\1a(è5\16\8b\97E\8dF\99\88J\12UÄEF£âúi\ 2 2H*f3\ 5¡Ê²\12\10\11\96C\91\10mZ\1cÈ¡¸bC\9bÖ\ 69U>ÌÚ´\8aCi\b=pyX©\964È¡.\82\ 230I\1cË´ãKU]rF2mÇÍ\\95\1a¬cÚ7Y\a\13\81Fªò\97\8bº°ìÀ\91".\ e+Õ.F)Z\11K\92«9`P\93\17\bÑ-\ f\87î"gµÕ\b\87 \14\83`6\92Q\ 5¢Þ\8aÄlå.R\18:\13"ÂIF\95|m\89\86\82?tâébÃ\10\93\89\eÈ|E\97`Ыµº\86Ø\14«æ?\a\87Md$rY0\8d£:Úb5Â:¦UqQÅ~Jy]?\95Å´\ 5\9cÓ!Vph\80øu\r.i\9c\ e)Ìëª\ 3\9dªÝ
-z"ÉY×0%°²¸\9d\15ÙÜø¤Vs`³XÊ'c±\r\12¡b%\8d\84\01\97$ä§A0\18¿\nÑÑÄ,\88\1aÅ,襹Gxm\96Eú AÊ11\ 2\ 5®_Ku\13¹áô\aÒ\89e\8f%áÌ¡kp\19`;åV\13¡R±\86\ ez\ 4\9e\82\96εvê\90»\8cÎܺè«u\ 5%vj1®\98ÅJ2\12\8b\85\80(ÂÉî\aI\89å'\1a \b¡\rØÉ\96\v\ e\ 6»ðr)\88\81;]`\84âÁ\19} ÇÙ5È\1a©ï vr{dZÚ\9a\17\14ôÊ\8c\9aöCJ;j/Ú´è\90ÔI;J\8e\ emZ±\80¤\\86ªQq\9cå`v¡jT,U,\98eUF\ fг:ÂøqÀ¡¸\fX§¶Ñ    Sï\9bÎ4\10ÐÜ\\1eAÈVEq"\0E\\86\ 4\8a\ 5E0éDh"\8cbQ\12¸  \81sè&°\89\82]v N$&ßhÕÊ&\84WÀê\9a
-´S]M\82êÚn\v\15K\93\12bR]=Ò¨¨e·rU¬°rS\ 5»\eJ \ÝqQîÅD¹#\8d\8a¥C¥ÜÑìµ\vïê\16\94¾\ 1Sx\17/\14\8fpr\bÝk@H\14È\1dÌ·&\81W\124vx  4*âÙÀÆ\14-¥/0¹:ªëí\9dlWùA\90\1f\8d\8aäßZâ\aLµ.G£âÕlõ-\87£QÑ6n)§L¥\1c\83\90cpA\90\90\8dåëCc\ 6\9c\8cÏȬjv|Ð\ 3½×l\15ôr\8aÃJ\ 5½\9d\ 5Åøt'Áå,/ÈrÌl\88;\bA\12ì\81æ3ûcÜ\87£%¾í\80Û\98\8b\80Òêz\ eoð7\a
-zÖô²ÉÍ$]¢Fdéz\98\ 1=\95\81b|kZÊ\896íZ@\92\ÅèÐ\f®M»xE©ÍD9&xPQUÛ¤J\ eÓ*øLü\ 5N¤Q±õm5\ 2z'\92(!Ek\1aS@
-CF\15ÏìÐ-\ 1¯\9c     Á\bèL\88á5ál\12(EMH0\8b\89²\9b\80\eUsßAäSWé\e´z#)®$°íÀH\7f·»mÌ\ 4È0³ \973XÇßp\ eZ_nº\ 6uR'\94\8f\0ÔׯHä³YIZ\b¢\84´ÆB×\15ô&0U\ 6\aT{]\91f\81ÝZkL\80èÒ\88ê¦\13ÛÆT\8c\ 42V\8d\80@\11]êÇ'mr¨\9bË\15\ 1K\88 Õ\89|§46YKö?Ô!¾\ 2RàzqÀ`\ 6IA#ÇDL\10¢ñAoÅé\ fä;0Dp\86\ 4Õÿf\ f\1d\f¶Zl¯Z(À\e\v\1e\1a\0[BsA\ fô@\ fô\ 4,*è\81\95\13       Ñ\87\8eAM4)kG!©Ä\a%»>ò\¼\96¤\12"$\17\ 4dzh>áE-jx\1d\90Gx\e\ 1\99l\94\88ðJ
-L\91Ð\aÒQ\1f\97\87Ë\9clW&\94¬\ eÒõ\1cá\1aÿö&º\8a¢¬Å\0\17\b\95º¬¾\89®\17ô\0½×lõ­\85T!\bµqK\1fô²,ý±L¥\8bPú3
-àIAÏtÈÆ/yJÔ\8c\1fÖìÂ@a!©\98ýF\995!N\92âðZÀ\0½Ã\96¨©!÷\17\ 4ùåÛÉmüó\13
-0G\80\ 5NÆgèúh6Bã¢\11³3\8ahxУÔ@²üF\bÁP¢T\9d      %¤DA.\7fß\ e¤s\90 £6k<D3¯>\ 1\10Cnç\f5}d7uû\95\9af\ 3ëO\ 5%ɺ\82^Å´}$\ 3¬cÚßÝY\87cгy4j\11O\95gQjà¡\83h\ 1\ 2§\ 40#Ö:\aæZÂ\89ÐÆx`VBè\81I+\13/+ù\94dyS\92pQ\10\12ðÃ¥¾¸\eRÀæX×\9e¥S\ 1A\10ô`2Ö-\80Í W\80­6]\ e¶Ê
-0\19ë\ 6Ó±
\0X9\99·Â\12\ eX+\ 1Ij¶îwg]îË÷©±Åz\7f>3æü¼»Äß/>1ïX\83{Æ·ÿî¸s\9eOËíÝûįõ\9fXküÛêÿ³ìún|w¶\99\97ù?\9f¶ìøZüü´\9cVèç¾Úfί%Ïþ\9cÿãò^¬1ïùr\9d?k~ZÝOþúí÷2\9f\18ãû\16ç·ö$\vÝö·¸ë\13ÿ\97Øb/@áÞ~ÿnû¥|\92.×¹w¾ñÖvc~9é\ 5\8b3¾Ûâ¿Ö\96\9bïÎyɵ}ýý{þ]Þs\178Ͻã\8cÿÞû\97\9f\9d÷\9c]vã½ÿ´åÞ»ð'YÈ\9a?¿9ëî¹xÇoõ[ûûsÞ\8fÏ·\96ÿk[ê¼\vXgÝ1YÀ\16?þ³ìüæû¿qçøË\7f|Þ­1Ö§µÿûæüÖfι¶\9fy?uïÛ>æeçÛ£å|ÚÞñµûä¯Ë}nÛ¯í\8fϳ\9fùËóK\97ßl?óç÷î\9cï÷\8bË,ñ4\ 5ÝOÎÉ}÷c}\96:ë¼ÿ¼¸_Ýû¦\15\19\93\ 5|ïÅ\sÌs.ïß\8dñÞ\\9f{Ûþ6ãKÒ\9d¿&ïK\16ö¹½\0\ 5û-\8d\96\9fV\9f{{\9aÞ9ßÞä÷Û\8bí-³Þ\85ÜOû]ÿw{\96ç\99ÉBþ?»íùñ.à^n®ûåÿ;¿þÝ5ÖçYÚ\13Ó
-ºÜüÞí\ 5(ì÷X¤ÿ\8bo>Ï­o\7f[ÚÂÞûÌ\7f\9fcls¿\9c\9f[kÍïî'ß\7ffÞïYv|\92\85\8d3\7fÎ˼7î]{´Âi{y~'\v=ç?ó$\9f¹\7f'ùÍ\wû\97Û|\92\ 5}\92\ 5»ïɱ\97\8b\14îB#«Á4»ë[Òy¿ÍçYî~ORÎøl4`µ\ 3\rÞ\9d[®Ë\1fð4\85Þµí\99VÈy{\ 1
-7ßVX«ÆR\e\rX\0\a\9a\80Þûí=ónñ½åãÇ\97Ä;¿ú>î\9c\97\13\97V\98®\ 6ÃýOίµ\16_Yí\80ëÇ\ f»\ 1\80 \81\15@í²°\8d\ 6h\85ÕVÛA\80\99Ë\960a­/Öî\93À:Ð\1dÔ.\8d\ 6,AVcé\0P£qÀ\8aáý\1a\8e7çûK«÷¶§-5~~\7f\9f¶ãòÏÍmaw{?óÜûÅúÚ|­Íwk\8bµí^G\ 5z\ 1\1aQÙBøªB£@¹\844\e\92Y\89\14Þ«i
\17\16^KS°\ 5«\v¶P°\85\7fÕ* è½j\15Õ¿\87\ 6 Ç\80xL»ûB\ f\fJM\v3\e·ôIN*}\91£Q\11E@¨Ïp¤\ 1\8aW¨T4\16ºl\13:\84\10\89\0\8c\0\ 1\fÃ\12H08(\14\8f\bäRòª\97ó\14\0\ 3X8&@@>88(\93Ë¢\910$
-\ 6\ 4r\18\85a\1c\ 4A\18È1å\90dH1Èù~#°~ßjm|EÁ\95`®j\b0¥?7=,¢Í`+«B\8ap\7fòÓÒ&\ 1ç\82\96Áº\88²\eI
-Û·c\96|Að\ fÜ\9aª\92*  n\16\17ý¾6\83¹\94\12ÑN\92=\99\90o\17]\94»\12ÂM\b\92\rÁ¶¼L¶ÏÀmî>lÂ34¡)Oip\80\vº®4ÐçW\7f
-@î4Lj9·ÿí\81\12m\9cE+ÓëÑÚ\ f8áºým2yþþ1¸Ô\99§¢d­\aM\vú;À¤ky\9ex\8cȲC1Pf8
-Áe\94\97\16\89Ã\8eSorÜ\ 6²\84\8eY\ 4?lºGP¡ª~xûÑ\b¾\8b\82Z<TUqºéRJ\ 5\91Þ¿ÿ\18z\ 2'LÈ#]\ e~­ü ºd6
-\89\9fï\87OÂù\ 39\15Ñ\8c\90\vp\ e\1eôg\9fçuµ\80h\13T3\88ï\1ck\90G\92N\ 47ÀAç)ÞLa\7fÊù\86T¥e«\9bä·\ 5 \9f#\ 1\ 2Ç\13à\13­»Nu\91\1f\ 6ðöYqHqá¨/\87\8c\19\18ÒÍ\89rézæS};ÖlMï2\91}XN\8c\95`1ö\f.\8bàÚH.\10ÉÙM>\9cÕ\8e®W°\9c\8dyOÛh\ 6þù*E\15\ 1ãz¡ô,Dõ?\ 5bµ+\16ÁÂÌ=ë\10ͱ\ 2\ 3üR©ûÓ\88\e\93åñ;ª\1a4
\98}¨@äÃz)=´yBK`è1ír\9f\eõ7?dô\85\83Q\vm\93©\9f¯^\8fÑyôÂkD^²\891Âê2B\95ZQC\16 \10ùrKdì\19Ã\ 2'BßíXº\99z%ÂлKÉÖ¢Ý-M7D\9a4_\9fø2¬ \99w\10 ðÈ";à\1fPIê!ñ\9f6p\13IJ\12òµe\b\88¶P£»ëf\bê5½\84ü\16ý¤\99\81\88¡c\85ЬëÎu\0u]\89nrÖ\h\9f½\vÔW\8b\87Rh\14¡Úö©<\84X"A´Þ»é¥Nñ\87¶Ôã\87ãÅïÕ\eý\9e\13O\93\90gé4\99I\1e* ×V3\0©û\v\90\94%H\12öª\80\98rmä\80\ 6\18\15¥ªb\89GíÌÐ\9bk¶:ýõ¦\ eðÉ~ÞÄÒß\16O\v¬NxÜ\ 1¤a\92ò7\7f\19r8=Ñ㩦\95­nÚ2F`e,ìp\82¨<öItõ¾D\8a«+\11R"\91÷\1cÊj\1f}\ 34¡(¦\88\e\ 2\9a\89û\14\7f7\13Î\83è´]\rvL\91é\13\1f\7f\9cyùÿÎT6\90à\89÷\17¢ºè½=¹Ci\85åM««HË\93I{Í,­\8b³\15Ò°\97\98é7oªª\81\7f©¹ô\8c%©Ã\17­Yfg\8eª>\rP@Q\ 6¯¶Kª\19ê°\9eÙ:%ô´/Q×/¸v^ËN£\88Ú3U0Ó\8a\87²À´\97ÓQ`|k\1fVrï\82\14äç:<ís\ 69w¢od7\8b·\8c¢ö\1e\ 3ÁäºcßYãíÊ\ 3#ê4¤\96\17\13¨\ 5ÝÙ\88D¸\19\99¡]ÊG|§\ 3\rÚ²áI¢s¢ù´xiê\84¯.Q9:r"n\v\96\r>S.Ê]ªØëÏC¬am¿yºÈÃÉ2z°Ö¢\87JªRWÏá\87ï÷$\84&Ó¹÷t|®û\9cÆ*p(®\1c\0\9bÐ7`¬â
-GáF\ 3»v:x©^\95\8c\9c1Ãùì¼\12#\ac¾~# ¦\80á϶1^Ej"\14÷8-\8aù\f\86 Ô\93¤C2úS\ fFúq¢Î²\11,7\10âÓá)ÅL] dp\99±\9cæÀ\rÛ6Ù­5º\13\ 1-\87¬ÆM\8f%\ 2\8bÆ\14\85%)¼\10o\1fàñÁjÜy@\1fɱqÙÙÓgæ\7fW
-\88Ë\90é\90\ fíw\ 6Ák\rÍ\14´\133°Ð\98\10b8/L\90õ\16æ\9eæy\91LL@÷Îx\92\1e\rÀ\88\99I?îÝ,\96\81\88\92ÿ\86ÑZøZO\84dOçf(¢t\8d\96CãíüѲò\94\v&j\85hRf¢\9bsæ~\89\88\93ÉþÝ1¹r\9a\va\9b\8a"(¢Ö\9ai\85\fùÃS;Ðñ\1c{\87iÔô\9b+J\99%z\95+ÔѪ\ 5\13±ù-ÈÒÍ\12l\ 4ä\ f2\7f\b!+#¾`px\r±.\ê\89`A\8dkWÙÛöºjuE\13$2³jL®
-Ït\9fè\97­\9d¤'\84|¿QL\ fÑ\8d0wo~¼º\88D\16¼Ú\11\92X"\99ñ1íf\95\e\1f.u5Ö£:N\91ð÷Î\ 3øfr´é)¥\9f7\97\89Äu¼\ 5(ï3o\1dýcá8îÛS¶å¿»/ÒáWÞ\89çdÓ\0!y°V&êL\82÷Í\ 3\f\19>$>7 \81ï<¬\13ª"{\93¯\16\a|úÕÈ,©7Ý»$;='+\84O\9e\8dÞ)½Søp\98X¯4Ø\94\ 2ç\80N¯é\9eöÅy ii<v"\8b;|²ñTV   Ö\8f{8ÊÌg±Èlh8òÄ3Ë2\91K£Hs¬ý\92ä"\8a¤v¶æ¨e\8aÜoG,Ýå\88is\85\9eµ\9f6egJBD
-BÕp&/à7j§
-G/Q£$x\8cÁCÂ.ñaW«2%«à\ 1È¡`L\81\ 4Î)´]£\r9cÌ4Ý{¥Ð\1ev\8a\1c\10=\1dm\ 6\846    \8fE\8aL\1eÓ\80Ä®=N\81î8'\93¿7¦`Ë\8eG{\1c
-\12¤ú\8egï¶ÃU>\85:\1d\10$¸²\1dï½Ê+ô\ 2s\98&¶²rÇý=\92BÄþ
-\12\14ë\8e3(\91\93\1a\nDZ¦Î]B\9e\88yôçÌ\1eì¸T@#ÿéñØN.L\9eA«ìx¤ÇÁ\915\ e½\1dÏ\12éñ©?\ 2\7fÇ#ü \95\92\99\1eÚÅtÛì¸)Q\1a23³ãOfuòYãá\8eÐã¶F*ýÝq\ 4U&ú£ÞdÇ\e=>©\9b\80Oðèñ\b~Çõ\81èÌ®ô§Ë;n  ô \11Iùì\8eû:`ºcÜmË\8eGz\1c\185\ ev\1c\8f|\1c§£ß¬\8f\82VTâ\8e»Ì0¯Çû7«ê\1d\7f\9a\96ÝãE\82A`;\9eL¿Çz¼\0={é\8e\86s\9d_\ 1w7Úñ\99\1egz¢(¢ßã:É\8e\8fôx½\14\88ì8B\8f£Êã\0tÇ÷\19ÀëñÎ\99dDÙñ\9b\96ÍZ*Cw\9cÞÿ\07¼Ö\85;n{\e#kd\fb\ frc\f    dظÇ%q\8c!?ÎGHc.Üÿ\18Ã\162bz|]Cë1Æ\1e2À{¼\8d\90\9d\92\8aX2ÖMR\8e1\8eCƾÇ{éÛÆ\18BÈ0ïñD!Lå\1d\8f¹¹K×\9cð"\ 2|ð¸;#\13\0\9dæd]#Ø{\vÉ£óÚm\ 5\ 4¡ÌX\86ê
-\1d\9fë¡h\84Ôr`£Æ#   íù\89\98ÑÞrÄ?\ 6FÜ»ý(d\8a\10kLï0`\ 5R\92ÀP\92\86(\16\81\92+ðUZÖ\96öÐÙ\17"¹n?QÆ\87@ɰæÉ·oÅ\ 1ÛúÎþ¦¡·Gíp\8e\98\1d\8e\16^:O\bE\87¡ºKÑÏcÀ\183è7¼Òk\ 4s¶+\92\86W\89}\ 5=\93ÂË\7fÁ«Çm±àÕq-\12¼RlWëxU¹\ 2\85ýõM0)\e>^ÑÍîù[Á«ÐvÕóðjË`xÛU\8d\81Wd\1d«\9b?2»ªíxµYÚmWö\1e¯@\8b±µ«Ê0#\1dÆÜ\1dvQ2Pwç#*ÑÜ»b½½¼Ò\15Abd\86\17\8a)\7f\89ÿøö\87¿åÁX$´X½`eZ¡Ü'LE£\ 2qÀìD­<î\e\83e{L¤Ùó?4Hº\8d\92\93É;©à._.SåFóº:<:\81:.¯ÔFe2&9NW @\8b¹H³6\80\82ŵ]ÿz\86\81¡\ 4"0J\98lçÐ'RH©5Ó¶\97QBÒØ\17ÎS¾:3Æå­yðX\85ðâ*/g8Ð\ 6\84uÀQöûüâ7¥ÊR\1aZ\ 5\1dÐá:íð\82!'grÆUI\9c¦a\84ìÿÿëÜߦÚÎqiæ\ 2_Õè4\16#4%ó\14\9e\1a}¡,/
-þJt¤|D\8d\9cuò$×ò^â¼ÌãåE\ e\f\7fcÕ¢©VÀjÈÀØ!2¥*Qþ¢;è\82«A²#\ 1ú~;XõåÄÈ\19\9dhÙ/I>SL¢\ 5g\b´½v4¿\80"\0Ð\f¸iº!\10©â?ku\14 @¿øc1¸k\19\92g¸Ö2x\1c\bZ\8d\18Y1\90T\10X\12]àÈøµ\ 1\16\ 4N{õ>¦iºé\932P\1e\bùpE³êPq¢­\0ª\97à"o\9cçx\17×§\86rh\rÃii j»\87U\1eyy     î\88\0Ü\ 3ôZYfª!\8c\19:3æ§_\ 3\84\15/JÃ\15\8f\87¯ãÐ2\aò%õS\8c'\ 4KPvºA\ 2\99GRé³íããÛF+½vÑiþPMD\18\ 22\18TM]\82ºaKW\89¤        9ï·õ\9b\1a3\82ÀNî\f±\8fò¶Ø-*'\ eï\8eb\95Q\12^\11þ\92\97XÁâEø\94\93\8eÚê\88ËÏIL\13\d\1e\9bvq\ 3\a\13Û'ò\16j5±\98\1aïRâqõº·\927o,ÀÆØùj\1a\83u\0bôhK\96°ieAÈ\94^\8a\855>ÿº4¥\r ü^Ò\97Ðiý\1aöMlKöì\152\99\80Ȥ;\18\83åwå¨\85]\92c`Ë#\81¡\ 6Ë\9dT$tÐ_\85A\9a~\82ú\ 5ÿ!L9­o\8d\e«\1f\89ÑO-@EÀì±í?¬\10ÅË-{·|Â\1aÏþ¾ò\14\8a\ 6ë8ßñ\9c\95\11`GB\99Î\ 2ƲÌþ#v£5*\83Íyê\9eÌf:&\f\8fOX¥\1cj\83Þo\0~o°Ê±\1a¨q6ìéâ\95$\1dÊ\1e]â³ñG´ÃGi¯8ðϯ.f@\aCôxêe<9=Ö;\9a«è\9fM{ñ\8d\eÈÜ\10*5\85ª\ 46ELzY\14õ\7f\98!k[\ 5wôÒv\a\87N}¿òj²Là\vF{Ø%¿üGÌ~\94ù\14\9f\1e^õ7ä\b\19\86èp\f¦\81\ eÏ\99± {\98.&Z¼\92â§\1c\10K\9f\1ap\ 3ÍB¤Ã{µ±=\1eµ\14»\11\17s<÷A;wE
-#Ð4    \83õ\86\v×Ê£ÉéÁ;\ f\8e_å2lV\eæg\99ÞÏâ:è\12\9d±\rË\83\17\1a8\1dvÇúÌÐu/K3.E̸£\v6Á0\10»ôCÎ\11\9cæ\89Y\13üdK\90Õï~\8aR¢R+\83ã\9cJf\0\10\18-ÿ\e\97\94
-wÆ\18>e!òÓü¢ÌÞÞa.§c±\8e\9c÷XÀ\84_¾÷%y\157\11\8d»°­â]\9f÷H6K¡\8bàùi\ e!Éê>~\ 3¢.Ïu\0\15Oe\11IæAü¶÷î\8a§lO\9aø>5\19ñ\ 4®9î\1d¯W\7f\8eÈY\9e\1aÇ \9e´+\84L\ f£¡xÚ\7f\1cAïÌ\83x¿\16¤\9d\9d0\14O\0\8eÏ\92o\8a\93u«¹#mZ\8ex\12\9dÌ7Í\9a\1fR<Å\9fo\8cG+a--\86\8e\ 2ÙW¶\9bo^\15°¹¶ÑZ    \13óM\12?+àÖrÁÖU\17ó\12m\ 2\9e\8a9í ö\87\9b{ý­\83?­àsD\86Í.}ä2OHÞÇb\7f\8f8¤Í\83Ì\90±B{µöM1Çä^})\80£BAm\v\81h=«LR@dFqSÛÄUø®°\8e|6;&\16c\1a\b\b;{/äyÈRÝwLâE\9c\8fè\88;;\8eù±øì¹L\16ìB/FÃw\1dó/ü\8aH\8eÔRîÂE:ùD\0\\8f\96\ 6Ì\13_tm7\8eÛj5¤-ôûT\18\8d\92\87DMrf\16Ì\ 6ª&ÎUG{x?ä\ 2éä\15\98\90³¥Tô\85\fa'(&O\7f\99}\14ïD\8c¥_­.ÜÚp%NË\9d\12\1az5% Ó­¾WüZ\ 3\0\ e\a`\vq\82Ñd]¬½A      8-¡\ 2£[\19ÌW\8eâ{è \97þ        ¥C)\9d\13D^/\89\1c\97ØÁ@y=ÜóÙä\91\93Zß·¢8{vÉð\ 5+X=\9bÙðè\1aE k}Ëh\8d\99M\9d7\17¸Î\8b\9f\131m\89\1a\8aÃG\19\ 64Dîw\b\13ûaH6uj\86\b\8d§Ç(\16"¶ô`\ e\84æ¨Uu\eýÅÍ\8a\90} øg~<E¼p\8d§\97ò\9dU\89Æù\1a]\95Ä\82ÿ&¶Ë§Ì\11 \0^
-Òæ6<ÛóxBPñDb\9d(Ãó\88Ëüú\87\8b-oRÙµ\88ìã\14bûx²í   \vE4\9eþ\1c\84\96¬aòö    /ÕxZÄ~ ÜÓw-ã´\87\94%O6T\8dPXÅ\98Lؼu\ 2ªØì\7fª­_\1f\1a\9a\83Ð)¸5Ä\1ckÿ[ð\98U®Ö^\ 2\9eÜÕÙ\e\92ø\ exPí\85¹nB_\10-1ÁÌü×HÆ\82Q
-FR\13ÅØ\85I\83ü`?¸\ 1
-\9b¾\vILÀñöZc\8cÌ\95\18;\1a\12wÐxÙ  k\10çCÀ\1aª>3Ê¥´4\8d\r¶~\9dc\ 2]\876E\f\95gAì½aĬÎÍp-u\ 1\92Ý\15\8c\18\ 3\87/\eÕ,ø
-,Ê\bKïùës\85U®4h\91L׸Q\97/áEcì\18§Ú+ît\93t\1dNp®ÄÛ(|Êð\9c©G)ñÿå\18G\9a
-¯mÁ\\96\9c\10\84¶LÌ7W²ÏFþºã\86\84ë\90.k¹
-\eó}n¿¨¼\81\98\86\11\12õ\b\ 5Q×A)\0e³sÑÂ\19bÕ[q"x\ 1\0\94Ì9ç\ 3³\8e\1e\14Q\8b÷\1dÿ\97\92\90q\1c\95!\ 6ÿ\9e\1e]EíS\8fJDÐI=z\f\94\ 1\18\85¦\87Ït
-o{+\9c*¯°TÝðÌ-È\9bh\108L\97@sçÞÎ\98k~ï{í\85# SH{Þé\8fÃ\91tͼ+Pà\8fLk)O®\v\99îzúN\13Øq\99.ÓBA,. @\eF·DG\92áw\7fVcSb&¹ \84\80ë¿ ÃFa?cõ|íÊ\12\17\ 1ãg
-ñ¾[ö\f\90çB£YO}4\bÖÉeyP¯e¢Rb¦ÆW\14º6m\9dú\1d\a%q~Ï\91^§Ãæ\ 3öLïß¹Þ\1fQÿ3¹;\15Û5tÔf?@ð½'ÞZvÚv\17ÙMw%áMÕ j_«\ 5\82\812\Û²ÍÉ'5è\96¨ªÚª\16W¢rõÑ\\7f\7fCìú°»¶\98Uö B\89²*b²éÍr"N»â§W®³o#9u\14ëj)"\14VX\1c¿Ô\ 5;H\1a\9a)\a6\8d ÝFL¨ý\12­\1f\81ã\b\a±\a%ïe\ 6\80RMËíJ'\86ö\9bÜ¡¶f)§~÷$æ\11½\1d\10ö)4ï\10å\87E¨­T]ÁøÍÈn\ 4Ö9\86\93\87HcX¶oÿÛ\18>Þr³Ë\87\7f\1aw\ 6¡d\a±\ 5)](oÜØ\1aÛôÓ\19òð\94\18ì´pQ¥n\9fE`\ 5\12Í.\8e\98!?g¨Jt\8e\19õ¯ØÏ\97\87\9d¬¹IïOQ\rßУç;\8be^Mm\7fþ¿LnÒ¸\11wÌÀ\15\80Ã*ýË\9b\80@ògãÀô\15\98\9b\14\r\11ʳ iüûe¶IÊ\14Û\92\ 68Òh»Ï\84¥ÅÞl\15,ý«k2\81(\19¨\7fo
\85\83\9dk*ï\10À¿\81\82¸\f÷
-óy\8f\9aéß_£\9f"öÿKÿªñ\8c\b\f\ fö\86\rE%\0sH¬¼\9b2xøWç²BÃÚ\91Õ¿AK\v?ý¢äÕÕÒæñîp-A\fÿR\19¡p¦\7fé\9e2v\85\7fINe\82d\1f¨®µ\f\11ð/^Üù\9bB£¬Ñ\94\9fÜA]\91\81ô/Óõ\9d\91\91Ü®,Wø÷\85\8a&Kê¿~ètuÂ\ 5\95ËúÁ\94\8c\8cûÛ\1c\ e1éà\8fW@EujQMa\ eA\ 6Êm%´\1c\133\9d\87B\11°Ac[¡Ë.cS©©f®Æ\91îÊÞ£eu\f\1dÔwJ\16\v\9c\94\8eë\87Vp \10Aå8\f\ f[ºbY\80h¹¡KÀ\1d×\19´\9dF~aï,Ö\9eÖ4xjæ×ò\13\98@c¤Dá    \98\85mì"U`\8f\9dB\8cÕnE]f>Û.úÂ\fl(G|Ä+é¨am~PYêÌ8U\9e\14m¡@ȤDWàæ\13\13H[Ñ\1e\8bõS\90ßkö\86\91\9aÕ@°}ú\98¥\ 2aZ¹t^_Wêf$¸tÚå¹\7f\17yÁå~»\82wk§LMu\81\12k\8a\ f\98|{^\8aòÜ\90ÚÍ1Õ\88óÔP5\ 6&\1dÜÿ\a\16²6´¡zª\10\96a7Xn\aô°êÕº4à\7f\92<ëMÈÌB\9bÚnÒ\9c餣¶\85Ú*D%\94*\ e¤Á\96\e¦Ûè\93¥\88õ`\86¤,®ÞeZBø`\9c©\82\88\fª\1aiµÀ\ 1      ¡\82\12/\87\1a»D\94\8eyßR:8,\10Ç\11wø1fß\ 6\7f\9d½\ fz{Ó\ 2RÙ9G»\9eïR¯\\K\88"\aßn\az{g\ e\83ôJà\10
-\1eX¯¤^\9fÊÿ\8cåSlR/ì^Yw\91P\84\98x\b\13\ 2ê½ÿ\96õ'\r\9aý\17J|&Ñ5\97HKo\10õ\89¹Ù5é#Þÿc\1cêµf\17\8b\e$ÐM\8d Þ8qªÝ\1cC~R/h²6©6 Z°q\ 3S@)M¤=\9c\94z5®7YW\1dÇ\11Sm¸\9cU15wAÚ\r&\98×hs\8a\86\19\ 2î¤qd}Ñ6\91\94M:¨r'Ó\8b´ejª>gÁî\9f¹\12rWR¸\96\8f\82\13ï·\18\82\9bëE>\8aÅn\19`þt¯\17=\9aþa$vY\1fZ¹ÉÂ5¸øI6Ð"Ú°}\19iB\89\8cÃ\16~]%É\eÕ)2FÉè`çâ\92$eL\91\8a&\84Söw(?ÞxÅf]\8c&ÄÔ\8e%SL¿â\950v,L¨\17\ 20¹8Àj\94\ 5õ>\82\9a%%}Uä´@\rHÇ   ½3^á?áxÌs\11w\8c\13Å,¥<JQIv\11âIP¬(ï{\ 6ìñ\ f\v±ì¸3Åæ+\82ï¥8¥­ ©\ 5\8dò6D~\ac\ e¾ë¨mV\9d¢$Û\92m/_$ùʺ¸\195X\809T\ f\1c'¹D\91Ç8AXv)\v-\8c^ªn\ 6Ĥ\16\12?j\ f¦\83\ 1\12µý\ 2Uú?        ÕNZ\9dJ\fñ\18\7f·%dG\8f\bü£§ÇIC÷mE\03|w­ÿì\ 6Ìv'³&U½è½t\8b\ 5\8cmdÜ}õ:iGD\9cæ\b¾S\90Þ\82\81\7f\870Qõ.Û\88Â\9f4\0W½`ÝÄ_Ы1íjÕ{+4ê\99\93ÎÒ\94'hl\99\1e\9cÃ\15Få¯û$´1h¯òò2\ el?ÀÀª7År}÷O¸|õj0\8cöÖ\99ãªÞ\ egW\b¼zA\8b\83$à&¤A£#VT½\90>×öª»W'¬(»¼CÚÍb\8c'¨ù¿\87Æ\bÛ_q\16\8cZuBã½ov¾\92\10³\86\81       ò\v\8f°G\ 1ì'öðH!\84Îí\96Ñs'95áÐÅ\11aGÄR¹|\81\97CÅxÁ\e\12ô0m\83\99\br)ðv¾I÷)b\16ard\877t4x\88wSIüZEÇü¼ÄÀ0\ 4\ 4H=^\8a\80ØJFø\8f¾òý\8dÊ+æ\19Þ'É3Eû¼mÒ\97ø\91\b\8b\fõþº3µnìDíúÜêi+\8a¬ÈúÊèÕ\12·\18`\8f\86Ã\97ïx\ 3#8\ f\84p\94²\85IAm°\97Ô×\88q\ 3   ¦@°\178ò;g\ 4\81+\90ú\ f#åEXî\ 4\86许|¡\85å|ÃF}\1aÍ.þ\94ÙÝ\19}Ë|| ®À Ëè9`¬\f&§ð
-{cÀ¹\8cmI\9bo?£Tåaý½\1cøÇ|/\ 1¬\8dc\b¢\9d\13\9f{áî^:â\97\1eî\87ywq\8d\95\8aûÍ¡3(v$8«Fb\bí\18ÅvúEOF\ f\ 6Ä\8f¿AÓøR'$¤ë¬³¢\84,)\94¦\94\9fGG\12\7f½~l\1aÞ]Ò\1aµ\99,{Ï|~w\8bý¤÷j\186-Þ­s\86Â/ð°ï®\ 2\7fã\ 5\7f1KÒóÇuêÝ%Ï\11ðµÝfpä\13Ç\97=^ýëÕÃCIº*¶ùü©     \8cðFrÇéÝ\8d´lóìÅ\eèݵÿÝ¡\ 3T:äÒÆ\87GÝÞÝ=³ÀoÀ´c²DÅ»ü/+ß$a\16ù¢\9ex7¨®Ú_æbzw\15D\9b\17\88uÝ|\8d\ f\ 5\19kªô4$ùé2g   N\92o\10\8e2\80Ý\8bø= o²â¨\80!Å«_´\88\83ÅÔ[<[à®Ç\94\ e\13è}&î> \7f[d\12\1c\82\13\88KEm)\0-R~kGÍ\96ÉÜò\86\8bk\19º¢5qQ9ñ\1dsÌÏ\ 5Ôý\12R\9a\99\8a&IM¬I§\19\ fÏ\83v\80 ß¨\8ag\19ú\96öÿñ\a|VÉ\8c\13-kÌ¥99ÂFp\a6âÃ\95ï\88äf\98\ eI\ 6Óê¨mª?&\8b\81\ 6®î\14\f\17Ãu)Î\8aëÝ(üwÒ Ê8ð¡\a\b\82¹*o,ì\87©\805\86Z\8fÁöÌ ´l-\96Â\¢µ\0FYL§\9c\1e½®ÑMXöY÷h³Ñ¡Û¤\19\v\b\8eó\0?ÿ<³¦\e\99KoyÂ\9dÈÒ7'ÚæÇ,s\ 6\18í\19\86S¸¬\8cÕúd\0\88\92A.KiJ\9a@À¡i\96eÎ$k³ß\98k~\8aGs\0´y¾±\9fÂU¡|û\1aëSï\99¶3xNð\94ö©r¼'¯\ 3<\9dr$\:õºÚÕÕ¬Êëh}tÂ=\89­jål&þ#n$¥\89óÎfn\99\9dXÂ{Gö»\85ÜÝéÙÄáeùyõÞ/RÚ\95h¢VtXy\15¶ÜÆã´üé \81Ý¥Þ9¨s\85\9e%j~\14ø\87\92ûØõ\rĶb\búé±\ 2\90îAîî«ø\14\19¿¼\94
-\7fLA5NRh\86È\174    ñzÛ²$ \14q&þS\ f\19¼\ 1fÇÐJ\ f®\r  \ 3\0\ 2®\ 4\rendstream\rendobj\r22 0 obj\r[21 0 R]\rendobj\r32 0 obj\r<</CreationDate(D:20200725234456+10'00')/Creator(Adobe Illustrator 24.2 \(Macintosh\))/ModDate(D:20200725234456+10'00')/Producer(Adobe PDF library 15.00)/Title(Jacktrip)>>\rendobj\rxref\r
-0 33\r
-0000000004 65535 f\r
-0000000016 00000 n\r
-0000000147 00000 n\r
-0000038245 00000 n\r
-0000000000 00000 f\r
-0000038296 00000 n\r
-0000000000 00000 f\r
-0000043346 00000 n\r
-0000000000 00000 f\r
-0000000000 00000 f\r
-0000000000 00000 f\r
-0000000000 00000 f\r
-0000000000 00000 f\r
-0000000000 00000 f\r
-0000000000 00000 f\r
-0000000000 00000 f\r
-0000043419 00000 n\r
-0000043593 00000 n\r
-0000044772 00000 n\r
-0000110360 00000 n\r
-0000000000 00000 f\r
-0000040363 00000 n\r
-0000142712 00000 n\r
-0000038693 00000 n\r
-0000040663 00000 n\r
-0000040550 00000 n\r
-0000039334 00000 n\r
-0000039802 00000 n\r
-0000039850 00000 n\r
-0000040434 00000 n\r
-0000040465 00000 n\r
-0000040698 00000 n\r
-0000142737 00000 n\r
-trailer\r<</Size 33/Root 1 0 R/Info 32 0 R/ID[<0736C03EA6374B77AEB4921C0FCAF2A6><B3D402B8E9994E6585EF6BDAA695FC42>]>>\rstartxref\r142925\r%%EOF\r
\ No newline at end of file
index 45d75b508c365b53211c450f96c6f277b6812a83..7e478af43ab9a728e47f284ae11007cc25a33c90 100644 (file)
@@ -4,7 +4,7 @@ import QtQuick.Controls 2.12
 Item {
     width: parent.width; height: parent.height
     clip: true
-    
+
     Rectangle {
         width: parent.width; height: parent.height
         color: backgroundColour
@@ -13,11 +13,12 @@ Item {
     property int fontBig: 28
     property int fontMedium: 13
     property int fontSmall: 11
-    
+
     property int leftMargin: 48
+    property int rightMargin: 16
     property int buttonWidth: 103
     property int buttonHeight: 25
-    
+
     property string backgroundColour: virtualstudio.darkMode ? "#272525" : "#FAFBFB"
     property string textColour: virtualstudio.darkMode ? "#FAFBFB" : "#0F0D0D"
     property string buttonColour: virtualstudio.darkMode ? "#494646" : "#EAECEC"
@@ -176,7 +177,7 @@ Item {
             width: parent.width - x - (16 * virtualstudio.uiScale); height: 36 * virtualstudio.uiScale
             visible: virtualstudio.selectableBackend
         }
-        
+
         Text {
             id: backendLabel
             anchors.verticalCenter: backendCombo.verticalCenter
@@ -186,7 +187,7 @@ Item {
             visible: virtualstudio.selectableBackend
             color: textColour
         }
-        
+
         Text {
             id: jackLabel
             x: leftMargin * virtualstudio.uiScale; y: 100 * virtualstudio.uiScale
@@ -197,7 +198,7 @@ Item {
             visible: virtualstudio.audioBackend == "JACK" && !virtualstudio.selectableBackend
             color: textColour
         }
-        
+
         ComboBox {
             id: inputCombo
             model: inputComboModel
@@ -207,17 +208,28 @@ Item {
             width: parent.width - x - (16 * virtualstudio.uiScale); height: 36 * virtualstudio.uiScale
             visible: virtualstudio.audioBackend != "JACK"
         }
-        
+
+        Meter {
+            id: inputDeviceMeters
+            anchors.left: backendCombo.left
+            anchors.right: parent.right
+            anchors.rightMargin: rightMargin * virtualstudio.uiScale
+            y: virtualstudio.audioBackend != "JACK" ?  inputCombo.y + 48 * virtualstudio.uiScale : virtualstudio.uiScale * (virtualstudio.selectableBackend ? 148 : 100)
+            height: 100 * virtualstudio.uiScale
+            model: inputMeterModel
+            clipped: inputClipped
+        }
+
         ComboBox {
             id: outputCombo
             model: outputComboModel
             currentIndex: virtualstudio.outputDevice
             onActivated: { virtualstudio.outputDevice = currentIndex }
-            x: backendCombo.x; y: inputCombo.y + (48 * virtualstudio.uiScale)
+            x: backendCombo.x; y: inputDeviceMeters.y + (48 * virtualstudio.uiScale)
             width: backendCombo.width; height: backendCombo.height
             visible: virtualstudio.audioBackend != "JACK"
         }
-        
+
         Text {
             anchors.verticalCenter: inputCombo.verticalCenter
             x: leftMargin * virtualstudio.uiScale
@@ -226,7 +238,7 @@ Item {
             visible: virtualstudio.audioBackend != "JACK"
             color: textColour
         }
-        
+
         Text {
             anchors.verticalCenter: outputCombo.verticalCenter
             x: leftMargin * virtualstudio.uiScale
@@ -236,6 +248,26 @@ Item {
             color: textColour
         }
 
+        Button {
+            id: testOutputAudioButton
+            background: Rectangle {
+                radius: 6 * virtualstudio.uiScale
+                color: testOutputAudioButton.down ? buttonPressedColour : (testOutputAudioButton.hovered ? buttonHoverColour : buttonColour)
+                border.width: 1
+                border.color: testOutputAudioButton.down ? buttonPressedStroke : (testOutputAudioButton.hovered ? buttonHoverStroke : buttonStroke)
+            }
+            onClicked: { virtualstudio.playOutputAudio() }
+            width: 216 * virtualstudio.uiScale; height: 30 * virtualstudio.uiScale
+            x: parent.width - (232 * virtualstudio.uiScale)
+            y: virtualstudio.audioBackend != "JACK" ? outputCombo.y + (60 * virtualstudio.uiScale) : inputDeviceMeters.y + (48 * virtualstudio.uiScale)
+            Text {
+                text: "Test Output Audio"
+                font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
+                anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
+                color: textColour
+            }
+        }
+
         Button {
             id: refreshButton
             background: Rectangle {
@@ -245,27 +277,29 @@ Item {
                 border.color: refreshButton.down ? buttonPressedStroke : (refreshButton.hovered ? buttonHoverStroke : buttonStroke)
             }
             onClicked: { virtualstudio.refreshDevices() }
-            x: parent.width - (232 * virtualstudio.uiScale); y: inputCombo.y + (100 * virtualstudio.uiScale)
+            x: parent.width - (232 * virtualstudio.uiScale); y: testOutputAudioButton.y + (48 * virtualstudio.uiScale)
             width: 216 * virtualstudio.uiScale; height: 30 * virtualstudio.uiScale
             visible: virtualstudio.audioBackend != "JACK"
             Text {
-                text: "Refresh Device List"
-                font { family: "Poppins"; pixelSize: 11 * virtualstudio.fontScale * virtualstudio.uiScale }
+                text: "Refresh Devices"
+                font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
                 anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
                 color: textColour
             }
         }
-        
+
         Rectangle {
-            x: leftMargin * virtualstudio.uiScale; y: inputCombo.y + (146 * virtualstudio.uiScale)
+            id: divider
+            x: leftMargin * virtualstudio.uiScale
+            y: virtualstudio.audioBackend != "JACK" ? refreshButton.y + (48 * virtualstudio.uiScale) : testOutputAudioButton.y + (48 * virtualstudio.uiScale)
             width: parent.width - x - (16 * virtualstudio.uiScale); height: 1 * virtualstudio.uiScale
             color: textColour
             visible: virtualstudio.audioBackend != "JACK"
         }
-        
+
         ComboBox {
             id: bufferCombo
-            x: backendCombo.x; y: inputCombo.y + (162 * virtualstudio.uiScale)
+            x: backendCombo.x; y: divider.y + (24 * virtualstudio.uiScale)
             width: backendCombo.width; height: backendCombo.height
             model: bufferComboModel
             currentIndex: virtualstudio.bufferSize
@@ -300,7 +334,7 @@ Item {
             from: 1; to: 2; value: virtualstudio.uiScale
             onMoved: { virtualstudio.uiScale = value }
         }
-        
+
         Text {
             anchors.verticalCenter: scaleSlider.verticalCenter
             x: leftMargin * virtualstudio.uiScale
@@ -308,7 +342,7 @@ Item {
             font { family: "Poppins"; pixelSize: fontMedium * virtualstudio.fontScale * virtualstudio.uiScale }
             color: textColour
         }
-        
+
         Button {
             id: darkButton
             background: Rectangle {
@@ -422,7 +456,7 @@ Item {
         y: header.height
         color: backgroundColour
         visible: settingsGroupView == "Profile"
-        
+
         Image {
             id: profilePicture
             width: 96; height: 96
@@ -489,6 +523,27 @@ Item {
                 color: textColour
             }
         }
+
+        Button {
+            id: testModeButton
+            background: Rectangle {
+                radius: 6 * virtualstudio.uiScale
+                color: testModeButton.down ? buttonPressedColour : (testModeButton.hovered ? buttonHoverColour : buttonColour)
+                border.width: 1
+                border.color: testModeButton.down ? buttonPressedStroke : (testModeButton.hovered ? buttonHoverStroke : buttonStroke)
+            }
+            onClicked: { virtualstudio.testMode = !virtualstudio.testMode; window.state = "login"; virtualstudio.logout() }
+            anchors.horizontalCenter: parent.horizontalCenter
+            y: logoutButton.y + (48 * virtualstudio.uiScale)
+            width: 260 * virtualstudio.uiScale; height: 30 * virtualstudio.uiScale
+            visible: virtualstudio.userMetadata.email ? ( virtualstudio.userMetadata.email.endsWith("@jacktrip.org") ? true : false ) : false
+            Text {
+                text: virtualstudio.testMode ? "Switch to Prod Mode" : "Switch to Test Mode"
+                font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
+                anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
+                color: textColour
+            }
+        }
     }
 
     Rectangle {
index 7a27a20689204d963b2fac2f142e04d23af1a94e..b8e835847ff5113c00bd2fc4ade99dd5e26a73bb 100644 (file)
@@ -9,11 +9,14 @@ Item {
     property int fontBig: 28
     property int fontMedium: 13
     property int fontSmall: 11
-    
-    property int leftMargin: 48
+    property int fontExtraSmall: 8
+
     property int buttonWidth: 103
     property int buttonHeight: 25
 
+    property int leftMargin: 48
+    property int rightMargin: 16
+
     property string backgroundColour: virtualstudio.darkMode ? "#272525" : "#FAFBFB"
     property real imageLightnessValue: virtualstudio.darkMode ? 1.0 : 0.0
     property string textColour: virtualstudio.darkMode ? "#FAFBFB" : "#0F0D0D"
@@ -23,6 +26,8 @@ Item {
     property string buttonStroke: virtualstudio.darkMode ? "#80827D7D" : "#34979797"
     property string buttonHoverStroke: virtualstudio.darkMode ? "#7B7777" : "#BABCBC"
     property string buttonPressedStroke: virtualstudio.darkMode ? "#827D7D" : "#BABCBC"
+    property string sliderColour: virtualstudio.darkMode ? "#BABCBC" :  "#EAECEC"
+    property string sliderPressedColour: virtualstudio.darkMode ? "#ACAFAF" : "#DEE0E0"
     property string saveButtonShadow: "#80A1A1A1"
     property string saveButtonBackgroundColour: "#F2F3F3"
     property string saveButtonPressedColour: "#E7E8E8"
@@ -57,7 +62,7 @@ Item {
             saturation: 0
             lightness: imageLightnessValue
         }
-        
+
         Text {
             id: ethernetWarningHeader
             text: "Connect via Wired Ethernet"
@@ -193,7 +198,7 @@ Item {
             saturation: 0
             lightness: imageLightnessValue
         }
-        
+
         Text {
             id: headphoneWarningHeader
             text: "Use Wired Headphones"
@@ -318,24 +323,27 @@ Item {
         id: setupItem
         width: parent.width; height: parent.height
         visible: warningScreen == "acknowledged"
-    
+
         Text {
+            id: pageTitle
             x: 16 * virtualstudio.uiScale; y: 32 * virtualstudio.uiScale
             text: "Choose your audio devices"
             font { family: "Poppins"; weight: Font.Bold; pixelSize: fontBig * virtualstudio.fontScale * virtualstudio.uiScale }
             color: textColour
         }
-        
+
         ComboBox {
             id: backendCombo
             model: backendComboModel
             currentIndex: virtualstudio.audioBackend == "JACK" ? 0 : 1
             onActivated: { virtualstudio.audioBackend = currentText }
-            x: 234 * virtualstudio.uiScale; y: 150 * virtualstudio.uiScale
-            width: parent.width - x - (16 * virtualstudio.uiScale); height: 36 * virtualstudio.uiScale
+            anchors.right: parent.right
+            anchors.rightMargin: rightMargin * virtualstudio.uiScale
+            y: pageTitle.y + 96 * virtualstudio.uiScale
+            width: parent.width - (234 * virtualstudio.uiScale); height: 36 * virtualstudio.uiScale
             visible: virtualstudio.selectableBackend
         }
-        
+
         Text {
             id: backendLabel
             anchors.verticalCenter: backendCombo.verticalCenter
@@ -345,7 +353,7 @@ Item {
             visible: virtualstudio.selectableBackend
             color: textColour
         }
-        
+
         Text {
             id: jackLabel
             x: leftMargin * virtualstudio.uiScale; y: 150 * virtualstudio.uiScale
@@ -356,47 +364,125 @@ Item {
             visible: virtualstudio.audioBackend == "JACK" && !virtualstudio.selectableBackend
             color: textColour
         }
-        
-        ComboBox {
-            id: inputCombo
-            model: inputComboModel
-            currentIndex: virtualstudio.inputDevice
-            onActivated: { virtualstudio.inputDevice = currentIndex }
-            x: 234 * virtualstudio.uiScale; y: virtualstudio.uiScale * (virtualstudio.selectableBackend ? 198 : 150)
-            width: parent.width - x - (16 * virtualstudio.uiScale); height: 36 * virtualstudio.uiScale
-            visible: virtualstudio.audioBackend != "JACK"
-        }
-        
+
         ComboBox {
             id: outputCombo
             model: outputComboModel
             currentIndex: virtualstudio.outputDevice
             onActivated: { virtualstudio.outputDevice = currentIndex }
-            x: backendCombo.x; y: inputCombo.y + (48 * virtualstudio.uiScale)
+            x: backendCombo.x; y: backendCombo.y + virtualstudio.uiScale * (virtualstudio.selectableBackend ? 48 : 0)
             width: backendCombo.width; height: backendCombo.height
             visible: virtualstudio.audioBackend != "JACK"
         }
-        
+
         Text {
-            id: inputLabel
-            anchors.verticalCenter: inputCombo.verticalCenter
+            id: outputLabel
+            anchors.verticalCenter: virtualstudio.audioBackend != "JACK" ? outputCombo.verticalCenter : outputSlider.verticalCenter
             x: leftMargin * virtualstudio.uiScale
-            text: "Input Device"
+            text: virtualstudio.audioBackend != "JACK" ? "Output Device" : "Output Volume"
             font { family: "Poppins"; pixelSize: fontMedium * virtualstudio.fontScale * virtualstudio.uiScale }
-            visible: virtualstudio.audioBackend != "JACK"
             color: textColour
         }
-        
+
+        Slider {
+            id: outputSlider
+            from: 0.0
+            value: audioInterface ? audioInterface.outputVolume : 0.5
+            onMoved: { audioInterface.outputVolume = value }
+            to: 1.0
+            padding: 0
+            y: virtualstudio.audioBackend != "JACK" ? outputCombo.y + 48 * virtualstudio.uiScale : backendCombo.y + virtualstudio.uiScale * (virtualstudio.selectableBackend ? 60 : 0)
+            anchors.left: outputCombo.left
+            anchors.right: parent.right
+            anchors.rightMargin: rightMargin * virtualstudio.uiScale
+            handle: Rectangle {
+                x: outputSlider.leftPadding + outputSlider.visualPosition * (outputSlider.availableWidth - width)
+                y: outputSlider.topPadding + outputSlider.availableHeight / 2 - height / 2
+                implicitWidth: 26 * virtualstudio.uiScale
+                implicitHeight: 26 * virtualstudio.uiScale
+                radius: 13 * virtualstudio.uiScale
+                color: outputSlider.pressed ? sliderPressedColour : sliderColour
+                border.color: buttonStroke
+            }
+        }
+
+        Button {
+            id: testOutputAudioButton
+            background: Rectangle {
+                radius: 6 * virtualstudio.uiScale
+                color: testOutputAudioButton.down ? buttonPressedColour : (testOutputAudioButton.hovered ? buttonHoverColour : buttonColour)
+                border.width: 1
+                border.color: testOutputAudioButton.down ? buttonPressedStroke : (testOutputAudioButton.hovered ? buttonHoverStroke : buttonStroke)
+            }
+            onClicked: { virtualstudio.playOutputAudio() }
+            anchors.right: parent.right
+            anchors.rightMargin: rightMargin * virtualstudio.uiScale
+            y: outputSlider.y + (36 * virtualstudio.uiScale)
+            width: 216 * virtualstudio.uiScale; height: 30 * virtualstudio.uiScale
+            visible: virtualstudio.audioBackend != "JACK"
+            Text {
+                text: "Test Output Audio"
+                font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
+                anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
+                color: textColour
+            }
+        }
+
+        ComboBox {
+            id: inputCombo
+            model: inputComboModel
+            currentIndex: virtualstudio.inputDevice
+            onActivated: { virtualstudio.inputDevice = currentIndex }
+            anchors.right: parent.right
+            anchors.rightMargin: rightMargin * virtualstudio.uiScale
+            y: testOutputAudioButton.y + (48 * virtualstudio.uiScale)
+            width: parent.width - (234 * virtualstudio.uiScale); height: 36 * virtualstudio.uiScale
+            visible: virtualstudio.audioBackend != "JACK"
+        }
+
         Text {
-            id: outputLabel
-            anchors.verticalCenter: outputCombo.verticalCenter
+            id: inputLabel
+            anchors.top: virtualstudio.audioBackend != "JACK" ? inputCombo.top : inputDeviceMeters.top
+            anchors.topMargin: virtualstudio.audioBackend != "JACK" ? (inputCombo.height - inputLabel.height)/2 : 0
             x: leftMargin * virtualstudio.uiScale
-            text: "Output Device"
+            text: virtualstudio.audioBackend != "JACK" ? "Input Device" : "Input Volume"
             font { family: "Poppins"; pixelSize: fontMedium * virtualstudio.fontScale * virtualstudio.uiScale }
-            visible: virtualstudio.audioBackend != "JACK"
             color: textColour
         }
 
+        Meter {
+            id: inputDeviceMeters
+            anchors.left: backendCombo.left
+            anchors.right: parent.right
+            anchors.rightMargin: rightMargin * virtualstudio.uiScale
+            y: virtualstudio.audioBackend != "JACK" ? inputCombo.y + 72 * virtualstudio.uiScale : outputSlider.y + (72 * virtualstudio.uiScale)
+            height: 100 * virtualstudio.uiScale
+            model: inputMeterModel
+            clipped: inputClipped
+        }
+
+        Slider {
+            id: inputSlider
+            from: 0.0
+            value: audioInterface ? audioInterface.inputVolume : 0.5
+            onMoved: { audioInterface.inputVolume = value }
+            to: 1.0
+            padding: 0
+            y: inputDeviceMeters.y + 48 * virtualstudio.uiScale
+            anchors.left: inputDeviceMeters.left
+            anchors.right: parent.right
+            anchors.rightMargin: rightMargin * virtualstudio.uiScale
+            handle: Rectangle {
+                x: inputSlider.leftPadding + inputSlider.visualPosition * (inputSlider.availableWidth - width)
+                y: inputSlider.topPadding + inputSlider.availableHeight / 2 - height / 2
+                implicitWidth: 26 * virtualstudio.uiScale
+                implicitHeight: 26 * virtualstudio.uiScale
+                radius: 13 * virtualstudio.uiScale
+                color: inputSlider.pressed ? sliderPressedColour : sliderColour
+                border.color: buttonStroke
+            }
+        }
+
         Button {
             id: refreshButton
             background: Rectangle {
@@ -406,11 +492,14 @@ Item {
                 border.color: refreshButton.down ? buttonPressedStroke : (refreshButton.hovered ? buttonHoverStroke : buttonStroke)
             }
             onClicked: { virtualstudio.refreshDevices() }
-            x: parent.width - (232 * virtualstudio.uiScale); y: inputCombo.y + (100 * virtualstudio.uiScale)
+            anchors.right: parent.right
+            anchors.rightMargin: rightMargin * virtualstudio.uiScale
+            anchors.topMargin: 18 * virtualstudio.uiScale
+            anchors.top: inputSlider.bottom
             width: 216 * virtualstudio.uiScale; height: 30 * virtualstudio.uiScale
             visible: virtualstudio.audioBackend != "JACK"
             Text {
-                text: "Refresh Device List"
+                text: "Refresh Devices"
                 font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
                 anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
                 color: textColour
@@ -422,12 +511,13 @@ Item {
             anchors.right: outputCombo.right
             anchors.leftMargin: 16 * virtualstudio.uiScale
             anchors.rightMargin: 16 * virtualstudio.uiScale
-            y: inputCombo.y + (160 * virtualstudio.uiScale)
+            anchors.bottom: parent.bottom
+            anchors.bottomMargin: 60 * virtualstudio.uiScale
             text: "JackTrip on Windows requires use of an audio device with ASIO drivers. If you do not see your device, you may need to install drivers from your manufacturer."
             horizontalAlignment: Text.AlignHCenter
             wrapMode: Text.WordWrap
             color: warningText
-            font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
+            font { family: "Poppins"; pixelSize: fontExtraSmall * virtualstudio.fontScale * virtualstudio.uiScale }
             visible: Qt.platform.os == "windows" && virtualstudio.audioBackend != "JACK"
         }
 
@@ -449,8 +539,8 @@ Item {
             }
             onClicked: { window.state = "browse"; virtualstudio.applySettings() }
             anchors.right: parent.right
-            anchors.rightMargin: 16 * virtualstudio.uiScale
-            anchors.bottomMargin: 16 * virtualstudio.uiScale
+            anchors.rightMargin: rightMargin * virtualstudio.uiScale
+            anchors.bottomMargin: rightMargin * virtualstudio.uiScale
             anchors.bottom: parent.bottom
             width: 150 * virtualstudio.uiScale; height: 30 * virtualstudio.uiScale
             Text {
index 9f07b58a1554ddac535e01fbb937572d3b121456..fffc304f6609809a1d0eae75b3715ec9abc4fb99 100644 (file)
@@ -21,6 +21,7 @@ Rectangle {
     
     property string serverLocation: "Germany - Berlin"
     property string flagImage: "flags/DE.svg"
+    property string hostname: "app.jacktrip.org"
     property string studioName: "Test Studio"
     property string studioId: ""
     property string inviteKeyString: ""
@@ -205,10 +206,13 @@ Rectangle {
         }
         onClicked: { 
             inviteCopied = true;
+            if (virtualstudio.testMode) {
+                hostname = "test.jacktrip.org";
+            }
             if (!inviteKeyString) {
-                clipboard.setText(qsTr("https://app.jacktrip.org/studios/" + studioId + "?invited=true"));
+                clipboard.setText(qsTr("https://" + hostname + "/studios/" + studioId + "?invited=true"));
             } else {
-                clipboard.setText(qsTr("https://app.jacktrip.org/studios/" + studioId + "?invited=" + inviteKeyString));
+                clipboard.setText(qsTr("https://" + hostname + "/studios/" + studioId + "?invited=" + inviteKeyString));
             }
             copiedResetTimer.restart()
         }
index 08e81cfa046904169a5f0c174ec7f0502c94bcdc..7b82019ce9cd4c7ba33c056fe4a41006a62646e3 100644 (file)
@@ -48,6 +48,8 @@ About::About(QWidget* parent) : QDialog(parent), m_ui(new Ui::About)
 
     m_ui->aboutLabel->setText(
         m_ui->aboutLabel->text().replace(QLatin1String("%VERSION%"), gVersion));
+    m_ui->aboutLabel->setText(
+        m_ui->aboutLabel->text().replace(QLatin1String("%QTVERSION%"), qVersion()));
 #ifdef QT_OPENSOURCE
     m_ui->aboutLabel->setText(m_ui->aboutLabel->text().replace(
         QLatin1String("%LICENSE%"),
index afff2b3a4d5d95f635d1cb98dbda7019217558a7..9d140e8b982d3906cec857b875e120657f166c97 100644 (file)
@@ -93,7 +93,7 @@ border: 4px solid black; </string>
         </size>
        </property>
        <property name="text">
-        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;A system for high quality audio network performance over the internet.&lt;/p&gt;&lt;p&gt;Version %VERSION%%BUILD%&lt;/p&gt;&lt;p&gt;Copyright © 2008-2020 Juan-Pablo Caceres, Chris Chafe, et al. SoundWIRE group at CCRMA, Stanford University.&lt;/p&gt;&lt;p&gt;Graphical user interface component originally released as QJackTrip, Copyright © 2020 Aaron Wyatt.&lt;p&gt;%LICENSE%JackTrip source code is released under MIT and GPL licenses. See LICENSE.md file for more information.&lt;/p&gt;This is free software and is provided &amp;quot;as is&amp;quot;, without warranty of any kind.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;A system for high quality audio network performance over the internet.&lt;/p&gt;&lt;p&gt;Version %VERSION%%BUILD%&lt;br/&gt;Using Qt %QTVERSION%&lt;/p&gt;&lt;p&gt;Copyright © 2008-2020 Juan-Pablo Caceres, Chris Chafe, et al. SoundWIRE group at CCRMA, Stanford University.&lt;/p&gt;&lt;p&gt;Graphical user interface component originally released as QJackTrip, Copyright © 2020 Aaron Wyatt.&lt;/p&gt;&lt;p&gt;%LICENSE%JackTrip source code is released under MIT and GPL licenses. See LICENSE.md file for more information.&lt;/p&gt;&lt;p&gt;This is free software and is provided &amp;quot;as is&amp;quot;, without warranty of any kind.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="alignment">
         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
diff --git a/src/gui/alt/Jacktrip.ai b/src/gui/alt/Jacktrip.ai
new file mode 100644 (file)
index 0000000..fc14ad6
--- /dev/null
@@ -0,0 +1,1014 @@
+%PDF-1.6\r%âãÏÓ\r
+1 0 obj\r<</Metadata 2 0 R/OCProperties<</D<</ON[21 0 R]/Order 22 0 R/RBGroups[]>>/OCGs[21 0 R]>>/Pages 3 0 R/Type/Catalog>>\rendobj\r2 0 obj\r<</Length 38021/Subtype/XML/Type/Metadata>>stream\r
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 6.0-c002 79.164460, 2020/05/12-16:04:17        ">
+   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+      <rdf:Description rdf:about=""
+            xmlns:dc="http://purl.org/dc/elements/1.1/"
+            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
+            xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/"
+            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
+            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
+            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
+            xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/"
+            xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
+            xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+            xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/"
+            xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+         <dc:format>application/pdf</dc:format>
+         <dc:title>
+            <rdf:Alt>
+               <rdf:li xml:lang="x-default">Jacktrip</rdf:li>
+            </rdf:Alt>
+         </dc:title>
+         <xmp:CreatorTool>Adobe Illustrator 24.2 (Macintosh)</xmp:CreatorTool>
+         <xmp:CreateDate>2020-07-25T23:44:56+10:00</xmp:CreateDate>
+         <xmp:ModifyDate>2020-07-25T23:44:56+10:00</xmp:ModifyDate>
+         <xmp:MetadataDate>2020-07-25T23:44:56+10:00</xmp:MetadataDate>
+         <xmp:Thumbnails>
+            <rdf:Alt>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpGImg:width>136</xmpGImg:width>
+                  <xmpGImg:height>256</xmpGImg:height>
+                  <xmpGImg:format>JPEG</xmpGImg:format>
+                  <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAACIAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq7FXylrx8yfnZ+ZPmLSbnVrjS/Inli4Nl9Rtm4PPIrPHzYGqsztEzcnB4rQAbk4&#xA;qgNU03X/AMgdX0nzB5d1e7v/ACdd3S2uraNdsGHxAvUBAiciisVcICpFDUNTFX12rKyhlIZWFVYb&#xA;gg9xireKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV8q+Svrmkf8AOR3nfQ/Lrrd+XbiZ7vVnf/dM&#xA;x/eFYyD9pLid4qdwP8nFUP8A85Atf6j518meXNYK2nkm/vYGnvVBLGYy+lKHNfh9OKT4f9Ynemyr&#xA;6yAAFBsB0GKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KviGy8h+Q/Nn5p/mV/izWH0n6lrl19S&#xA;4XNvbep6t5depX6wknLj6a/Z6V3xVLPzK/Lf8t/K0GjXflbXH1W7uNQjhuIXurW4CxEFi3GCNGG4&#xA;AqdsVfeOKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KvhyD8n/+Vi/mn+ZH+5b9F/ovXLr/AI9/&#xA;rHqfWLy5/wCLYePH0fetcVSv8x/yLHkC30jUTrZ1IXl/Ha+kLb6sVqC/IOJpf5fDFX3virsVdirs&#xA;VdirsVdirsVdirsVdirsVdirsVdir4Pu/wApda/MH80/zE/Rl5bWn6M1y89b6z6nxfWLy448eCv0&#xA;9I1riqUedvyS1/yGmlahqOoWtxHeXsdsgtfU5qxq/L94ij9nFX6D4q7FXYq7FXYq7FXYq7FXYq7F&#xA;XYq7FXYq7FXYq+Y/yY/8mn+b/wD23G/6jL7FVH/nJ7/jgeW/+2zF/wAm3xV9RYq7FXYq7FXYq7FX&#xA;Yq7FXYq7FXYq7FXYq7FXYq+Y/wAmP/Jp/m//ANtxv+oy+xVR/wCcnv8AjgeW/wDtsxf8m3xV9RYq&#xA;7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXxR/zkn5l85Qfndf6TpGtX1nFKtjHBbQXU0MQeWCMfZR&#xA;goqzb7YQLNIJp59H5G/MWO4nuY7tkuLpzJdTLdMHlckktIwNWNWJqfHL/wArNh4oW3PkT8w7oILq&#xA;5M4jbmglumcKw/aHImhx/KzXxQyr8ofMnnyH86vLujatr2oXCi+RLm3kvJ5YmBQtRlZyrDfKZRMT&#xA;RZg2+8Mil2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV8Pf8AORP/AK0k3/GXS/8Ak3Fk8X1D3sZciyPN&#xA;u4jsVYV5B/8AWldF/wC2jF/yZzV5/rLlY/pfeeUs3Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXw9/zk&#xA;T/60k3/GXS/+TcWTxfUPexlyLI827iOxVhXkH/1pXRf+2jF/yZzV5/rLlY/pfeeUs3Yq7FXYq7FX&#xA;Yq7FXYq7FXYq7FXYq7FXw9/zkT/60k3/ABl0v/k3Fk8X1D3sZciyPNu4jsVYV5B/9aV0X/toxf8A&#xA;JnNXn+suVj+l955SzdirsVdirsVdirsVdirsVdirsVdirsVfD3/ORP8A60k3/GXS/wDk3Fk8X1D3&#xA;sZciyPNu4jsVYV5B/wDWldF/7aMX/JnNXn+suVj+l955SzdirsVdirsVdirsVdirsVdirsVdirsV&#xA;fD3/ADkT/wCtJN/xl0v/AJNxZPF9Q97GXIsjzbuI7FWFeQf/AFpXRf8Atoxf8mc1ef6y5WP6X3nl&#xA;LN2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV8Pf85E/+tJN/xl0v/k3Fk8X1D3sZciyPNu4jsVYV5B/9&#xA;aV0X/toxf8mc1ef6y5WP6X3nlLN2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV8Tf85WafeaH+d1tr00R&#xA;e0vYbO7t2AorG1pFJHXpyBiBPswyUTRBQRYR1hrWlX9slzaXUcsTioIYVHswO4Psc20ZgiwXEIIV&#xA;LnU9OtYWnuLqKKJBVnZ1A/XhMgOaACxf8j7e481f85C6bf2EbfVbaeS+mkoaJBbxFVZvDm3Ffm2a&#xA;nLLikS5cRQfd+QZOxV2KuxV2KuxV2KuxV2KuxV2KuxV2KsV/Mf8ALTyv+YOgNo+vwkqp52l5FRbi&#xA;3k6c4nIbr0YEEHv2xV+fn5meTU8meetX8sR3RvY9NlVEuWT0y6vGsgqoLUID064qt/LjyafOnnbS&#xA;vLAu/qP6TkaM3ZT1fTCRtITw5Jy2T+YYq+9vyq/J/wAp/lvpMlpo6NPe3NDf6nPxM8xXovwgBI1/&#xA;ZQfTU74qznFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq/Pb/AJyR/wDJ2+af+M8P/UNFirv+cbv/&#xA;ACdvlb/jPN/1DS4q/QnFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX57f85I/+Tt80/wDGeH/q&#xA;GixV3/ON3/k7fK3/ABnm/wCoaXFX6E4q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq/Pb/nJH/y&#xA;dvmn/jPD/wBQ0WKu/wCcbv8Aydvlb/jPN/1DS4q/QnFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq&#xA;7FX57f8AOSP/AJO3zT/xnh/6hosVd/zjd/5O3yt/xnm/6hpcVfoTirsVdirsVdirsVdirsVdirsV&#xA;dirsVdirsVdir89v+ckf/J2+af8AjPD/ANQ0WKu/5xu/8nb5W/4zzf8AUNLir9CcVdirsVdirsVd&#xA;irsVdirsVdirsVdirsVdirsVfnt/zkj/AOTt80/8Z4f+oaLFXf8AON3/AJO3yt/xnm/6hpcVfoTi&#xA;rsVdirsVdirsVdirsVdirsVdirsVdirsVdir89v+ckf/ACdvmn/jPD/1DRYq7/nG7/ydvlb/AIzz&#xA;f9Q0uKv0JxV8q/8AQ8//AH5P/c0/7M8Vd/0PP/35P/c0/wCzPFXf9Dz/APfk/wDc0/7M8VTDy9/z&#xA;ml+l9f03ST5O9AajdQWnr/pLnw9eRY+fH6qtePKtKjFX01irsVdirsVdirsVdirsVdirsVfnt/zk&#xA;j/5O3zT/AMZ4f+oaLFXf843f+Tt8rf8AGeb/AKhpcVfoTir5U17/AJwgZLGWTQfM/q3qgmK3vbfh&#xA;G5/lMsbsU+fA4q+YdW0u/wBJ1S80vUIjBf2E0ltdwkglJYmKOtQSDRh2xVHeT/Kes+bvMlj5d0WN&#xA;ZdS1BykIduCAKpd3duyoilj7DbFX1L5O/wCcMrfR9V0rV9Q80PPd2FxDdvbW9qEjLwusgQSPIzFa&#xA;rSvEfIYq+lsVdirsVdirsVdirsVdirsVdir89f8AnI8k/nb5pqCP9Ii2P/MNF4Yq7/nHAkfnb5Wo&#xA;Cf8ASJdh/wAw0vjir9CsVdir88v+citObT/zp80wlQvqXS3IoAARcwpNXbx9Tf3xV3/OOuqxaX+d&#xA;XlW5kICyXT2m/TldwSWy/wDDSjFX6G4q7FXYq7FXYq7FXYq7FXYq7FXYq/N785dWTVvzW813yNzj&#xA;bU7iOJxuGSBzChG52KoMVZT/AM4q6c95+duiSBeUdlHd3MvsBayRqfoeRcVffGKuxV8Yf85o+WXs&#xA;fP8ApmvolLfWbERu/jcWjcXr/wA8pIsVeB6ZqF1pupWmo2jcLqymjuIH8JImDqfvGKv038r+YLLz&#xA;H5c0zXbI1tdTtormIVrQSKGKn3U7H3xVNMVdirsVdirsVdirsVdirsVY7+YnmyDyj5H1rzHKVB06&#xA;1kkgVujTkcIE/wBnKyrir80JZZJZHllYvJIxZ3Y1JYmpJPvir6X/AOcJPLLy695h8zSJ+6tLaPT4&#xA;HPQvcOJZOPuqwrX/AFsVfXWKuxV5F/zlD5Dk81/lbdzWkXqanoL/AKStVUfE0calbhB33iYtQdSo&#xA;xV8EYq+sP+cN/wA0Yntrn8vdSmpNGXvNCLnZkb4ri3WvdW/eqPd/DFX1JirsVdirsVdirsVdirsV&#xA;dir5F/5zF/NKK/1C28g6XNzg09xda06H4TcFf3UFR/vtWLMPEjuuKvmXFX6G/wDOPnkJ/JX5X6Xp&#xA;9zGYtTvQdQ1NCKMs9wAQjDxjiVEPuMVej4q7FXEBgQRUHYg9CMVfn7/zkN+VEv5f+eJhaQlfLmrM&#xA;9zpEgB4ICayW1d94S1B/klTirzfS9U1DStSttT06d7W/s5FmtriM0ZJENVYfTir78/I387dI/MnQ&#xA;gsrJa+Z7JB+lNOGwPb14ASSYmP0qdj2JVenYq7FXYq7FXYq7FXYq8f8A+cgPz30/8vtHk0zS5Y7j&#xA;zhex0tbfZxaow/3omHan7Cn7R/ya4q+ELq6ubu6mu7qVp7m4dpZ5pCWd5HJZmZjuSxNScVex/wDO&#xA;MP5SyedPOiazqEPLy5oEiT3JYfDPcj4oYB47jm/+SKH7QxV92Yq7FXYq7FWLfmV+Xeh+f/KtzoGr&#xA;LxEn7yzu1AMlvcKDwlSvhWjDuKjFX57+fvIPmPyN5jn0HXoPSuIvihmWpiniJIWWJiByVqfMHY0I&#xA;xVKtF1vVtD1S31bSLuSx1G0bnb3MLcXVun3EGhB2I2OKvrn8pv8AnLvQdWjg0rz2F0nVNkXVkB+p&#xA;zHoDIBUwMe/VO9V6Yq+h7K9s761iu7KeO6tJl5Q3ELrJG6nurqSpHyxVWxV2KuxVC6nqumaVYy3+&#xA;qXcNjZQjlNc3EixRqP8AKdyAMVfNv5t/85gafbRTaT+Xg+t3ZBR9enQiGPtW3icVkYfzOOPswxV8&#xA;oajqN/qV9Pf6hcSXd7cuZLi5mYvI7tuWZmqScVZL+WX5Z+Y/zC8yRaNo0dI1o9/fOD6NtDWhdz4n&#xA;9lerH6SFX6EeR/Jeh+S/LFl5d0WL07OzWhkahklkbd5ZGAFXc7n7hsAMVT7FXYq7FXYq7FWI/mX+&#xA;V/lX8w9COla7AfUjq1jfxUFxbSH9qNjXY0+JTsfnQhV8N/mp+SHnX8ur1/0jbm80Vm42utW6kwOC&#xA;fhEnUwuf5W/2JYb4q89xVP8Ayt5985+VJzN5c1m60wsQzxwyEROR/PEaxv8A7JTir1bRv+cx/wA2&#xA;bGNY76LTdWA+1LcW7RSHbxt5IU/4TFU8f/nN3zkYyI/LunLJQUZnnYVrvsGX9eKsd1v/AJzA/N7U&#xA;UZLNrDSFNQr2ltzcD53LTivvxxV5T5k85ea/M9yLnzBq11qkq19P6zK0ipXqI0J4oPZQMVSbFXqH&#xA;5R/kB5y/MO5juUjbTPLgb9/rE6niwHVbdDQyt8vhHc9sVfcHkH8vvK/kXQY9F8vWvoQD4p53o008&#xA;lKGSZ6Dkx+4dAAMVZJirsVdirsVdirsVdiqldWtrd20lrdwpcW0ylJoJVDo6nYqysCCD4HFXhP5h&#xA;f84geRdfkkvfLU7+W79/iMCL61kx6/3JKtHX/IbiP5cVeB+aP+cWPzi0JneHTI9ZtVr+/wBNlWU0&#xA;7fuX9OY/QhxV5zqflDzZpTFNU0W/sGXqLm2mhp1/nVfA4qlSI8jhEUu7GiqoqSfAAYqneleRPO2r&#xA;sF0vy/qN8W6G3tJpB1puVUgDbqcVek+Vf+cTfzd1tke9s4NCtWoTLfyrzp7Qw+q9fZwuKvfvy+/5&#xA;xK/Lvy28V5rZfzLqUe4+tKI7RT7WwLcv+ejMPbFXt0cccUaxxqEjQBURQAqqBQAAdAMVXYq7FXYq&#xA;7FX/2Q==</xmpGImg:image>
+               </rdf:li>
+            </rdf:Alt>
+         </xmp:Thumbnails>
+         <xmpMM:OriginalDocumentID>uuid:9E3E5C9A8C81DB118734DB58FDDE4BA7</xmpMM:OriginalDocumentID>
+         <xmpMM:DocumentID>xmp.did:49477e0f-276a-4cd3-8c1b-cab8815bed51</xmpMM:DocumentID>
+         <xmpMM:InstanceID>uuid:2e5c36ab-b08f-3840-94fd-90b8522b24ab</xmpMM:InstanceID>
+         <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
+         <xmpMM:DerivedFrom rdf:parseType="Resource">
+            <stRef:instanceID>uuid:dab6724e-c618-4184-9b2e-7d44879e5e5f</stRef:instanceID>
+            <stRef:documentID>xmp.did:008add62-65b7-3547-8416-6472cd533b2c</stRef:documentID>
+            <stRef:originalDocumentID>uuid:9E3E5C9A8C81DB118734DB58FDDE4BA7</stRef:originalDocumentID>
+            <stRef:renditionClass>proof:pdf</stRef:renditionClass>
+         </xmpMM:DerivedFrom>
+         <xmpMM:History>
+            <rdf:Seq>
+               <rdf:li rdf:parseType="Resource">
+                  <stEvt:action>saved</stEvt:action>
+                  <stEvt:instanceID>xmp.iid:49477e0f-276a-4cd3-8c1b-cab8815bed51</stEvt:instanceID>
+                  <stEvt:when>2020-07-25T23:40:45+10:00</stEvt:when>
+                  <stEvt:softwareAgent>Adobe Illustrator 24.2 (Macintosh)</stEvt:softwareAgent>
+                  <stEvt:changed>/</stEvt:changed>
+               </rdf:li>
+            </rdf:Seq>
+         </xmpMM:History>
+         <illustrator:StartupProfile>Basic RGB</illustrator:StartupProfile>
+         <illustrator:Type>Document</illustrator:Type>
+         <illustrator:CreatorSubTool>AIRobin</illustrator:CreatorSubTool>
+         <xmpTPg:NPages>1</xmpTPg:NPages>
+         <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
+         <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
+         <xmpTPg:MaxPageSize rdf:parseType="Resource">
+            <stDim:w>1024.000000</stDim:w>
+            <stDim:h>1024.000000</stDim:h>
+            <stDim:unit>Pixels</stDim:unit>
+         </xmpTPg:MaxPageSize>
+         <xmpTPg:PlateNames>
+            <rdf:Seq>
+               <rdf:li>Cyan</rdf:li>
+               <rdf:li>Magenta</rdf:li>
+               <rdf:li>Yellow</rdf:li>
+               <rdf:li>Black</rdf:li>
+            </rdf:Seq>
+         </xmpTPg:PlateNames>
+         <xmpTPg:SwatchGroups>
+            <rdf:Seq>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpG:groupName>Default Swatch Group</xmpG:groupName>
+                  <xmpG:groupType>0</xmpG:groupType>
+                  <xmpG:Colorants>
+                     <rdf:Seq>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>White</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>255</xmpG:green>
+                           <xmpG:blue>255</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>Black</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>0</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Red</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>0</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Yellow</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>255</xmpG:green>
+                           <xmpG:blue>0</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Green</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>255</xmpG:green>
+                           <xmpG:blue>0</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Cyan</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>255</xmpG:green>
+                           <xmpG:blue>255</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Blue</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>255</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Magenta</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>255</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=193 G=39 B=45</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>193</xmpG:red>
+                           <xmpG:green>39</xmpG:green>
+                           <xmpG:blue>45</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=237 G=28 B=36</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>237</xmpG:red>
+                           <xmpG:green>28</xmpG:green>
+                           <xmpG:blue>36</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=241 G=90 B=36</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>241</xmpG:red>
+                           <xmpG:green>90</xmpG:green>
+                           <xmpG:blue>36</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=247 G=147 B=30</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>247</xmpG:red>
+                           <xmpG:green>147</xmpG:green>
+                           <xmpG:blue>30</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=251 G=176 B=59</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>251</xmpG:red>
+                           <xmpG:green>176</xmpG:green>
+                           <xmpG:blue>59</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=252 G=238 B=33</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>252</xmpG:red>
+                           <xmpG:green>238</xmpG:green>
+                           <xmpG:blue>33</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=217 G=224 B=33</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>217</xmpG:red>
+                           <xmpG:green>224</xmpG:green>
+                           <xmpG:blue>33</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=140 G=198 B=63</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>140</xmpG:red>
+                           <xmpG:green>198</xmpG:green>
+                           <xmpG:blue>63</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=57 G=181 B=74</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>57</xmpG:red>
+                           <xmpG:green>181</xmpG:green>
+                           <xmpG:blue>74</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=0 G=146 B=69</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>146</xmpG:green>
+                           <xmpG:blue>69</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=0 G=104 B=55</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>104</xmpG:green>
+                           <xmpG:blue>55</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=34 G=181 B=115</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>34</xmpG:red>
+                           <xmpG:green>181</xmpG:green>
+                           <xmpG:blue>115</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=0 G=169 B=157</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>169</xmpG:green>
+                           <xmpG:blue>157</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=41 G=171 B=226</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>41</xmpG:red>
+                           <xmpG:green>171</xmpG:green>
+                           <xmpG:blue>226</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=0 G=113 B=188</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>113</xmpG:green>
+                           <xmpG:blue>188</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=46 G=49 B=146</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>46</xmpG:red>
+                           <xmpG:green>49</xmpG:green>
+                           <xmpG:blue>146</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=27 G=20 B=100</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>27</xmpG:red>
+                           <xmpG:green>20</xmpG:green>
+                           <xmpG:blue>100</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=102 G=45 B=145</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>102</xmpG:red>
+                           <xmpG:green>45</xmpG:green>
+                           <xmpG:blue>145</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=147 G=39 B=143</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>147</xmpG:red>
+                           <xmpG:green>39</xmpG:green>
+                           <xmpG:blue>143</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=158 G=0 B=93</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>158</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>93</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=212 G=20 B=90</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>212</xmpG:red>
+                           <xmpG:green>20</xmpG:green>
+                           <xmpG:blue>90</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=237 G=30 B=121</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>237</xmpG:red>
+                           <xmpG:green>30</xmpG:green>
+                           <xmpG:blue>121</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=199 G=178 B=153</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>199</xmpG:red>
+                           <xmpG:green>178</xmpG:green>
+                           <xmpG:blue>153</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=153 G=134 B=117</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>153</xmpG:red>
+                           <xmpG:green>134</xmpG:green>
+                           <xmpG:blue>117</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=115 G=99 B=87</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>115</xmpG:red>
+                           <xmpG:green>99</xmpG:green>
+                           <xmpG:blue>87</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=83 G=71 B=65</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>83</xmpG:red>
+                           <xmpG:green>71</xmpG:green>
+                           <xmpG:blue>65</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=198 G=156 B=109</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>198</xmpG:red>
+                           <xmpG:green>156</xmpG:green>
+                           <xmpG:blue>109</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=166 G=124 B=82</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>166</xmpG:red>
+                           <xmpG:green>124</xmpG:green>
+                           <xmpG:blue>82</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=140 G=98 B=57</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>140</xmpG:red>
+                           <xmpG:green>98</xmpG:green>
+                           <xmpG:blue>57</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=117 G=76 B=36</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>117</xmpG:red>
+                           <xmpG:green>76</xmpG:green>
+                           <xmpG:blue>36</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=96 G=56 B=19</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>96</xmpG:red>
+                           <xmpG:green>56</xmpG:green>
+                           <xmpG:blue>19</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=66 G=33 B=11</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>66</xmpG:red>
+                           <xmpG:green>33</xmpG:green>
+                           <xmpG:blue>11</xmpG:blue>
+                        </rdf:li>
+                     </rdf:Seq>
+                  </xmpG:Colorants>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpG:groupName>Cold</xmpG:groupName>
+                  <xmpG:groupType>1</xmpG:groupType>
+                  <xmpG:Colorants>
+                     <rdf:Seq>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=56 M=0 Y=20 K=0</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>101</xmpG:red>
+                           <xmpG:green>200</xmpG:green>
+                           <xmpG:blue>208</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=51 M=43 Y=0 K=0</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>131</xmpG:red>
+                           <xmpG:green>139</xmpG:green>
+                           <xmpG:blue>197</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=26 M=41 Y=0 K=0</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>186</xmpG:red>
+                           <xmpG:green>155</xmpG:green>
+                           <xmpG:blue>201</xmpG:blue>
+                        </rdf:li>
+                     </rdf:Seq>
+                  </xmpG:Colorants>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpG:groupName>Grays</xmpG:groupName>
+                  <xmpG:groupType>1</xmpG:groupType>
+                  <xmpG:Colorants>
+                     <rdf:Seq>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=0 G=0 B=0</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>0</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=26 G=26 B=26</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>26</xmpG:red>
+                           <xmpG:green>26</xmpG:green>
+                           <xmpG:blue>26</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=51 G=51 B=51</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>51</xmpG:red>
+                           <xmpG:green>51</xmpG:green>
+                           <xmpG:blue>51</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=77 G=77 B=77</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>77</xmpG:red>
+                           <xmpG:green>77</xmpG:green>
+                           <xmpG:blue>77</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=102 G=102 B=102</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>102</xmpG:red>
+                           <xmpG:green>102</xmpG:green>
+                           <xmpG:blue>102</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=128 G=128 B=128</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>128</xmpG:red>
+                           <xmpG:green>128</xmpG:green>
+                           <xmpG:blue>128</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=153 G=153 B=153</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>153</xmpG:red>
+                           <xmpG:green>153</xmpG:green>
+                           <xmpG:blue>153</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=179 G=179 B=179</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>179</xmpG:red>
+                           <xmpG:green>179</xmpG:green>
+                           <xmpG:blue>179</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=204 G=204 B=204</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>204</xmpG:red>
+                           <xmpG:green>204</xmpG:green>
+                           <xmpG:blue>204</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=230 G=230 B=230</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>230</xmpG:red>
+                           <xmpG:green>230</xmpG:green>
+                           <xmpG:blue>230</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=242 G=242 B=242</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>242</xmpG:red>
+                           <xmpG:green>242</xmpG:green>
+                           <xmpG:blue>242</xmpG:blue>
+                        </rdf:li>
+                     </rdf:Seq>
+                  </xmpG:Colorants>
+               </rdf:li>
+            </rdf:Seq>
+         </xmpTPg:SwatchGroups>
+         <pdf:Producer>Adobe PDF library 15.00</pdf:Producer>
+      </rdf:Description>
+   </rdf:RDF>
+</x:xmpmeta>
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                           
+<?xpacket end="w"?>\rendstream\rendobj\r3 0 obj\r<</Count 1/Kids[5 0 R]/Type/Pages>>\rendobj\r5 0 obj\r<</ArtBox[260.012 83.8406 713.5 947.255]/BleedBox[0.0 0.0 1024.0 1024.0]/Contents 23 0 R/CropBox[0.0 0.0 1024.0 1024.0]/LastModified(D:20200725234456+10'00')/MediaBox[0.0 0.0 1024.0 1024.0]/Parent 3 0 R/PieceInfo<</Illustrator 7 0 R>>/Resources<</ColorSpace<</CS0 24 0 R>>/ExtGState<</GS0 25 0 R>>/Properties<</MC0 21 0 R>>>>/Thumb 26 0 R/TrimBox[0.0 0.0 1024.0 1024.0]/Type/Page>>\rendobj\r23 0 obj\r<</Filter/FlateDecode/Length 572>>stream\r
+H\89ÌTË\8eÛ0\f¼ë+ø\ 3a(R¢¨kÒ¢§m\11äÐ\ f\bú8l\17ØæÐßïÈv¼NÚÞ\8b\0\8aI\9bÃÇ\8c¸ÿt¤ýÓQèðîHi\7f<\v]®$\1cÚîNº^^Òþ\ 3^\7f»&\8fÌÖ3E\ 4w    ÚYfU£ÜY\8aÑÏ/éë\fu<\93L?:\1f?¦¢ô\8bÒ+åÉ\95ɽ\92\ 6\12þHÃ1N­ÊjJÏé\9c\15\9e,Zæc7\9d\0ÿL/\e\14ËÊVZ\ 3Tf¯(c\83·ë\8d\9bQCa¡@hÎ\91\95nÿ«ã2ç[AK4î\8e¼\95et¸BÎx²"LÈ\99\1e\81g<a\e\1f\8eÓ\813\8dq3\ 1u®ÔJù­:Ka\8b\8a1\f#*¦ÜgC\ 5pÑ       M\171Ø£{¼TÔµµ/©\82\93ÞÞ<ÏÉ\91lëiý\ro<ß\12]\12,AÀwðxJÙ\1fhû¿\8b\96¥ô\99\80¿ê8ËèÈéU\88 \b5\1fÂ:L¾°2ùf±->¿÷m¦\ 1źA+\90   K\85Æ×\99ì\9c\ebw\19\9a\984}¸Ó\18p¹B0\14\1d\16\7fDþ+°Vô\82\17]\94÷\8aG`Ñ ÃÌb0­A\94\98\16\9aÁæ\88I7\87vîm|ÎV\9d¬ãnÛ\bÒÚoÖ%iæ\0Èb\8f\v\ f\ 2\96ÈÅZ\81o6ôo¸âh¦+j2à©pFªq:¾\1c\8d-\eb\10£õ^jêÂ\92\15Á`<*HX;\1dj\8bV&²\a\8a>,\17\13ã\9c- 2T\93\8dV34c\83\99`\95\82Í\81yöA0·\9bñ¸\11L¡?Ülmà»·»-\93\v\vè\9aÆ    Z\1d%\8fû±<Ï`sw\86ä&È\83Õ\11¨\ f\94\rÕdcGÚI]ï\9f°\8bOé·\0\ 3\0¼%\16}\rendstream\rendobj\r26 0 obj\r<</BitsPerComponent 8/ColorSpace 27 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 106/Length 325/Width 106>>stream\r
+8;Z]b5n\c'%#*ZsM8NlC%==^R8%K72"G.)t9]nQ^%[548!jiY1;/VUTKn49iTS--H
+:D61!;o5\DU2I]V:<Z%U4eYr\o[Zs%pKfJ>Un69cBV(lgd[ZmSZdHu6Bn3#,lHrg3
+#5(qW)EM(MXs_ImMkkW5OYfjN;Le:;<smU_:`h5aMf9q5OsEV^,Y=0u.&E8$qAjXI
+eLD<cGAro`F-<F,e!$\%cq]5)+^BL6PJXbBaP>'pp*td(FB$EU&31tPed@*(WDI8`
+ni_M!9C%2gd.4%pr\9@8lMBA"D:Vq.SLs+6kaQ^Wo8-bp.#N&;49bf4%(e_~>\rendstream\rendobj\r27 0 obj\r[/Indexed/DeviceRGB 255 28 0 R]\rendobj\r28 0 obj\r<</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream\r
+8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
+l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>\rendstream\rendobj\r21 0 obj\r<</Intent 29 0 R/Name(Layer 1)/Type/OCG/Usage 30 0 R>>\rendobj\r29 0 obj\r[/View/Design]\rendobj\r30 0 obj\r<</CreatorInfo<</Creator(Adobe Illustrator 24.2)/Subtype/Artwork>>>>\rendobj\r25 0 obj\r<</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>>\rendobj\r24 0 obj\r[/ICCBased 31 0 R]\rendobj\r31 0 obj\r<</Filter/FlateDecode/Length 2574/N 3>>stream\r
+H\89\9c\96yTSw\16Ç\7f\9e\90\95°Ãc\r[\80°\ 6\905la\91\1d\ 4Q\bI\b\ 1\12BHØ\ 5AD\ 5\14ED\84ª\952ÖmtFOE\9d.®c­\ eÖ}êÒ\ 3õ0êè8´\16×\8e\9d\178G\9dNg¦Óï\1fï÷9÷wïïÝß½÷\9dó\0 '¥ªµÕ0\v\0\8dÖ ÏJ\8cÅ\16\15\14b¤    \0\ 3
\ 2\11\02y­.-;!\aà\92ÆK°ZÜ    ü\8b\9e^\a\90i½"LÊÀ0ðÿ\89-×é\r\0@\198\a(\94µr\9c;q®ª7èLö\19\9c\95&\86Q\13ëñ\ 4q¶4±j\9e½ç|æ9ÚÄ
+\8dV\81³)g\9dB£0ñi\9c\19\958#©8wÕ©\95õ8_Å٥ʨQãüÜ\14«QÊj\ 1@é&»A)/ÇÙ\ fgº>'K\82ó\ 2\0ÈtÕ;\ú\ e\e\94\r\ 6Ó¥$ÕºF½ZUnÀÜå\1e\98(4T\8c%)ë«\94\ 6\830C&¯\94é\15\98¤Z£\93i\e\ 1\98¿ó\9c8¦Úbx\91\83E¡ÁÁB\7f\1fÑ;\85ú¯\9b¿P¦ÞÎÓ\93̹\9e\vom?çW=
+\80x\16¯Íú·¶Ò-\0\8c¯\ 4Àòæ[\9bËû\00ñ¾\1d¾øÎ}ø¦y)7\18ta¾¾õõõ>j¥ÜÇTÐ7ú\9f\ e¿@ï¼ÏÇtÜ\9bò`qÊ2\99±Ê\80\99ê&¯®ª6ê±Z\9dL®Ä\84?\1dâ_\1døóyxg)Ë\94\16\8fÈçL­UáíÖ*Ô\ 6\16SkÿS\13\7feØO4?׸¸c¯\ 1¯Ø\a°.ò\0ò·\v\0åÒ\0\rß\81Þô-\95\92\a2ð5ßáÞüÜÏ     ú÷Sá>Ó£V­\9a\8b\93då`r£¾n~ÏôY\ 2\ 2 \ 2\ 1+`\ f\9c\81;\10\ 2\7f\10\ 2ÂA4\88\aÉ \1dä\80\ 2°\14ÈA9Ð\0\a\1dt\81\1e°\1el\ 2Ã`;\18\ 3»Á~p\10\8c\83\8fÁ  ðGp\1e|   ®\81[`\12L\83\87`\ 6<\ 5¯ \b"A\f\88\vYA\ e\90\ 5ùCb(\12\8a\87R¡,¨\0*\81T\90\162B-Ð
\aê\87\86¡\1dÐnè÷ÐQè\ 4t\ eº\ 4}\ 5MA\ f ï \970\ 2Óa\1el\a»Á¾°\18\8e\81\1cx ¬\82kà&¸\13^\a\ fÁ£ð>ø0|\ 2>\ f_\83\87ð,\ 2\10\1aÂG\1c\11!"F$H:R\88\94!z¤\15éF\ 6\91Qd?r\f9\8b\A&\91\v\94\88rQ\f\15¢áh\12\9a\8bÊÑ\1a´\15íE\87Ñ]èaô4z\ 5\9dBgÐ×\ 4\ 6Á\96àE\b#H     \8b\b*B=¡\8b0HØIø\88p\86p\8d0MxJ$\12ùD\ 11\84\98D, V\10\9b\89½Ä­Ä\ 3ÄãÄKÄ»ÄY\12\89dEò"E\90ÒI2\92\81ÔEÚBÚGú\8ct\994MzN¦\91\1dÈþä\ 4r!YKî \ f\92÷\90?%_&ß#¿¢°(®\940J:EAi¤ôQÆ(Ç(\17\94WT6U@\8d æP+¨íÔ!ê~ê\19êmê\13\1a\8dæD\v¥eÒÔ´å´!Úïh\9fÓ¦h/è\1cº']B/¢\eéëè\1fÒ\8fÓ¿¢?a0\18n\8chF!ÃÀXÇØÍ8Åø\9añÜ\8ckæc&5S\98µ\99\8d\98\1d6»lö\98Iaº2c\98K\99MÌAæ!æEæ#\16\85åÆ\92°d¬VÖ\bë(ë\ 6k\96Íe\8bØél\r»\97½\87}\8e}\9fCâ¸qâ9
+N'ç\ 3Î)Î].ÂuæJ¸rî
\18÷\fw\9aGä       xR^\ 5¯\87÷[Þ\ 4\9cc\1eh\9egÞ`>bþ\89ù$\1fá»ñ¥ü*~\1fÿ ÿ:ÿ¥\85\9dE\8c\85Òb\8dÅ~\8bË\16Ï,m,£-\95\96Ý\96\a,¯Y¾´Â¬â­*­6X\8d[ݱF­=­3­ë­·Y\9f±~dó      ·\91ÛtÛ\1c´¹i\vÛzÚfÙ6Û~`{ÁvÖÎÞ.ÑNg·Åî\94Ý#{¾}´}\85ý\80ý§ö\ f\1c¸\ e\91\ ej\87\ 1\87Ï\1cþ\8a\99c1X\156\84\9dÆf\1cm\1d\93\1c\8d\8e;\1c'\1c_9     \9cr\9d:\9c\ e8Ýq¦:\8b\9dË\9c\a\9cO:ϸ8¸¤¹´¸ìu¹éJq\15»\96»nv=ëúÌMà\96ï¶ÊmÜí¾ÀR \154      ö
+n»3Ü£ÜkÜGݯz\10\1e\95\1e[=¾ô\84=\83<Ë=G</zÁ^Á^j¯­^\97¼     Þ¡ÞZïQï\eBº0FX'Ü+\9còáû¤útø\8cû<öuñ-ôÝà{Ö÷µ_\90_\95ß\98ß-\11G\94\10\1d\13}çïé/÷\1fñ¿\1aÀ\bH\bh\v8\12ðm W 2p[à\9f\83¸AiA«\82N\ 6ý#8$X\1f¼?øA\88KHIÈ{!7Ä<q\86¸Wüy(!46´-ôãÐ\17aÁa\86°\83a\7f\ f\17\86W\86ï   ¿¿@°@¹`lÁÝ\b§\b\8e\88ÉH,²$òýÈÉ(Ç(YÔhÔ7ÑÎÑ\8aè\9dÑ÷b<b*böÅ<\8eõ\8bÕÇ~\14ûL\12&Y&9\1e\87Ä%ÆuÇMÄsâsã\87ã¿NpJP%ìM\98I\fJlN<\9eDHJIÚ\90tCj'\95KwKg\92C\92\97%\9fN¡§d§\f§|\93ê\99ªO=\96\ 6§%§mL»½Ðu¡váx:H\97¦oL¿\93!È¨ÉøC&13#s$ó/Y¢¬\96¬³ÙÜìâì=ÙOsbsúrnåºç\1asOæ1ó\8aòvç=Ë\8fËïÏ\9f\ä»hÙ¢ó\ 5Ö\ 5ê\82#\85¤Â¼Â\9d\85³\8bã\17oZ<]\14TÔUt}\89`IÃ\92sK­\97V-ý¤\98Y,+>TB(É/ÙSò\83,]6*\9b-\95\96¾W:#\97È7Ë\1f\15\ 3\8a\aÊ\be¿ò^YDY\7fÙ}U\84j£êAyTù`ù#µD=¬þ¶"©b{ųÊôÊ\ f+\7f¬Ê¯: !kJ4Gµ\1cm¥ötµ}uCõ%\9d\97®K7Y\13V³©fF\9f¢ßY\vÕ.©=bàá?S\17\8cîÆ\95Æ©ºÈº\91ºçõyõ\87\1aØ\rÚ\86\v\8d\9e\8dk\1aï5%4ý¦\19m\967\9flqlio\99Z\16³lG+ÔZÚz²Í¹­³mzyâò]íÔöÊö?uøuôw|¿"\7fűN»Îå\9dwW&®ÜÛe֥ﺱ*|ÕöÕèjõê\895\ 1k¶¬yÝ­èþ¢Ç¯g°ç\87^yï\17kEk\87Öþ¸®lÝD_pß¶õÄõÚõ×7DmØÕÏîoê¿»1mãá\ 1l {àûMÅ\9bÎ\r\ 6\ enßLÝlÜ<9\94úO\0¤\ 1\98¸\99$\99\90\99ü\9ah\9aÕ\9bB\9b¯\9c\1c\9c\89\9c÷\9dd\9dÒ\9e@\9e®\9f\1d\9f\8b\9fú i Ø¡G¡¶¢&¢\96£\ 6£v£æ¤V¤Ç¥8¥©¦\1a¦\8b¦ý§n§à¨R¨Ä©7©©ª\1cª\8f«\ 2«u«é¬\¬Ð­D­¸®-®¡¯\16¯\8b°\0°u°ê±`±Ö²K²Â³8³®´%´\9cµ\13µ\8a\ 1¶y¶ð·h·à¸Y¸Ñ¹J¹Âº;ºµ».»§¼!¼\9b½\15½\8f¾
\84¾ÿ¿z¿õÀpÀìÁgÁãÂ_ÂÛÃXÃÔÄQÄÎÅKÅÈÆFÆÃÇAÇ¿È=ȼÉ:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûÛ\80Ü\ 5Ü\8aÝ\10Ý\96Þ\1cÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäüå\84æ\ræ\96ç\1fç©è2è¼éFéÐê[êåëpëûì\86í\11í\9cî(î´ï@ïÌðXðåñrñÿò\8có\19ó§ô4ôÂõPõÞömöû÷\8aø\19ø¨ù8ùÇúWúçûwü\aü\98ý)ýºþKþÜÿmÿÿ\ 2\f\0÷\84óû\rendstream\rendobj\r7 0 obj\r<</LastModified(D:20200725234456+10'00')/Private 16 0 R>>\rendobj\r16 0 obj\r<</AIMetaData 17 0 R/AIPrivateData1 18 0 R/AIPrivateData2 19 0 R/ContainerVersion 12/CreatorVersion 24/NumBlock 2/RoundtripStreamType 2/RoundtripVersion 24>>\rendobj\r17 0 obj\r<</Length 1128>>stream\r
+%!PS-Adobe-3.0 \r%%Creator: Adobe Illustrator(R) 24.0\r%%AI8_CreatorVersion: 24.2.1\r%%For: (Aaron Wyatt) ()\r%%Title: (Jacktrip.ai)\r%%CreationDate: 25/7/20 23:44\r%%Canvassize: 16383\r%%BoundingBox: 260 -941 714 -76\r%%HiResBoundingBox: 260.012435076958 -940.159420289856 713.5 -76.7445203867428\r%%DocumentProcessColors: Cyan Magenta Yellow Black\r%AI5_FileFormat 14.0\r%AI12_BuildNumber: 496\r%AI3_ColorUsage: Color\r%AI7_ImageSettings: 0\r%%RGBProcessColor: 0 0 0 ([Registration])\r%AI3_Cropmarks: 0 -1024 1024 0\r%AI3_TemplateBox: 512.5 -512.5 512.5 -512.5\r%AI3_TileBox: 232.5 -892 791.5 -109\r%AI3_DocumentPreview: None\r%AI5_ArtSize: 14400 14400\r%AI5_RulerUnits: 6\r%AI24_LargeCanvasScale: 1\r%AI9_ColorModel: 1\r%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0\r%AI5_TargetResolution: 800\r%AI5_NumLayers: 1\r%AI9_OpenToView: -379.499237432242 87.568545097045 0.654974427262942 1428 807 18 0 0 6 43 0 0 0 1 1 0 1 1 0 1\r%AI5_OpenViewLayers: 7\r%%PageOrigin:112 -812\r%AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142\r%AI9_Flatten: 1\r%AI12_CMSettings: 00.MS\r%%EndComments\r\rendstream\rendobj\r18 0 obj\r<</Length 65536>>stream\r
+%AI24_ZStandard_Data(µ/ý\0XÌM\ 5\8eUÆÒ\f'ÐØ°b\ 3\14\13«|<\8b­l\9b¶©k"â\8aM\8aìM;Ë\f\86\rÎ\8cR\ f¸àª\1e\r\10Ñ\vÍ\vRD\1a3\82î-u\92Ï("\1a\13UO\17s¯3\A!U\86zâY¼\9eNs|É~b\99Ï\9c\84åpEejN/ë\86u£*8"\952â+Æj%u+òÃ#\8egY¯!\8d!\8aãePE+6ëuS£dRD\1e\919}:Ã\14CßG7\91\19\9e\19Ga#åÑ+g\83\8aVÃ:¥lÓÑ\89Âá\9a³\8f\94Ã7É\91\8e.%óÎKÓ`ÅuÊG¿ÖÃU6\ fVØÜøèfi¸aè\ 2\b        !¸\0\aDMôýQ\9dX\99\9cµjØDõ|Ç1\8d\9a(\92äúô<Ä\14vSCrªì»hXïÝÅÆKtÆlÝD7w\1eT\82R6cJ\fysF\1dsÓ:s\Óºå>nÈÒ\14]x&Å\92\84½ÐÌø\rIµuâgÜ\14%V}\88u!w\94(N¦]¤\8cÈÌ£&îN\8dÆM\9cèbô«¹ñ\9eÌMô\92ã(cç\ 6\9d¸E¬¬¦?ÎÄðþ\12£°[\8d\96°×w¾ýGYÌÈ\8dH»*þªWgô\9eÙ¨º\8d² mÎÈ,SrFV,Û)Ã,X33zÝðÆj\10\89+\8e+\8a\92>¬Ä\95x\8a\8d\9a\94\8c\9a\18úÔ\1es\14µ\8c2qr\12Ò§ccNAι~þLeÔå]Ý\9dÝpL  ßØÍ/ù\83äJß|Ú\84EÞ*Å#\9e\85s+¯æ\13\8f)afuæ\93jFI\85I;hâuñüá9H*Zw\98       #9Oé´7nÂJnB?ß\86Oa²\8e\9b8_æ>\8f\8a.\8e2a\92¾\88£hXó\85èã¬Djþ\91ÈÔ\8bæß\95ãRçú~ã%|ZÍ]d\88\89âO̯ÙãÂá\10\13C^ÌãRA¿\1a\8cS3\91\94ë|¿:FZ%\14¡[ï\86\9d\82$6|\82\96qRa#3Î\84GÆÈgõ\86Ù\1f\95Oì»ò\9d~C66G3ùtß aMi\93_b\1fÄ\8a:OKhò\8d\97\9bz\  êÉÈ\87Æ\95`\8d\rù½é(V\94|\ 6\9d¨\97\89}¡Í`+\8aj£~æ\92R\14iH'zòá\v;;\91N?\r\9e¢ÆÜ±\98Ы\86\83NºêhD\94«jm\1d\96\85Å8\9d:\92GäÞG]\18\89YÍ.Rß·c\87HÍa\17C³ïwÈ!RQ÷\8d_èU\99áÛøE¥ìÒYw\9c¯¤ä\86>G7z\14¿\14EìæêJ¯\18\8d"ÏæCäÒ\85¤ãÎääCS"׫!\95¨N\86¨ô9\1e½dTºe\8cT¿l\9cH\95HgDzhj­\96o\86\9d\7f¬J·Ï\f;\8aû\87\85bL\92¡\17ù\ 6\1d\85í¡íu7£"4Ýl5xv£oP(ªè%ú±~!rì6õ\15\89\89>U\1ae\14coÅ5[\15ý*4h¥O\194G\ 6\15ÅXõ¬$+Ý»£×\94\8d²ÆìLK/£¢Ón\17\19$\85ËcEíÜi¯åD\97+\ f\11ˬHÌ\9es\95ìéN&6tv<\91JNj§#Ý\88ø\1a,
+\96\19k7\ f\87\90Â*¥£×Îᢨ¯T»\94m\9cPôS9º´8ªÆFÆ>\1c\e%\14e\96\eÝfjTQ\94ülìGdc\84V\14µ\9fl¿2\r\11\8a\12ûèUÒp\15\8d_ÌLU\8d{\11\85ÑÇ/H¼a]h7JwÒö\96M-\13\89Y±N\8aµfb\9b\9cý¬5Ve\91\8bívѨPÜQ\19g\90x,K\99¶[=£b¬\13ÕÜtØÅ¹\83ô\11\1a©ËÐGÑÝ£\17\14b\1d½í\8d)
\9d\8cÔiä0¢ Ý1'\86çÖÉH\9döFª\9fÍÑ\86x\17+\1a\89üª\91×Ì\98\13¾;¶B¥º\9f\1a6w\961'N&¥:QmØPL\11ÇMÔÝÈÔ-\9cQ¦ð\85\83'j´\9e^m\a\8b\17@H`\10V5êD9®Ñ¯Ôñ¢øéq&h4:IQЮ\83L¼\Ôºí8μ\0\aÄÔ\84zT\16â \13UDR\1c4\14ä\92A&æHE2h\86üa\13îI#\83\86\17@HÀ@\ 3\8e\13\9aLÊ,'wâéçªkç¹\1dëÞ\e"\81\ 6A\eÀ\ 5\10\12\10p\ 1\84\ 4\ 2\ 2\11l\90A  >\80ÁÂ\ 5\174@!\0B\ 3\ e8X0\80à\ 5\10\12\ e XÐ\ 1\ 6\ep\90Á\a\1fÈ á\83\ e\14\fp\ 1\84\84\r\1e .\80\90`\ 2q\ 1\84\ 4
+h\0\ 4B:À\ 1\ 1\ 1!\14*\10\14$\10"\1cÀ\ 2\rx  |\ 1\84\ 4\14\\0!!\82\82
+4  ä\ 2\b w\96²_^ÇYAý\88|\10QÐ*S;}j\(\88EÃ,\12\ 4\10!\ 5\19\0â\0¬!Éiä\17ý¨®ºÅj\88\8bhõyª2k·%Ü8ÐA\1c\1e\1a\1c\1a\1a\1a\18\1a\16\1a\14\1aÞp\rÕ@\r       n\98\ 66H\83\ 3C\ 3\ 3\ 3Ã\ 2\83\ 2Ã\19\8c¡\18ÌP\ 6apXhXXXø\82-ÐÂ,páA¡AaAá
+¥`\85*\88\82Ã\19Ê\84S¸">\9c\r
+\r      
+¿zph`XHXPø\15yaa\81\v       \ 2 @\84\ f2\18A\ 6ÈúÆû:ÙLJ\92\9a\eM8DØQ\95\9fk]L\ 5ü5D\98Ë8|#×z\89Ô£\92\98Ó×-Ë]\8a\86tÍæ"ä\f\11c*±\1a\13Y^\r\ f\7fH\90\82Ã\83,$\9c\9cN\ 5.\90\81\r\ 3¥téú*t¡\fm¨C\1f*óà\ 4\85Ûl&\93mqh\98\85Yx9\\90\85\ 4\a\86;\8aÐ\897N¾ák\7f\97Í\9a\f\11C¯!\17gn¥*W\9d]ìåÁá¡á\81áaáAáá\ f÷`\ fõ@\ f~\98\87>ÈÃ\83\83\83C\83\ 3\83Ã\82\83\82Ã\1dÎÁ\1cÊ\81\1c\14D¡á\81ô\820\88\83<\88\90,\87C³h<VUm\86\b\eR\9d\91w\8e4¡Ô¥%#\91ÛkH8\85\85\87\ 4k\18\992ás     \r\r\ 2 ê\10qê¥$\13¢9\1a"ZtGcW\15\86\bÚÕÝ\98ÜÓ©!bJfìZÎø556      7\1f\85\ 61]\8fù|\ 67\90¨È\14\1a\12¤luu\86j(\87JPH¨30$4ÈÔ\1f\14\1e\16\1e\18\1e\1a\1e\1cä\ eÇp       ?;ºa°\9b\19=TC-PM±\1e¨\81¦Á\fVð¹L\ e\93ÐðP\87«Õ\81\r      m`0\12\87'ÌÂT\eLzð\ 3y\9cP3\81\81\f\82$<0|\81á\16îî\12ìªÁ\18nÇP\v¥\90@\ fä°0äà\86:Aa>7f:$,ü*A\16\1e\14\1e\14\1c\14\1c\14\1a\18\16\14\8a\14<lxBÃ\19¾p\ 5>\9cÃ)Ü\9dQ\13\1a\8c¡\84á,å@\r´@
+ttT    m i\18\86Y\98[æa!\81\95\ 6\1c\aa\90\ 5Q0\9b\1f"~ºl­m\88\82$\8féñBÇ\9e\8e\8a\1a\19\1c\1a¤\81n k8\83L)$$ A(\15aèB\15Ìt \ 3\17¨À£I:HB\ 2\12\ 4 \14"\10 \88`\ 2\f6Øà\ 2%DãB®³±\1cIFD|þ\\86B?«!B\12<X ;\88F\86\b¢\96ù¶éb"\14\19½:×Ii\9ax\88¨:O*þ\87.W¤QG5\e"\84Чù±âq\88\98;\93MK"*{ãñßC\84\rÇgR§Ü6D\\87V£¹r%C\ 4\85\15©jÆÛÅ\1a"®Ää\86\8c"d\87$p`êð\863\1cݼ$4üÎç\as0\akX0\ 5³²2ò\98C9\94\839\98Ã9Üá\ e
+\ e
+\ e\v\ e\v\ e\f\ e\r\ e\r\ e\ e\ e\ e\ e\ f\ e      \ f\ eò \ f|àC\1fú0\ fóà\a\ 3=ÔC=Ø\83=ÜÃýAáAa\81¡ÁáAäJ¡\16ª¡\1eJ¬æÛ\82\83ñxst        µàÓ]á
+gxÃ\1dîpQ¨Má
+\f\r
+Gc\91H\1c\96u\10\87\ 4\ 5\93¢P\ 1        B\19\19b0Ã0\94\81\fÂð°à°Ð°À°°° °ð\85\85\ 5/ÌB\17dáAÁA¡A\81AaAAAá
+§`
+¥@
+V\18\85*PA\14\1eîð\84\ 4$\90ÜoH\82\ 2\12\1c\9a\9bÏÂ0\8cÃ<\f]ÛäòYÁ\v\83\85JC¦¢£Ó\ 21\90\ 3=\10«5EUu%\95\a>840,(\9cÇ\84\ 4H\82\ 2\12\1eJ\8cV\e³%\90\95\99\9dÝ\14\18¬Á\1cìÁäx½9\1f]\9dÝÝOá\16\8eá\1aÎá\1eNÎ÷s\9f^·ßÿ\853¼á      \ e\7f¸(P¡
+£`\ 5R(\ 5S8\85+((,(0(4(8(<(È\ 2\17º0\v\85\85\82ÂÂÂ\ 2ÃBÃ\82\ 3\19Ê0\ f\v\ f\v \fd CB\19:\ff0\ 31\10C1\941\1cÃ1\9cá\f
+\f
+\f\v\f\v\f\f\r\f\r\f\ e\f\ e\f\ f\f\ f\fÒÀ\ 66´¡\rÓ0\r   n \ 6\86\ 6»\867¼A¡A¡a¡a¡\81¡\81¡¡Á¡Á¡á¡á¡A\1c\84ã0\ e\ 39\90\ 3É\ay\90\ 4\ai\90\ 6a\10\86\ 5Q\10\85ËÉ\89\89\15y\12JIH@\ 2\13\14\90Ðð\85+ü·×\13èó^þp\ eÇp\v§p?»:º¹\1eOÎÁ\1a\14ìvfFf\e£\89=\94C5ÔB)Ô˪jªÅJx \ 6\ 6R Ó\91\11\91i\88$ô`\a3xÁ
+¾Ïæ²=¦é\87q\18\86a\18\85¹±\99:4!\ 1  
+H¨\ 4\1a\ fyÜép82\1c\99\87>4Á¡\rm(C\19ºÐ\ 5\85÷zÖj\95JuÝv:mËJ¥              °\10\91 \80\ f<@A\83\0\81\ 6\1c,\0\ 4\e84,$x° \84ô`á\ 2\b \15\0\82\10¡\10ª\10B\88è`á\ 2\b      .û\90\84#ýÒô\8eÄnH\ 2ÉÖº"öÓW\95å7rUå\90\ 4I J[êÈ\18\8b\86$p \ 1\ 4\v¢BD\82\0XP\82
+\88\b(Ð`!\0â\0\1fl\10!\ 3\10`ÐÁ\ 26X\10/@\ 1\81Ã\ 5\14!\ 5\19\ 3\10l\10A\83\ 51\82
+\b\ 1D8\ 1\ 6\80\0Á\ 6(àà\ 4\80\a\19  \ 2¢\83\b Ø \83\10\8cà\ 3\f\81\ f"l\80\81\ 6\13ø`\83\f0x@\a\18l\80\81\ 6\13\b\80\10À     8РB
+6p0A\a\1c\84 BC
+2øà\ 3\11NàA\a\11&\10\0!\0\11l\90Á\a0èÀ\ 2"\0B\0\1f\ 2       < \ 1\ 1\82\b-È \ 3\ e>ø@\ 4\f\83\11\9c\0\83\ eD\90\81\ 6\1a\10¡\ 3\f4xø\80 "|à\ 1\v*\10A\83\ fdðA\a\18\ 4\1e\ 1\a\1e0\ 1\v\81\a2xÀ\b\ 1\ 6\80è\80\83\ f2\0\81\83ø \ 3\ 5\ 1\9c \ 3\f\86\ 6\1cp`\81\ f:P\b\80\10\80\10\80\ 6\1cp`\ 11\ 2\ fPÐÁ\82\18Á\a\18L`\ 3   lÐA\84\ f>À`\ 2\ 1Hà \ 4\e\ 4(à \83\ 5l\90\81\bP Á\ 4\b$\88`\83\f>Ø \83\ e\ 1\a\11¸à\ 4(ø B\ 5\81\ 6\1ct0\81\r2\10A\84\ 5\b\10\12<ø`\83\b&0\ 1\a\f ØÀ\ 1\ 2\84\84
+@`\88@\80á\82r\83\b\1f|\80\81\ 6\ f5\8fXö÷Ò\93rãD\r\ 4\19\80ò
+ J\1e`\83\fD\90A\a\12\88 \ 2\f&\0\ 1B\82© B\ 6\18ؠ   $À±¨£09q5EýV­¶ÝTC\ 4YìB¦+\1av¢nÇ6ý=nS\0\fp`\81\r"\9c@\ 2\1et\10\81\ 5\18\ 4(\88À}\80\ 2\r8ð \ 2\ 5>\88 \82\ e\01Ðàá\83\ e\14\r"\80\80\ 3\b¼\ 1
+\10\12(\ e\10A\ 3\f>P\81\b\0\83\a\8a\ 3xðA\ 6\e\83\b\1a \80\ 2"v\ 5>è@!Â\ 6\1cD@\1c@\ 5\112HA\84\v\v hð&ú\9bj\90\81\ 5
+ h\94\14á\ 3\f48\81     "Xà\82\11®°\0\ 1<(A\a\18\98à\ 4\1c\80\ elÀA\ 6\19\88 \ 2\ 58\10\0\11\aXX\0\ 5 @H\10q\0\ fD°A\ 6\1f|\10¡\ 2\11D\80\81  \1ap\815@\ 1B\828@\ 4\11`àÁ\ 5.\98\ 6(@H¨[\1c \83\b\1e0\ 1
+"\0\ 2\r2@ÁÂ\ 5e\ 3\14(>ÀÀ\ 4\1d\10A\83\f\1e\ 6(@H(Á\a0Ð`A¨\80\ 3\r4\88°\ 1\81Á\a\eD\10\ 1\ 6\10\10\e\ 2\ 6q\0\ f:à@\ 3\ e\18<ð Â\a8è`\ 2\1fl\10Á\ 4\0\a\r\10 $\mu#%ÛFY\ 1\ 4\8d¡\89¢ûUê\13\87ø\ 5\10G/\13\1a\972<\88@\81\f\18\0\ 1BBY\ 1\84i\82~\ 1\84\ 1VÀÁ\82\b\0\ 4\e \80\83\ 5\b\10\12æ¦(\ e\10¡\ 5\19\ 1\ 6\0\ 3\ 6\b\10\12ì\ 3L\85Ô\0f\0ª8@\84\ f0hØ\80\83\f\ 4\90\ 1\ 6ã\ 4\19tðA        >\80\81\ 3\ 2 \ e\10A\83\ f\0\ 4\b        \ 2\b\80\10À\a\1f\82\f\88\r\0\ 3\85\0\88\ 3tÀÁ\ 3\ 4\b     \1c\1d®8À\ 6\1cdàA\a\110pÁ5@\ 1\ 2\84\ 4\19®\10\0\ 5\ 2Ð\ 1\a\1f`ÐÁ\a\1e @\ 3\r\1a Ä\ 1:àà\ 3\f"tÀ\0\ 1B\82\901\ 5\88à\ 1\ e@ P\80
+L\0\0\10\ 26Ì3\9e\67JÆJ(¦öQ\95Ë<#öz=Ì'ç=´¹9s\19\91Èk;©¡Í'dÍ\8e6\ fk"¶ÙD¬UËf\93+{ûÜ0©ÑRñ\ 6\1c\ 1\ 6\1fp@\ 1\13 à\ 3\1fPXX\b\80\10Á\ 6\19tðA\ 5\f \ 40'\9ac
+\10\0a47=\11\12$¤É°i\99m¾öJʾ-£%lâ\8dß\12\8fVG\9d\91ÏhL$>\8d§­q5UªñMHÆ´WÓö^ã;Ú>\19\91Í\9eDQÑ­$üÖ\9d?Ìu² 9jé­û\8d\12\91v©«\96\}øÄ\83Ä\86åùþð   »Ä3I}g\92\99\92gF´Ï\96\9e±þ·t\11´ÿLgOÿEb\1f¸ªò}7*2ÊQ\15ÍrTEfrT6³»\92#*J\89Û7sYñ=¯Ht«2\91àÜ\8e\ 6\91hoäè&á(\eYF\8e\88Êñ]Ï;ú\14Yâs\9f%¨Å\12SV×\921$*V;ú\9dÇèʧ\97kL:²ík¥n\1a\ f#\8e\94¥\8a,u3¡Q4%Eìç5Ï$\1cEet$SR35£Ì\e\87Ç \16v-\r\8d9
+#ߨ\11URc\1ar4f¯s\91 ÕØ×LE5\8f¸\fQ\91QLÕè\11U$\15Õ>8f\14w\11*iè\96Êð\95K,½\16\8f\1f)\97×¹èd$Ã'\1e\ f\9fI<ôÚ\1e¾Îuhøî£\9d¡Û\Ã÷Ñ
+\93;C'\97Í+<Ýì\86\8f¾Î\87\8fâC6ª¢èQGQ*òÐ\91\86üZ%D§
\12     Ñ9XÁ\9bë-î0\11£±k\réelHOX©ø\8dYQ\84\1f
+׬£\95+\v+ìħ_FIePåLR«°LÏRA\12dä#È·\93¹\89X\8e°\9a\91}¾¢Ä¯ÇΫ--Rí×­\86´¥¶¶´?í\8eW¼h´¥­U\ro¨ã#ÈÆsì \8bù]ÄA\9c\99øVûùì³ð±&¶M<C&\9eNM<\172±§¥\1aBÂbWE\164Ñn¤$Hì¦Ê\8a\9f¡¸(5\8a\ 4\87H/!9)ÑD|\9az\88\90\8b¦ÈÜ\88)â1\92í\1dϸÀ\0\18hJ\96\11\8c\9c\95¬êÊb{Ì\8a\89ãÁÖÆÔ\15c"Í\92ÌômLÅ\19\15ívp\ 4M5ò\b³#\12\ e\8e¨»"\1a\1dÁ\12±\921ä¸\8a©Þ\94;\8c4bE¾ibI#\9bmvu\e\8c\86Ya»°læ\83*,õÜïKCÄJö"\92ÙXî>\7fÚ\fó¢uG碪ùÝ/ò\8c;i>/ISá\19Q)#é~\9d\8eh\8c0\191ó#éV\1e³1¢\8e¨ã\ 4Q\95b\1f\13òÏäRúQ\98\89\ 6q\90°ÍÆ$'"Ì+2\r\8aÞP\8a.F\93E\91F36,LÌÄè×\12ûxÑf1\19b\94AÂH>,nuVe\91Q\98\18
\84Ê¢Å+ÛÝ\r\90\8cN=\8e«\19aºäd\94µ*F/Iª)Fbs>²\ e±Úô¢²*MD\9aR\15\12©áut\84±}Ñ\10ã\\91\aÙ¹J^˱JF1Ã\1aµ(¹«è¶Ô ÉI}\1c\854ó­7\96L¯±$L7\8aê¯"¾!³A*{Ül\9cÅÑåNn:ç\1eg&>Ó«eã\8c¢¨ÎvL\1fâ\r9
+*\17ÙC\97º\ e\9f\9c¸Ä³Æ-ÈeSºéÙÓ³\8e[Ôâ)ÝqÜw¼\85U>¥»\13£\e¦\ fñ\8d\e1\95\1asv¬\11C5#É9hó\aIxnÐIjH\9asè7ï ;\12Õ*\9bäæÎ"z\9dÕ ön3c64E5!Á«\9b¢\1a\8b^+\8d\9a\10éQ#aÒrÑË\9eQ\13\eBâD.º¼fÔ(%|\e\87Þ3\91¬%çZó-7b\Î}\97k\88ܰÅ˵ù¤Cbn\88Êä\aʪþ\96\8d*Aò*\7f¨Æ§*²s­ê`\15\15ËhT\89O\1d\95I\12æ\93"\9fNf\90È8\8baKdb/\80\90`\82©±²°.\99fGÏ\99vW\9a\19\e½²\93\89\fÑê\9b1ÅD+é\99\8b\1c\8d©!Ú\87¯Q±gN®°»¢yò¼\95W¬´SÕî\92÷\eå\90\8fLÌgRÍf?\9aÓ\98ðèúZÏ&{%´Õ\b]åb\19\9b¹\ÇæR\13¾f~d\8dÐ\95\89µsÜ!5Ó*É!´\9a±/­ÝNdZTlí­Í|\8cf´*èø1Tá#ú\8c\fsO¦n^ïG]q%ÆWkìNT¶Ó\1d\13\13Õ°<f1MsJÕ¯Ælâ\e\9a\97g\83x\92\9f\9c±\88ìÿCcCd±¡ùÑÜ ªÉ\ 6QÅõf85¥
+\92ÔhÚ\9cî\8d³\8dØíj\88ÖA\17&\95Ñ|Æ:,.¾*ùb¨<-\ e_\;fd¼\91á\v¢ù1\17\1d\1aÞ\98\8bK\95ç¶k\1cUnÌËsTQ\91\9a¾æ®\18\12$·Ê°\89ãÇDGä\9f¢"þ3=\9e\r\91Ýæ÷ª*¹1÷\8f\rÑÐüFF#\1eoI\1as1Ò\9bæô¬2xâĤãÛ¼áö.\17ñ\7f\93\8d1aZ^¿ZQõÏ×F?*¿¾\9b6öÚ vLÆÔ\1aUN\*?;\1ftQÄÖxÚ\9f}×Ñ\eé\86I)O>®\19½0\87|esU\e\8d^\98ñ¬|qÕ\10Ö\8eê"\92þ²òOh½è\89­,¬¸Ü\98\bù¶«\92Y¶÷ÎC\84ã¶#27Jh~,]\90\84B\95\999Óò)©\9f\8c\8a\8d»°YÕ>x\17d\9b\8f#ã§TLy>»óW©\98±\98íb\1e·|ldØ\1a^M(î\93ºG±bxD[¥J[yb\87½Jþ"UÝK&\93q)\92\87\94ÞX\91\ eþgï¸PqZ.\7fZ\17É\86\86o\8d¸ÈG$âýw£X÷ø)̽Ö^§\95Cf³Ðl%e\e\1a\15+¥]ê\1fS:«2\13£\13]       \8bµ\15é\86ú\9aØåu\83x\1e3"&F¤ ª£3Z\89½Èè|KQ\15­Ìt¾\8dÕ\18¹Q\89}\848\8ac¤bn\9f\18ñb>ÍØ~òs\9cÒJ¯r\14\19Æ
\91rªêP\98Ýfü\93áp+c¯Á!½:w584ú\88¬\88\7f:«ºÍ<8B¼\9aA\19\9bY£eZ=\1a2\15\9c\r\19\92úÔÏx+ø2­ng\192õgÎqí¸ÄV/E­£J3v\85¯\93®£5\8do¾³¨CJAU¢zP+8\14«_u3¬\15dWDs\8eúbõÄoM\87§¢×¡ø6\9eþ&'<Ö¶hò.gHÌe\15G\11¡2\19\8aÏé\9d­®Bñ=B×ÌV63KZÅ7z\86M\8bT\11\9fB\ f\9b
+\92±]M)È|~^{\r1)|\8bY\8d\9b^çt\9b¾i68\15õ!bÉ~^v\1aâ
+²Ê^/¹\1a'\ 5Ç\8aN\83L"+K©¤ýIé\8aF\86äæV¬uäæWï wê\84\84#rs1ÍÞ<cGcåPÙÜV7²Û¼¥\1aä\9a%«O\15Ù\90Kå|ÜyÝz3X
+\9fÙX²ùT\85Ϫu\96\ eSÅý£HQó££!UÊ\98C\8a³\8d©ú\14\97\9f|Ã:\88¥è\f\8d5Ltf¼Xª\95£E\1a\16S\1e\19\aÉ·¢l"Eã\14\1c\8bÕLÆ\87ÍNÕõ\9bò \8dÂEr\18\ 5Ñ\1d·\8c4.\96\87yL\1a\1aFi\9dï\86\95êè\9aY_2\9c\1fd\8a·<¦BmMýn\95§d^Ë\97\9d\15Û`Ey\99ª¹Á\8a2eªnúøbÖª³÷\98á°
++£]wé\86\98ú©WåFo.£\16,ªr\8b\1e4Âv\1c»\83VA¯\11Õ{ë¨aU\fyÌêÕÚ°òEl~v\83#|¡Ï\ 6[\1e×È\1f÷<%c=\89]»Í¥þcÑç¸\94ñÓ\8eWѱf\9e©]X!v_+CF\1c\99t\84\86\8dèk\8e\86CFtêæêTs\90Ì \11gUG#ß*_ù\9aâ\8c«\8dYæµ3Ñ\f3\9d|\9ca\16f\87zRl\99&råG-î\F;]Ù 9Äâu©ØÍý°3²!¾\v\rZ\14\87¢î\19å9G+ìßT4ÅV\8d\9c\98\f¥ÄQ¨ìzucH¢LO\r\97gAÖËUõJGV÷pªÚa\167"¥GH7\99ÇÕèË\9d]\91ÕïlƵNVW©\96Õ[â¸R\Ñ\86Ytè\7f}ÆlÜ=Nâ<&±{¤Fñe\1a.a\9d\12\8f\96b^\ f!Q£\e\9a\1d}u»R̶k}\1cmq\1fÿu*û8\9a\98\87-*R\7f]\86\1fG\93²¿\8e\14\94q\99\88ØÉµqä\f[\94Ñ\88Ø;¬q$\vû\biæ-ì>ó¸\90ÄåæÚG\94\11«ö\11ñ8á\9dÔÅNÒ\87Ù£¡«\9b\10\r\97¢Nn:u\e\1e9ªÓ\8d\99×(\89\8f-®)¦îã$jÛS\17S\94\18~被Æ\17ªÛ\18OZ§®NhèF\8e¤ºÈɸ!\87\11\8fDró\947\19´1Ê        \17\85n(F:\83JÜZ$\8dg\86Îú\98Ô\10ª\a-LÎoý^5Ê$?i½b2\84(\8c\84ÝȱÎ\9f\83D¶Æ\91¸\9a³á\12~)23\%¬â\1a½\ 4\rõG·9\8d\96\90ò£ûW£·kÕgèÎ\8eê7®ÄÜÌÑG\8b¢tVÖ;ª]\8d+a²¹£\ fýÑ#QöÜéB¿\re\94Å©æ§\9b\9cÆ\91GLïtDÂ\19\1e\88oFòGn\13JëèF¹1#Ã#X®£ó/+IÉÕÑÝ¢1%æð\b\8eNeîÏñ\11çù¦qDA-\1aµ\98£\e©»¼Q,\8d«Ð\10[>)\13Ϥ \11«öañU¯\97/\96¯\9f\8e/\96Dözu\e\1fQñÜ£JQí\84C¥Ø\8d\r\877¥Ý¤Í\94Ø\9búu2u\14Û¤j\e\85åÇìÛD¿-b\9fÞPï1\92ð~5ÿvÇlä\95íÂWxç\9ag\8c\8e.IG£Ú      ç<×*³\12\13ÏKl.²¸Ãî\96ïh'IÒPùäÿöÿÿ_â±ù\84lU?³\9dÔÐÂ
+9d¦9Y¾\18Ç\88׺\9c¿ðÊ\92pÆÎFd:FÂûÍNÎê3\85ö߯×ëÿ}\96s\88\rÖ\91Ù\87Q\19\19\19ñ\86\86\11\r#SëU®*\eFV'\e&[\r\93\11Ñ0\91y\98L\96A4TCªê\ 6\91Ù\19éîséÃl¶\9bhÔ7d3j¬º\8d)\99"r\8d)ZlL\9dÒ\1a¯âÕ ã\rÍ0;+3Ñ2;2;{¯\1e½ÔÎfÛF\93Lèä\17]ëó¡Mh¬\7fcÙ°¿>~\99\9b\11\96h¯ÒDZ´\92}\11\8d4\1a"[ÚÍQzò\89\11Y¹£\93QŪúªªôÉ«*o"q\85\96\89\91\15\1a\e×XfF¦\r\89¦M\91iäï\84S\ fÑnn&ýùGÂ\9f,32t\8ffºÉ\9cZ»¡ólLáçäôÓÑ\89)Õù~¿:\1e©&âc\1e\ e\16\1dÍ\akP\9dÍ\89jTÞ`\rVëÊ8Zm\95\8f£U2¬jg£ªÚ\1abb41Zý2h\83fZ¬ê&³\93ë\9d\1c-Dz²³cÝÃ\8eî\ 2\b     \1f ÑG\99Ý\87«ÊtÇá:\12\19®\91\91á²×\aÕ\98µeEGýðm?v\vmLlõ#ÛÝYÅVÿTȪ\ f\9déµ\12Ê]\vm\15\8ḇ%\93\1ekãå¤^Å:ë&ÊyÊæËè®\e\9eUÕáÑÚ+*Ou¡ë5\855D!i¡XX&ò¤\84u\12s\98h^X&z¨\9dzÍ×\rm\84\86jε%³ÕZ¦\99ä+k\999c
+[gì\91jn\86#-!\9a\95±\89\88ôÊ"-!\16Ñu¢¡WÉPäÌ®ú\92Ccõét¼äÅ\86uÇÎ-uWSÒ÷o"*ó(²d-:Õ*5r\84H\16ë\91!ãGÜ^±$Ë®\14ùÅLÖ\18\15É\94\90î*V<y\ f¹È¦íz¡ÉƯ©³\11»\91rÂÚKj;\91$óù|>\9fKËõ˪6w½ÞÜÍÍ\98ãÿñ\18     -­;½N\1ft:½l3uLh#Iä\8c\87¯ÚDääGEa\8dzFÓ\91§\9c~±$ï?ÒhjbDZk±\9fõ¯\93W-é÷*««\90\8cîüm6®ü\8dÌÇê­\15uh\9fÓÌÙ©Cu3\93\9aLUÃ\1aÒP\9dÅz¨lÈ¡RÙ\90ì®áÛ2×\90?×}öqCsêB\9e\8d\88¦q\9a\v $|\80w6\86|6ÌF£\1eô\87733\9dÑaç:nª\1eâ\1a6\9câèP©Ö\93Auu\88\83:¤Ñù\94\87§&\1f3CòÑñ\87õæf\n*6DÌ\10©{þ\10Ê\9c\8c¹ñö:¤D6r£d\8c\fieH\ 1F\86HuHyÈø-§ãfPÙ\9fÞQÆÚÇ\8dC*µ\f©ÌÇ_\1e\ fé8søÃÒ\1ab65DHC\8cn\86tÈ(\8e\91\92!¬Q\17@Hø\0;\8a3ª4hfFMÕÌ\8d÷h\eïyã¥ßxë\91!#Óºê¨É\99q46hË[þ\83|ßÔa\12\9aa2\99\86©Æ\1a&\93Ô0               \11\11\11\11Yj\ 6QM;\88\86\83¨Cè,$çÒQ}\94èæ£ä\e¥Q*QK£tÒq\9bm\1cäûÝ2Ì£T\1fDDd%¢\ f¢¢êq\14u.t£::6v\15iÐ%£!6\15\rñÔ\10_Õn\88i\8fÅÉeÄâ|ØXGÃtÄwÆ\11ÑÑQ\89Æiê<\dä\1a\89íÆÚ\87ýþúÉ£®\7f\9dG\16¹M\84¦ÐnEÊ&ÿý·»\8c\95ðW-\91\8a¯r³Úo¨.dR\9bMé¸ßX\9d»\8d:^ÜÉ¿Áó<\7fº±a;»\89Ý\ 4\95ÝngBÃlìªh\10±\1e&\9a\8e¡\179tÄë\r"£w\1c\99£\88Ô\13ǹ\1dã\19cs\8cÇW\1fõ\98\9eó \9a3\eg;ã\10ÿ´\9bÍx\89$w¼Æ\8e×e\1dïk´\ f\9b\9b»Q\92"ÕùÆÇõGuØ\eÕ3Ú¨N½F\15\ 5\19Ð\80\10@\0ÄCÀÁ\ 5,8\ 1\a\f\17l\90\ 1\ 6\10è@á\ 2\10\0\83\b'\88@\81\v<h\80 \8b±YI\91L)Ë&Y\8d<KèwC.V;±ã«D\8e\16«\95<\1a«\8aU\17E\16+:±\91\7fA<ªÑ\8f76F§*­=¡½Ä<LVêµ\vÍæFh®\14\99\8c#4ÛQ\8cDB\9b¾(e+ªÕªco±\8aF!zLs¬Õlb\95dVy]\8d]é<'"«kÏtVd×\9bé®ì[IJª2ÓË$4sI\95\95õÌwD¶c\89ÌêX£Ç\13#ÚIrVé\92\ féÿÔ\99ÝYµìî\¼;\9f¤¾UU¤?wîVv­ê\99ÕmÞ§\18º\97\15}¾¡\9b\15ÍÊÞ\'dßøg.éü\r¥\1fû\9d(±ÈMqyä¦t\8aä\14Ú\11ÉMqÕÈM¬r&é­\8aÂ\9b1úiçÏxEÒYGRKº\95ÔßNwåM´n%½\9f\9fÝB\9a\9f 1\9f\9a\9aK*\11\99ôhÌvRC§\ fGÚ*3kî\ 4Í\9d\86æz¢Ì\8aæ8'èeÆaW'=IΩÖ\94n24\1cT;\9a\f\1e\r¹\8f%c¢²3++ÕqLX{\93N§8«\93\15\92Þ\9dF÷å3x\82æî\90î\9ft\15ºÿë\7fÛIê'}^Â:¬(Cª¹ )W\11çâ¡3\13t\8bOT=\95{º^õó÷Tt    ²Ì\9c¤H(§\12\9fÚ\\8ads¢ªÆR£È\1d\86 ÄÏ2ö8áIÕ.*§\18\eÕNÆMµ\93\e\ 5ejhCÞ½Þ©\19'Õäg\83Ãq\154"QM\7f¡zM\1c7\1e«ù8\85\19ûb}¥\19¶µ\8b]è:5X»Tk\17NK¡Ø\89WAU\e\1dÑúõ\8aJ\8b_ìÇ$Vd#)Þà\90ØOî\1c))VJ¬(Vä\98\88\9b\¿s\89ñ®¦\94³\90yõ²Ë¨~Ô\88×\9cb36âFBGu#4\866ä"µCûüìå\88©*­d¤\91×Ù©©\1a\8c¤Êc4½Tª~$F§\1a*\8f©|U*»,ÓÏ\8d «²Kl6Ss5\84¬F¢Ê¤:¢9R¡{«Ì¡·\8a\ 4\8dæ­2I\90\8bE\12\12ý\ 2\b        \f4ÓºoÄÝK\96ù<\95"NÝ\94f°FNÈv"3>ÂçñÄÛËxª\8f8¢ñT¾;\9enDÝL3ÂJÚh\98X=[§\19¦FP¥üÌtD\rï×\11\1e³{Ñ\10³P¬#l\84=®¢dîNç\11*!¢ÙÑ]¿}xÊÆè\89é\84højúM}È\89P>äf\94cúÝÜ\90\8d     kÈ\rOñFMFëbàïD<
+\9f&¼z\8bÂ\88¢Ú\1a\18ÖÆèÆèÊv#5\88¢´\8dnUwVS£\14)\13GgF\1dD\9c\9aY%
+\1aR\0ñ\9fQël\92!5$4\99k­ëLÄÝcS\97MR\17\89\98\9e|ê(ª$5ewlTÔØÌ\14\994HX\8dTëÌ»u¾\a)¦Êæ}\b¡ ã\90ê\8e'Q\93\9f9\9a\1aAr=¢aÑ\91°)\9eê÷\11­\99S\rÅ\9d ¸¬\8aC£ðÑ\98\90KÌq
\13\97\8cäV¿\9f\9bë£J\13Q\99\8fNÒÝjF\9c\11E\8a\ 4Y¥(q#ÍÕ[ºèL«Qã«·c\14#²á3\1aY\8a¡\1dù\88F\ f\8b\91Xµîuòâº2\8dUJdt;\13_6»\ f\15K§OOl\92M\91ZE+éV\z¥\95\15Õ:B\16=D\15\9a\11\1aËS\9c\12\9a´X\16iNMÚ­Xô\9cg;\94\8d\8dÐ\86\8e4féuFµd\9a\9dÖ\87\95\13û\rÉtnÊr\bËhÚÉ]\9fjÝÚ\8dêsZݸê\8dóêsV:íÄDsî\97ªñ\13Æù\91fF]\90\88\8bR©1\v=33Èí\8dݱ\12\1eÍP\7fQæò\ 5éÒÌP\854sþ\9d\9a\8a\15Í\8c\96Pj¦Õ¾JGsÎ\bÙ \89k\8cYÚul\171²ñÅ#U\9còØ\99¡\9aªó\90Í|f.­\1aSU\ f}Rã\8e\9e\8bï!U^øÎFó³\99aÿCN\7fN\96\8eÆÏSs²\98¦ãÚ>ó\9bÝ\r]\9a¨\93¹±ÇLNX\8bè8æ\84Ñ©c÷}î\8boNþçf\\91ÏÍøÓ\9a\eÏYgnì\8aÒ\88§N3ÕQ\13\1c¢i\88¬D\89~6n\9f:xÂF~\1a!\19Rj\86ìÄ\99)5v§¹Xï4wÂ$\9dfdz\9a!:£\9e¸!ÖÌ9\9d)+12\9e\99ºý\1e£·¶ùIéÿ¼%2õ\95d̳¬lÐ\84\8dIõ©T\822\1f°ë\84\1aÝÄ'ö\88\9c¥Njxñë¤.3¶\9e IÄ~M5ØVgÈEM(c»qønZ\1ar¢7Ñ2Xé\9d\1em\8fü\97\18\91Ñ\18\9d\8c\96(\93Ð\ZK\90C\93Ê\98\12.Kó+\9dq¹Q\13&.ËsÂg¥ÆÐ\86ö°\8b\9a±1ÿ¤vñO\8dynÆãĪ\1cóÝ¢qR» \9eÕì¢.êÙ8¢Ñ\97Iv§c\8e\17\9f\91R±waSe2ý®vï«Øº\9aô׫\9dD¬,Uö\7fV³9\96Ï*²\97«Ý:eF§2\85ÆNý\r\v\19\ 5bê<æXS¹V\1fE¯;{Mæ*ßTwÿ­ÊùòÒ\8a~5$D\8aÝýµ\92\91¿BÆúRb­\86^~YÓÓò\86ffLÒL½ÎdÖæ\16\97¶'²\ f\ e\87\1eZUæsj©'&íL¥.ùû\11·\8aRFGqM+®)¹âK+þÝ\97\9aÒP\8ad(\94³ºÚ32\9bô\8arz(71\8aM¡ó¾ÔضÊ\99³\17±Ç\1aû#\85Æ\8fÇãPN3\85Æü\84&\ eѤ\93Î#GOªÍÐÔ¤\9ebTs\8b\94}M}»ÔÎes|éxF²\91Nò­J~\94sj:\8e±ÎÎ\95\9a\9e#ºúèbGvD·áQõd\87\8e>»16dõ\12#ÉêZ=³Õµì³\9eÍÊZ\17"ÕKxRåa\8d·ÌÿÕÕÕU\8ee¿ß²sÑü\18ïÌh謵\8b&\9d\99ÝÔ«ìÈ\8fêJ\99>\8fÔfµõLxURë»\9cfV´2«²²*\9aTËL\12ñ¾\95\91\15\8c\8a­²º;\99\fÿbmX\91¤Ü\19ê\14\992&ÇÍa§Ó:SÜrl¢Ô\10EZe?UÏ/v\96\88«¦=%\16s|¶¾X'!\89Ä£7cTRo\15yT\95\1a«\92²[Õ\8e<³ÖQ¯¨×£Þ8G-Ï\15ÕÆ5W­¹º\8cñ\8a*|G+f$éê\9e®Ö*Ç6³\8b5\92ÔH;\1aK\8aë\84ÿÇúª½N²\8d\14\ e±2U$\1c^©¯³Lc\87\8b\95'Fd¯Î-    ýêì\95{GV×\e»]ý\11rTëb}-gÊ(7jê£e*Ò\1aÛúÊ\9a\99\19·Böæj¬ìÙãimNIùv\fegöT!\9bì³$û\96Ò8k\9f­Ê\9d<ìm69Kõ\9fS7ßf\1f$\95\13\87Y\9b\9d\92É\84ã³ô§»Ïç\19éRuz¨¦\f\8dê·Sù¦ÊìüÈ?\99ê\85.t¡\93X¾Üw\9e\94\85ÌjB¿ÓHkvÍ#µj'§]y£'\8bO\9f?\91ãØ\98\90æ¬+\8bé%ùà±CTÆÛr$ÎI\87\1c©Ó*T'UêlY±Vèc\16\11ï\9b©\92\f3\12íE\9b#C\91cíb#]\91\18ïªÄXVóè%Æ*ãÝ\19I¬xcNºÚX\8fTÆ£\92\8b¦\ö_t,¡\93f\96ÎÉ0©ÑH\9d\8d±¨e.óÏýYhvë-RÒ¹H\ eÉç\9d¦Ûê\85l,Iê0V\8e|zÊ<Ê\882£X¿4\19Ö\ e\8b|;\12_\89jª-³\8c\"eÓ\8dm\9fí\8djrgö\18]q\8e4zÑs­cËä\83ZÿÔ\8fn\9bß¾b+\14\93º§Î£ÌÍ\89Oº    OèrÊÐ\91EÆ£"_õ\9b%º]·ÍÌ\19Õ\b  Å\86®æJ\13j;¨8¬¢ª*\1agh\1c+z\19Å2\942¢Ñr4Å"\11âÔÛkÝwd\99¢\99¢û\11\87<ľUæu<e7\9e\9fø^Icój>{¥hÊ&õÈ\9ezM±±Ë¥:\93«\86Uù\12²ù6ròp(Vb,9ó\10«!C±\97_õ)\12\9f\8bw\9a\97>§)F\9aþÔ¨)VÛý\½}×P®wå¶sÝH²éÞ6C7=\9bD\8aÅÒ\88\ f\91Ìl\14©\1f½÷_Þ\12©+/D6e\8fÈÑ9w£\vÇU$ÓhE®\97Ù\1a©ËØ\19³lר\88î\91º\18\1fÒTµÚ\9bß­¬>V\93ÌnnªÞ³b2\9dW¬®NG\19îQ8ä\96\8b,¯idÇ\90ò²b·ý\86\91ÒÖ¥tí¶Ú\10\12\91Ö¡!\85æb\9e\12¡ÔDx\95éÐpk\9b\1a\935Ä)y4Ô9)d\r±\8c4]4gfø\8eצèhCd3Ç×áÍ<Ý\88Å\9f\1e£ßi!\8e\91Dñ0¢\94½e§\97\89Dr;\9d®½Ó\89Ç{\7ff\99\98ös\8aÌ÷\86x\862\8cxgvqæÈÅú\98\11\8b\8c\88îÒ¥xÿÄn¼X%d&\88Ä\19j\9dN×íusaQÌH³î\12Ç&«ÑØQÆ\11\1e\9dÎF×0¢ydÈdóÙÐh+Ô±Û±¿í¸%wÚ!Ö>§7¤í\95\8aevÄæ\8beJ~µ¦Än?<}NÈÚ.Ù¾ùn\9cµ9Û/©"Év$\9aB6V\8eZeëò9ó\8cêãÒªI>ä²\96ØÈЧ´^\89F\9eZgÛË7Hj¢9\9f<å)Í#åÈ\8d\91²LG$u$u\1eéMî\i[ÞU\8d9rk®Tse\11çb<ªYSº\98    \9d·:¿C\1c#½Ï\1eéGº\86æ(VSº×Ðé«M\9dµ¡9Ò¦c\8e3ÇóQJ?\92Ðýó|\8eÑ é\90\9d¥ÿµ.ß\884wB²Ðë%=\9f¤¼×ÈJÌ7lÇ:\1eó\87\1d2ºù®Vä¢\96jlÒò§þ(\87ä\96k:VW\9c\1aÇ\16iö­}Ù?v®ªÆ\97\9b\8c\93\1d\91+\8db©H¶X\8dï[hü²\9eÉLÝ\fjGÆÔÞ¦Eï\r\92lm\\85\9eé\87Înú;ºöóÈÇ\95\9c|\\8a\fºU¾"~^®\96\9f\9eLM\9d\16\9fÎ7h:BÓ\9cöôÛÚÚ\92Ƶ'\1cöF\88EFçÜçæöÂ_Íß\9f\99÷¹\90K\16úÒ\96Ç´SgÇm[ºÏïj\9fW\99ì\1fã\8c\9bÞÔ4\9d\e·VW+bgµº\9d\8e\8dÛzlWûêVýp}³3i'jÕÇxCÊaÕ¯5F\eÖûüVUë[ª\8b\15\ e\8cÃZ½\9a*}/³Ø\95]\15\95kF!oªÌxFVõ»£Á!¯7c\16ëC34ÕpN,wý(\93¨F\86\99½«!=D&K®eæpj®ñao=s\98\8fÍÆ\87s<W-W\1f»\1a\99²Mù$Òúü3\84\86$uò´£\1f½\8e~\16\1a\91h\86W±T\11\94,sDºq8^¬\9fè6öÄ.B¹««°n¢°ä0±BNÉ\89·bõX$\ f\1eiªh:£ÅÓÏX&:\19m\93\1cmÓØc\e2äIä\88~\1c:\9b+\19$ÚW)#Ö5/\12Ý\8cC¢«³\18ñÎ:Û\9dñèrCã\8cE-]Þ\19g\94±Ñ«,Q\91k\8cyUSïycÌ\11\9b©©1&\99±÷iÝÄ7Τ\b\16©\1fQl<75æËª\8b\99\f\ f]Äú\98!«fx¹\92¯ªFs×\r\8bdDæçÄWWS\ e«=«×¼,?\99»ª\9bðĨW³«:\8b3t3ÖSDz\9fÍR\93E¿ó\96Î/wt¦)×\8cênu¢\9aNÂëå\94\96\8e\1f©$µç\98\a\9dSVÆf\88\92ó\8dçÌb®°Î¦77=\r3ò.&\1e\89\8e'6úÑ\14\15\95¦ÊSÅ)úI?j¤kÑ\18¥­ÒmîF\1dmXãÇ\1d\87Xrez  iÜx\16É7\16M\8fGÒç$Ùo¤\*½GÛ)B%³#ô£\11\12¢3\9a\8c5\19\13\19tÖêÌÅû3\9d£ai/ssIy\17©ûØII«cý\ÊÌ\97;\e%=#_t3.5\9b\94SW\16vNÊ?\96\86ή\97øãÕãØ©9\1fkF6;\95±¹¡\92Q¬Û\9b\16Û"ª#\99\1a\12\1dYÚwH˳:»ÞØÒÞÍöÙ³_v3\8e-¶¼\94\88ïfH\91        Ýi\Úº\öS¾MùVÔQ\1aÎ¥\84èò=%kþÝî®w¾ÙÒЧFLÚk½\9b9ædI¯ó>³¹uì2¤³\1dÒG(Sú\19mÈyb¡Óy\97n\96\8c\19§\9f¡_3¿1&\8fÚ£ö¨iÔuM\9bâ\99nHY\rÒÝ8\9fùq®\8cû.\ eS\8d\95\14\r*±!ö;\1abFb3ªÆÙæ.\80\90Àp2'\7féÏç\9f˯·SÍ7ï\89Ç|n\11\9fð|wwòü\88S\ f:º»\91MYçÈf\90Ù\9d'6ö;\19Wb\17@HøÀÙ\8d;\9eç\aÏ\ fÞL?ÖÞ~\1c\91\8b¨ôQ"³G©DçQ¢ZÇyHP8D8¤N:dL<D\ 6¹2(v£(\88Æcz5É\8cy\906c\86Çö\98ãÔ¨Ú\15Íq2NÆÑɸq$\ef~\ 6\19q\90q\10uPÉî¨ÖU­8ªÚñðLÍøØØÐLÆÍM]fÜüãò\i\90i2î1Ä14\9f\8e¡¡¡sÈ4\1dåagÐãaUè\83EÇb\r\93\90ùÃtk\8d*«ÕlÔj5W\91\87\90Ñ?Cʵ\87\94\94PJêþñ£l÷6>#\1e3õuÌÌÌÌÌ\9c\98lÐÜFÍçÈC|SÓº\1a/o4¬%R£:ª¤\7fT«ÕjuTÇ\94Z\8eÏ\98Î8«Ö¸\13\1a\8c£uÜUI\8d²ñ\19Câº\r\9b«\8d²òd_ä/·Ü\88\9cú;\91ýª½Þ¯ZÒÜUý\88½\93¡\98ysä(f5$±\92açò«¶ÂN±úz\19Oäõ*©${;E®¢¢þäìjªîÄD!^j\98XiûË\14\9d·¸¼²\94ie/)¢ÊKHHL\8e3&D,«\JeºêåYÏê.OH+\19»Üªw(fEu\ eYå¹>¼-§\8dìª\8cÌ\8c\8a\86tV&õ\e\9a\86\1eö\9c\19\13»°ÌÇ\96è³^óèèì»\9dÔtnff\8aÌ3_rÑÍ]ÊDâ\ 5®4¨ÔÏg&Ã"Ç)¥\10Í\8c\ 4\ 1\0\0\93\11\0\08$\ e\ 6\ 3B\ 1±\80\a\14\0\bÀ\96@`\16\84\10K´¥2Î\0\0\0\0\0\0\0\0\0\0\0k\13±\8d\a{\8e%\1eäx\9dd#<$âN¬þ\1d\80>jïP\v\9e\18\83\ e\1e\93\ 5Ï w\98\16\ 2àÉèÛ\ e\1e}$í°\9a\v©A²\83\8c$\ 2vxùÅ.pò;9F«\83Ä\14Û²\ 1£:\ 5¹>\8a`$íþE0Ã\95\7fQ\1fuÐñx%)qwÛt\90\91Ò3Ýj\9f\84(\8eÔáú\9b\88í\84ÛÕ!òïÄ"Jß\89-¤·dÕN²rÄwi;1\86âwb\aã\11\ 5|'v\83t&ú\9d\90+u\88o;9\81G\0¼ðB\92©v²Å\89®I\a5Ú ¯¢C±É\ 5:¨FôÎÁÖ;ivsȤñ\84]e\ e½\90â\85'\98p9Ì$>åàÜ?J\ e\e)\ 2r°û\15Ça\94Üüà\89\9b\17\87\94x\9a8Xø\9d4ípH\10\v\85\83kí¤\93\ 5\874c\15p0ÑNú\8aß\10Ó
+\ e¾ß\e\9d\9ccÞàñ\88¶:a×ÝP\94êÄ\8eº\ 1õì$I4\10\r\f¸á\1cÞ\89ÜÛ\86\8dØÉD®\rvÌJ\eD@\ e\ 3v"ÑdÃ:`\8a\r\8b§\13¥i Øà\ f\9fNÞKu^\83{Q(\ e×°¹pÎ\1a>>öj\98O\8cªA\81Ó\89\K\rKa\ 65\1c}NÄã4\8co9\19ÚK\83£Â;\ fcÒpþ¹£aWÉ¥hPYN\ 4]hX¯\9c\f\8b@\83;IÞ\95o9!\9bÏ\90¨\9cü\81g\88×\93s\86\ 2\9e\92Iª7ÃÉsâÅž\8eQDåd\1e3\83à9i¹¿\8bN'RÃ\f+y\9dÌå2¸0\84eÐÇ\9d¤\982\14\14\9eØ\ 6(OV\9eð¢®è\ 1*îà\89\96'<\16êÉà\9f\92xùÄ\9cá>Ñe\8fª\93Áü~Ò=\ 4@\91¤\90@á6e(1\9dR\ 6Í%(äY\10(ãÕFP^\14mPÌL\19ÔH(       H\19º°Plè5\14\ 3­\fº}(I¥\f¥\10
+{ã8¢\ 4\87²Z0¢|\8bñP,áüJI÷;\r\11\8b(ê]\19&)¢¶à\84\87\1aHm\86²Ì¹to\19t ÎËP\96¼L×\95A'Ü­\fÊ\1dJ_uêP\94FÊðÅáË8\9d:\94A[\19¼Û¡ôͼ\88\94¡Æ\ eQ=\19:\14\ 6ú\1a\8f¦ã\10¢hÜÊ00D9\a\15ú\81\Ð¥ö\88\88b\91¤\fPü`Ê·¥¢%âÊ`ðÏ
+\91[\ 6·Lý2¨9Q2\18\81fËpV\7f$L\14\16®\f]C\14ëR\ 6\942Q:GúÚAB\80\19\97\7fz&J{\92\f=\91\150Xâñ½\94N18ÿ¸1,7y\19\83Ç_.\86Ý*Ê\r\86]\14·S\f\81Ì(Ì\94\18J\13\1eÄ @o\14>\1c\86¬<\8aé/\f\90\ 5)QL\18ê\91Å\ e\ 6`\8b\94\98\14\f\8d\94\947\16\18\93\12_\80¡\8eÑü\ 5\94@A¤¯\94gÑr®F\10\97ÒÏ{!-Êê\ 5\11Á\94®å\85\bÉ\14n\v/TMJ)¼\0I\9b²Cî\82F\9c"\12vax\9d2dºà2=¥¿s!¥\9fÂ\90r¡oP1Y\\80XC%\p¡iQù\83·\10×G%/\89*\8aR\91r¶ =¦ÒÍk!\959\15®ª\85Æ\85*vÆD\88k¨K\15\8c\87\16\ 6S\95£ë,\98ܪ\b\15³°h¬2\96Ê\82g­Ò\91\90\85\1cÅX\bc!\90¯\12\97±\10_Xy{X\88ϱ\12Û`!\10\97\95§½â\82Vbí\15\97Z\99Ó®`\15[i'¹B\12n\85Åm\85\12·\15£¤\15\10ûV\82öÊ
+\9d\19æ\9«°\82Áº"\8dü®Ðå*´\17½òÈÉAâ+k§
+óú\95S:T\ 3\96\ 1\ 6\8b\878\85üÿ \8c
+ô+ÐåW\8a\f*¨4±\b\1eó­½XN\0\1eöÆ2\1fï\7f,\eµd °G\161\88¿\ fe¹n¥ }\96%«I¡QÌbN¤\80n\18¥ø» *\19k\16¦úJ®\8d\9d%F\8aÂvùY¦\81(¸;´t»PH\ 5¤\85\96eß9à\962-S\ 5
+U²ñ'\80\8fZ\ 2Î'ôbµ<©'dik\89\ eOH\ 6\83\9d\10\vÉ\96èÏ     í¥-ß\8c\13RÙ¶%\a?í"·\88¦M\10m·ô©MH½·°^MhÝ¿ÅzÑ\ 4È\83K\90Ì\84¾?u!\13Ð\82±\81\1cTÓ¶üù%¤­\\92xÐ\\92Ò%äz.¦×\12\90\8c.Aa        ©?]þ`%Ä\90u       >gÔò\18»\ 4\1d%D\11l\97\ fÇ\a¡»T®I\80óÌ\92ÐDßÅ|$\ 1£ð\12G#!ïxy\1d\91\90Ìå%\1a!!\11ôòõ\8f\10\92z      l\8f\90Göò¤\1d!Aw/5+¤>ñe\936B§æ\8bu4\ 2\ 4ëK\142Bôûòè\17!\1eôK\90-Bkþòª\15!\19ÿ%ª\14¡B\ 1æ\ 3'B\8c\ 3&ä$Bø\ 2óL\11\10Lì@\84\80
\19\ f\f&E\12\ f\r¡©\b\f\ 1W\13&BYV
++Ì^\15\vc\90      \ 1\ f\r\132\84\90x\1cæÉd\84\1eæö¶F\1eÄ\88\9e $Æ\88yó@ȨÄÄ©@Èyb^1 $Ã)&#¡øÒ¢Ì?(ºÄ¼¿\1f¤\9b0&îü »\8cyà}\10¬\1a\13V}PÇ\eópêÃ\9ccJ\b\1f@\ 4t\95{\0y\8c8ìA .æÇéAÆ\85L\98\9e\a\9d(2\1f+\ fb;2!\18\ fBM2wÇ;Ñ5Kò\92\91­w`È\14w   '\93íì ºPÆÍÊ_ÐÅ¢½\ 5¾ñ,¨ê \96\92é ¤+ã;\\9dT\0V\969aÎ\81\96[F\18æ`ü.³·\1d0ó{r\90\ e\88\99x\ 1ã"3lã?dÍL\85\85\ 3\98ÑL\b\81\83\10kæ)ߠ˵\998\91\iý_}3\10Ï\rú±\ 57\0ÚãL\1c¢J\99<\87\81³ANv\86'\9c\ 1é\89gL\\10h`_\13Ï\14\935\0\84J5(S\9fùþ4\88ôÏdE»Ö\ 3Í~K\83lc\v£\8d\ 6\10\9f\b\rZ04f{\ 6ð\85hbÉ\19\ 4T4Oi\ 6±ïÖÙ\v1£±
+3\0ñ\vˠʣ1üd\0O\91&\88\91AÑIóÌc\90åJ\136c\90ïKó;Å \10\ 21p\8eÓt[\18\84¤§áÈ`\90\1dÔ\98\180\0\ 4ë\17´T©ù\e_\90â©     \88^Ð?Õ¼ú.È:VS\89Æ\96v5Sm\970bÍ\10R"®IÞÚLy/qÁÜEå\8b\v\80ª54¼\ 5ivkÞÍ\16DûibÑ\16\14á¾Z\0ì_¢\ 5ý©f\16hMk\bYÃúæÖT0,°eÙW H\18\ 5þ¬\15<#×\F¦\8f\96ùÚ5Ób\15\98\9c`\1f-õs1*À®      åSÐ(>5\ 50>b)ȯk\8cF
+°L¯\89Ó(¨ôk\1eF\14ä\19lB\11
+\12÷°y\ 1P\10\88±\89µ'\b\ 3Ù|³\13¤4e\93C\93Ùd\1f'\bél\8c´      °<´\89\8b&¨0m\1e"\13äUmB\7f       \12óÚ|
+\9fmL\11à6j$ÊÛðX\ 57\ 3p       |\8b\9bÖÄ(72\8eÎ\r\ fÝæfê\féæ\8b+A\88ë&\81ÿv\93¥&àÍä±òæ­>½1È\85{#Â\ 1©\94À¥|Ó\96Ï}£Mp¿!s\ 2àLq\12H\9eÀé\8a*'¼\82Ö\ fZíàD)fÂ\99?_8\7fr8\1cÓ¯\ 4Ê\828i\8c!\vJ\1ck\10êâ\12l\ 2r%X\95âÈÓÙâPDJ\90Ñâ¼\b.ei\8cÃgaã$\18%è©ãØ2`A\1f'\89!AA!Çë¬\8a7\ 4\1c~ª~;r\8a\1c\12 ^r\82ù\bZ@9ïs\ 4ñ\8dÊiT\8fzÉr¶Ã\b\1cÃX\ 4à}òDP$æ\18\e\11`iæ\84÷\10ä·æü¢!\bð\9b\13¨Õä&:\87a\85 Íx\8e}\b\ 1\8a>' \ 6A\7f óò@\101\86N\8c£¢\93g@Póè\18\8a\95/;éhìgô\ 3:/>¶{ÉÑÏ\v¨\90\v\e±Ù\aZ\17Áj¥\92ùXèA³Í>`ì;p\ 2ÅÀÇÒø@fO\1d\16çóh$áø\0Ýñó'~ ym°ø\80+\8dOq´»\91ø\80ó\19\11\1f\10T\ 4^ܨ\ 5\8cf\ f,Ðr\ e\b±\1fg\10VàÀj\82
+!çã\81à\ 4X\10æãÓ*°\89÷\9fÔ¡¬µ¶\91\a\8c¦ÀÚôU\9d!\ fÄ~d0\9bÓ¥20\90\a^|~¤Ðø¢\82\85<@¼-:\0D\1eà\9a\ 4Ê\9d\81-R\90\aö$\ 2á£\\85¡È\ 3V]0gÞP\ eD\1eÈ\ep\b\10FZ\912\ 3È\ 3\ 6|ã³×Ø$fY\1c\80Á\b¡\10¬´2\8f\a\88X¡3\7f>Û_fÎ>\1eðÂIB9\1eX¤À÷\14v!xØnÕg¨º\14Þ1®@\10¢;»\83j\8dM\8e\b+±ï±yüĶ&Qx{í@}ÖR\15ÀCÑ¢vÀ\1dFU\rA\8a\8a·Ú\ 1s\8fè\95\94ÑÒn¯b\1d(|LOEí@ü\14\ 6ì;`\8b'qDk)¤Sß\81­4Ü£´54E¶\9cbsµ\ 3\93¿ùEÐлÕ\ ep`å\84\94ìO%\ fë@9%±Ñ\81ÂOúrÂ\90\1f¥Is ½Êá,pï+r`¹\8c|Y\96×\1edË"\a8:¶\97"\a6'{\18U7÷R8à½68\ 2N\85ØÂ\ 1ÕQ[ª\9cªP²p\0¤\98G=\9aR\8d\84åï\96FxÅqÀ\ 5/°òu\1cÈ)\81¥ÑâÔ|¢l8\ e` Z0¥1;\ e\84ü\1cØh×Mp\1c8<T\86w\e»\14\ e0nõE\94Ô\17E\ 2ßÀù\15$F!¡Ë²\8fÜ\80\ e^\1cè¬OÝL\e@w/\94U\ 4cï9eÙ=`\ 3:ëº\8bÖ\v\ 6FáXg¥\8dºt5`«6]Lj\83\89Êi\80» çí\81\9bÊ¢\ 1øø\13òB\ 5\9cy]ð\f|µÕdL51/´\ 3µÔ<\ 3\99'\ 2\b5<\ 3\eº\1fî\8a\ 5\10\84Ú¶\v\f\11Q\9d\90\1e\11¤\fì\ 6ï\97\14\fø
+Ûé¼#Å)7~\f\83g@Sr\8c&\vhF\87o1pI/\18)a?ü8\ 5l\18pZ[¶Ü¼\97\102\14\fØ
+<Oº\9f\82~\ 1(9È\81®§:e\0þ##Ò¶\ 3\8e\89Öº@\89_Oý\94Çu\81n8¹\12C\11\17Xýï¬yô/\8e¸²\ 5pf©q\ fÙ·\93\0Z\0%ÿ߯%¦\8d\8e\ 5ÖÎ"A ¯@±H\93ÁZ\ 1\0}ºË\97¬\ 2÷^\9f\ 5o\a×G\ 5¨Í¹%é¦;'\93¤\1c\93\14\85üßH
+èP\rn]\ 2\85¥\14(
+$@\887\966\ 3\ 5P\86\1f1\o%&\eO\0\8b\183®!9¥\ 2+Li\88x\93b\9c\ 6,\9c Ü\12F®©¦`$\8a\80C\ 4ì\ 2Æøeþ¢'\93\80\8f^\8bøÂ~Ê!\ 1IX5i )}ë\b´§:Í\96ñ¹®Ä\b\88\8a\99-k \b(©ÝÍ÷KY\1f\ 2\801úúÉK\9f·\10Àã\8a`ód\97q\1e\19\ 4¨\96d\0\99¡ß\95V\199.¤^oFRú\ 1䣢£ÚQDß@ºeØØU\10\9a\8dÿ\99\84\ 6>\80Â×Ì\17\ fdðy@\7fØYFyá\99\b°\82w\80Ð:7¡\ 5êò\ e\88\0?(\9b×v7T\a\8c[âA\1e\1c` Èï\9f\9e
+\aH"ßH
+"\8eeÒÜ\80\ræ ?¹`ôP5pØ\07eؼÞCGê§\ 1ô=6­ Å'å\19Pyð©×¡Ë{e@>\\ 3\10\81¥\ f\85\9fî\18\ 3øÜÏÀÇ1êä\15YW½þÓû\83\ 1
+&Ý\7f\fÜ\83Õ\vHbæ\9b?\r\88b_°Ç\ 5x³®±ª\95láÐ\ 2æó û\0>¬2¿\ 2N±N©ç\85zZ\ 5\1c\8a\1d\ e;sS\80µ×i*\94í|(@\9f\19:ùÖ    àF\88£ÏÞÿµ­Né*;hñrè¾ùçT   (.bÈ\82\11\10\ f        ØlÈ\17Äõ\r \90\10Sâ¶þ/ #\807»¦b³x>\ 4\14Ççt\94\84\ f\ 1Í\0)L\99e\9f\82Õ `Π \9dI6Õ\9a¼~\80z\11Ehµ7\13H$z\80h9\11ht\1açu\9e\1d \ 3C6\&oç5T\7f\19\831\ e`õÓL¨ü¤Þ¤¥\r\10Å\aÊÈ;\ 2m\80        ×@z\ 4åR!\1a`\ 40>þ\86â4\f\ 5/\1d7\85í?\ 4\9b\81\ 1¸L¸X\ f\Þw\v°ÂU\83¸¢Ê\94®\0·Ôó\96,\8f\16\92\ 2xÖ7X\91Ù\ 4 Ô$Xe\14óo\19\92\0û\82 Äô}×\89\0bÜ­±ðS\1a)\b0/«me\9a¥õò\0r!\8bw\83×uÃ\ 1àË[\13ø¸âng\0[å~"*DÔ¦¡\9f\17Àjº\81uÅ>\b\1aò¾\9b\99*\0H9ÖAM\887\820\ 1èe@²I,®p\b@Â>\8eL\a`ÄÓgkÐ>à\b^\f\80ñùNþ\1eíx¬E\81\19(\0\1a=\0\80|&Õ\7f\08\ 6êC>¤ 
\91§Ë\ 2ÀrIa\9cÆ>\93\ 1\80æ2\8a¦Á;\0 è=r\f¤ô\14\80Dÿ_[\88Bûÿ£ZM\ 4³O°\93ÿk${º;\89\ f\7f®8\0¦ô\95w S¤\86÷Z¼û_²Ùæ\9bÌ®ÿ¢\9ca_ÙÌWsþ\af&äù\8fNñ®\ 6­\88©¸øO\12\ 3Î$¤"Â\9fwÞ?m`^ü\8bÃÝ\87Åì\1f¢ë\84Ü\w\85 QýO÷ÿ¨U\ezOè\7ft×0vùGÎ\88k»g\96é\88ã_\97åço\ 3´Æ=(ü\eã°,\15øþhÖvÓDX\88¶_æþ\fiEö\10
+aTûC\9bÒ\14\88Ò\85\1dìß±\9a\139¯þMñÐ\81-R×\9dþ\995>\f¥\90\ 5\16\1aý\r¸\14MRTôü\95S¥6\9b\9aÿCq]þ6öÀ^,ÿøÐ\83éÈ\85Ì\8eüÁµyùû\13áð\94Æÿo \89vGäùUÄ?4kÕ\ 3Q\11ÿ\aë.\10O{Ä?\82\8f\8f\9cÖ«I\a\7f\1d\ fþ`/¬Ü~%ò{\7fÿ\10|³9ð;V~ºxÅaµ\90\0í½Pl÷Ó{¤#M\aC\81\93û#\90Ýýð\8aÊ\11àA\16DóãÒE_\1ag        \1aç`\14¾\ e\1awãð\10¼$ûuìIÝ7Õ\17Àþgz´Ë\95£QfÙû\94È­?Õ\90cç¥\96Ö®~e¥i2Ûõ\89<1\95ú\85\80ª\8aûS·Ñô*§¿\11;'÷\9fô+\ 4é*>\18]x²Qô\87+\9c\94úáùÙA\ 2èw\88     \ f´\835ªR¡\89áù/\ 1\18\1fãE\94?VJ§\95òäö\99gf~aãr\90â[ù^|\97¿¤*@ù¬dΧòWVY­PùG\e3NåQù\19~Ln\ e\ 5\9d\fçÊ\ò\a:\8f\91D©nüò\85ü\1d<\9e\8b¦.ç\1cäø¿}5º\ 5\89±s;ùâ§\98    AØ\83µÍ:É ëMl\11`âè\ 5îðãêJøÞ\fÀ\89\8b\85\1f\88ï·\1c\147\1aüÔJÀQ\94-+\ 2?ø¡\ 5j)Æa¿ß«ÿ]\ 6nÀõ'ßç\90?P¤÷ýÜ\98ÑóGLÁûUPM\ eeŸë>ä \9e=,\90{îËÌÁ S\81¬\8cûåÊ_r½ýÑq\ 2:¦Yl\7füÐQ<\81/£mj\9cÛSû}
+IÖ\9cë\ 1ç\ f\1aÓ¶\81@X\ eJ\12Ï0û`\8eDG½BR0w\98Ù?íó3BÌÎvwUd\7f\1a1Ù+ö3­ÊMÁG{¸`_¬w\vá\eöíóúI#q&õAÓçNo\eÃõ)öÉ\99#^¤·³¾\8e\15\95(Q4\97Ø¢«\9fi7p\8e{s\9fS\17\80ª_ÌZBÔ@\96\97ú¹hõA   [6\84ú\ 6À\12\0Ò:ýÆÜ°_¦_Û¢ò3ý\r\85      T\80Ï\9d÷G¢ÒoÅ@\1aDzn\fé;\1f'\90\90º@Q \8eÑ'B{²\1dxk²>ô\85ñ\1cVùcÐw\86
+\83óN?\1fSLÛ4Ì®\ e­\9fO\96úñ'B·º¹z~ÆÄ()w\9d\9fRÇÛ¡\14¡â|\\bï7ίCé95:ÖG\8b褥w1\14\18´<°bõ²\ 6{\ f2_»´Î~ù<\82\829n\10w©±å¿­\8c¾îo¼Â°G!jåWþ\01§ÐRÓ´#å\7f\15\19\7f¦=b\rÞäç+X2!d~\95äÿ¬Ó¶h'öÂ\9a\13ùlTï¹B\19zÿ|è\1a\14\90\7f\9eÝ.¹ãw·{/\16È27~'YØC¶M#\1a\95æÒU\19ÿ´hì\11\99=M@E¶\19\9f¡\95vpS¸'f|j°\88\aL"þ#©ò.>ecƨԨøT+¶\9b_äNðCK|1«$*Âñ½Ä7\18«\ f{é p\95'+ñÉ]ºJÃ\88\92\95øòå6¬\0\85\87\12\1f#\92   ÕåÃ"¤Ä×Ìý\99ã\ 3È\85î\95ETd\98@PâÇð&HÆ\80)\80Íl\19¦¢Ä·LT7W;óÅéÞ\8b\ 5îJ%$\10âÈ\84Õ ~¡\î#z\8dø >¿$\ eJSÜ\83\1c8\88\7fûÚrK+º\99\1f}r£c±Fnø78²,0phnø\11\97ø \87\9fþ\15E{Ô  ®\ fg\91ð©\9c®ësð\aÝ$|y4­ô§hý\81>        _Å\b\vRßý\92ðÉ¿\8e)ÊÓÉ\13G-ºÙ³\93ðe\b¯´þÈàãFøÍ\91¡$#|Á{ã¿áÕÞ\ 4\18\93R-\e7)\82Ï4\vZàá\99\83À?\ 5D\b\8f\b\r"ðÕÆâ\ 5\1c\97J\ 4>¶T\10ÞD=¦é\ 4\81\7fÖò\8b;í§¨wÐ\7f\8fT\10\82ݸ®¯~\8f\91ñɵú=\89Ë+QpÐW(\92Æ\9bÒÆ÷²Í\1d[Njï5J´dĺa\9b\aîÐ{é÷&VK¬\1e3áx?\r\89Ì\94þÚã};µ\7f\ 4Ø»\97Ù\80*Úf-Ð\86\7fGËîqøíaOã\aÙýÅÛ´mè\9a\1f
+\b©{ò\12­\94\88\ 5m\82¼áÒ¢\9alÊrÿ\90ƼWMÀ1\14÷I\8f\18\1a\ 2\9b\rà::p?)ï\ 4÷\16\1dÆÐS\11\91·\17'C\93e2ôæ'¸½·s¦h\ 2ñz¶g¾ý"\14âCÕkß\ 6ã>º0£WP©öãÞ.Vàü\8fiß³ñ\11Q\rñ    ¤\84V·Jê4T'SÇþ\89.\97G\16Á`ª    c/X*GÙßI©S¢?ö\1fekwýÏPm±7Z^       Z ï\92X@÷u\ 5\9aíf¤\80ësö9!:VÍ~MS©DB_¤Ó¶»\ 4\98×\1f\82ö\83.Ç­\9a\90\8d\ 1éZêúVðýî\81]Â<*\\7fh\9aSÈW\b;\86­\1fÆé£\12\a¶~Ì\87û`QEÎüYß%KL&½5¿±^:\88õ¹W\1f\0\? Ç÷2«/5ç\18\8e\9fµUõ¢9ÅUÕs\b\8f\91QÍ´+à5T?nâ¤\81©'\81ç²ÌÝ\99GýW½X\906oÙª\15ÒP\8f\93 2éNy9Õ§ßæ¡©ÿÙ¦b:ý«\12òÿÛ)âÖô'Û6ÜCem\f\98øt!\83ç+ÛXÃÒ\1fº\81ݯWTi\8c'}\81\8aòE\80û\1aéña\86\ 2\82u\8f~¼B\8aFϧ\rË(£\91¬è;­=ËîAêDôü#Îõ\93ñN\8b\91¡Ï\83\13\b=þ5M\19\ 3Áâlâ\81¾zÔjFÜØôÏÃã\9f±ñv\ 5\18\18èóÝ\9c\8c'(<úü\9fð&v\16\ 4´\9eß,Ñe\19¯ø\8cx¾¤R
+mÌÓ½ìü (l°\8fÓÆ@çÁð9Ѩ$o¼(\87\95 4è\9b·]ûÙ\19c\95òAÛÕÚü1·µêÞ\95Æ\9açîê\8f\93\ 2¨>\8dæS£ÊË\ 1\8af\81¸ËÍ|X9\8d\7f\8e\8e1ɼ ±\15ÐàÏ\19Hb\1e^<QOfY9\8a\ 2æ\1d ¹¢\9c¾Ë«\11\82\9ednk\80¸å\95TñE÷jôY\96\9f
+\1f\13\17«\97å'Gè\ 4m³Ö\8bl®|/A×õ|\11W>\9eþaýù\11±©|eºÄÓõЬ\94/zV\9bXÔöãÓ\1e\94ß·»\93+$;\8dáä¥Å?\ 4Oe\85æKÞç\b-   s\93\ 6ËMZ_9Ñ\1eùK'âÕ       \ 1¥"\8föu\87W\8fð\eª#C\1e\bÇ×à¡=\90\97®\ 4Sqh\19È·\97\e\88\84I0   Ç3þ oÝ+\83ÇWNÊ\0gñmøø¢ÎñFÖé/H¨t9¨\ráã'J\9bY\86Ï\f\80(\8f\17\1fo\95.\9aü\8e/g6eî\8fkÞñ`[á\e98å;^¥ß$*ò!Y!\80\80¾ãqÂ\ 3\9fª\1f¬\90Ó¨\rAfï\ 2±ª*\18\93äGÐ\ eÌñééÊl6ÇÿEìN¦VÄË)kæxå½Ô\ 6¡9¾:Ï b\96©Ñ\1c?Å­\ f\8e\8a¯½\0æx\17ñ\¢<i9^\9c\89XS\ 5±\1cßëÖ\a\94ã3¹q\86h<"»v\a}9IæÆ7,²ä\a\8dØ¡ÑkË@8k\ 6ð\10±2>\ e\16\0cUê\12XC0~ \«M&\85߸øYO\1f\16]Ø+~Ó\16[ü¿À#Mñ\1d\93\14}J'\9eáR\88è@m\97s\16\83\9a"Ô"¾*ØQÖ\9a   \ 1Cd
+U\10\ f.6\8a<Q '{øÐ\8a¼\ 4Y6yY\ 4Þ2\f\85\9c3mKÃ#$x[^\98û\96½\8b\ 1\86g9ÐØÎ\124aù¼ÂÃ\\85æ9áE°\1c+õßL\8a´w[\13á\85úZ4§N|Ì\13vðà\92÷#«\1cÝ@¯\86(*\99\9bZ\86¹\vb:\88IÁ§4Ñ\1e\rÆCüz \9ac\17XSÖ\v<\92\8aʳ]\17Ê0Í\1e\0Ä\1c\82]\9d·E¶\ 1Þ\87{\9dô>\9eèûï­\ e\91ûyÂ\7fS_\90çï+\90'¯­»{¢mP¿»\8böÈz1\1aÄïmÙùá\19Õâ÷\9c=\9eåÞÜJöýA\f\1eñb) }ç 9/Gõ\84¾SQéQ$ò ÇwÜ\9aA\86\ fxj\8d\91ïÝ\92¿U»À\11yÒÔÞß×Zò\vÖ;\1cJ\r \0\88Þ?\92\90Tiç\j2ï÷4\ fðáá\95gÈ{\9fU¹SEG\98õ« \17\17Î\84Y\81\büî¨\fÁ f,\ª\15uwåºVñ{\1c=&c»\v\89n`kL\80C\8fÝ\91\9cÓFìÃÍé£uÿ$£\8e\83±,3ê>\1f¯Êùëc\8duUV\0énûµß\9f»;ã\88ék| ³NÅ6wj¹\7fzÎIáSÛ\96{\89\83AU¹µLrÇ];\97¡TÄh¹\8d;Lî\1eô\8cU\17&î QS=        \8cÖ°ÂÝòn\9cç\86r     ¸Ë\ 5ú2[U\99\19\9eضðí%é¦\84<?ñ\ 5ôn\17¿V¡\91ZL\9dÛË\98 FªÉ&\86ÅÛ\ eºÀô\ 2Xµ}Õ=¤o\ féäÎlÏÔ\97"DÚbÀ\1e¶_\13b6\80\85°³ØòÎ=,ÖÎ\9a´$Ó¦¯R\vß\9aGµK\98]¨Ü´ùi·Ê®6\8dJx\89ÎÒ\ ek-\98yX\8fz\19G;)=9¦iw5´ã\98\15eí]\96!ÛÏN\1f¤A\86a¨h¸:»Q\v\8c\90\81Í®éX´\8eùÿ\95\99\13³³ú\1f²p\92p\91e§dF7ñÆ­\ 2\11\a¸¯\8doàf£\9f¿"%\1f;4\ 3Íf\e;^Ç¿\89îΰ+µØWÌ&hüë¹ØÙ\vj\ 3Ø«¬ÄN\92x\98e0Èô¯Ãþ(ëMÐPù`\9a\14ö«©vW\9cì\15J\vv\82\17\ eÑ\ 1j\10ò\81B\ 3ìÜË%cR.ÀÎ\95õM\ 3\90Ñ\12\96_ÿ:U»yà±ã\ f_?u\86k2à¨s^·HÂw7\14o-?¾ë\9c¹¦B\95s
+ëú{Î\88F\ 6å\88r.k®cGì\99Äõò\8d è\8aÈ­aÁn=¶\|ȪvëQî)\17\b0q\1f[7ÈÜ4°´Ø­Xj=×TÑ\1f« \ 2\ 5´¾Ì\r\10\90ø#\8b~0ë ¯\9c\13¢3Ó<\88=~\9d°hæäþذ\ e6vçüV~uô×ÄÀ\8duu\96 \12GüKuuÚ¢é\81gOlnÆVgùñkeiaxÆX\1d\90¿²\8e\89ó\94V]\e¸\9dì!#ä&T=È\8b\19\19ßÒ?ª\aYv¬Ø\1d\9fO}\17\e µâ\97ûlê¶\r­³p`\81üÔR\87¶:&sPR\f\9f¤þ\1a ï\8e8碵Qw\13¥!ßl \ 4\89zÛ5¤_\a2\9f\ 6\15w        õÔu\17j\vD_¹\14\97\ 4¹U\92lMÔmrÑàÀ\87 ÐôBAubÂ^NNÇ\89\85÷\17kæÇ!äqÀ­íÊ6·à5\9aL4=,\846\\9db\87\81#Î9\8c\97
+L'¿}\ 1É\87oé½-G>¾#®t\96\0t/\¤Ç\94®\vÓ\87Cw*\f\19%ÊI·:Ñ71Ù\80m\92\8e¢#ëú\f\v\14éh\86MB\8b\88ëéí\ 2éË/ÝC=õ1\9e\8a\9b\1aÑ9\10¿~£s\ 6±;l\83\1ek\93\19Ý\8e
+\9f\13OnÍvÑU\1e\84\ 2±qÝM*º\12ÊÍó\12}Ãñ¹\85è\bîðý\buw\95C\7fáKÃèrÈB0t0ºã¯\v*4/I\93á     ÝQ\18\83¾bÙ\9aCb¿Và}·
+:EÇÄ[\fj®WüĨ!\ 3ý¼}æ\ f(\ 6ú\ 6Ô\13BzF\8d\ 1ú-\82a,\1ci\12\86ýùùA\eÈ2?Çé\1d\8d|!H¯Ï\17\90ï2aÁX|âs©ç¶\9aöÄ\95|çÔ7ä[\9cÔGÏ¡\ 2  ªD\9e\ 3\92\89>\151\ 1ú\9d7_\87øAÑ\80çbc\95?BÉÇ     ?Üy5Üna\15ÅäsìÂ`hoûu.-Ú:.a1\9d÷H\11Zð+âA\ 5¬¦\ 68>\8dq\0\8f&çT³i\88Ϭ\152|-N¥â¼ðl¨XÒE_Ó}ï\ 3çÝÛ[$ñæÙàã²\96oó;\v%0\92$
+âHTܳq\ 2´c>4·rÖ!­\97ü\84cj®1\1d\1195\ f}\9c(ÍM\vÀÞw\88\f}uAs\11:\1a\ 1¹°\13B¶ã»Ò5CØV\f\95nÕ):Q=\99óó\13\95\90zE¶c\9e:ñ,\140\80\8eyÐm¿e\8ay7\12i,ÌI_Ú\ 5æ\8f\92¢\98ý?_îÐϪIþHC\8a]ÞʤsZµ,Ô\ e.Nh¹÷,\14\9e\1eËG\80¿÷Ëþ\8emP\8a$\r\ 2.jåÌ\18*\89Úö}È*ï8\81[\ 4¨À*7U§+\ 6ü-\9d£òÏ T{fI9ÕÕ\94ÿ \16\970\85¢©\87úO\8e<R\8eF.1«(\8f"wÕÎÉ@\8b\81r\8b¢å\88\11ÈÎ34\80\âÉc\10\8e­y\1a\b\8e\93G­%\13Ù/aB\93ßk\17cfRÕÏÖ¨/9½\8aL\9aرT°M%¿I&©ä¡_hÀaq^I\9e\ 6´Eï\92°AòªBÞ¯6þÂ\91#\10§8jdøÝ\86\8b<®ÑFQ2æ3%rú\99¡\a\1d`(ä\90§uÈËäÓJj>\¸\94\14r{JK¬r\97\vr*=\9b³+°\vÈ_\17»\15\124äÇÇ.Ri\9b:@?\90\97"U\ 4âWsçñâDc0Q!ÌïxÇÉ\86"\18ùw9áêøÊÙð«_uHu|{þpS~ç\99ãV\ 2%y*'\rÇAUh=N\93µéÆ¡è=>Ò$3Ù8-Ü3kG_\ 2J\8d\ fÈ\91\84\9b\95\18Ðø\9dËý\ 1®\Æc\18\80\16\14%\1eo\ epòüVa\\81¥Tʨ¡VXøâR\10A|\ e\ fR\9c\14äEÏS¡íXh©Z|Ù\12Wâë\17û\8b\17\ 2b?\8bñ°ø+9m\9f@C¡Ì\15\93@lIú¾,+GM|¸\ 6Î\14Å9csÌ#\15\bH,¢÷ñfâÌÈ*\9a\ 1¡x \97æ\ 3Î\r7ÄQÜ[±B\9f>\1f=\\96ô¿!.R\8a¹PÊ\87q\8dW¬ÎèkÃ|¸\9a\ eíÊbÀ\16\1eNK%\1aÀ\ 1\1e ÐáÔ/ñÜ\e>ïú\8dSy5üõjsÅøy\7f}\19NÀ}±à\8c\97ba0\1cÀ\rzN;\8b¹\85¯\9d£³¢p\18µ\89ºÂ\e"L\ 2Ôg2)|ª4¶     ×Í}óÂX\12>\84¤zZfë\f l*0\8b\ e\80ðu\83íµ\1dmº¤\1d¼3èmc\18°\r\8eU)T\\80X\90\eþ@'\83\91\ 6Mh,m[p\0ºÒ¤`ÁÏO\15-Rð1\aYQ\12<'\9d帽?ÿ\f\ 4\7fÆ\19\v®øk4l*ÒAá\rüŪH.Öoà\885\80\1cþ¥\9fr\81ÏÈ\89A~Í>y\vS\9c\95Í4\9e\86Ñ\ 6\\ f"Oé°\ 4\9c­¢Ö°\13¹"àÐ\Ûâ\85\ e\ 1\10ÿ\bx*>\87\90´³IM<     pï¡ÊH¡%\ 1>\96°íe\ 5\94¡        ð\ 3ö[ÆW(\ 1\87\1e\9d(\92¢¥ê\12ð;¨\86Õ\11Ê1Ï_\ 2n4\10\1119àÑý³\v\aüR°[V´\88\99\80+\ 3q\vÏx<\99\13ð\92´1é\ 4|\1d3F    «¢\9bì\ 4<\19lr½Ð&àü;\86\86t98ýOÀwëZá\99\ 4\1c\81\92 ç\ 4Ü\87þ\16²x \9c\80Ó©³*ä   8[\v\97\9e\80Ë\vp¥G\86A¡(À\91\fÐ\ 6*\12\0?¬©G
+\80#Óc\9fþ\93\80\ 4À/c¥ÀHÌ\9e\17\0¯'\ 6rÔMøo¦¢¼syý\8fïo:ª\11\9e´ÈÏê   Koù»±Ð\8fS\ f÷ûÉAü\ 4\8f9!À5ýÎÝïG5\13å7\16\9dôë=B°à7©*îÌ8\84\9f\a¸o1\vt\a±ï^v}¯\92é\85W»Øô­\8b~i\96)ýà9gu*\r t¾\91\90O\882¹Fùn\1f'G5®\1d\9föºø>]øö\12lp¿à[C\8a\ 3\0\89,².ïÝ4f^\8bäu!\ 5÷\ eÒ \9e\99½OæÐ-Ålx¥c]o\\19Ë\89\eT\1a+\1eS-\84J\9b±ôö̦\8e|¿ôN >±,.\18·Bo¢\f\ eP>}óÖ!\83\9eê.ï&W\164Òá\84\a\e¡Ê®|Ùâx_ìÖdu\17ÂÄÛ@\94\81\17¤ð^\10ÔøÊ}"à\8d\ 1\0\82ãç8|74\10¸£ç\99\11¼[Ù\17\97CÇ×nâ\9c»\13Éi@k\99\9f\1dÖ}µ\9b¹\81\13ÀìFXKf%Ê=Âî6Ån/ã3ÌòH¹nl!\1a÷ÕM\14ͯw\9c^S7FP\1e\9fít;¿3ÞÙ\8f\18\94n\ 2ì3¼\ 2U}ØYtsöN6\e\8bó     ºS{QN9P\bç<÷x¦1©¤ë\86áܦ\7f¥\81m\82tsæö¹ È3wÅ~¨\1a\89ðr\8fb\1e®mQK\ 1Âf\1a\ 6U¹%¬\86æLî/\8c\8diR\13ç!\93Û\9d¢¨\ 3\10\19N&÷à[ZÚ\rø\ eáw\1c]% \86¦9:îD\94¬\14^XMÇ=\88[sA\86     2AÅ9Æ­Æ}\91\93õ¢Ù\9c¸}\9fð}1V?PÇøÃ\e\92Eá¶c\97\8e\1dDÝM¼_\99ÌxÁ]\r\12´Î-¸EÝîÒ o¿\ fº`òW-/û˲\ 57÷é\b\7f¯Ù>\17Ü-Ö§\\91ûÔaÁÝbýØNQµà¶\ 1|«3\89Hãé\vîI|wÕÀ\ 3²à\ 6\9f§ï\90\10ýr\1cåAIzÁ}¶\1dóbÖB\e\96ÝÀñW\83Â\1d\vJ\9e pK\e\ 37/\v\80SJJ¡p[â®ä\9fpßë\ fh\8f\84¤3 Bs\ 5T\v·6\85»á½\ 5¹¨T±Q¸\13TF\95FÌO)è )Üî\9bxt\9b\82\94%ÜMÒdù\8e\8e\8b\r·\96µèóÀ1m¸½¦¨\92'ܱ\89¼C£9ÜÙ¿\17r\11\b8E8ܲ\vçj(Ñ VY×À\86W²ã\1c\ 3°Äb\ e÷]\9eä\ 4\87[¾ã\89Ë\14'\1f\87\80=Í9Üé^¬\8d\10\87Û(\7f\14ÓéÛ­A=\ e÷I\96¸c¦\13×\127sö4¶\91I\0s»:Ö­ÖóÖó\ 1¨Äí\80ª7\WÍ%n~d½H2\15\94¸\81^\ e·Íö0æp3µÖw\89|e\8eÃ\r\1dS @\97yµá&ÜC¢\rzb$Ü¥vP»\ 3éo\9b¿\84»Þæî½áæ\93Ô»ØZm¸·!nÂϳ9    7õ\1a\f¦\84»-©kÃ\r\ f86+\98\86Û\08\1aÊ\1c ©ê\86ûÓ6^Úøßp\17müZ\8dÛ¦sÃ}ìÁܳán*½\85(Þ¾\84»ÇµI±×¤/á\86\ 6½5ñÀ\0«\84;!\f&nFk\17 ÷Nö\14¹\12/.á\86æs³b/Ø\91\95\9bÕÛ \97W\90C\8fÃí+§¦Ä=\ fc\10l%î2&Iw\8bÛM\9b
+âö°V\8a\9b\82a\84Ä=L»ap\12w/£\87þä\ e\849ÜL\9beÙÚ\16B\0Ôp\ ew\ 3\8aAâ¾¢
\84\e_H\b\8c¸N©0(\9eJEpj\0\11\ 6à\96r{?YpC¹>J\8b\10\98òª"÷6e\90\83Ûæ\0F¹Ûä2Ñt;¤Mèz\ 1T¬Ü\ 6\a»rFh\15U:¸í\12\8b\9a\15Ç ypÛ7ÖÖï¯íz\1e×       \15\ 1\9b\ f\9díýágo:Û\1d
+3óYa¨\8a\9b²½B\aÊ\10ô/ê\ 3ìb[ÂX½\81Í®`\e\90\1c\r;\10@yí\0v\93n'\82&\[iÜ        Å\97"#¸³öÑa\17½²\83¿×.\87\83<A\aç\0©jwg\80u\88ßÒÈÔæ\10ú#äm\19gÿ&ñ\84^\91z\88\v\92Ëi\1f\ʦ\9fm}@\11»\81iïO \1aC Ó6\10¢ZØ\97\b2aª\81/\9c´\81ëv4\92¸_£G;}\17\845\97§\17\13\160\1eYh\13ÚR|{7{\14h#\80\ 1\1d\8d¤nä³\87.?ÆbÈAù'\86gÓî9w\8açð\81º9;Þ6\9f^\8akrÎ\9bmàó¤g\1c0\10³U³\ 1\ 2ï \9bS\0ÏÌ.CÃ\ 6_³|~\98Ý\1aµü4\943x\90ê²SnÁ9\95\18ÛcÙØ\7f\1cv\1a\ e\18\95\r¼¬.IU\95\1d\1c¬\9c\1c\8eh\b\8e\1eÙ\10å<\12¾Ü\87!û       ¶¦\1e²ßqUU©^!¾\8fýF#¾\88\8eí6$ì\1eר#\ 1­\ 3¨dìl\98=ºè\93£m\8b\rw\89¶Ë̼¾>5µ´\14\9béÓX\8b\b\83\17@ ~Ð.\fL=\ 4£/ 6\9f¡\ 4ª\11Üæ\ 6
+\87íÍ\809\87-\95®\aùVV\81\12\86}bâÈ\98ºÀ«\7f?aw   \ 4P{\1eí'ì\vP\18 Æ\ 4¢sáÑë¬\82Íë²\84Å\fòÈÀÎi2f¼¯éºd`M¨\88\ 3\9dú\1agÈA\7f\1d\7fb\r¦iÙð\8d\ 1¹!J§ÍsfèëÆ=\b}\9e\7f\8efæH \9e<8\ 1f¾õ\ 1\ 5a«]§®\1dYóº$5~ º±¢|\11¯]\1aos6\9c5Õµî®\93F\16\1e\91\ 4ÄWvÝÒa­^¦®ÕyoàZ\12tý¯\99\15¿¨\81\97ë·éßê\1d»¢S\1d×HFû\94\v\12\9a\93\eªÈùÖ\82\17ñÆ\17±\95\97\85\1eZOê\9fÿt\14`ïµâGÑ\8cB#ÃÖ©\90\96\16OØò\ 2Öú·v6Õ\90Ø\9fÖÐØ¾ßÞ|Ð\ 12Z_Ëæ\16Oæbö¬A\8aÿò­\ 2v\97²4ë\0öob÷\eã\ 6¬¬A;\ 4\9bÔ KCd\1dYòÒ\91uáØ\90\14¨x}äV\9f\1a\ 13E¢\ 1zúX\f±\9eÛÆ\84 Ù~\ e·\aëZ\93\17þê\14\15\8bõj£s"?\8dÉøìêÓ÷\ 2\8c\99ùTh\82\808Gqµö\ 5$\b%\12³Õ°Ð3ñj"Ú³\1a*èô(0[#Ù\15Ë\82Æêüô\8bÀ\81ú»W}ó¶hevhCeµj¦ó[´6(ÚdU{+"¨wP'\f\8fª\rákàü\ 6;Jy\ 4a\9fãÇ}e\83óHuI]¦þ­2B\10Õ\83\8b\95ÜÿS÷\11X¬¨¦\9e3íÔº\ 4ÉÆmjø\92F.IÙAI¦vÂî¸\14ó@5\ 5¶Ôvhë~Ò{±\94\9aN\85}®Âé\18vHêC¯?UL¦é\8f\9a\15á\88\94\ 56j\11E\9a3R\80§\8c\16õ){\9bi\ 41zC¢^\8d${þ\86:ð`k\8c\91à      uê¡`uóp­ ¶\96\1døµ\18\88\ eP+y2K[ØÃñÓ]\90 þÕ"\8dݽ§µ\1d"\ 3;x±yz$z¸¦;ýàb\97®5ºÓ\93 \10²´%'DÕiZ\96\80§R/\83\1e\15\ f\84újü$«±³Ãéâ\90ÆÓ\91nºÃ¤n`lzp9n¬_D\ 5pºÂ\e«5kÙiÃt\15¸ü\b
+ìV\99\1ej\0\12\8a3¦ù\91\aÓØ\96=\ 1³\12¤\97V\14^_\1aÂ\8a*.͵\85ô:Kó\97 N\ f]i\85µ&½\80ëý\12\176ªJwQÛW3*\fß(SºQÒìx(}\ eûd\ fÓI´æ¤\95\1a,Èw0ip¤\1e\9d¤¯V\8c\15\1eé\86Þ\13\8d¾"½ù\1fE\0\86ôüVÚ\b\1aªºA\ 3é|\ fK\91\8b\86>z\9d ÉÌ \99\8dG\876y¯Êxó\1c\1d\9d$C\ f8\93\eí\95\97Q\19¦\14\1cªÑ\7f\9d\9b   3Ú\1c\16®O\9e×FT\12\86ÚÃu\8c¬uÑ\90qÂ?ïá\8a,`ÑÆ
+\86\87\aj\ 49f\7f\8a.\10Ì\ 6{ÓlOô)\84\ 1\0°\95èÑꫯD³¥\eÕ3f»X&î/»\88®iw­Ù\0\84\v3\17ø=\v¢ë\ 1&W\0²        Õ<ô¢]\88)*\0phàôöì\92Á3tZÑ1\95\ 4\96G/´ªé§#\89\0?\14T¡Çif>P\b^\0â\85X\95¼xyXäEè\r\1dçeèOWóåA\ fù\88\ 3\9a-\84\fz´çq\ 1\90ÀÎ%\ 5-»bs       \b\1a\1eE­£A¿³{\81\ eÉN¢\¤\ 1½2ø-5 \v\90^"¨\81\17 ÐLÉ\8aâÅ®ûgÿÜ)\b­BÙ¼ÅJ¶æ 69çO³égKc@÷\9fWf\17øÙê\9e\ 2x}¶\15­¦<Ù\0\80\b%¬ñ|Î\00M@="hUù\1c\ 3\9e.\90\99ÕCï¹u\83\1a\9fg\9c\93öÜ]\10\15\ f2\99Tõ|¹cö¤¼ëQp\17z.±áãVöíQ\ f¿Ëó­ãßW\19\7fïxÞø¤FÂó\9fh\9dÇç\92¼|gzçèÝ\83þ\0y\83"î\±\82`\ 1hg\89\17\9e\87\ 3\18¸¯s\f\1fW\1aÝ0cku®¤iy±é\8crÈëÕÊøyV\ 1\f\82\89ÎÆ\82á\1d´sNÁva\18ÑDæ|ÃÙéÌÙà\8d`ÁØ\8e\8e³Ê9Ó̰ê\94]\9cÓ\90óZ¡ÅËà\9e\90%ó+p\83\19,\93¦ëx\+Ä9ïÓ\86\9f#ÆÁ9\94-üyOÞýÍ\16ãB]¨\94e<½Ù©¤H\9b­\9b\a£=ýâæ7\11@źâ\98bu²ÍM÷\92ÇXÔÊÄ Í\9fÀ\9d­c£\9f\8dÍ\vÅCiÙvnø8½f?þ\8d)\15\13­Ùµâ\ 2ñôÞ¬æÑ©\16\12\9e\r\a½4jV\ 3UiN5Í3\92ÿK\8aG\9aáSih:Õ\18 \9a\8bÈR­ôÛ\1dû3[«O-væ\18Å\15&\ fÿ\8a\97\9b¹B\9fHl\91&¿$rdæÏFæ\1dIÖȸOË\Þ\ 2­\83IµÌ\924ñ!M\949\9c\9cä&\92¹`\ 3t\14ù1\8f©\8bñ\1a/7\f\1e\81?\10É\r¦Åü\jÞ\0\9d£\ 241Ë)\94+MÌ\1c¸¹W\rÆ\13±\98\98%nËVNæ\97Í\14M̶6¥¬\12db>\81ÙÕb\7f\ e\88L$¬±\96\82\1cf^At§\1e ?\87Y\8cÂêb\90q\98µr6     ¾\9c*BÑ8Ì\87ÿw¢/Í\84Ù\ fv\8aU\121\1f\13fÂß\ 5󬯱9avÂÈ |ÅÏ:a¾!\80
+Ö·¦    3£\81B\1cN2}Â<U^z}Ç\1c\8e©\vI¶>×¥\9cU0\8b\91a\86S\85\86\82\99æ\ 5*\15"U¬`îñ6¯H5j\8b\82¹C.¸\19JbÅ\849Du\98Çç3¥v\98ï£\1a½\19\<%;Ì\8d\1d¨LhÈLa´Ã,
+AODf\rÁ&æ¤
+æ¬\0W>\eµ\bváÌÄìg\9d\85\86\9e\ 4\8d \ 2ïß"\98\94\80Ér\98EWèå$Ä\1a ó9¾?\13\ 4\84Ù³r\9665Ô`\ e=Â|\1d»¼ôÌútúî[Q\8b0\e\13±2?æQ_\11f\8cfCh(Ãr2ÿ³17¸Ø\9b¯\1f9ÄLb/{Çê\8a\eèT(vØ ÷Ôð_N<6\99(`\1dÿ$õeáì\98eð\©\97©8\95ÍJÀðò½4ݽ$Ô\ 1N\99À.Û7fÛ\8cLü+«ù\^v\ 6\96\1dC®q\99\96\fRl¡gB\19³zË\r\8b«\a3\1fÚ²}¯\87æj\19F\8aeæã\ f ÑrL_ã\9c\ 6+Ê-\87¬Ìr=Ü'\9f\f\90ãc\19{IÆø6,?Éï\9a¥\1fÊé+\9byl\18\8d\98xf$ºr°4Ñ\95ï]\86ty%ñ¿q\96µrß\0Û\83P'9ëL\å\83>{ul\ 2i©·¹\17\1a\16ÚL[¥½]\9b\9a\17þ´ÎÞ\19tÇpº  ^4\1a\19Ñ\83\19åMË)kÕ¾\99«#&\\14%Á)ô\18Lp2`¼c°á´\81ÖNÜp\ 6fq¦U\1f¸\1f'eJ-ã(gI8¸\91 É\f/æTýÔI\91Îé(\14jëeEt^sQ\9f¦³\95Ì\98\bµ\ 4¬Nr~Ð\85\8aÖLÞuê®\a´\95\9d    .«ÅíÔ@×\7fÛÉ6Ï`;M\86\ 3¯®ß@M°vú³§7ÝÉLhæ\81¾ó\ 4Ãó9&4\r\8f§~Kn\98§Ô:aUè\99B\0\976\r\8aéÌ»´Vû\947\9eY\81\9br^\13ZËýÎ=a¤¸+0i«\8d\8fK!öß\13Äíöp\8fZt\b»ÖÏ\90ëi;ýÉÝË\r|¦üÏÅ®v\ 6¨­æY= °¼\8c>` ÎÊ\92ð\1fh7¯¥QÐ\f\9f\fª%%å1×ÛA{CÃ\84\bÍ~\1e.nB³DÎ\97\15z­Ôó¾P[\v(ACcr¨}\8dCM\ f\95®KÃ\8d7\88úêjFd[æúmÀ^²Â>{¢9¥´ø\14½íd~XTÿo5\93\8b>pÆJ\18M\14#ò¿\8c~\95\ 3ñ4Êì8\ 5áë¶C#årr£ñ®V\95)GíÉmî(D&v\8b_`j¤GÓhþÑ>\82å\91\11\ 6©Úµ©èCúÅ¥õú\8fjdÒNhD÷!\1c3ÜIº:»H\83£\9b\8c\80\89\93J2P}\83ÒS\7f\90tJ©lRã©ô\86ã\9b+\8dÅüeé5Ãõ\vw_ÊìÈ        S°\1f\9fèJ©\ 6¹Ù\ eÓ0\ f\vdJä4÷Ì\94Ý-=6\9c8Wd|ÊÕ´ìÓ;
+a\8a'Úô
+!8tpóµ\eÆi\ 5\8a¡øsjWf°ØéÚMD#\ 6\8b=:<\r'+sÛ,T\ 1ÕÇ\ 2\94¢ P\9b\96\ 6\18â9͸ÕéñG¢-ÔQ85?T\87ÃÑBQõ¹ÂXŨ·0\80\eªÒ7a\87í\ f©§\95\8a
+\93jX\1fj\95zü²J^*\88uÒu¦ö|\8358µ¬Ï²=O\95"¨B\86q:?©'æÒzÁ\4Z%
+Í]Hª·ò*\1c\9ajÔ¡hÓ¹FJ\1e÷AU/ÚZ?ªZ,è8`Uµ\ 1[KÝ\1f-Z=GXe³yçXV½¥\15Õj\15\13\96¨±. \ 6ç1îçªÜ»Xãw\15ì´ØðÕÕCý\ 6\1fÓ\19LÕ¸D\16\10
+«d\1e= Å\8a6u¬\8cí¼h²&\1dªö_Öà\ 5E40qÖi\19\16\15AëW%ác¥u@äz\93j\8dðZk\12     î³Õ@K\v\87\r\eå­ÜkkCpÍô\9c\18\f®Â\1fó\85qE\99]]S¹ª
+UÞs\ 5%EÚ\7fº®ê\1a\1d\8f\ 3°«í«è\80(RåðâàU\82\1fJTy\95¤%{z½\a\19÷Z\16\e6ùÊ£9.í+cí2\84ýÊ?I\ 6ã¿Rìª1\8b¿à"?`çÜ"Í®\8f·;"ý2\80\95Ý=À\b«§÷\96,,_zT\86\0\9eJ\11\82\ f«\9e´\1c\9c\ 6o
+=\93¨}b]\80KP,¶\9aQ\ 4>\1fTÙÁX½¿\8a\92 iìv<  \ 4äØ"õX5\ eø\1dd\ 5%'+\14ÙDÁ\89?É®Ë\1cd\92NVLYï¸>_YP\r®\19\97Å\83\b\85:\98\15£ÌêרÕ4;Ý\9fþ\84\9b\8d\95R\86rÖ?\¹êÎ"\90{6nè«\97+@k?I¶\94Ðö{oJ¢í\97\ 1\84\e-±kùA\926²-­È:äÕ\18<µwØ\f\7fZÓká9©\15%rMò¼]Eª\15Ô\vH»Õ¿ý£\aÔJ¸µ¯l­\8fºV\97\vå¸@º\8e[\11\ 5é×v\9b´\1c\88í#ï@êF¶Ìζ÷ {1m\8b¾\93\1a¯-\8bK1Ámé^Ì\8eàÖ´¼³Y\89N!#\ 1\92\9fna\82ö\19¹[3Ú\80Ä/\QªøíÞ*Ý·A¿1\ 2¸H\85¢ÕaãµH\ 4õ\84ëfó£6ÜTG(`ò,\127?}ùªÅE\81âx5\84\0|\ØHîòÝ:\ 6Y\8drׯ@\80f¹9\90Âêæ\ 5\1a\16s\9d¨ '^sC\99JÈç[\eì\80öN]ÿ\86\fùÊB×\réªLÃÏÌtå\1du\15Ù\1c\8aÕQ\1cz¬®>\ e\82{µ®Âf2_wú±«¯\18\1d´{Å\ 4DÉv»\90     \82¸\9bb\ fTÙÝçÆ#¡zW¯$Jñw\9fz2\ 4ò\fèØÁk\85\8fÈ\84gÚ=âs\94\14í,âÀGÆ\eÑ\1cÂ\9bvJ²¼GeÍËæî\7fÏ­Ó£×Sï\11\ 4õV\95|~òÐw:ÆÓ\16\8a½¹+}.ko\8dgPÒ½6\b\0\ 5úÞ\7f<è75(UÐzáð¾\ 2_ùÎñ%_ ¯Ë\97\8aL\1côm\ 4À§\ 5:<X«ªü\eÐþ\1e\99\11ÄU6ß\v\0\8bI©Ò\1dCþ²oжÀò\87ñ¡Iʾ­g2L\9a¡Â\r*úGp\9a\80ÙU\17©/È¥\ 2\83øÚÑv¨¾?ò}|¸A0/ª¾-Snu8""¡/B\81,\a+¤ýMè»sË]ß\1fôUY«!\ 2÷è\87\8cP\rÐMè|\99\7f:\8c\93_Õù\92WÜá±ê·Y\86Zb\8f`çË\85\9e\85î\1aù\96µ;_»¶©õUÊrâF
+i{À;¾õ}\93çË"¬\93§¯\1aL\ 3@VgÑ\18§¯\0PJ8ùȳ¦/º/   +;óE\9eé\vÄ\9f5ç)/\eÓwmekXÎábú¦\ 2\15\8a\88ÈXD¦ï\9eg8òx\ eK\18\97¶÷η\9aÌêV\9dïEJ\8fÁóÝ!&ö¿4m)\ fð|±¾\1957ö\80ë\1cÏ·p`¦ì\1d©(Ô´gÓÄO\14        0zç\e\848s¹;_â\18ðd=kæ£u¾o-3\a(_¯ü\13\10sƪ|ñÙÇ\88|\ 1bå[Ìá¨äù\82%¬½Å\12åKÕ/s\\9e?c\8e§½¬¥¹ÒtùÓG\10\8a÷æ\9b\1aØ8*_mså17NÔNå\ea\ 3Ùÿû\15\93o5g#´\89ß½\17¿\9e\ 5±&\ 2{->í\ 4bEñ\ 5/\8c\8bç\a\13\9f\ 4EI\bS|õ]¢\b>¢nµâk\8a`\0
+>M¾]Í\91\81ì\98rK\17\rúúOzL}i\v\9cÍ*!9õý\80\97¦ú~Îâ\93Õ\97¬\14`Ðä×<\11­\95H\ 4?¾éïØ­ÃúÖ\1arÊê\9bëàCôýz¦kæK\8fü[\90/\ 4^\116\8aðÃw\ 5»¬\í\0        \10_°r\19\18A!¾x\99Ĥ\9bøºê\1e\8c)\11ß¼\9dö's,\18ñ\95/>¬\81\8e\11_àÂ\1d¡T=\ 4C\11F|#Þ\bÞ\80\11¡\96«\rq`Û0\15Ä·\ 3KÒ©î\88¯^FEa:C|%\0cM!¾á\ 3\1d\ 1\8bøâR.\ f?ñýÛ\9c5ܦ&¾.M>r\85d\16$¾7\e\8e\ 2\9fPN|Í-\91e\88Ô#\1eºâkù×0Ì:ZE\8cjɽ4\81Q\rVU#t$b\87-\a¾\83e\9e\1c\aø\ eK\14f\80o´Ñ:¤Ýµ\87\ e>PI¾½çGyÆiMUÐg\10_.\88à)ÄWÂá¯kä\ 3ñurÒ\9c\ 41iî±zØ\83î\ 5ë%¾\\11ºÊý¤q\7f\17Xs`ò\85Û\94\99É\8atò=ÏE\8cMGM¾\93¯#\ 4Õ±ÔÌÛFô\88\16¸tk\9bÉ\1c\9e\8b\14åÛ\99Ò#E  îʯøF0\94\8aP|×nÒR\18A,Øf=Ú^ÕM*U|õ+Ó\1f²XÅ·ê¼tò­1kpÁ¢ïrzÉä+P/@\88¨R|×}+eòw÷.á¼R@Ià\v+¾M¦\16Ù\8aâ\9bËy@%\85¼°\8aï\99"ÖY\0f\17\98M\895I+¾\ 2¢~\ñÕÓ7\98Ñäû1´Ê*Å\97J4=ðä\8bÝy*¦\9d|ù½@- áq\93¹¸æ:\9c¯\93÷X³}\8cìη\8cÕ-òÎwÛr\95Æ\89\9f¬`
+\ 5ÿ\98mH\ 5Ü\8e\1diÎ×Y\17Û=ÎWÅëVÛ\82\9c/xÅi\892$Éù\1eRf|§ýA\80n\84Éw\94ó\82î/B¯¾\r,+ê<ùB\14\9aèÕKØíìÖ}Ôå\88Îù:nbÐ\85\9cj\9copïíào-¥o¡àwZ_ ù\0   ¤/#\99£Dð\0Æ#      ¥\8fíùhÙ½ÊI\8c­\ 4\1cc¡z5ï¼;Øù\86\ fC\84éÛ2
+\13z}\89$ÌÊ\86ûÒ\1d\8bÁ\82__Í«ªür\86ü£é\97\98¢\93àî÷Nµ\f%\ eÔ×\9aÝ\9a¿e¤âÅ\ 4¤¹_\aó\87\8fa¹ßÇ\10ÁÕ\8aÄöûcð\16Ô¾Iö§\99s]ÆÚ/ùyC^]´§Ú¯\1cÆÆ\87\9c½·_q¹Æ\ f\ 2C\»\95ü\91I¿\17²)\14²\ 3Ü\15~7°r\ 6¾/­¢_QÚ¬§KÑ\aÿÜU\95Êné¼½\15{OÛÚ.\19Ý߯\0\ fùEßçµe÷$Ý\9dAàâ      ùÕ\8b\7fü^åê\ 4 _\98\18\9e\97ñì\17e\82\87Å_z8+àõ÷\7f\88«|\ fâ<îúëÐÄ1ýÛÀdyÛÿf\ e\ 1<yº =Àño3<¼9è8\18°\8c1a
+\81+\bmQ«ÀÙÑÊ`ÏÀ9\ f¼¬Q\85\14Á\12;12\90\85\85QF\80tjÊW°\1fs\f\ 4\83\93\ 2­ÆÌ$\1a|½o\ 4*\ e>:ýÀzðÖ¨Ç\aa*fñlF8TWX©\841\88ÍÏío}\9e5©mnç\1c¶iéÂ\83e\18.Y̰0j82M,ãn8bS­k\18êÆÃ\95`#<?ì1\ egT\10+ó)lu\88\ 5shà­æ¿J\7fÄzRÈ\96w\8b\12\ 5Q\8e\89#\ 3\14_'®\12ÈÝPìð\11l\ 4¦Xú\8fæWÅʶ«\98W\f\9f[\ 2e­Øxõæ,Næ\9c\90.¸xÙ^¬o\vÑ\84ñUý«%\8eq\89ùÉËø\1dh_Ñ\91\82Æ?¥Æç\1d¥Q\95\8d\83Ù\8d\ 5º\bøÄ±²\ 5D\fæ\98\91p?fÝé:1Þ±-EJ\1f\1fÜyÌÓ\87à𱰹Š?ö\92"\14\93\11\1añ\80¬\9c
+ÕÁA\96÷CãBþ\13\8ek(AMJ³d\8aü#úÃÿ\92¶£æ\ e\86\13\9a\10N\8e"'\89®\9d;Sõ!_Vü§Ö Åx\1f2\aô¶XÑ\f\13\ f(\8f,É©×B~rÌ\ fyf$°þð!GL\10ØÖ`I\90Ra\ 6ϧ³\90\11#*\ 3ó!\9bD\915M\v;\19Yh÷ÓéÈ!\97«\9f\1cYqè\95¹UfÊ\91é½\8dtD¾³ãÄ\91½ö\ e:\7fàx\95Ej­;\8eì\0ócâ¢+\12G\1e8\93ºâÈ"\b\8dÂ5ìK\13\0·J´ÉgÁ¾ëðIó 9²2îÎÂ2\9b\a\18
+ÉÏ\9e\92û\8a\0\bÉ+^\1f1ÜÜ\17\92ÓÍæ\8c\vÉé\16\ fù\11E\8a¬j?¿%9\96\14º\19»\ 5,ÉC»§\18a\85xY-{
\ 6Õ²¿\ 5sR\92Inp¨é£9Jrqîyj*\85lqI®\85Q\18X\92uÚ*%Tòå\1d¾X\1fª®\98Ðö5ÙR\88\80ãt\9eI\14n>S\9c\92ϰ'ÒCJîÂËî\ eN\ 4CHÉ\8fíi\1dÁî\89þaL¡×\16»\94\fÏÄiî\\152$%\93Ï&\17^)yDî)\br*))â\ 3l?\1cFx\8b´ö»\90\btJ¾+\83\96Úkèi)Yrh#ø¤äëquù\86ýH(\95\92+-\98Ù\ 2ÉR2\8fÛàqo±ªØRrÆy¡jK¾\8a¶ü\8bÒÅÄ'\12Zg\r\7fF&?Åßj9\99,T5h\8d\9fz®´\90É÷v\b¼;Éäó\ 3ná/I&ã©D´6\99\ 1\97î7\99lr\bh\86+utd²÷\0Òvdrç~Sh\93CÚf¿\93Á\19ID\80òÛmI¢|ø\ 1\94L\99´)[ëÏhIå&
+\8cÐ*gà¥\12ºÍ\14iNj+k©¯¶¥iÕõWF\8biTdù\ 45JEË"\91\92\9f[oàûq\99\ f{MAme;\19\ 3Ò\1e6ê/\9f\99å[\eî\ fÄ\9c4uâÎ\98§ð0´È,\8b\85¼Væð*ħ\99\ 1Ý´EÏ\9cáQù0\9a·\1a\8a?ÍDGs\12kf\aùhP\v:\91ÉE\10ùÓfºàmrs{-`\87_¼»&\83\8f\97\1f\9cS\0\rë\9brΠ\ 2Ñî\9c\ 1¼ýyLç\0YÂ1²B¸3}SÇ\v\82çT@N-|\8aMÏûRÿªWª£)÷¬K/¸ò9õG»ûìü\1a ´\9f]$\r\85ý\9c#\b\bþgM\949\\11è$"hNó¹\93\ 6\1d8m\1d¡±_¼\92\85.\eìù¬¡ó\8f ÅH/~\98#\1dÑyÏ£\85¢µV\ f8gÑ\17Ã\93\7f\16­RËQbôÙù_Ð5\9aNëÅ×h\r@[¬£3SÜS\1d]ª\þ£¿(P"ÍR\81/s\92\9f\8bF\ e©\91M\1aõW9_b~\v\e)}\bÃ\vÏñ<\92Þ÷¤i®ÑS~éÜ¿¤\1f2ýx©Ð75H\12Ц·n\7f\86¤+½a§×\17\85ÿJÔÙÌ\9f\1e.\83ºå½\8f\87\8fbÔiF \f\92\86â\ fþB\10\ 2\81ÃcFGí`ÅÏdRÇVd^^jd(ÃÜK\8dm\ 1\8f\e/5û
+Ãø\ 4\9e\1cºÔ$¾ð\9dB«¥þ@5\89ÚRs\vÇâ¦å\ 1O@©^³IK «\96\9a¿öÄÍ\96Z\90×\90|®Ý8)]\10Æ\ 2Öu}¶Ô|h\\82#0ã\0?\8d\14\\ 1&«Ij:¶,Ø+hIj@DÖ¤·\17|JRÿÀ\875GÿÑ\87¤Î:sá?\ 5Z\99e\8c¤þáÅ&­É0Û\84¤\16Ï©º$u
+ö=æ<i\90ÔtY·Ç5\91æ\v\92Z\9d-n'©µ\85\16ÇÙCw!©wÆË]-µ\12 á\9d¥n¼\82â\12FG\96q¤æVJ=ò      á\8dÔ:G\94LVO$µb\8b©+âº\0\13\92\1a£ÔÂ\8c-µÚ\ 2\88(Ë7KýN\ 3±ç·fI\ 2èËR£ùÔæ\85\96Z\b\1cÁ½¥>Fî.;&%I\9d\9eF÷H­æoNç\9d){\z¤ÞÁ4=;ÆñH=ÉÕ\r@\80«_\97N"µ\97xu¿Ö'XcÔ\92z¿\ 2ZVjpxDf\a宬Ô\16\97'\93¦{[©ÝIuªÓÔôýÛ\13Lm@At\8aéå¥V\98ÓËA\86      \9eï¥~ñ3¨±\1cú±\19o'þÇK\1d\12\82\80%\13%\vd/µ\99[\83l\1a\90-\97\9f\18F\8fV
+m©a\89\ 38\bÒRó\12H&iû²\ 5\8eÔ/\ 5:X:Þ3yè\1aä|\9c\f\8aÔ\12\10?õ7\15\vÜâN'ò\81ì(¹W/p\83ÈìÎr\16©%îRmÍk £vú¡1Ë˨ÿü[\91ßÌ`Ôr\8f\1d°\7f^H\9d\11¥Ö°ËÖ©¥R;Á1\161àG­\9cJû_\92æu<ê\8fÞl´*xÔ>À að¨\832\82µ\13ÕRQw\81!8\9dgÑG¦\f\15u\96\ 4_6TÔO\80\84î>\ 1\18\15õ\12\8cú>\9a=VÔ~ÂV\9a(RQ\87Éjß\81¿®¨¯ßç\8d*\19¦\12ð\ruu>RÙ\eê\9aAy`\ 5V\9f .\9bì»&¨M«Å`\12Ôf@T4aPKP\87~Fí:Ï)Am\13\83ñá34P£B\1e\$¨\aK^\95\17æqIPC1\ 5Î÷P\1e3Pÿ¿zå¼ù\92¡®ó¸q5\19jDÜ{Â\ 4\1f\vø\fuÚy#Æ\9dì½íe¨ÉO
+4¬±\18j\ 5kuW|"á^\9b\ 3u\97üèk \8e\vq\95¡¾ÅÝ\97\8a\1aO\9b\81¶£Þö8;\93\8b\81\7f=\a-¢-L­\8f\15\13pj\ e\88\8f\8eWC\0J\10N\rÈ£¦\ 5b©;c\7f©\1dbdlòRÓ\90YZ\9fó¼h\14/uæÄÈ\96SëVë\81P]¼b\11+Õæí\897\99ªó¹\18ì¹jq\99\97©²øLmeõ/Å»r«#£\0ß»º2ÌÖ)`\1d¦÷eÊ\85k\12°\ e\e¶´Ý\vYL»º`úèý_­\8b$¨H¬ÙË\92r\ f\91¬\8f\ 1\ 1M\9aµù" c´&\95ý\ e¬u¬º v¶\eíøÚº2¬5áµp$:µuZòy2>EF¬5\18\13qÁ©\ 1mýø¥¸Ö
+\83j]¤\\12®fk´\94Þý4[ßà\816·A\85½ÙÚ\1c1\93(ûëö6[³¬Â\94IªõN¬\ 1rX¹&ªõ\19\11Ñ8B\14\ 5ÇP­u`\1f
+\1cZc\8b\ 1I\86Ö\96\99¿L« \1dк\91\18¤\1e\ fÃ\16\94\93d\19´V\9e\0«¦Ö\87ôÛ\95²¦§Ö\80cÅÖWÜ\9fZGX¥Ê;Âh¨µ(Sw\8bõ\ 1ÄÅ¡Ö(Fl\9f83äÇ¢Ö%
+x­Õ`w\91¹Ë2£[`;\aµ¾\8c;ÏZ\86N8ÖPkR\9dü  É\86Z'#@9\1aÛìm¢Ö<]Ì\86aëT\ 1\98ñ\9bäd\v[S¢:ÐÖ9\ 5¶6úà\1a\92Ë©Øú\1cÒ\8aP8þ\87lm\18)1º\19C\97\95ËïrÙºDÖ@¶å\8e\85ÊÖ\16þ!\ 52QV)n¼Û\18oW[ZLfk\ 4ܪ0\e\e6[kÇP\8f·Ö»Äh\ 6}\99îO¢:o\9d®ÚùJ\18\85ç­ëÿ¸àz\ 1BPÞ\1a!\89\98>\98
+ÞÚ¹?ÎÎ\11\8dÁºu\88¤Ã\98qm\r_êÖ¡Î\93¸Á%jl­¯;¤¯[\ f/ZÅÐì£ÐÛò»V-ݺ\15%Ìòñ\11æéX2\?L2k<Dî\8e,\99­èg­}¯{\ 4î\85å:ìfËR×¾] uwÍëzÊîZïÌc<¯IÈtÀ×D-$¬-\19\99!¿Æ0É\1a¿lÁ½èK¶\7fJ«OaÚ-û|)l\19¯©Ãæ%\1fh,#råÌ\81f|±\17í5å\e»\83   ÷~l\92/`íÒ\9f\vq\e\ae/!(5˶ö$)\16\93\87?\9d½4{¶Î\bm­CX\97ýqÄ,míO\9b\8e\99»Ö\0¬JEµrü`m%\14iε#V¸0é\1eìrÈ\9clÛMg@!0¾ÑvëͶ£sB*«Ù\8f TݾÈ|Ó\9c·{Ío+\ 3úº\ 5wÒá\9e\97¶I]ܬÊâù¸í¨yk&·Z{EnÉý4\84\e\96[Z-{hn}\ eÇ
+ÏýÛ¾\18\10Ýæ\ 1\1d\8aMw¦2\ 5\a\1dõ¥Õt|ÝüÍP´\eÙ\ e\ÜM¸\13\10õnö\vÞ(Ð\90ñ\16ë\1c<awmO\ 1uÞv\1cO¥w$³£Zï\7fµ÷WHn\8c\f£_\1eÅàβî:**P\12hu1ë1-\99ì;\91ßXwo3ì·¨\9f\98Ëêo9ÿ»#Å\94~\80Ãàfc\15¼xFà82}A\ 3×R\9dK\82ÃríB¸àüopé\9f½\ e\80puV\12\8e@
+\17Ö|k}ÏmÁô»\f\ 18kÃé\f°­ÃíçÒ¯òYÜ>\94wýûÝù\91M{]ý¶h\bQ<¤SäVq\9c0<ç\96\9c®\ 4#Â8?6`p\8cÓ\9e\88ÆÙáâ«lÚxÓ\14Ç\róÒuüö\9e\9eôy\9cù×vòã­º \9f¿\13ÂÌÍ<¿Èï¨Ú\0H\9e\99çðHɽ2yXÛ`{;y$ÊQ¶uÞ\94\13o\98\ 5Zåx\16\96/¬Ibv5«NÝ\0\1d\80øò¹lC´0oÈ\84\9a\8fùßMè`æ        2\19\81Ð\1cü3WsûI\8bW\ 1^\8d0\9bãènn ÎÕ\91æ¤d@\eC'h\9dËÔ\eÐùÎ\ 5\97²\85\ 6l*欽ãsç±}Y?׫1\b/\ 3úâ\18ô<\15ºêcZïÐ_¼Ìé\83\1e#V\ 4l\18=29úì\90\ eB\96×;\93\9eÐ*\1dD$µÏM}¦ë\87=ôpºåî0\97§\1f\1a\93¯\ 4uãÿ¶ç¢\8e
+       C©\83kûoon;u±W\a\96>\19³\9bêVx   LX\1dò\9e\9c`¹~~1JX\8f%QK/ëØÿ\aß§u ·¾7$xåºX=&r×ñÍu|´×\87\7f½\89\0ëx\84\9dJ#ö\7fýc\86Ò¨\eÙ\13øÝþ\1eá\fé5;\rð\98¨f'é<\9c®>²«S­aÖLRëªDÚ       j\7f»}_åAA\92Ót2¶ë\96\96«ÙvmL\92êvNcÚ5~»ã|à\ 1Äh¸7\1eÇÊÇ=ß>BÀÜ\7fÐ\0±Cw\1eÎÅ\17º\97\82ø\84\1f3©î#ÍîýÁ\ 10ïî[j]¼sQî\13\91!\88øYï6°\15×1²\ f%\vúþð£±ÿáz\ 3rýÝ»ñÏ\1aàiB\8d4\ 3ïNà¿\15\98*4úàm)|÷.Y#Ã\83\82ȯc\87OÑßÞ\ 3UuPÃ]\96Ú\8d\ 5Et\89OdÕ¢\82LO\88\ f8ü!;\8f7\88Ï\94N\88»Ë\aÚ\83xb%\a\8b³´\89Z\ 6ñ\898)\15¢Ø¡TÅü\0*ñòH\a¥\85n4\18\ 4ÝG#R<yd\1d\1cQ\8a\7f        30\8e÷»THj)X³µxÑ\8b\95}
+'>\8b|5\94¡\16\9f\9bÝr\1c²²x²üx
+yM;\²x¼\81¤M -·Ü,þÜ\a6@\8cÏ»\86\86w\8d÷\ 3S\13«ZaõñתþqãÑ\ f\130êÈ_¸äã)\86\ 4ÊÛ_\99\14*ß®e&\1aË7\0hÔº|[\ 3Ôv\98ÿ\18¹üÌ|º\80\92\9fêcØÞ|qô\95ö9¯\82¯SC±óð|H\1e\10<Ù¬R\90,Ð{Ô4b¥'\8f¦\92á¥0¡7ÙycT¢Ï!Ô»\9d£×-é\11\92¡´»ô>\86?\ 5Nßs¡\94&\85 ~$·9©ÔÓPz«©^\8c×Û lá\7f\94\16W¿º_¿¢¬\97\1eßËsëëF\99Ñ\vÞõÿ\ f+
\7fía&(Fûb\7f\88\0 ì¹\1e+vö\8aªCËn\800íåZª¢_{eÌ\93\ 4·\8f¬"á\97k\81ÛKe\ e\84\aÜ¿\15È z\0÷_¯±3¹\1f\12r5È}\90Ä7^í°\7f±èÞü\ 1N¡Ý'\ 4\1d¸ã=Å\ 3Sa½G@\11"1­óûó}\18Çß÷´À_k\aß\10,|A\9açê\81ÿÈTPäݱwmÉø\v¼ã\8bFäãg\90Gmò#ÚÊÇãËWÒßÊÐüIJÙ<Î\87Fôü\ 53è§\8cÑ·\8f*ý(|\0r\b\1eý§q~¨\fìÂ\88ü\82\8d\86\1f¼\9a>\ 5¶ìµ,\1f»b>âfÁÿ\ 5Ó/ûZ\1a\10pÖ¡×\7f¯u\90ë4W²\80\_ß\92\12«3\18&\ 5ɸYc¦ ãº¢Abâ\118\ eÆ)`'N\ f4Pç¢\11ÃWë\9fÚyÆl
+\9b\95\8aÐ\9dÆÉË>ÃöT¸\v\9eX½jÖùª>\82ºzF\7fz\84µ\eÁ´9>®\81i\9aè£õê\89}nF\85\84Éì\86ë3\80f\8d±àÍÚ?§¬p¨\96khY\8fg\a\184\84\9bÿæ©~ñ\9e\17/¥\Âߦò¯~´÷zü\82\83Þ\19º\9bâ\88gYáé\94õ\16@;Ý®\9c1ôí\15\ f\85û]kOýmu\89Zµ\MÎá§uÖ9¹ÓN['ÈzCoõáV\87ìq÷ù\0Ýè2RÅ.±\a\12P½¦õP:\81Ò\ 6Õ»×&BûI¯\80\1eXLÛö\1aL\1c\85\1ccE¨v\83
+Û·"9°\O©S?\f\80Ûà\8fÓ\ e'»'ë\9b\9f\19]¾xß{\12¸å«åÚ\1fkC\9e)\90\8d\ 4¹°¹E\95\19ÿ@Cö½\93L\1fºälÖ\ 6§ä
\ e\11\ 2îÊàÑwv2á\8bG\84\17\9a\86à.çB\8eìBb±a\94Óµ\88n\ 1À\ fR\84\ 1#µëFÂ{ y\1fý\ 6ø\8a\91\83ÿ\b
+9ÓXÔåITßd\rÙ\9eO\10Wà{\ e\9a;\8c\16\90EÍé\9f\1e\1e\84¾&¸ª©¢hê$¤L|$\ 33gboY6\\95ÆÀì§¢xF¤ ,+Ïq$6Â=Ö       é¸\86FëôÌÌ\\17iæÈá\f4+¬YX\ 6K\95ôؤYhO+ê¥sN®\92àÄ"\8dÕÈíØºA\8eÀà\ 3EHu¦xì\13\16\7f>å*k\8a£/Ê£\90psY¥\13\9c^ÖÜ\1d\82uÛ°¨ã\7f±u\ 5¾jÄe7\f!qîZC\0\a\99\b\85\v\9b\19 ¼ñ|DxÒØ\r­¸\ 6\8aÃ#a´xý\19Üa½w\8cÝ\1cSx\viSh¶\1f½lÿ4q\94ŲX¦k\12B+'bLÆSÍ-ù\16æª93ü2ï\ 5|®,\15µ/\9fÅß\vÐ\7f7ç©æ´c\94}\9aðIã\93\1e\16lëm\1a\8aø\eV\90\12õ\145#õ\11Äô§ÜÅJGÓmã¡\ 4ºº5·ß'ßehÔÈ\1eéØÍÅ\ 2\r\7f¢k5\99\8eB×þ­t^Ú\ 6]\fà$Ä#½{8»\7fú´k\97\ 4¥Z4JH5\8b@\9c3ÝRrʳ?âP3\8f @\11\81\ e2\87}ç¼\ 6\18r\1f{eDÓª\89çÕ\99rîÑ$+Ñ¿G\81\98 4Ük\86ÀéÓ\95âÒM \ 1DYDV\88ÜsJvÏÿ\ 5;\ 3<\13é'0\8138hæ(ð\87qh­\18Çl\ùGj\14ºy¹  ¡\99\9b\87ªf;XvfrLɪ¨\81ÏÏËç\1cÀô\1fû?[X\80Á0MC6+çd^Ä\11'\17EÃqÌ\85à®{\8aÜ"   "×ãÓàÉ\81\14cÎs\18\ 3\81T,\ 5²*XóìÐÝëÝ\19ìh§\ f\9b·@ôÞê\19!R\95Ð1t®¨^Í1×\83m\8b4k\82\82À\8aÜ\8e\16è0\8a\19umr-\bå÷FØ«\eX\95\ f\ 1\12êzÆêÁ£z\82\98á¼TRÐý\18qs\90\1d¼â\r`\8cÁ÷Î`Ãé\18¬ßwʰLxm«gç8Ôú\17ÁçØâ*\90\96]\0aw\ 6¿×]%ü{È*TÞ\7f\95\1fëL\e\16m ÜN^ç\98Ê®_êÍ\a§\09¡wÿL:yJ\1ahO­çhiT\ 3­Yj˾\8a¤$½·\e\14ÞL´¹Þ\84\10ÕÄ \7f\93ch\7f°zìY\8a\ 3R\85_\ó¡gA\bEq\92l¨6|+Y¥\82\8aº¦\81ÛÜï òi\18î\a\12¾)(;û±të\¦Ï7g¾á¹\87f=J
\92\7f¡®\ f\99\bÆ\14\82æ\82à±ÐX\8c\83\91º£\11ªBvú\1d'`×)\98\a\9bS\86jû+áQ\11§\92\94fû¹Ñó©ÿee®ç×\91#\84\96\13°æa?t\13\9e\ 5û       æÑö\ f\11<=!8|\13\0ð\15\9doÅO\18óàeS\98×\88Mÿ\0"=ã\95\890DzÆ\82¾®\bÛqò\aKÕ¢[Bmï%\956\8d4\90mâ¸\16\ 2ï\9e\9bØ(¸\1dm\7f¡\94\0\ 4³\1a\au`\r\8f.\eS\8fèâW\82Ò6]Jq \88\9aǦ0ctç\95³²(æü`\94âà´Î\9fÃd§ Z\9d\18\ 2¡÷\93¨\85\a\e[B\80«Q³ìD\96     \0\17䪲u\8f\92\9c\8f\18zwïJ\89W£n\ 5¼rç\19\86Q\er\80²×®çaî5ÝØËSøÍ    ¹\9bX)ñ\avQ1¯Ö\90\e!\7fë§Å~YXñ|DL\ 5      \945\91°ì\8d\1a8\7fC§ûü\98\81\ 2*¹¨a\a\88È\10\8b´Ì\ f\ 5\1fO9¤\99Iu\7f6\96QõSó\90¥,eüçèl?\9cúK     '\8cÆ\1f:\r\82\9e\17±u¿wjÌÔÇ\ 2èÁï\86ÕåÓÇ<Ö\eDH\r9\ 5\ 3;3ZRæ\80ôEágGPy\84$tÔà\9a!\12º\ 6f$vb\anþ|p3Ä\9d\0ÅÞ÷Úo¶2+yC\96º\90\8bÓ\8e§U6\bÃ\11¡\17Ñk\8f¤\1d\17Ç\ 3¸\ 1«Ç\96»ªà\87°ÿǤüºB\98Fô·\94\11¿¼\9a³úo\veÞdg$\86\92¥Ì{ñ\9fÀ[]\ 2\9aåp9Úºb,ݹèó.\ 3n\84\1eËMthÏ*\ e\15\v\13x0lu¼º64˪®9åô\ f\8aÀBºäÈ*EÌ+\84w'FY#U¢TT\95È!É6¿\ 5H\0\93YTvÀA\9e\1dó?¦¡½
+û4®\0ö£V\ e[õÈ\96[\1a\r\8c~#°K«|%Ä5Ã6c# Ð\81õòù\91\ 2X.\7föOä\b\ 3#        9Ic\8cè+\ 4ʼ~wÕ\88ê\e\83Ö|HÎ{×\ 5¹'ù]qQ`ÿûr?IÉ\16eÿ\14\9f¯\91\1cø\87\15<\85\7fF\10ð8P½í²ìm5\86$cü\\93M\99_\0\11ÿx\97\v\85°\85lwQ9S\9fþ¼¨\f¥\ 45ÄZÏ/@¨u\8ehÚÝÜq3\0\ 1â\ 5\ f»\8eÙ¥q\85¼!\12h,ܧô\9b"þhè2¨\14ˬ\12ê\ 2é¾0ÖjK\95<þÂ3Øk\92ð(\97\b\977\8evÊ\\9atZÖ`ö        \ 6ú¾½\82\85>Âaë\99MÞT\ 2\93°é\98r\87\9fÑ2© ¹¥0TÖÄã4\96J\8e\93\9a\1fð¾ÁÍw7ÕWXÕ3[\0
+
+öÙ^Aê\19\eý¢.b\8c2×ÝãåÈ\a%¡×aÈzÍ\91\90\1c\9e\12h\85\ 1q\19E]!áò\ 1¿Áò\ 6\ 6r\8eø\8aQàjrj·\15*u2Æ\8cA.\ea\18*]A*\ 3\18T2\ 6Å9Ôi\91"tC{\80\90\ 1\95Û\ 3w"\84ñ\96ê!¹ô\ 4¥X\10\8c!|\17fVP\18\89N\18°+¿ÏÎÎ\11z×È>A\92ê*^:ük<>³mYü< VÞ\8e§hÔ#+y\1câLáØSwªøka\82=\89\9f\ et\8e\12¾,O\14á\eD\94OÍjCÇ\898qn c|}\9dZu\1f\97Ò@Ã\15ÒA;´\13Öy\0ÖÚÀú9±\1d|\94\12eQ\96!@\ 6\99ö%î½wµÙã\9cY\19;%[²S.»éL0Æq^î\8b¡æ\8c}ÆÌ\96|F(HÏA\11q5´ó\ 4­f\11ṬÂ\83GçSÂ\18Üñ51\88ÞKµ¨ôþÜ\9e;Ü@h\83Wt\86©o±\1c0r±.;}æè\9b¬±ÔÍ\15±\fz±*\85\ft\99@Dîª%\1a]÷Ä\92Ö\98\ 6Òñ\7fÙÎìT:=L\88Gâ=L4n¯á«\92{¶yzªÿ\18\ f\94ð*%\7f\94¥óäÌðº\ f¦9ixô\97üHr\8dJË@Ï|\b£1\89ðR\1dÆA¬I·\ f ´½D&×ãË\96S  Å:­$ÊAÆÄI¨\8f\8eý¬ú°wPÀÅ\1f\ 1«è\fÚ1!wµÃ]¤eH\19H2x±4^"g¤\ fI\9bë#â=±èÍ*vD³\91_Ø<ê¶^þE        \5øSZP\96wͬ`8\7fð\130ÞÁ*$Ü\8aå²Ä5ù¸\10±G\95\9eÃräTþ\1f\91w5#Þ¨\94,M\ 2\1cÕ\8cþ\8b³\8aè³ÆþiéBÅ\96^Nò¹¾cH8±I8Æ\9cw\e\1c rD\11¡\91q\13\92­ÜÅBïsé\17aÁÒê\eXB,*ìyl\11I\84ظâc8x6æ´C²·ËêÌ\96ù\19´\13#\10ÉùB\ eä\e-M&Hb\8df%\98ê@s\89)\82µ\fô]ÜùZJ\9f¾\17Ö!Û\15Üí\ fR\9eçH\ 2\87ÔH\fº=       l\8d\80ÚM\91ÏlC1Ð\80*\823²±£ªÁ1\80AF\9b½bfÃd\øð\90¾\e¬t±ÁC£\892T¿Ë\87t`Á\7f\0\7fq\81»\9f\10\8e  Æ§\ e N²|¤\12\8d\11D0s·\91p4P_ZVÉ\17å*zF6&v\ fÚ\84dÒ¢³IÅE¥?Þ\81v\ 2Ê(Mz\84ó\85l_\f\80ê7\85Éí0\12\9b\89µ\90YÚZ\ 6#d#æy\92\b\98.\90\9c¹&ÌÊÝ.y\81TÌE=²1%ûÈXFX\0éO(uj\85o»XwQs&ï÷QüËëj\98>\83\9bpH8\11ØV©\9eº"ínëÊ\ 6';\b\91«\90Ú%\84úó\0©JÅAs\8e¢e}£«Ñ˨,\90·6QGÑ\ 5\8eÎp\86¯\1aý\8dGÑß\8e\88\1fo\1142A\16Y*´ ù\9aE>5æ¼a\8c\80çʳeèÜ\989\88Í=\80ò&y\10ò\18\92\85\e\9cÃ:\19¤K©¶F/§×\17\vV\ f½órñÜæm\88\13Gò¤±(\8b^\96¬êÎÓ:bV"\88\88\87ÔÞêIF1\1fÎ\18\89|íb\9cÁ\ 5\13´¡¹E¢B0_sVm6÷ª%Dùý\r¸\83\14-['D¯=òB\bî[\84V4½Ý\82øôP·#u\ 6àZ\a×Ðwi§Ü\ e¸\aÖ\9ed`Ä\8b\15äkw{ùÇè\8f#yà\1aæ2×\1da\vä]\ 26H\85Æ #\9a(uD\ 5\82ç\ 3\1f\ 3á\80Øa\14\83\94)\ 3c\9f\1d¸ ±YæóF\ 2%1\ 2^\ eþÃ\8eü\80\v&k\fF£¸Ü/\9aU\11ð¤±/q¤s]T¢#T4\98\92\17\12\8eS\93\13\91,\83ñ\r\9d$1\aÍ\1e\9b
+©$\1eól\8bXÂUÚ8@\v\9e\1c\9e(\13\94\14Û¬A9ÀröiØì´±&\99\r\80\ 3\19ÍÅ"Ç×õ½I\93\ e\bçj\13_KÕe&\1c\86òñuN Ò\1cFÉoIÆ\15ÁL\ 6úWÂ\bã\14ØöÔà\7fHôò\17¤ÔE"è\8bu#Cüþí²ÞÌ¢U\1a\13[a\93M\1aòy\16\86-ª¿\88~\1a®ò²í¢ë\rnG\1aó$ÂJ0²ä\9e`t\8c(âË\15fh4n\ 39­ß\ 59/\82ènz~¸«¢\02.ü\96õ¬\9d*òªÊPÂh\7f\8d\9d\19~t\ 1\11Q\14\17"CuúÇ\ 2\92»u\8b­Û\89\8dII\9aô\8f\1d£Daìs¥\8e\r\81Ùõ\80\11Ý\9deQ徺\98\ 5ÕÞC\98à°Ézx\1a%ìmt\84¸Á@×Í\0ã¦Z+C£d7@\e\Ïâ@«P}¬ûÖ¥\1eS\13\85¾<\9d\\r´\87?\13Ƕ\87\8aÆ÷"\85\ 3<{õ\ e\ve\1e¸ñµ7Y~ü­ì\19Ìë¾¹7À°   \18ýe¹Eä# ÝÜB3ÎÙ\96fpïW\9b\84@àR\9b{Eg#Ó&G\94\10S5\r\ 1\986\aj\1cwWPìØgÈ`\rB|¶"\90µþ\1d\8dæÍ¹Æ@I\88D.ÂT
+R½^1¡\-\bÉ\e\ eºv\ 3¦\93ül\9cÿ/w\fR\1eÁpEB³ \aÊ\94"I¤àA¢õÕ4Ç\9d!\99å}H\8e\91\ 2%\1a!#8\80'1±ø\9f\ 2ý:7/Æ\8fÄVìJWr8\99ÒH\r¾üÞp°¢\¹ÉVÕ\b/ö~\ 3K]AÒßðz\ f a#\87\17Ç$!\80ê\9b\9a=6â\ 1     Î\ 1#\e 2ä# \93J-ñÅ7G\80F$'\82\v\12°r\91!$T{¦òW+dÇ\11ñ;(~Ü$\93¾LÂ\1f!Ƽ\83TÉÅe­\93cR,\86æ\8a\b"us¿­4£Ê
+\13\ 6qùa6Rf¢\0\9eö\7f\92È\84\9aW<ó\8dd\89°À^
+%¼\19\18ãÙ
+\8a"ÂED\88®\ 4¯¬Âaæ\e\98øQ\16¦\9ao\1e%Wä\90\v5¿p\8e\82iBo\r\ eª\9e)\ eg­â\8b'\1d\1fË\v\81\ eb\7f\f\ 3sâ<¼gNß­]n\1e-Öµ\ 4\eµRú\v\12>7»\ 5ÄFêb\9d½\10 µYOÕ\ 1É\9c\18\85Û)ü\0(zydÙµ-ûÀ0\12£\14¡ýФB¾;÷Åôè\ 5Ôå\f÷\93Ê_õÍ%\87ä@\126ÃÊ\9fx*\eèc²\fc\a\81H\14ê,î\1d\ 3¢Ú¹\a òBªf\94ùîÊ\19å\ e\8cÊþÊ/\\ 3\88\86Ré©þ|q\1cÔ°Z\15y\1fRyü\83\90´Ðm\87¿s\12WäÆt0\82\9b\94ìcP\ f\ 6!=
+¢ZǨ7Ð\7f+§Ñë²1(p0Öô\12M\85o¹cª÷-¼\8e)\19¬}N¡\11J=û]d\7fP\ 2\9fOøAÛT\12¤ð+¿Ñ¼Ì*¨\98\98T\vJ\1a\97\84\0gé½;\f\b\ f\81.\9fÀ\ 1F{\b^ïMÏ\92ß\87\83e\fí³1iÛ-¶,¢\ 3Ñ\1fC\91@\13\e?\1aÿn\v¦æiÑY8Ø\19GjØ\11\9b@ZTX\\v/È^W\ 4î\9a\82u\8c=\v×\aŦ'G!K\8eÈÄ.jøn{\14
+c\95\14\7f¢\ 3Òh#\14\97ÙÓ¡Á\14¤Å\ f\8aR\96DèXsdÐ_-;}!:~·ö¯\98±\b\ 1e\88²7b\ 2\84¾\98K³îû=»ï.\84Ì\9d\8eë&#{¨Ñ\ÑAYõ§ñ/·\1c¥:g\99\9fÊû\93\7fa\ 5³\8f\ 4wD\1c\14./G\ 6\9e\9fª\16ýfQ\91ñûJ\r \97Lºû}O\92I,¨Ï4çÊ`Sf\86\ f\b6\92&\83Gg\9f\16ó¦vn\81ùÅeúô\90ú[\9eé_Á¨-\1d\rÄÃû\17:X¯\15p`ë)°6
+Ý@Ôì^eÍÎôw \87þ\84\8f'\r\9d8\ 5\foï_\8f|Óß\96
+n*ð{a²R\14\94ØÊ\8a¸øý¿8øÉ\8e='\ 4\89*}\f"\81qÞYQ³\92¦à\13\88¼r~ô ÷0ÍÑÉ3SÇ\92ÙÃ7
+\1e\18Á2\82\ 4í}ÇN\94ª*kì0Ýï±È 5?0I\9a\ 5
+\89É+Ç*<Ú½,\8a\13\1cT¯l,¿Æí¡vs:â\93ØÃ#zÑ¡ªU'\8c¸´{¤Ö\92\13\1e¦\85\ 1\8c\12×cä\9bêýÀÂ#&\81\80ñ÷RÍ\ 2BÔ¸ì2â«\v\1d\9c©TèÎ(ãRfK\b\ e\99}q?ÎS}\11S-(r\aÁ
\a¿£¼JM\8a?Uie>\87-:ãìéb¶\b7\ 6ÍË\8aCÏ}'\8d\aÁ¶Ì&¹VÝ\16    \81°¼í`\ 4\ 4Æ8ÞB\8bÁ\1dC\ 4}\1dT\92>\13_\ f\ 2\82\ e\9apÇl\1f\99F\90g\0\13ä\11\96zªÎ\9f\8fä\18\80[·0bZ²\1aõú\18­\89äp\98\9e\98¼E.%«×\953]%9\86êé\rI¨8\8d¾5ô).äLuÍü¦³\9c\rX\f­ù7\8fÑÆº©Ì½_ÊÆ&KoydßAµAUJðq\9b©w ¯\ fÁÌ«RN\99ÀÁð­A\88s\82°ºÃ`\8fc\89ü fõp\97y:ÿì\8f\1em
\ 4æ-JDNì$Û7\ 4@\e$\19\ 2\19ÅÃýÂ\89ÂwÁ\92TD­»5Ð\97L?Ú\ e\14\b  v\17Ìé\98\97¶¿ÝFNe+\96Ú¦À\ 59ïàV4\vss«ý¹½\0\9b¦Ïn¢\84;
\93¹-q9yZ¶lÏc\95ì\96\84\94/\ 3\94-ÌfU\85\9a\84§U;\ayp1±m\90j%hÝM\8d\86ðÑ\9dO(\8b\12\86\12\vt\0ØzWýëÿw-.\14âÚy\8b»-qR\93V {\80\ 3$säÌ\92GÄ÷BO.Q\96u<7\7f 1Y\ fü©dUv|×me\9bG\ 5ðÝ?Ü­OÓì-ôbÔV\9f(0Ñ׸i¤Ìe®xÛO\9b̪ÃìG\ 3\17\99±~\g©:\894sÚÍ«\aeV üw\8aGY5!âV\97\ e´\avaS\86~Eô\r\0\99½@\12µÆØ|%\ryÃ÷zPÁêºóéþD6O-eä~\91Ù\ 6¸\e\89^þ­zª¥4õq\e\9el\r\ e!eg\80årß8ÙÉ+\f\1au²®³}k\ 1\9d\17S\15=Ac]·+²5GÏ\86Ô¢RÃÿ2hø\11f\16é\f\Àñ·â¥tpòÕ£èå5Tϵ\18z*û\ 67tÃ\rxÕs0\83»\83LQ]É5\ 4\0\91\15ù\12\ 5I\11îÕm\ 5}\8fáê\8a\ 1Ëv\99ë)\8c³GUðÙ_Q®¥Àd&Ai
+ Õ/ùóF\89¢ª\12.ËL\86:\84¶Æ\12h\8fE·¸ÑZ¸\16\103«Vú\95\ f§ÁX¦#\95\81Ó1[¬h,\83Nh\7fITØÕŸÕ\ 2ç©\84\rÙë7ÑüÜÝNGѶ©Ïvh\rfnâªgæþ`½\92¼þ\95éþBo\80g\11Æn«      b\ 4ª÷*\94\85\97²Ó`XÖv\17\87«J\14\8d¤«þ\1a6FÁG\ 4É9Þ¿\e×H\1a¡Ì\8d8ÀD\95!Õí²úVÂ\90ÍÀ\95RLÌ^VXÍc\fã~\12Û¢\84\93\18\10l\8c4ëp+}nÙÍæ¥§TZå\bå\87¯Äl\v_4\894>¼\96ò<­\98ô\99P\90O©ÃN¹i \98\ 2c¤)É\1fhª0\88>cô|Ú¬z͵\87ºônU©$q\1eH\10cT {ß,É\ 21ôÉ-%ä8\88¡ðbÁ\9440kç"\ 6\83Y\94\17\85Ʋ·»\9aõú'j5½\8eê{\ 6q"r\84Çt0\88}\97õS    \9a X»\83µ\8a\16L\a­\86£N\vO5\93Æ\84\12\9f½/å\13l|­lOX\92Aðt¥¦ã\14>°¶$\9d´õíy\ 1 \10HgÐ\99(ãqç]://y]Y§Ð\18Y\17[\89­¢\8d\8fÕóA\9d\aÿ¢^¬v
\97â­ÃÄé\86d\95øGAæÅ¥ÔË\88¹¬5\89\9e*çÝN4\97´äKÈÜ\ 20{\99\rÆ\13ºªt¬Zâç¬Àa\ 6ºÕ®ÚÝH   XI²¢\92\89×Þ¤Q\e\vû   \85&¬ÔSQQãA\97!½¿Èol¦xðJ9\92\8d\19\1fij&\ 4CT's/a\1a\aj\93Ñ\9eR\9bh\9e\bI-¦3+
+ëà\8dqONQøÿÈrÓí\búå»ÄÀ9\9f\88­éÄî\ 4ô\93S¦ÅÍ\18x;\84x3\19±\99`Þ9W%O,AéÛ)º¹\18\98ml\16)\12ô/\9dßñ\ 2\b\10¢ñ\13µµÎ¯\18Èî\1a!\\ví´­\0V\9eï§\ 5hÕÄtW\1d·\8e:ÂR÷ñI_\rºÔ&\93º\8c\ e¹F« Ù\10F\814t8ÑÚ ªÈ\1f¬àù\9d¬\ 6Fóç@\11fÂ%\85\1f\84V4\10"\fÚdöÆ\9d0b/ª V-§r9¤ ¸[·¹6:®\97\84\88<D\16«ïÌÙ¡¾¦v\8d\11÷k\f]8\ 4ù\90îêǤRæV2O\97åLÉÍ®f\1dê\1cÎCÌlß«\95æ\81\11(ª|ª¢¥hðE«\11T·Ø_êÆ\ 4H\91d\99!\ 3\118÷ÏEÔ\8f^GÜ&öäs:Tu\ 4Ö*ë=t\1dÛ}fÉ\9e\ 4é\86j¾«E!\14rx\ 4ì7e)\988?4´/¿êª¬\80H²Ê\82IÊ÷\82\bb\ 1\80.ù¨å èKØÏº\86\13\89I\80\18\98\91\v\847\ 6Ó\80ðÌ,\ 4d¨JF\rà¯\ 6}+\1aò\90gT*bË*\97qóµ~Oë_\92¡\93\9e§\9f©­þ\15\16&æRnÂ\9a4\84ÅåüÒ¡.G\89l©Ve&\14\90ê°N\0L¬G\7f(\12­úÇfñËyÛ¥p¤Ò³I\ 2vþk\füO²AòÕ\95b\92
+\92u\8bt?1Ë"þ\9fmÊ;`¡ß/\8b°(\ fUâР      ö\v- êÕ\99\7fN\bÏô\12#\95®@âËÀ\a¼\84\ 3 F\98¬oBzåÖ«þ74¸"¶\12ô\88sy¯u\f\9d\r0\8ew\13ø\9d\84*~-ÊÒc\e\87\rN§VZ;EkÀT\8fnIÊ\16ÖÄß\85ÀA%8\17C´H?w\18 +\ 1\ e\16EHÔ\88\9c(\1c\80x\85jëòN]c½øz\ 2 ~Y©\eº%8Â\8a\9bÚéÃ}¨\95\ 2\0Khü\15\ 6í\9bOz\94øiÓ\1a<OgôÎ\8e\8bðû\86Ïg¹\82kã_@\ 4\9dh¥é=\1f\9dù\1f\8aäÖ¹A\15$P2è¹÷@ÓÅ\92*\aÊ¡\8b8\93ÑN IVå\8fS\vâ¶2!^R%KÑÙ   ÆÐæ\82oÖØKدÎ\93\92)Æ~\90\0%\r\0ƹ\82?úbZ\82g\08!¼\18©ëKô®vìbsjd®Ùdé\\aj¡}»ÉNa\1f,\ f\9e·A\9d®O¸-\84jçñ3 \8f\80q\bÜ4-\96f¥×z%gÁAJ¥|>ÙUQw\91Hª°\ 5ToUè~\ 3?fdÝÿÒ7\94\1d@rýÐo©ðË\9a\92ù|v\98´Ñ\82\15O+òÝLÊ·¥oÎ.\90nx*ä\97\19,3FÁ \ 4Ñ\b³ã\12\17à=\eæ£Lé V<µCJSÚC'ÈD3\9c^\94\rþ\9cl2e82Ñ\95n\8c\82\0±EV\10ÈÔ5Þ\b\11U\93{¾è,αvÂl\9f\9bòG'ùÀ´¨$\9d\³ø-_\99q/e'è\82slf?¡\96$\ 5\92\83\ 11ê%5cÕ\84\93Ù\1d\9d®-|ßÉÿ\85ÏêÙ§Þ«ZàÓGhÆqKî\1dN;ù²\87vE       ç\84\8d×    »Þ\1aìÞ\8b,FÖ:E\98D¤:NÜ$A\16\98JDÛRcõ\87ìôf\ e¨oï\16sz°ÀTüÛÌþC]@\8b~÷t
+Ï[Æ\85\1aXU;$²\92Ö\97\91\1a\8e\aM.­ÞåÓ.Ã\98\94­D\a\0è\ 6\17²ÿÑ#\83\b¸»\1eVJq[Sò±w\8fR6\9a4ãLx\ 3\15ûËÄþ\8bo·íô.Þ\17ëcWn\r¢¿ù¾ñPÊ\11\01\11D4\91\9aó0<Øa£59Ê¥`×M:!Q\8e5Ê{\1cÞ&\17ð ã.NÑLùóÅ÷§¤*¥FôÓ&c\b\fë]2\9b·®²G\ e³qÿ­Èe¤?^"bK¡[\ 4\9f\89Boîé\15Øh\92Ù\ 3IÝ0O\8aè8\0f3ÇÑ1oë\1cb5Ä\141°Íÿ4¾b\7fCKkcx*\a6-ü\r½\7fS·HDÒÍ\81È\97p=åv"ãò\b\ 2\f@ï}þ\e\0Ñ\a!Û»\19©ÝÛÀaµn\9c.\6Q{Í\92Ç\8aV\84)\85 \89ÑÚB\a{\92L£¦±gãÞ7©Y\85\rxJ_\ 4Øð\8bô
+\9b
+¤BÑÄ\ 2t\8e\ 4aÖWï\fݲY\ f\94tHñ)\93;\87\11t­úïy~\eO\9aÃý\0gU &ÙÂ%\ 6µì\831´F\ 5!\983ë      \86\85tô^DÎuJRí2\9c¯Î»5íÍN\9dW\89°ëÝ0õÜ\87Åá\r\92Lqe_?ó¡\10·c&?Ç\82Ç\87ÿY\8fЩü»³\93Y\8b\0v\ 5^3ò\85g)#:§4q\8d\1a5È+8\10¡fxA÷\936A\11Hüÿ1¬nH´
+#ù\92-³×¹\16Õ^b16KÐ\87\91G^Ý\80 \9a{\a\11ÓNÕ$5rß    Ìb;\16\ 59\vrÀbF\1c&\12\ 1¡k´      ­+ðz\7f\8b*|ùf\17<Îßoþq\9eé¦\rX\83ï\8aÆ©­\8f¢*#I\±Ê[\ 5õ\e5?\0î\19HBä\8c"I?\14S3ºÚ¿T\80\8e«\90\83\a\1d©â\87TóÎÚnÚ8T7Æ\ví"s\ f½\16¥RùùïÈ\8e\80à\bp\8b&ZêñU\94´v\94¥\v\86\80eXÈ\1d[½"\92T¢Áÿê\83ÑF\1aô\9f\80!E\95ì\ 5ì§ÅÔ\rÃzi\12ý2ûÓ\ e\82\azU£øSG\85\97»æ#È\7f\ 3¬`\e\0;í;5\99\95C-\0Ý\84¶Ô\ fÖÅJ9¤J8       á\8f÷?§\96\96vÒ+ØDµh\92q\9c6\ 1ZÙ}?$Óq'\16ç%\11Q\12\8cH{\92®NXÌCX\16ðáe\8d{&lb\9bø+{\93N\94=\96ú9]µ£\88§À½b"Vøê\8dWoy±ò\9dn8;\13æ§?\1f&y¬x¤þ$ý½\1e-\902Á>\97\80÷\7f´R­\16íÒcJ;ë§\f-\ 2$T\89ìþR=;\9b¥4<­¤M\9a\1fhME,¹\ 52Û2æ\8fE¥þá1|Ê\11lr\17\91&7\7fU\ ez\ f\ 2\13\8a¿\9fÄ!Ê\15\f\80I\97Òcñ!Z³ïÖd\85\13Ç'£$×\9d9\vôÿõD;³>=ò\95É\10ÿ\\9ab¸Ær\9f\91«0©|\95 ¤\ e\e\94x\ e\v¾Q\b\18\82A3üÑe\83\94ä\1f\82Ìóå\8c¨\99#Üf]\a#\8eÁ;0oåÚ@\9f\1d\95\ñ¼\8c¡\12\ 2\1d^\f\1d\rJcú\8fL`h\9a\90¥\82rà¦\rK¼wÄZa\9d\a´\92$µa\1a\8a\0)±nâª=pH¦Ø"Q\15ëûv(Ò0õ\v\92}\9cºSù\93Z<ÿ\e>
+òå#ì7¾ (\88(^ض÷\8bôªzV®\9aøu\12¼\10\86OB+Ù\12áf¾ÅðA\93Ò\88ü~Aõ\ eÈ<Çìxõ\93kýÜ¡ç1Ô_L\84þªPÊ¥u  \8cç\95&¿7'\134Ê÷9\1eE\17\94\ 5t©<©ñÏj/j?ø£þu\ e:^4   ?ØÅ\10sô¼³{;ØDÉý\ 2\ eSU{A\19NÑììÏ×ÙÍ\18Ð~\r\ 1uTõ[\1dÖqeñiR\a.¾¶\1cmt§\89Úé¡\84À9j½ç\ f\10î\89^\92\b¡S\10zWJ\89g#&\9b]ëO\ 2®=ªí¹Ô¦õüÆ\88·\8bX\b-^í\11N5¨]\81_îw¬÷ölè|\11Î÷âö\16`*Ë1ãÉ1AMæ\81ª\16\86æW>¨ÔÞmt\ 1mmzoTã55­\ 5\9d\14õC\9e\16\16\15M\82¨Ó¯Uî\97¬\92\8f²bc\92:\8cÛ\95/¥'¦*Cå\16\18>\12\17[a]öi\94zÕ¦}=\9f9äÛ<#®\rpçífÏ´(«výYî=R¦\1cÌÜX\8f\99\1a÷\9e@ë<\a\84\ 1ÐÄq=ö_
+º¡Àü7¿zä5wo\12\0µÉ\rÖ],\ 4\17Æà2× åÕî\81\9c\81\ 5ÿ\8eÑÁaiSuK\10{Ü,\ 2ppr?%\84\8a²`¾^§uØ\93r{ë\v\88¡%\18\88(Í lAçZ?õ\91e/\12z1$w\90\b1Ä4\9c Û\1eÎ\83_?TưÛoàg'    ¹m\8dÜ\94\99\88g0\89÷¢\19\91j\8dRE\16½èÐ\ 2«Ùß\85ý;K¶@ô\89pzjQ¸i\8e©o½\12áeYWã¤>Ä:ÛM\Ó\83\98+\14\13\0+x\b_ã´ ç \85Ë\91\9fXJ¼Ø³ÒÕCC¸\8f    !HÉLïö\83ôÑ\83Mpg\18êÂ_MM5\7f4\b\8aPëÖiÇMã3\rãL0\v@ÊÂΣ\95¶Ñ\92Ó\ 4Ö0¿hìO©\1f]¹µ\r\90\81åra       `¶·M\r\12ÿÏ\ 4\17s=U'À\13Á~\8e\92\83ûïXÑMÕÓá<KnÖ±R?¿¤3Ò\ f÷7°\ 25q\1fh\9d\84ý\ 1þ\e¥Ë'@1\0\15ÕE\95£\92ª\90\ fûéA\16èé\9b\82ÀIQ&\9cXz\17\96\15\82±­¬\19Z)\87\95¼«\94Å*\1fRE\8dS©ú   Òö\97¿/\90\8fúRS\1ex¾Ðü\87/¿DF\17e\8aì\ 6a}\ 5\11Þ\ 6¢V\11qsÎà HÇ\14§:íÁð\87»\ 2\82Ñ@[|\82
+\fÊüÿ%ñH¹Ñvù¶¤î\84pe\0\v¼ð\ 3î­º)\1d\ e\85J`\8d\82ëN\90ê*H
+x[6ò$U"aê)ñom\ 1\89\14ðòH\9cÅ\9d±¼\1afy¤LKþ\ eS¾u¹M1\82ðÅ\91ry¯\r \9a\ 4\,õ/ùtUí>\16»H\92\84srX¡        ôa\18̯\97\1c.\9d\1e5ñªêµè\94cXë¿\9bC        FöÜ\95ý\8aþ×ÌÇú¨yrÎc¯\15æ¨À\ 2\ 4³\91w\1cÕJ\v´ï@
+\ 6ÑØ9RóvúÏèy\9f\ 3U<\90*\1c\7f\80ëÆÿ6àä\91Ãl"`\97¿SéµÛ\92|\t    ]N¸\9f¨cy­6i¢\ 5\90VÉë\8e¶Ã×Ëżª7\ f\86_zy1×\17ª¯ãH\15ÇUÃ\89®\92\ e¿\85é-¡÷áÐíø\86È\e\86r_(\94Ô>p\17òá1Ü\0Ê\ðá\ 2]ðçöB·Ò\9e+\98ç¾;\93È×\99\85v\96D\9d5%¨Î^W7gy\8c³Î\9b\83b;ÕÜð\12\9dø§²¨=í·b6é\aON~\8a\\8ajùÏÚ­LÅ\eýPß\16{4ùë1!,¶9EEþ\17½®
+\8e¢ÿ}\14\91\95«âw=þpñìˤo\ eZ\85ÐÜÄ}7\94ÓÇ\85Ã>\16Èr^ºE-Éc{ñú\ fÞ3ï\80\90»T#Z¼\88.GüD\92ê$}-\ 5-¦L4Á X`\18­\fð\b\16,\96¾µ?å%\ 4\97\9b?\88\ 1<G;pZ\93\91\9c~\87\8cNæ6\9aë\ 6K>#\9a\9e\7fO±XßöñHÁ¼Ø¢¯B\87v#\95h{F\90´\11þ\ 5¬Õ6\92ó\ 1sÏÂ\7f\81\87­Ü\8d\94Xª¦4u5Ä\82í9v¸rÊ¥\v\8aõ!G\81b*\974¤Q\8bqÐê\8bÙR\92Ã\1eP).tþ\1fLÛ·CÂ\19®uÊ[á_\98ßO3H­?²ÝǦéøÚ7\ 2ª\19\13¼¨Ë\16\19\94¥aÄ\87\ f\11p\86©²?­\92#\95ß©j\8fªý«üæ¡î2iÈo\90\ 5ÑØr!2æ\12e\8dv\f\93\99à\92>+¼\19G\8d°¿\87+\84\15\ 5¥Eðêø¨ÑÄíjã\ 5ÍÔÿ¦\b¢^Ú-¸¤÷ý>Y²\ 3Ëh\ 3    bÊye\rþíϯڬô\98øL§\84\ 5@4ü51¡­[Iµ÷\95Ï\b2\0FTI ÏÆ7¿Tr#éöJO\94*7GÚ\8fð;'k¼\88\a\9aè\8fÆÕÈKR±þ\15]1*°þÿG<Å/2\8a\1f\7f±?\9føßûzF\1e^\9fF\15\7f6?@ô#\11\13\15\1ey¯?©¦`¼»\8f\1cM)W¡YW\ 6\96ª\94¯ÂÒª:¬Ô7ÚW©Z½M FnßÍðÒoø\ºÇ¾;        ëãÿCêö·o\7fÁ"\85\8fõRsÚèw\ fC\ 4ä\92¿ªì`é-S[ÏI\eè\86\92TÅ­°\9eÙJ\95ÐýÁÔ\1a\93g\97Ùåß\9bò.»¶,\ 4\7fG\96\18\9e\90ë\86\84ÜÑ"¡\9632£ø\9a>\18ùõ«áJ\8c¡¹C\ eÿ\a   3d¾\82ìKø¼\7fΩn¾6z\95£L\98\92+Ñ£ñgY\ 6\9d\9aR\98\ fL¤ìL´çu\rí«0íK3ý\ 3\9c\95\7fÚ\83s\8e\86S¦ï\98¶ë®\900R\98t\86×Ã\1a£k"ÙÛïq?    \98ÿ§°zM=\b©\ 6¯ï\80ûn\9aG\ 2þ!ïíüË83\99\97ãå×$YH      ¿tH\ 4ü\17?(&\10\ 2U\ fÑÊ\0Òñ2Ìá\10k~qÖ\83JwIÿþwT¬(\92x¤ãß\90\13\15á)í\ eh\85\17Íÿ÷\1e\8eÇøÆÆ9\b\10\¹òÁqÌ\8ag\rt\82\12Ö\7fò\8d*å@\b\9e
+þjMºW­·ß·\86\ 2òþþ.[²\7f\1eÇ\9aü\12ê?¿ÓÛõÏFÿçÈ;ÿ\ 1tf\ 2J8é,-ð¨f$\ 6\11ªFk¡;¥\84\11¿´]Ï\ 1â\8eq\ efF*Æ( ¤¤$é.¡, Gô0,z&ò\12°\ 2T\ 2g\ 2\87\85v9µ\1f<ZÅÁZÐ)=Í£­5[Ý_¨ô"«ñÇvY\89\86Ä\82\9aÔ|Kc÷$\97\95bÚlKI\9d\8b\8b\93\95\88z\858YTDµ\98Du{\93DNÅ!òÖ(*)N\96ÚM¥aæ\7fÏI¬DC\82Á¾Ñ»ÚÍÝѤRC\1cŲ\8d\9a^¢!±`\9f\86<«¨cÛ\86\g³ãi®eN-Õb¢3qG+¿°\97fÇÞ³ÙÚYM4$\16ènÐk{°\ 6\11÷öi\98FC÷¤Á##\1e7¿©´\93\96zfû3ó\7fèuÎêªg\rqVí{\96í\1a¼   ñvm\9bnÐG\1fæ^q÷\97\8bÎï\a1O\98\9b\83k;v;$»ßÝÒiåÍ~*\1dkÐîæ\8aG¶]Êß®×r\8fhÍZs¹[§·\95¥E7òU]%â«æ*¿ÀD5ª<£9*\9a³´Å?ó÷¤Y&Þlna¥)Õ~\aKG¿8XùÅ`Ý\99Ùà=/\8brÎFf\9fûiÓîª\8cvi¬Òyec\91<Þv^ù»¨Ðð¬ò\8b2û!NåN\9dZÎêÒ\18oSU·\86ª²Rͧ7TI6ÂSJ\9bÉZõ4»«ëºKt\17ÝX\9f_\94\7f×ø÷Úã¼íTÙ/·ÆÅ°`´ÿi(Ò\90X0º\9c¶¥\1eÕñ\85ßóÝåM\95j%!î®ýèTÜÌTó\99\9a®£¾ÓT\99g\r\buÖÈò\8b\86\ 4\ 3C\91Ò(e¥îP-æ$å\17\89\86ÄÂÕo[PÜZÎ*Òò\8a½y\88NzÅ\19\14(ªHñ\1a2óâ\90\ 25«PohtOÝ£Yª)ɺ8\94\12?\19(¿HD\147HúE"\ 2
+\14d\11\89\b\14((±@A    \ 4Ð\ 1"\82¢\80äñ`Q@BY*\15\ 6\ 4\ eÉ\ 2\v4&\f\vÄ\ 1£òp,`\15ÉÒ ,\104\88<\18ÐE\98DPqxðX\fð0\99@2¡\10 \81äÑ Ò°0LX\ eÐ\0by<L\16\1aD\1e\f  \93\85\ 6\11\96\a\84\85\ 2AEÂ@\ 2\8as¨8\1e\vh°@\1e\130\96\b\12PØê\1f¥´Úcfå¤\19¡Úús¬}:ós\ 1CäS¢)O\95\8fÊ\9f²Óå#\9d²mÓø&\9cÛFûÓ\83&2Ú7>\9b®sváøÈÆçSÒ1ÓÙjиåoîÓ£v¦ª\vo\9cÛêêUE¼- \8eú£V³uÖùü¢¦þ¯ÞN=¿¸\95uÇGÚ\1d[Ú)ÿ\9bÿöç\17þ¿\9e"µ§\1aÇnw·\e3\1d;\91ÑÜ\1dUqîé±Ê[\e+4«Á¯ÿÁ§\9d~\f\r¿\93¿é/¿c\87k\1eÅ<}~\91\83¿©,\9bükô¨ó{ö\87®\1fíì\19\8cÌ\8alhoÈÊ6e¿)Ž2\e¡\95úc¶3Ûìæfs»\1c3ßÜæfù\85\99}\fOhE\93h¸ó\9bÆpN8i´iOË/NÕÊ.E_Ëò\v\9a5¯)\96\8c\8ct_óë³s§i\9e_X­Çw·«Ç\10Çw_¢<\9dãÚ·{\8bóÕBÏ­l|ßiìó+×\87¨S\1f\1fy¼zÿÝÎniÇÎÆìÔw?{\fÓ\ 6Ï\90|9y\999V:8\96\93G\9eÓKº:\9b»\1dÛÓ»\1fÍíç\8cpì:v\9eÂ,KLý \92\1ak
+ÍsfS\98\99Ò\11\9a\95±\8cV\13á\1a))ÚÝ\98\99Íáî\1cz\ eí\87÷9ÏQÎáa\12~0¿\18L\9c\9bK?\11\11\80\86\ 4Ãâçºh·1Ë\1d³µ¬zå\9e\91\9aÑ\98͵Ô\9fëë\9f\15ý5çë¾òó¿\91ýz[×í\93È47mÕÜä¹Oïª;3Çõë\13o|½±Ó>N-T\ 3k\8c´²ÆH+ÓH\8d»\8b4§G\89\8b\98«öÚhÖë­ûÎ\117o\88Ô\90\8ej5\9dié6j\8fújól*M×îc\88ç1ÒßoÌg{úÔ©9Þ³åø\96Ôª³Ç\9d=y¯¯ûQïvìh:Fz4\BÄ¢9d¸µEû\90+\87\8c\9b¸\89\18¶M7¾ò}sn:ë\9c\u\e\19ó¦Ê\11OÙdZ·Cúh%¾¬E~º¶lkëã\9fy\191­Õ\18éø\12\10\80DCbAO÷Gæ\1có\96ÉÿmÎ÷¡úÕNùòtê\8e\85õOY1P\14Ú\93\89jå9E3ÅT\Ä\9cc¸»KÕ¼ú\åÙT&ú~c\89zOËL#K³LWÍåÙ©\8ee~q\97ù˳Õ\9cK\1d»´´\9cËËËÌÃ<˳ÌÌLô¤iÖ(ý4­ôò6/ÓH5m\93\94ÖWJ\9a\88s¥ÊPjUªFcM«¹ôôj%B\1d«âÎõ\9a;¿æÕ\94~cµc?3\9dÓÓ£âÜ\93z;GÍÓ\1cÔÕKÿtRóZ£z\1cÕ¯\9a\19ѦÑZí\10êËì¾·XUs·{\87»_8ĵҵmîmÕ»¿Ùe¸\12ÙF:v_\94\13Iï¥VvÄ¡\93ÖÉ\vZ×äæîÐ7¿ØõmQîÜÒm~ak:äµ3ZÓñ\9e\8d7¿X[»ü\82hi\9c6þ=´ùEi\95\96&\1a§ù\ 5j~a§f:§ZGsº:¦tZô,S³\ f\rYÎ5çê\85+*C\95\925¿¨-ÍÌËÌ\1d¬\1dÌDÓ\1cÌ"Ìü"ç2¿¨|êÐ3¿¨¬üP΢!M­\17kÑvQQ1\87²Ôu¸&«94*C;ÔÛG¨F\7f\b\vÑFC$Â\9d=ôî\11î¹ô\16önô2)s2ï\ e\13\vïêSwu\97_hÍ-îU\9a÷hªNu\85Xj4Þ³V\rÕ½.¿¨û­ákͶÔlKugiVcVw\85§Î¹\1dNÝÖL     m?e+[\8d­\8cÊÌSd6%ËE\1d²ííhO\9e%×M{ýRîËöz[\16ÖTÒ  O:\97_¨û\91tïô\ fý¾\87~§¡Ú¡ôe\19ñ;ç³C\9bÌf¾ÕZ×éÌ4uÇhs'¦j\1dU\8eo4vVjÖØ´\ 1å***\88\17Ê]1x0¨\88È£\ 1\f-\b\v\930(\13\ 5ÇBQ¨,\90É\ 3\82ÂäÁÃ!y(,\11\10\a
+\92e¡<P\98°@D44<\1cV +È
+.WÃåp¸ L"\vå\ 1y\80`@\91<\1a\16\87ä¡(E)(\14\88¬ ²Â\95\82¬P\8ar\ 4§ \9bÀ\80@\0Y$< ¨\ 3\9c\r\1a R\16Ç\84²\0\r\184``A¹Ñh4ªÑh4\1aÚ¨FC\17\8dÈCÂ\88\88D4\1a\fÉD\12\99P\1a\1c\a\81<\1a\1a\1ah@\18\rÆ"y@*\ f\87c¡<X\1c\90\ 3\93ʤBaT \16Ê\ 4F\ 4\bÃ\1a(\ 59xP*\8c\88\1f\18\rT$Kdi0 \ f\10\ f\ 6\ e $H\88 ±@\16    \8bDÂpX\98°\80\1c,\1cøÁ\ 42qx LÊ\11\ f\a\832\f\ 6äá¨\92 aa\rX\16\8a\ 2\90Éd¡\1c\13\a\96\a\94¥\ 1W\1e\103ú+¨
+*¨,\11\87Ê\83Âp\ 5\15¸ü@ò\90 \18*\92Ç\ 4\ 2        \12\84Z4 \ 1DäÅ\ 1\8ex ±<@L¨8D\18\0e\ 2\994\16\ f$\8f\8aÃ\83\adi0\1a(\11Ǩ@H&\v\92E2y\90°\0\85\ 1\89h,\ f\10T\ fLp8*\vDCÃÄá°\ 2\12Æ\ 3\ 2"\82Q\80¢D@\1c< ,\f\1c\15\b \12¼°\b\13\aÃA\ 2È\ 2aQ \ 1\ 3\v\fâ1q\0¨4\18\94\ 6SP4,\f\12\80\98<D&\v\96<$\8fÆÃá\81A)ÀÒ DL$X\1e&\92Ç\ 4KCA`T\1a\ fD"$®@" \16\8a\ 3JD\ 5b\81<&\80phT\1e\15    &\92\86d\89`ÀB!À\ 2Ápp4´4$\v\ 1\12!\82\ 4    \13&8\0\80¨\1c\ fÇ£\1a0\1c\1e \v\1a0°@\0
+\85\b\10\ 1a@X\1c\93ÆC\92\80\ 4\14\bL\ eH\b@\81Àò0¡²8&\12'\ 4 @@²P\1c\90\87C\83A¡,H`©D8xP*\15ÆbqL$\90\88\84\ 3\14
+\8b\0C\ 3\14$\90\18\80"\81\ 4e©@\1e\ 4(\80\ 2\82D\1e¹×J\98\94\f\11ÅB\8e\98\84ªWté\8e\9a§ãÍ:kb¥ë¸c\8aªS@¶po4Q}µg\9aÕ¤Ú·Èx\8be\8c  !I, á\0\81¨Ó§*ª­Ô\8c\18&CíÚ\19b\92\8f\f\91\1f"\ 36b\8a\ 6?¢K\84«È3Ò\9b®ö¤K5t»Ó«Âèl«\9e\91%Ñ2ø¤\96\8a\1e3(@J\eR\f)(]K\97\89¤§IT5ô;ûÝmÞF³#zL§»»Û\80ÂpH¡¸\11-MDKG\96äS¼è\1f²Ê[\r%\1eðêaV\96\92Ýhb\96\rO6u\98\ f\v\14Ua@ pH\16H$ Ñ\90X@õ âÝ\92a\12Î}\b\ fÓ4T»Þò é\9e·ô¾·\88Õø<Úí÷\86y½}3 þ\88fãôeÚN§mÅ1ÖØþÙvÙ\98l\a\9a>¨´\95i\92Z*\b\0\0\0     ã\11\b\80@( \vGdRÁDÜ~\14\80\ 4brFÂP$\8e\84¡`P¨\f\81`\84\ 1\14P\0\18\ 2\80\ 1Ä@d\ 6Dn\a\15Ü\83\9e]OÿîO
+Ãy\906\83¦D\10I¼¶\89\ 5\ 1ô«-RùE®¬ðÁ\91£4í_^\e©DO¢    =ZÄ\86&\875@kn¦dÜ:¬\1eêé%6J¯?°ZÈÕueìÌ"F\rÿ©ë\18\8bé\11±®û\14tF_\8f\19ý\ få÷jU\81x\8eÛW\f=PÆ\9fº\9b.ofvÀm^qit\84úM$<»\18\ 6ÅH³øß\fÛÆ]j\Äl\Ä2·\9fÐ\8b¬SØ{~ýé« \18\15'Q¢*t¤_Ç´;ú¡¾\81\96V\81\8e=\1cløÍ(z\88}9\±N\ fDG¿ý-SrÏ\ 1`n .m&>ÜAj\93~,\89Á\92ÊÅ\ f¢\10\95(\997B\87qQÝ õK\9b      ®55\85\ 2V,\11Íü$r.w\1a¨án\89q®» 7 \1eNdð"\10Ô\e­?L8\9e\81kû;ÖIº\19U:\b\1d³ \ 1VÏã\1f\97ëî90+\94×\95\93ë\17Üi\1dÇà}\8aH\87ïί$)5̨\9c\1cWÝÐ\88òvxÊfiQ,DTY\90»\ eºçÔ0XlÕ@\ e½Ù¹\80æ\84ó7'TN\86î´¦ûrÉ\8flp:z¦³8vòVXÔÌOc¿Ñ¤]­·´$\90\12\ f3;`Ì\0\12\e¼
+H\1a     ã-'þéÎlr\v2cvK\8f³\aS\9d©;õ¨ \96\9eÈ3\90t\f\9c¾oºì®\f&ÝÞ;\97\eXüDb§A²\86õ^²B\87\ f\9b\ðaô\ 3Cäë\13Ûë\83\9e\9b\119\7\7fh\13\rµ\89.·8è\10Ý£\14\12]\19ÿ\1f\9d
+Æ9Q­C¦\1d\ f       Þ/+^ ¥¢\f\ 4\Ö÷j)x3ÄÑì±\7fó~\9bJ§»ÙJ\eи&\93¥\9aþX\1d4J¿\18bà]Bµ¹COºIR\1føBÄøû\1eø\1aÿAA§a\89\ f\f'«ge\ 2w\ 2ÁÇæ~RE\a\9dBo\ eø¨@\8c¸±"\16¯\ 3\ 6>\94å£\92APê\97u\8a\12\83\ 2A©g}Ap\b\19¡ ÏÇf\8b[)ßL¹d\80u\ e|wªÃ
+\r>\98\8bôÈYõÇ\9a%\8bÅ\9aK²sB0\e¥\7f2\ fC/¼bf\bó°{+¶ëjAý\f»\ 4\9e\1d=ÞUD¿ÝxX«C\1c?\1f\95\90\88ö»¹\81SÖ²\bûf¬R?b\14\9dêKl#\18\aR\95åâÎf\17bB\8anÃ^ò_ÖK\ 3K\17á\88Ô\14©|\91+V¸<\90óù%¯þ\16ä¥\98ü <Vk¿'\ 2=#¸­yYÕ­\14Òëºi'7<1ÿ£;-\8b³\11Mél\88\10\8bÑ禠      ý\13\91\1e\80¼\9d¿ü=)\1eçÊ\14|³X£Y0J\e,s\bô\87\ 2·8¶\92#\8b²$y\8c\9bæè\ 6\8cã\1f#\84\ f\8eüfpâAZA\16\9dDõMt±x w%«4¯4\0|C\v\aîW\ 6¶î¢\85\92\14¹ÿSwá8\91üàD$£\1e®lf6MÞ}9_]¤m;\v\ 2MßøÂñ\r¦\98ûB\ 5wè8yC0\fzv\f\14Â1\14uæÉðWc§\828ö%¤Ü ¿\0Âh<±Ø\95¾xUbe\12Ó]Â;B+«üj¯<ð°fÎ*S\ 3P\869²¦ÿÈÎvA\9e7ÚH\1fÛ\1fØ\9c¡Â¦\v\93\86M«X\ eG\8bëc\1c\8f\95 Ð`\90Ôå4ùÆÁBq\ 3,B\ 1   ´ß\14¦\8c \8a\ 4e\15S\19\18\ 2\v\97õ½Z
+Þlüpö\16ls¢i1Q¢ooY\81¹g\84\9bGÑûIô\94Oïê\95cZ\ f\97ÖC\16-£Ü_Â\8d\11¥\ 6ñ\8c¼ß){Eü¶Ä_\ 3DUääb\96K\99\9aß`¹\970L|\7frséQtGbV¿÷2û\90¤\9f§ôîÒ\19ÓK«Ò1G<ѬlÆ{\87\88w\eð­%D0\13¨xx\13\88P\999<\81çnÞ©\94F
+"Û!è©kô(f4«\15Xú¾w{E\94QuÅY¼¨\83\9a\83bjOb)Ë\8eîiòÉ\0ÄõÌLÐÞ´¦éª.Ã\15¼Ùx\9f\96¬}×¥<Ž\ 4!è^×\bº\87Á¨ó¢GY$é¿9åbè\87çã\ 6Ëê\96I\9a\8a\9b"\8bü:\18¬í¢èd®m¾Y\18\13\13¦S\7fjA~U\12ü\82\99\ f\99ã³w\11ÖÒ9É\1c|æ¦\8fo=\80;¨sä\9eQ|\80³¨\83\87\fÍ ÿ\85È\89\v\1cô&\99\9d\82ÐeÚËz\92\ 2\ 4Ú03-ö½\13 \8b*¿)ê]¢Otcx¿`2=oË\1f \1f£\8c\ 3KA¶+½ôï°D_bÉtú\1fÀ\7f\ 46*W\a\9a¹c\v´\ eu8]HcvB¨\9e¨SSE\8fg|\9d"\97Ý\ 3\1eþF\97LHA\8e©ËA%Mî^;\8f\99Yûü\11+\7f\8e\18v½©¥] {\11Í.2}¿äb¦HDÇ5\18\9d?+T\ e\88ö®Ë!\9eä»V\10ñs\9b
+´xnéäz\9fqY²ûÉú\86&\1dHñÁ\ 4¾\esÉQrC\ 2Öw7HÚi#gæ50\r\80\14\ 6n°f7í,\13´=³LÕx ¸\9dù_þ¥ã]Â+ûѼ\9d<#EYf÷Q\0,Ñ'˦\99\1dÿv3AÊòô\7f\1afd\1e©zp×\84N\e\91ßÌT¬ÚØ#\90³26\1cÆ:¿\ 6»Ê<¹\7f\89x@T6\91§\90·\7f¿\v\1f?§Jçä{\Z\86Ó\9f®\aÅ\ap\9b8%\13Eê¤Ïâ\9e@1;°Ã/WtÂ\19ñ§³\ fî\8eѼɳ\82\94=\86î/\11¨S´ú¡ôq÷\ea¬H\ f¤\8f \86i¶³TH'Wàþ\9cûb\b\88K\19\99\ 5+Z@ù½þÁ\r\1an\13ò\0\101ëUê¿ö\13 \rÇZºÛÜ\96è\ 3ûÕd\11ù\9a\1eVXC\f\8bû¡[Ä£\87Åûº2\85o\ 6í\9e5*UhtGzU\9cóf\94^\8cc\e\e"¨@4ªìSôÐC§\12\82È$LA\1d¼    s\e\ 2Ô¬­ËQ\11¢\0çß¶\87`6&Ò
+½KÇ\96ÞRè\94K¡ *¶áÎ\12ù̾?\11&w\91¿ñ\80\r\9f\90|auì \aBA\ 4¾Ó|þ¼¤×\0Ðeq~ä4\ 5X\9f[ñÏ0±\10dG\89g\94£àì\85\b\r\81ìgÄÊgÐM¦;cÐQ;§Wþú-<ñ2á\99Q3\81\13\eãC/5\0 \8a\8a¢\10¬q£KÑÂ\ e\9bw\89\91%[\ 1|\ 1\ eêáä®øÌ¹)z\8a}0¼2{x\93î­¨KEðǰTß\17¤°Íð\7fV÷ø\90~4Gï7ôco7VP\8cºØô\91\99'\Ù\89A6Æ^~úÉQëæÀ\88\8b9i5\82pH\92µ R\16\8f\9c\97f\b%¡-0¥\rJ ýp\8e\13Ìþ\90¼$\7fÞ\9c\83Ùÿ¡Xás\ 1ñ\8d\bºæ)8\0\9eº\ 5LIÇÞ\98\9ce\ 5p^£\9c\8aQ\8cï¡\88îáÛh\94ߨÙý'Ðâ¥Ä GXèä[ªä\}f\89kù÷DLß_\8dJÔ¨«\81PúÎÖîêeÇu\94àÂK\9ct@\0Øû\8b\\9dÖ¥(\99;FÕÝ®BÑþ\81T\12áMÙ¾µÆ»à3æ¦\9a²\8f\8c¦×&W&j?©4\18,YÑ\8bZeoöÀ wÞ\11\7fFÒýmÍèÂÃÄT\1e!¸b\12üX#}6*_\18{î¡\81QOÃà\99y\86\86\96Æ\99FPµîÌ\85Ýyc -\ 6]4\9fw¢ú |\80Xä¼\7f¯\ 3mäÑ\8cC\9be&;ÐòñSÇÏ\0ÂÜ,¨óNZ³Ý¾\85\ 3TÊ7>Íâ\9b{X\bò\97\1a)"\98ëØ\eð$ýÅ\10OeqX\bÈ-\16?LlùTBÐDNw¥H\rõ\e-zwL¹Î5\vW\1e\99ë]`"k[ÿ\91©N\9e.PW6V\96\84Ù\9c*Â:©\83e\95\92õ²Jxãm\97\ 5Ä\ f\a¢&MN*áªàúKQ2Ì\ e­Yë\8f\90<z&\13A\1a\9e¹t¦ûà3gf4KuP]\1fæ\8eU¨Ýõ\1a¹lÊ\ f\89j2k^wD\ e\88 sìuø\14ê¯VU\8e\9d\99¿+\8d\1dD77LfÉAàß»\89ªDbqSεÂ\8a\rÜ\e6Û®'*zÊ\89\8e\1e»epýÁ.\9d\19æ5õâ¡7\96\89\85¬åT\86:JâåüýÀT\97´\84¾¢N¬0x\9eq\8c\93e\83`m$Õoäd\9bÈ*Æ+Ê^\8a\91vÞÓ@\83ò%\v\93ÔÆ¥c\bÛ\9c6Éãð\aXz&{Zz¨k\7fçyÂkå©è\19røaÝAûqx`pÀ\9aðL\7f\14\9cúfÞxRãþ|\1c%\aÃß\7fÊ­õ¦ë;Y\86\94Ï2Õ\13\91èu\19A\0#\ÿ\9cëBº<WÞ\9c\82\1erÑ®,ñJq.1µ8\8aæ¤ó'^Èá\ 2p\8a\18\0\1fÈ\92¤ø\1fÓîUÏ\13\ f\9b$\ f÷\11Þ®Ó®7r|ú\93êMoñ   ½AF$\92à\90è0äLâälF\7f\13\1dr\1c\84Utq\9b=#óý#ç\ 5àk\1f¨qZ¹5HÃÙêò;ëAV±åú\19³\10ã\97º÷ßj-Íí\9e\92«!81Öè¶Z\1aÄ¡XtúåÙ\83°ö\94ð0ÄÉU\1a\ 4Q\11@\1f\12\1c\9d\83¸©öçâ|òë ûqÿ/ \18vÓ}õï\8d²u¿¯:>\12N#|ɲª\ 3î\f\189á       û\12\8fþ08Ø< cÈ¢íìÖj\bÅ\98\ 3:Qw@Y¨oGu¯Í¸mº\89Ã\ 5^,4\13\8ffCXCV<?ÂEÄ\99¡$hP¦þtI¦\1a0p² Å«S|Í\92\ 4ìÛ        BÇ\90Ðe$?ó\ 3ü\8f:·Õ)`Ü\bæ4¼(0]¼U<a2,?\86\\ fð\9a\13Ä\19\9dÇ^;Ç\11\86«\rðt\eÎï}n¼{ÎC\ 6|\1e\9f\192B\98Þ}\85='\90±ÞD9%´\98ã\ 4þTì¯\\ 6^@Çð\1e\17\ 6\84ËÃS=¿ÞS\8b\14\ 3\96v¹k\f\9a#·xI\12ÇIÒ¸5    ÊA\a'Ïg!T4¤ðs>ªÊ<Ø\85\80"\ 3>\ 4º4;\1cYÖ¯\ e:'\13\95*½ð¤g2\8dÞ\97d7ÿO\0\95\13\95¥1AÐ]9¨\by\r\14²t¨;§x
+\8a9A\8f\8e\83W0\94«Û\18Â;\r7\7fºnßÍè¡\b\82#J~µÍ\10­y°<Ë:M\ 2î·9i\96K\88\rð\bBU\13À\7f-ÄÆÝªçëê\b\1a!Üiº.ÊÍär|\91];ÀC\1d\1c
+\84ð\9bû\1fRX¢û\1fë2F§\88\99A"UBeäê\14%­`«P\12\87\ 2Wrºôà<S\85\1e(`\v\9a\83\171\9aí\8e\8cϧÐG¢æÕ­\ 3{¥J\ 4Ü'\ f£¾9\11\81FÉD\80\1c\9cË\v\81ï\8b\1e\ 3\98µ}QZ\ 2))\94þ\7f\17ûÝÍ\ 4\aÙ\88§\18¦\1cå\15\93ë\ 1%\ 6®òó \81\v`\87°\83ÂS\e3A0'fsì\\9fè\90ÅË"\935\91íR\9f.Ìï¡éqÿè\87ýï!ßÀI¬ìõ\1eª\90õ7IZ6]\96+8\1d¥1\ e\\9d)\86Ø«\1fV\85Ýø´\84ÌH2j\89}\96\8fûiÔ\0)8ëó[l\84»\89È\8f¸J¼/\86
+9f,Þø\rëM\83cbLt}}º·i\1e\99\10d\84$ÿ
+ß,\ez6Ës7       'Ñ·mT\1f{\11\'\rÙÆkeÝX\ 11Á®¶á\1d\14ÌÕn4Ø\ f%\95¾´Ôn½n\1f}È@Qû\ 2°ÑT×6\9b0°Ò\8aº¢à\10ãú\0+[\9ex\1d"¥À}Á©è\13\10\988ÿêýx\f˾\19þ`R[åkÀpV\1c¢E\86\1a\ 2\ e­\fJ\ e9\eG¬ú«\rÍéH£-\1aà\ 5$ß@zG"XÔ_\86Nßq7\96!"cäìFRÏ\9e¼m*º³\b\83\8d\82\14°ÂتÝ)Q²0"õ"æÅ\1aX|/¯\92èS\17·ðrüh\JF(\14\96on\0\7fÖòh\ e\ 1\1d#>B\fI\1d5\90ÚL\80\8d½§\ 1U\ eYºÅ%Ëáx$j\9cì\94¡Û\18gcã­¦2ò¥Ê\12¨\1e\81\1eã\9b\83b#mi\9fwg\10÷\18\89P0',£«å¬:cÇ\1a\19ì4\ fñL[\9a1Z=Å\1eÏÓj_\1c9ÌL\18ζÆzm¤ó$à\1f¼\96»È\eª_¥ÕzrÀ\12' y8©\86\18\ f\ 5\bÉ5\97ôõð¸é_ÉÂ\1d»,ÝÈ®¦ökO³\123ØNà\10\1e\aH\ 1\94]\8af\fn\94Ïc·\13(g\90ã¸b!¼<Á=\92 º¨\ e'Oº¾ãß\ 6\15{ê°Êå¦5\9e\96!\8a\ 5ó-\85Ùob8nH;Þ­7À\97¿\17 \93\ 5\e \13¨·$,\ f\84\
+\v\97³\999\10\vÅÿîÿ2CU×äñ_ºî\80\82\94¤ ®à!Üì¼¶\1cÍ.L\ f\9ff\85îzíÿ\96\14¬LT<­&\ f7I\82ñ[i·vòe\12£ô\7f\1e\9b\914ãuή÷fíF®\12ÕÂ8`¸.¯ÅuY6¥@\f~²c\826è{¡\89®Á×è\7f6)n\13\92\8cÈ\9fï7C¶?ô\86Æ!\8bí×\81&1Æ\9aB[\99X\86\8b\10\12\r\84\8e?9$\87rÂtÍ=et\8bcÕiõ\12Ë{$¶mGQ³Ë\ e°\91 \ föNî`Uf\89\8eµDËkN\0\\ eÚ^i\b\15^éè\93C Lþ¹­\ f\ 6Q\98\eðø
+AË\0P\92üAd\ 6AÞ±\0ïrŷij)\86%\f`¹(wsW\ 3Çn\ 5\84\b­¼ºz\9f\85&8ó:Í@ü²\ 4²´\80;b\9f\98{­üeÿ:A\87Ïv+\1e\ e+¬"¾t\8d\8bÆ1ô\18\19y>m´=\88\9a\16@\0\15î\ eÏ8kÿI\19Äñð*\9amÙ$ñ\15\93ä¿Æð$\10ë$\8d\18ëô$\8e\ 1\98
+5\81\80LO½s¿=\11¥\9e$\0¿V»ñ\8f=Ãø\ eê\15.¼4âT\ 1\99Ûx!ò\11\13úQGþZpº÷º¥Q7\ 1µ)\18\föî8\9cÏÞ»<Hgy\1cA\98\ 6\19\ 4Ù¢I\9d\10*\ 1\87øUáÏ#Ð\90a\95Iq\862Cäe+» Hë¦Ðx\ 2©¤>c¤$o\93ª\r(3ê\b&\99\9c\133*m\ f|ô>¢^ó¹_ñÈW>"T\19Ä»\10ZGÚ\90)Z\14mB\19\1f (\v\98#3üÙî½õ$\8a1^Aî¡]#\b¨\r\93tüå=hdPp#8[\80\99\83\0¤\14 f\ e/$¶»>Ì-=
+Üf¡C¦¯Q\894F³\«õõ'2\97òñ´\88ò¾.\13\11\b¤Ü\7f ý\8bSRÊk\ZµÛR\ 5¥ÌyÇ#b\8fL\ 1\8bqt­ñ³ý \15gj<¶
+³p\18\87\ 4g$¿ÛD\86H¤Æ\92ÖV5\87W`\11n\82öx\18X³¡\84\ 2}\ eR\99ÄϪÁ\ f\90\80B&\7f\82\ e\8dD»À>\8bV\a_\12\8dþÆ\99y' ò@MÙ[Âëðih·É\15§\93Ú\16zÊ0\90ÿºú15©\ 3TáÚ{\a\8aä90\ 5ݨ\157gS.Mâ3\98Ö;\80\fÄ¡P\ 1\12Þ\ e\ 4JÙ1ø¼§G,\1c\9e:Cña\8f7Ü 1\9c:ó¬        Ô\7f\8an    Ò©ËY$öâ#ìÌ&ð¤\8dhº^¢ÜÖ¦N\9ctsöã÷    Þê\k\96\88Ö_)\9d\87\82\93u\11G\843\880K\ 2ä=\ 6\9a\15\ 5·hU#°ßùér-nÍãYÑ\9d\82aå{?êN>êÛb\8eË\12\1f«"^À\ 5\9eÄ85\ 3\ 5Æ'¹\80\ 4\ 6~¥´\8aj\90\81r_g\1c.\ 1\bÓ@KÚ®Ù\95\1cµº)¨Õ\9b1/,)5$Ù'r\1d\8e¾Ü\88 *IKÈp\84pqê\96}sÑp?M\101e#ºh5é÷pjÁ \7f'¥Æ-Bõ\1fiÕM?·$ÉÁV­µ/ab@âLµ*äu·\9a\175ídB» c\88²§;]¿¡SV_²Â\13¥ë\97e©i\99\93Q.}³ë\13Øç\80\89N-·ø~Ir3s\9c§\8c\9b\94\80«Ë\81ÉÜ$`]/\86Úzü\9f\1c\ 5̰lÑI\8fwFH$\8eE&¥\ 6\96ÌF\1dá\ 1\9aÙOü;^ôY¾a2,Ø\1a
+©æäÿi¸øéY©T¨_xα,Þ,ãÚø\ 3Cê46\95\16k°/²°LÄy£\r+!Ï~j§¦rE\8cy\8bÆõXÓ\1dÂ?ó
+)\8b\81\18×EÀ\0<\97\b\1d\ f\99F\17ND¥|ÜúÐ1\a«e\8aïÃÂ(Ês\8c)%\vêìIg©\9b¼\ 1ý ³\11u\12«v\82¿\12FÜ9;vÙ@\12u_w³-Qºv'\86_¶»- R/\84ú%Ð
+êð ÎÄ\9c¶)\9a\9c¡\9apZéܶQ\0\ 5â47¡a!SäQQ»¢\1cü)\14\12]áwþé¥0é[åMåâÁ®¬W-øÿ\8ay·4\ eþ#\12ùgãC\0æqdȲ\19ä³m©µH¿à-\ 3ÑÑ·nïVÕ0ÿ9\13±Ø\90]¶*üÐ5Ãyòó3RÉ2)a'\9dÀBð1«6\93ÌÌò'\etvhÐ\90$\89_Ës\93j"÷r°aÐ;\92éÊ\128ü)Ú\80j\81Ê\1e\89\ 5Y0$Ä\9bZ%ìFæ\19r\1a0¹ÆO\eøái Nzb­÷.H\99Z\ 5^.\8a\83\7f±\842s¤¿Î\87\ f×\ f\9d¥\99«ËòGçO\82íc6
+\16è\v\ fïçÈL4 ¶\93+i\12÷©\ 4`\8f½õ ¦\ 33A\9a1Õþ!sѧi\ 4úW\98%´Ö\16C\9a\99`µ-.\ 39\9b\ 1VYJõ\ 2f×*ï>\16\\ 5Ä\8d\93M       úQäÅqè\86ð\9a       ¤ÿ\14Þ{¡µ\94x\12:]*%\f¼ ù|q¦\1c£\81\94ñ¬Æa\ e~\ 1\14\14Y\15\r^  l6\90¢8 ¸&_®kU6>+©\86ÝÐÜ\8d¢\18\1eóJÉk\0ÍIª¾\f\97².\97¥\90!Ô?\8a\eð\aĤ¤^=-ã  Ã\ 6Õ a¹M=H       ­\86uD\8dL}®ªÈª¤ï~\12ËUÆ,£²N\vÃ\8ah\ 2¦ïíàÙäî\8d\11íÚñµò¼vò\8dø¦gpË{¿Ì@Ú\1d»a§\12\a\1dPÉ÷H \9eÚ\85]\8d.#\99®5¼ÄÛÊ_\95È© õ5\98\89ãqø<\ eë¥.\85á5aÀ©\168\87^"Ë-\81^\94¥~¡\8d¹Ãéw>À\9f\8c*x2\18\10~\85\ f\8fµ\98¶OfO÷wOI\8eÉ\9f(zD¾{r\82&Aö\ e%Óø]{+@´þÈ^\ 5ÕÃL\b\90òAÁhh/©-\89\8f\0f+ت<¥qøPNä\9e\Hñì\ 3Ðm&s0J\87à\0\ f
+\1a\ 3·b·`bê\81\87\1e\8e\84\94\a\8f¦)#xàMâüWr%q'\ 5a\ 5`Á»\8as¿'\8eChd\19®aeíï\9bîþv]aéÃ\8an¯²H¸`íÍTR\10ô=XM´{Á¶\85r×¶\1dd?,\92úê\1dfÊ9^c\88µ\9cx0lM\1d\9dø£²µ\1f\8a:\17U%\9a©\v\9e\bcúÁû´xÈB¸B6Ý%<¿\81Ùv%ûðI&\9di ß\15-\12\13\ 1{ÑÖZ#íx\89\96\81Âæ.m[eƤMf>jù\9b\8dØYðLÙï\a¿\81b9)Ò\8b¾û-\96¡\9a\8c   \14M\98\86¸x\0p°ÝrÔ\88   ÙÌ´¾ \8có¹\933Ý+¢d_"ï"=(W¨B\ 1#Ô©hD´;â \fKp\ 3Ã\86Üý@´´º¾\84Lr\0¤ç0\16,s\8bT\9c\85\b³çÆ{\8fç0\91\93VÃ8\16X¾1D\8cc\14®\86¢rC¿3\12\%¾PãD\8fxÆ+Ò¶\1fOY\87RUP    \97\95ÝÏó\94dÏx"»IX3-\17­\ eÙ\93ôÞôù=3\81`\1a\10W\ 5%áÒ $â.\91|\87\9eA3\1a0þD\89GHí\90\80\ 3h\rÄ÷i\81\1a#k±bn\ç©Ú¶\8diAÅ\ 2Úê¹f\15\9f\89ýö\0\a\ 5'jÅ\ 5ÅõÅ@sp¡7ºÃ\10Bdw\8d¹r?þ\93ïKäp&9Ù\94Ü¡\82\b^¹ÃW'\8c\8eAké\82ùþô\18¥º\V¾Zl6>ñôT,uM,\1dÍø\88êbzãÆ\ 6oR\8ab\1fU!\96\98[\12\14·\1e7e¡\8dVúõ)T\97\04ãöWÚ\85`ÅsôÙ'\9e \9fNâA\9e\89\ fÊÁ\87\16\fß{YÔ        Çbø\9aHlBÄþ%\14&§¥~Ã\NÝOør\9c1ì`\9f\95­$\84B¿IôoXI\90à©õb{¡\14÷ú÷\rpºHM®HÅ8\U\97\92)#»*\123"´Å\9c·\8a\96\93c}\ 1\85IP\98t¡ì¸¡\ 4\9a\ 4E'ÐY¶ë9×>\ 1Éì\ 4a¿JGy\9cä\1dõ»#Ú\96ä*»\9bX7Ï¿Ä\9e\ 5\14Þ7äj|/wòÛ\83[Ãê\12\92tÿ\85\94#³Î\\99\ fDÃ(=\18Î,ÙÔC-g¼éÉ®\1cÎ
+dÊ3ë|VE\11\rM\9b\10\rw¼Ö<Z\96\9e¥*\ 4Léj1Ö
+)P[?1\10k;ú\8b§¶\84B¾)ϬF31Ïpå\98\ 3ÖkÞ9[\9fb<QuÎLþO£\1föD>~ b\0±V\14~\AI\9cÛ/9\83î:Î\91í\10¾0ì!v\15/"õ#fz\7fz×å±Ú­O¥\ 3\14\ 1\1aPto+¾K\12W=WD°)\85\f7\90/£Á|wØ"=ìL\9b¾\8e!\80³\86\86¥Â'\86äÔ\85´T[6¡ÚðßKßÎ+b\eE¥-­KÞ)5ßw$b:7\8f#\8dé#O¥ý^ÍÉ\ e¯,-{ãe¢\8569\12\88Ûâ¸P(y\96É=­¨Å\80\9b/\8d\81ô\8cúÅjÁ\9c[\r\96\8bû5\19\9b\80\10:\9b\94wvqè\a\95"\8b÷ø"×e\9e>öxð½\98\92+\rLBÓ\8e"húk+\94±è\17\19¹à¹\11ZÁ#¾>\13}Ë«´k\94ö¤T»È\85ò\82>\94\91\93Ê£m\1f³\1c\10½ì\88g\1e\95\eØ-\1c\8fB3NÛ"ݾZ\v}Ìצ0 Ù=\90ÄÒ;ïæ[Ýa\90/ùdÇs±Õ\1dÜ!qñ\82ÎWògÜ#\9a\87G*zÙó³Ó¹ãL\94¾)6Y}\94*dµ\94YÄé[¼ÁØ»9û-û\1dÞ¯5AF\ 4¥\ 1\194G¯qË^XK\87Î\rÂ\80Àjì ;Ða\ 5¶1H0Ö\89áÝÍ9¤R|Ot\89\r\84\8f\vÊè\ 3\8cvÆK¼¹FïcÞ©\9b©ó\15\8d\8eàGjº`Ñf ê\89\ fn\a\9eQ\99ü\1a\16\ f¾=àj[&?%\1e\ fÃÑF,å\8aI;·®¡F°ð.åî+\83\18xEÈ\1e!´C\12\0kd^A3Ä\99Q&E\91Kþ'ýËÜù>tÎ\ e¸X©r\88y>\9cÓ+TÆê\82oK(Éx®ÄÉZ%.7âºÀ¹Y|ô6\86Üç©z\84\82(>áè'\92\80J\84oëUBõÇejG×
+3\80\82íôDûñ¯\7f\89ì¦çø\8cØÓ±\11\eióÅbce\17\1e¢:0¾\f,;(N\vdòGÂ\{\rKÄìl\r_\8d*óÿèÆvÀw,/e\8b\aéÀ¨\190\1a}\8bâYqÜ^ËÔÍ\18?´#qÅî|$\ e®u\18,ýb\19\17ÐÅd\8d\9e\85L­æg:\8dÌl\84AD©7ëc`ÜB¼g\92ʽuÐ[ã¸\ 2d\ 6·V\9b\1d$_&"\17ý\ 5';6I" \92²¥\13IJ^\93ö\87Í,sH<\eÕ\0\ eÀoÔÿ\9d\ 4\1e\v      %?¨HIôc"Æ*ªô°N-Î\89\ 1°D\8fÅ_\ 5çO,\96\95\90ÉJ&Ii·rfi(ÏÚÀGÙ¾iy\eC\eÇ\18·Æ\9b\ 1z\1ax\8cO¢©\98\f¨éDäóÏcE´{f°#U¸%}\93\1e¯\1fÀt\1c×i+xd\921\17y\ 3­ïÏà\98©\14\88 ±Ð\18\1d±À\11ì×\8d\8cJ|-A\rÏè\81­A\87È×rêYÏ\9fâË_¡\98(YÖ\13f|qÕ\9c'c\9e\18ùÄ+n¨\r²
+\96HðlÅhWm\ 2§ë8\aéÍÒ9ü4ÕÐ\13d-k¢Ü\81\0\86¬\8b\8f\ 1¤+\91ó\81\9a/\7fù`\7f\ fv­äÄ.ÿúSA"a\7f+«¹ýµH6ì¢\8a¾\9eê\8b¾­¤¶\ 6\88på®ñ\10wtXM,\8f\8at:\86<³"\14¬÷à\ 1X;l¤%~\a\81½\ 3)\16­töî×\8aÌ1\15(ÕGC8ñ}Ó\ 2|Q\15»G\19ÆWU\7f%FßV\86D\1e½-ZÜ\85\17+\14X\88\99< hí®\8eT±ö*5Þ7x;\89Æðåîb¦Ø#\ 5\15$j\15>D3À\vÛaD¥Zd\9b\8c3² 8n-ÛZ\18s{îíW\93c\9f\16²ØÊ°è\8a\ 1©Õ8z
+(?Ä\83\82\8b\ 1\bdf5±\8fE0¡\ 52D¼ã¸kcKâñ®¤uà\e\ 5\v ß>Âs °\8a\93\8fæ\e¬ÿ)Äæ¦\9cKÂGPôߥ\83Q26\85ÒÔ\8e\81Ë"\85%4³¼\8c?\82\b\12¶l3=¢\v×\r¦¶·óh\ e\a<= \198EBÇ'øgÀ>CØ\18]Ö[à+å\14\8d5{ìû-ð3\12\9b\ 5\86\14xl3väh¢1\12hlö\8f\0\ 1@¿w t°%:úF\98|l6L\9eº\8e@©2®#ñUg\82ÿ\98µîÈ·Î\bê/×ßû\7fq#yÀ\87qàñ ØÂF¥¸J\vð|Π¯\17ÝæÁ¯\98Ç/\11*ïiâ^\ 1\9e7Om\90#ÚaÔ\8eo\87â5\918\e\b\80»ITC\8b\12\9aOê!ò]\ e[y\869\bÛ.¨Ç\19Èȱ\10ì\9e\ 4ËpÞeÛâW6ÝV1\87\8d\ 2k\10\87¶Vû<ªvX\bl2§@v3v\0I\83Ñ\8aÝ\83ê3!s\1eï¼"´/\ 6\88¤=÷ý\83öh\87%àOz®ñNq1n\ 6g\8b$ 5\13ÿþ|¹#É7Â\b\eUþ¥5\9aósû\94÷»YæÇ\88ò. ã\9a2ÐD5\9f\ ey0¾¸Í#Nª\9a$½ÚÄ\83\88ý\8a\1ariÄêè\99\96é\ ef\81Xëãzkû$qì[8\8e®Uþ\9e ï\1c\80Æ}%¾ÙÎ|Îá- mWgPP9¹\17T^7N81£Föy´¹jÿÞg'\14\93øÀ\93,\99\15\1ceCÊ7'X¥7½NRÕ}\97\7f ¸áP\82!Û'aRByh(mk.Ïú\97´h©é­R"¦\96¢\15\1cîÈÏs\f\ 5'\91ÿ\ 3 ^°Uè0Ù$\98\80#\1az:\15\9c\11ç\91\80#¢¯ïX70\16\91\vw\ 3\916\12ð   \9c´znÖîÍhÓ\14ÚÈ?\bµ\82ºº\9c\86\91\8bÏ\81\ 2 Â\10\18¶.ʾ^\8dÆÄY\ 6Â\82`íñ5Ã]c\913×y¸Ú$>}#îKL¯$ÎO<·s\12\rä\0\ 5Ãü´ßT]QX&ér¢ù;\11'*\95ë\1cÌM¨Ü\O\18tÐB¸+Ü7\8ec\92ìúCýÄ%sO\94¾N\88\bÌ\90î«{vX|\ 5\9er*\82%\12Ý.\ edl\1cI¤Æ\97­U\15(QV\1eÎ\·\9cÈkÄ®då\95DM\93\9c\9a¾pä«Þ¢\85åö\19ÿZKGº¸ºq\12~<D\9fpÓÓA\8bóFì\89Q¹Ïe\ fyÉe§;Îýü\ 3\9b\98\esZ\88H.M\ 6\9cÿø#/ñîÔ}s\14\11c´ET\91\7f4zó\¦A¡xUW5Ò÷ÔÏØ"\9bñ\bYñQc"fCê>\18»Òã7Î\116,¹Sg\ 1çO°â\15ÓS7Ó\r\ 6\87èU1­æ\ 5¡\15BlB\1f\8d\ 3\95O^x\856´;áÉ¡àÐñ\bcò¶\88WPÐ\8bÖ\81UP}f\0\r\84è\82\87Ûq\ 4§\9cLoð}\ fW\1cñ\r\ 1[\0e1|\83\1a×»\ 4\80ãO/Ä\bY(¤\93Æ5úav¬ÓA0jò\9c\17æ/¤U\eÙ¿CÝ\89'\1cãzZ\v®I{\8aªÏL\15\89Ìb\96¯lÆ\9c{\ 1ÿÌØYüØø©g\9a0\ 3¿¥h\ 4¦\12;ó1~%ú"Z]Þ\84²\ e+º?³ÜÎuþI8iñ\82\9f\80z\1c\930ÄsË-TÈúØ´\15\ 6¶p\1c\r    Ü ×eº\8c¤ùn ½\ 6ï9ºÃËÊ\18æ\ 5ø)\7fM W;mBßæ\9b\ 3WL0®hE%Lè\ fï\8bdônïBÁ\9e\8bK\f\aè`\84ÎIx|ùp      NÇ\88E\8fFS¦¹ìHh\808.\97Á"o\91\17VW3\ 6Ãaά¶®ÈáôK\82õ\8c½ío\1eÒe'\15ð¾N94F.@\9c\87\8b\18'\ 1¨\87ã¬\12\82[9§Yúßså\ 5\1dÊ\91²3ÌX«\v(åjsê¿\92ߨ.ýð{Åúqî\rΣb\15¡iâÄDyK4 Õÿô`\ 2ª\0z4Òe®\97é3&\ 6\81²±å0§\ 5O\1a1ñã    ø Ìqéu\aàªbÿ
+):\ 4wÞù«_vAêØÈu6\1a\v\17´<\ 5\8eݲCÄNÇxû·¢\12Ø!ý\15ÓfËkllB\0Á\10ÖG\87Éë\rê \88Â#±¥1\16Å®Y|\15\83Ï]ðs,$ç¯D¡3\6\88å!$\9cȪ\ 2\8dïÜ×\rä\ 4âv`S\94\12ùgdûÉ\84Ö#\f®>\90¦«\87%êìÎÐ)é\93Û%\9b\14ÙzÞÓm\e\7fPݾà\8d\15x0
+"/ÿe\94¢\8c6Vu\ fßßÇFj\15Ó=\1e¢j³,Yó\94 \18\f\91\9aÒ`Ê\ 1Ú\18\1aì\b\aÅ\e_½ø0@37òùºH\\85Ó:\18\9d[h\ e°\18\1eü¾Þ¹þîý£G¨¸xÂUH¦k\9dó\1eK       f\88E)|%\94LR!ú\90fSaD=Çn\10©A\86Eê¢L«¯§Ày¡Û\12?
+ÍGYÆc\87<¹ûW\ 4í²«:µCù\1eHw¦\1fÛo\1a%H\9f\87\9cïênÏ¿cËp\$4Ñͺv@,\9d\8d\923«ê\82V\ 3R\8b\88[íJÀ¾}×Õbå*rÅ\80\9a\82\88"eg4¢½Ðd\1e¤áY+ãûÇ  Ädôrå3¢¾àÎU÷(\eæð\9dP±°8Dø¦ÊÂ\84øL   ë"Ý-w]Å\98H×X\19È\8d\8ep'}C04o\1cW|Õ,\81U\8b\88¼õR\1e~'¨Æ\\8bØ\1dS\99G[bLÍ \v\93MKpò       \91:ÀÍ    a\e\17¡\8b+u¬Rc\8d\ fF\9dµ \8e\ 4
+p\eÌßQ\96©LµÌ°_i(\aà\võx@è\97eºrs\11¬Û\bpOAl=qhß
+Àí\rêv×on\90\12K\8c½ Ü\8e\11¬4\9c0\fõoh6¾rÑ©Tm\1dô'\80CZ¦\ 5u|v\ 6\8d\12\94I\ 6øóC\1eÊ\93ÿW²ã\8d\1c\ f\12ã0\13åMÈ»À\82`˳²Lð\8aþT½Z«Err`\16yV\18}xeH¥âh¬\13)\aÃ\ eù\ e\9bË[`Zº\1a\9d\ 3\83bC\8f Ç\ 64®²,        ï\ 50,n­¯\94\19W
+)`ö\ 3þ\97\8c¼e\b\84ÆúÓ×\18\8bÖX{\97\86\1eÊY£LΨÌ\aDr©±7?ÎSnàX<\14ZwÆ\9a\82\85\*\86\ ev\ fö \ e\8eR°ª\8eY`Ò«\ f\fDO\8c«mµ\84n\fÇ\15àà\88¯ï#Ù×c\ÿ `«<¹Ó\85\87Ù´OäÌϺJ/\9fJ¶0§]g¾{ÑèÇ\9c*@Ƽa\8c¸Â%¤M¢ÖfHÇY\1cåaÜïi\ 5\94J1k°Z]3þ\86\1e¼\8f[\19;8\86ó\84v¶µ\8bÁ4WÐ\8dW\aáºÝî/ê¤/\e\ 5\8cË"d\92 ·Éϳ8$Ø\b0ÃZÙ`\v\1a1ÿÂ\1aÒ´\148ïÊûymÕcHO\ 6¿q\83pªìmÑR\ f¡\8b\96®\ e\95)4\85\r/1+h|#M6O\810\14ìu\1e}g,øzÌÜÉY\7fa]=JèÕ\7fy\98\85\ 4çú¬E\952¤ô)Çq(9\ 4ê\7f¸¾¹æÀGì
+\90;\8e:!\9f%J:\81\ 3ø\fqe\8c\ 1h×F¿\8b³æóùo@\ 3åvBl X\83)\ e⿪Ë\b\9bÄV\87¥\1eX\ 6®NCέ&K0K\fX,±Å\12\ 3
+\95û~\19\12êO\9b\96v²Ì\18\80&©qN\91V8¶KÐ\89Ów3Çäp$5\12óëÄÆ\94_¨ÒófÙpw©G˨ØÐ\9a\ f6d\8e|[ä\ 1ë:\16\rê\1f\9f\12Z,'þ¤\1d\84åñÝ\8e\19~ÍøqbKó\9bË\1c\142\1aúÛqX\ eÕrWc¡\9büG \8fJBc\9fC\9d@º"\ f 
+\rÆ¿ÉWOð\7fd¶3Ó\b¸Ñ7fJ\85\87¿\93aXY\8b£/\ 3³ã¥\ 4¯+\19v\90\ 1\ e\11ägG]×ÁE\89\9f@\e:3dªÌ-¾ä\92\8a[\18\98xG\86_[G\7fCµRÀØ2E¹ ò\90³\89¿¼´³ðßSÁ\97ØËl\1fz\89Ô©(\98Ü~\83¯vª¬P\86\8a\8eðYøI\96~
+\f\ 6,\1elÒp~d\16\ 4\ 6Í\8f´\14izËC\8eR\ 4ft;\fÎ\v\0\vâ=\17
+ΤL\85¡Ô¯,íÿæý\v#\11j@âÂ[O\16²z×ï«X\ 6\83B¸Z0çx/Døî²Ï¢ïã\1d\9e\9cA\14T@ð\ 5\a\ e\16ò>G`2ÑÆô¹"©äZÅ\8f\7f\1d|Ûy\11Õôò«â\88A\86×\9de!`g,`\12,þó\83Z\ 3\9f\ 3V\8bO\1aÎ\v®ÔÝÀxUj\a7\ew\15ÁR\9b!ÏÏÊ<(
\bZ¼Í\87\91C¨Ê\9fúÌ\1fÇ ;Y±ªüèÓÊÛß3È'|çh\840G\95\91Z|=0BßÂ\7fØ\9fR2TøòëVC]Ó§C\14VZÖÁô\17\80'\b\ 2\10§¤
+Ú4$Çóå\06\a\7fçBFH\rÆqð\86§P> ÌÈ\83i\f   \9ecʲ\84ö+$\ 6\10ôQHh¾|æ\9cF\arZ\13M4ry¥£HJ¶\ fz\87\ 6Q\f¯²i<ì\a\88¿bZë\87lUЧñìf\ 4È{q\9e\98Y\92ú\80¤º\98«{\89\9bö23pÛ¿G\9bï6Hë§å\85Õ§o0¯â\8e$S\18\b*½­¢\ eÕé"TÝN\15íg±6\9aÌ2qUò\8d\17õC >\80­©\18Ø\9d Kn¹\e\90~Wâ\91êkÇM\17\0)\97\89ü \9e¯èesq\11DiuCØ6vâ@\9c \9aÙø\96Ü?ðW\8ab\8d\ f\84mJkIvrnä\10×\8c7\89\11ªa\1c\e\9cn\85Ã;\12²«À*$.¾F¾U\96ÄG\1dü{£¼¥Çóá\82ô~Dê\11\11¯\10\83\10r\b\19ÉÏ\1dC'ú8Ù\1e\84ý¿'§\86t-r\10(²Óáò\8d\ enkú\1cq»WÇrt\ 2eÓ×´´1µT\ e£ìLëøe\14\9eó>\97\´Ï\81OtÇ\9c\88PlýØHÝ\84i\84q|îá\84½kÓк§Û\1f\13©2ù\87\ 3ª\9f\bfóÁ_ MÝ_ûNI¯\834\få­zÏíÖÆØ\8c\8a]\07¡?\eêØ_bôä~é\pN#Ð\ 25ò©ÎÿJä\8dgt Ì¸\12ñ>ÐSó õÌÖ\8b4V      Ï\96k¿) \1aÒ
+ئ1ä¿G¸þ¤«\89eøcô#}¶\15\85àE\1fµ%(f\85\81ï½Ô\eí$3+©Âhü\1a\8eÃ^ø\9b\10:\9aþ«0NA\81\ 25¥xw\10FÐÏ\163B\rÁÆ¢]ußúë,µ×\15·m¬\12,õ&Ù\8fÍ.}\81\83¡iy
+o*¿AÛd}]2ôÎxM²¨`]B@\94ÛJ÷[樬@gár\7fu\ 6+\87¸ð\87l\0\98ç\94bQ\1cÖ\14Ó\µ\98\9fn\ e´\12(3H\85Äékgf»öÉÝ?½ì\83ñ/\86i6\91\88\8f\18Zz)¼#çÃøq³\19÷\v\8a\8c\fì\r\ 6oï7å\Á
+üM
\84·\13bOÙËXbm¹mV\97­M\17¿î2\87 §X\89\18\17Рé\16G\ e)\91\18°á\86î6f\8c\96aäï!np¼n¨¿\80Ó\96ÌN@Ä\90å\8c\8dísÐ\16\80ã\\95\13waÌ.åçï\ 1BwLtQÑÙJ\99\90b+\86B\99ÿßJ\94\96\8e\93t/_\1d`\ 2Ão\11ã\fù!\6\88Ùö)=¢]ù}\rb\f\9c@¸·Dg\v\91f\7fR\95^³s\rçF\96"eF+\86\10\1d\ 4\91¸ð8t\873ÿ©\8c¹,Z,¸a;\1e\136d+\ 5v\96\96\r
+Ät\88ÖÍ\14P4!\ 4     G)\0P£ùÖ &ÔÚ\ 6áö\ 1}B ÛÝ\1c¾\1e\92Âu\96bNæ¼¶È¥\9a\r\ 6Ez_N¹»\18\12\96ÓÌ\ e\12\0*\8c0,zEU#3ây[éÍfR¡!äÉÌÂáN\17\9a'l\ 2\ 5       Þ\8dï­ÎæAÞô³âÛ\f|}ù\8a=\1e¢ý\8d\ 2¡Së\82£ûP\8c^@-%qqèqÓ[T"\9dÚ_\8fbN\\r\12s[ò\ 1dB\19\8d-#\9aø*Ô«¬ã>AóÚá\8aá\8b¢ì/ã*Êâ    á/?<\9f^Qɬ(k4\vU)Y\fð I\8b£\1c\b¡9Ù\17\1d\ 6M\80;O0\87\87{\ f\99Ð\83o\89\ 4@\9d\Î~JYAt\85¯ïv\7fÓ©\19\86\88ôJ\r\vöá\97\8f²ÝïxqoΡ#\8bÉùêß~Ð\ 3ð\8a¾\19¤/ê\14y³ÕP\12¹ãÒJÐÐmc 0ÝBàñÆ\18*\955t\17\9c\1c\11n²èÃë\10ÅSK\82p\80q\vÖãæÓ@\ 1Ö¹ä­\1d\88Æ\ e\14\85·9.ïäí³<ô\82°Ô?L\97GnsxÌÝ\8bpZ\9a\94gÿ\81r  ø\9bd«ÈÁ\1a Ê\96\r\8e\e5\ f\1e\15NO^7\a¢Û\ 3Ùø"\88jÏ´\94\11\82¤\ 3\12hêê\89~Gá=ïæë\120°Öóp½Üܧ\97S\8b\13Z\196Hcì\82þû±\8aµu^\ 6Lo\P\8a!\84K\87Hc\18\12\17µ±  ôs\96ehDi·|â\9e/
+Ñþ1\10] k1\8dos\ eâO¼'£wí\8dY¹30 Ê>²\11,\98\8dΠRë`v.\ðDÚ\1fæð}ì áu¼URqÆ|)1\88ßðº­\8b\9aÙÀ$C\19\97\r\8e\87\b\81\8fµßa\8c
+9\10¾\1fÃ\14ù̹C\ 1\9bÙ\1dQ§0îö\Ú~â\ f\92~®"ŧÎÀöÍE»e\18ê¸] '\86Érê\86\16\85Ù÷0g%M[pn\88\87x\b*@-¼\92\99\19T\aLáé\87øåiÛxà'¾E+Ã\1a/\8eâ{\82G\99\17\99@\e¥o\90\ 3\8b;\8c\f¡{ðÙ7\83´}\8f\19ÊÐ1åm\ 4#H\vWL¤wët¶÷]?3x\16`\18htq+  ßX        ã+ª·yl\ 1+2Õ\fãdOg8ñ\17¿\9a\81\97\r\87!\ 4½9©ãÉ\92Æ\90EG\ 6\ eícB¼'m\81ôÛ\84ÜR(
+6E\91À\95þ©\b\16Ú\aÕ\10\9aåN0t
+\14\7f<ή6z¥ÇT¢^øÂ%\9cÀß3|]\84\92£jt8\15u\91C.%¼B\87»Ýn \14\ e\92Õç\83Ä\18\ f¸mÁ°bQÁ\vÖ\87\rUnÀ ¾fö¿\98-\e\83\10LOmð­Zß\ 4/Ññ\88Õ\80Ø)+ÇÎAç× ú¦Ù/\vk|\ e¿9±\18ç\9b*F&ã\9axàñÜô-Î\1c\8eí\ 2ø.@êìe"í'À\r!9ªx\14Ìxø\v
+>û\91¯Éú­;WHæ|,öRW5¾\1fP:Kt\8b>\8bùÇ\85ñ\1dBá#4çÔ\8bßÎ\199ÛÄiö5[e\93\19b\0(8\17ÿP*
+äm\7f%\0`ðo\elÑ&ËÃ~K\91±Ý\92\16³& ÿ«12?w\12C\1cä×*3»Þ\1a¢éC Æ»ª®ê#0`ïäû\197\7f2T^A\ 3nÈòÕ\ 2\rÔÔ=²\ f:3Ö½»\a-å{ø0\e\11t\ 1Û¡\83Â*oò       a\84ÒúñDÞ©\9c\87,G<Y\ 6|X\96êg T,)µþÉ\ÛP\87f_|#5mÇnÆå\98¸\968©GH%Y\8a&\ 4âÿ,\80Ê}&÷¸8}7e\91K²ëD&è\lÀK5\97\85ÃÀ\94s(¸e\19#E©±\1aÕ3üTnOKð~­\9d²¿\ 41ªÇ~\92«¼]ÐÙ\84ñ\86V\85ð¼\19\9aE<õÏa\88p`&\1fjkre¾âåKÌ   ¾Ræé\e\9d\ 1\0å>ÍU\ 4Öf§iT< [ò,\ 4½\84
+(ôØÍÅ\8965Ñz¦A¸\11\8f¢\1cT|³àÆÒxJ^\18C\944MXÏ\8e¶@C\95Ü:]U³«\ 4\8f\82ù\961["O\85#ö0£\9b\a\7fÊ1\91\14#\1d,
+)\89Ïê\8bùDì\1fã®áÍH\8bã\9e_ݧ>¤«[ ñYLAw¥:¥¨\83zá}\ fþ$\ 5 8\83\85\83àÄZ\9a}\ fý¹©d\ 2\ 2»\ 3\9a\85%e×ü\18ís\95ølý~|EòÅq\84\87\90ù)g\9dG\9aM\7f¬cðºq\8d\1f+,uçKîj¦\96\94xB¬\82q=Rèf§fúd\aÆ÷S\e®\93)\8e\84«\eWÝÐÿjY [\\160«Wl\9f\0X _!ñ ôIZ\83nÝ¢8\8cI\17Âl¤\e\14BDº¶eAѯhya\82;ÿ\95Q\ 5\16\rà&É\87\ 2G\1a&"@Þ\91q\ahmäû%Óð\8faïw\ 4í(fÿûã³Ï\10P\97\ e\85»ßAðcGéâçý%\10pú¿°¾\90&ö¿"\89ñÿÊå"ä¬\ 2IAýD\10\88\15ä:\91ëÒ
\8ep\10´u"\84ö
+¹Ñ5\12\16Êt"B\8d\85Ú\9aÈä\12\13©X\16Ì,\11*iLÄç³\10\9bQ\v5£Ø\82B©[\90\9dn\8báB\9fÀ\X¹X\17ÌRß\85^KD\ e½ÐÈ\9a\17ÖKï\ 5_ß6hY"2\ 40T\ 3p÷_@-þ\85\8e'\87¼¿ ô\18\18\83A>\12y\84a |DÒ\10C=\12\91«\18*"g\f\13\92Ç\90ô\ eP\1cÃe>\b\ 3\1d\89\ 4\r3\8cû\88\Ã}f#\91\f\ e\8bÈ=\9d!vÞgpV\86\86Ú\88\88䣡K\v\ eÁ4¼\95¡\86r!2\95ª¡s\8d5\84S]\83Q-±¡¾j6P "!Ö\86y!rêÛ\90;\88Ü \e\1a\81ÈÁxCï\87\¤o\88ÿ\81\83+\1fÂd8ØÒC\18+\ e\10æ\1e\aÓË\81\8d\86¬\9f\1c*ßa\ eÁ=ç`;\87\10\13:8r\97{\96\ eL\92êpwCîu\1d*6ä\88e\87x3~·CC\réõîÐ|\86H\0\97!2\11\ fÅc\88ÜÈCi\18¢|<´,Ì\83¶/ä7\9a=ct!\vÄ\83¹\16B\80=øb!\94Ë=\18\11%s\85\ f6T\bIù`;
+a\9c>\18}B\18î\83­&\84QùÁ\19ø/÷C¼+\1a\ 2\ 6\869Bòçb"\84ª|è\15B\1a\19\88\8274\11\84~x³\82ðÌ \91ä§ç  ¹@¤O\8e\87ª\ 6¹aÌ +\e!ú0ÈvùÕ\ 5\99a!\1acAÄ·5\ 3ñPAdÔ\10Í\13DÕ­\ 41ñ9D\17\16\1f"f~ÀX\8d\13\85\93\82 cP\11Í<\906\16Ñgº\b\11\ eäö0\82;\ 3\893#Z/\10ÙjD£\ 2\eÑ\97@êÎ\11M\bD\16\1eÑr@TÊGô0 r\81Du±\9e-$X\ f\90\94\14\89n\8b\85\8c?\10Æ)\aj\94\0ÊçHT1\80\ 4E\92\18\e\0¹+K"]ÿãì\95D"þã"2\89*úÇQÔI4¾?î"\94\1f§^JtÌ\1f¯\95\97øcK\95hy?f]\89\ 6¶Î\12}öã
+.\11U?\8e\92\97È¡\1f7Y`" æ5+&¸1?\ 4L&ê\1f\ 6g¢ú´Ò\843\81e\13q\98&غ\8f\ 6¼&Ò[K¿Ðù\8c\9b\0\82õN\a'À±\8ffW_\ 6Ê£\9c°&\94\13±¬\19úÉ\9dÈ×\91¹y\82dó¡\0\9f(-\1fkç'*ÉG\8d\80¢l|ÈyAQS|H\80(\14uïÁ^¡ \13ø\88ÜCÑ\95ï!ðDQtÌáæ0\8a\1cE9÷xJx{Ì\85\14uµÇ"1f3{ô>¥\88a\8fv\\8aÔõ\bT¦ØX\8f»»)\ 2Õã\1cì\14±|vö§p*=d"**F\ f\19HEÕè!±   =¼e*Â=\8fæ£\8a\94ó\88êXi\1e×U«È\94ÈÛ\ 1\rV\8c0\ fÖc\85»ò   Za8y0³\15N\91\a+\áðx\90TW\983\1eL\93âá\ 5yE\9eüë\ 2¿ð ì+ª\83G#Á"\16x\ 4Â°Øø;N\15\8bJ¾ã\84c\11Ò;NK\16mkõ\85\18\8cåe\11°;Úq\16å¹#\f\83\16ï¸ã^iQ};\8e¦\16¥¶ã\f\\8bfí8W¶H7·\85iõnÑ\8e\0\17½Ì\8e5qQ\83ì¨t\1cvX#¹\bpÛëµ¹øø\96y\9f ý$]ää!Åú|¡u\ 1("öm\17ÿV\87²ßECªC\1aò¢5\9a£\92.\11£\17Â`«ËÛ\và¦Ãy\:ªÈ\17´¤#ÈöÅàè¸\¿(\89\8e+ú/Z¡ã\15\1aÐ1sÀ(ø\1có\10\8câ;G\8d\1a\8c\86\8e0´ô\vÃ0ç\88\8eÃ8»9®A\8c\8e\9aãZ\89\91\979Nv\8a\91\ 6s\9c\91\8b\91p9NUÆè^9®ìÆÈ£rÜpÇ\b}rÜ\ 1d´,9N$\91\11Sm~%\19\17!GU\9b\8cÞãèê¥\8cF\8e#¬VÆ4\8dã\ 6\8cú0\8eã\7f\19\15\8bã\8aÅ÷Ä\91\83fh\ fq\1cÖf0;\1c©~\86#5ΨU8*_g´\15\ e%\7f\84Ã\17=£rp´ÙÏ\88\14\1cá\ 5\8d½Àq\98C#øç\8b\86#ÀA\13i\98ù\e\9c\95\86é}\83\8ak\1a\1eó\rZ\92î\r\1fø4ê©7\82ßQãcÞ8ma\13\1c\12\16o@8«q¼\e\97|vcG¬ÑU7&_k´Ð\8dJºF\aæ\86âר3<l(\8f\e\18ìáFÌâ¾\8d\1c\99\8d\86n£*Ú¨ë6ôecÛ0¡ßØF­¯6Ð\93Z\e~0º¢6\92\91\87´ÑõãF\9b\8c\11C\ 5ÝÀm6b\9dÝ\18*Ì<P¼\ 1O²á]o\94\8d\8d\eMb#¼¿qNØ8gàh\ 1l\9cèÁ\11èÑgó\96¢EA©)\1aÃH3\84¯A/\88#$à \14G£yÊ8\84T\ 4{\ e\bv\0\7f×pÔ\9bkøkÐ\89\1cGº5j§²\9dÈÁµ\1cràeÜq\94 I\16ÌãÐ;\\86Î8J22\8e\11·Æ\rÆ\91\7faç÷Lk´3\1eék_Â\8bã\91¬ñÅ\aÖØ\fã((á\ 19\8eS\1dSY D±ÕHPB"¬ÕÈ\87ã(¬\1a/SF5¶/\8eúé (°NL55\9c0\8e\16R£}"\98\1dj\18yqð~\1a15qL\89ö:\r\93\8cM\ 3ùÄ¡Å4\1eÁ8ÈóY\96FzÐ\93\86\86\89£áÅ\88H\ 3\7fâPîh¼,qPÊhdê(\1a\81&\87F\1drBùB¡\ 1(ZÐ\98s8*¦{²'\e£ò32/q´ýÄ\85e\1c\15ÅPóÞ\19\8cv\1c]P\99åqÌ{¢õ8Þ|Ì`%Aèf8_ð±\19\1eû\86\e5\83È=\ e\97$ù]\1aG\1c`±âø\a˨D\1c\15\1a3z\80\fÇtaF²'1Ëj80ø2³á\98s\19·\848G-#;1,CiÁÊ\bX\9f2J)\8b2|ä Ä\93a\88:\93\81«áP¤\92q¥     É`²ÇÈè;\ f\19Þ\e\8e\90\ 6\19\11øý\18\b\1c\ e\8d\1eã_\9e:\ 6\85  G1\1c£RÂÑac\b\9b®g\8c5¸X\1fÞ7²UR\91ôöb´Å´\18>\18«\18H\r\87JQ\8c\17J&\ 6wÃÑþ²ù\93\19r)7Ä\18ÎíÃØuÐa\98K\1c½Ö0\1akÅ0\80&\ eM\16Æ\9b\18
+\83Ãñ\b£aù`8T5\18 ÆáÐ-\18ÿ\f\12\f\92%\8e\92\r\8cf\1c\8e\ 4\86Î!\ 1Ã\ 4\88\ 3?Hð2ß_\18r8B;6\1cåº_ô¬å\17.\ eGá¾è²Ä\91m8\1cÕô\85¬CùÂ#\96\vK\817T\10Ü\vÖ.\8e¼°\17\8dµ§\17@/\ eÍóâ\8dXyÁ\91M±OÌ]\88ú\ 5/\92\eÝ.\8eâ]\1e\ 4ü\7f\89£+^(X¦Xº»8t\9a\e\87\ex\11àÇ1ÿ·qx[£B"à#\968>\8d\17G\8d\0ÇQ\vwÔí \ad¦ä(¤N94ÞÅ\1d\97\83\8a-s\18î.bçæb¦A(_A7\0\1d\9eã¯ìBsçº0âæ¨§.ú\18J\17à6\87>èâ\19\1fç\82\91ÍÑñrÑí6GÑ\15É=\eP\T sx6\\10\1fs¸       .x\8c}\vg-G/y\8b\81\8b\v"Yp\v\19-Gµó,\a²¶\b\98f\8bkNl±xÍQÛµØè\1c½Ç¦Ð¤Z\98M\ fµÀ÷9TL\8b\13C\a\88ᣣq<o\ 6\141\1d\9eÏ\82±P\87­§ÒY¤«:Ê\9aEݬ£`Ëë\90\88Y\\8a\1dD\96EÔÙÑCY(^;jG\16;a\80çcQ\0îh\1a\8b\8eÒ\1dyÅ"VÞñD,\ e¸\f\8bE}G\rÂb\ext\ e,
+\f\8fÞ¿B±âQ«¯Ðx<:ö
+\81\93G\1f¯P\80y\94#µ+r(\1aDW\18\19z rE`\98\1eó[qnÝ\91\15\87½\1eÙZq7Ì\1e­´âþíQpVÜè=ÚdÅE\83\8fX±âÚñ\11\ 2+Nuùȼ\8aó\80>
+®âDê£Ï*îÆ>Ú«â2¦ªb¢ûè\98*vÃ\8fn¨¢2ó£Õ©\90T?º\98
+\1dïGG©\90Üù£\0©Ð\ 2ÿè0*´´\10\15öä?ÊAE\v\ 2\90\büáõ§ 5@lz
+ÊZ@,l~b\81@Lq
+¾Í¦pb
+$¡)Â\8e\91)02\10ý\97âë\ e\84\ 2\11AÊ[
+QM\90ú+Ŧ\15¤aJÑzAú\9d\14ê\19¤F9\1cDMR<\99\aa\8b\141\82\90&H¡Â"¤\94G1 \8d£è¿\12b¥cÀ\ 4
+q|Q°©\10\9f\15\ 5+\v±WÞ\854M\14ÊÞ\10žº\90\9e\1d
+ɸ\0¿$C!­ªB\91\e\vi\84P\94@\854\18\14*L\10\14α\90Ì>ó\ 3\8a
+*Ä÷\9f`ÄBÌú      B«.Äß\96Ñ\11C¢øÄ\r3$fO\1c¥AO\f·\fi"O\8c\r~'*´\8e®¾do\9dHzH'jS\86\98Í        :%9á5Â`Ò}\8aM8\9b\86\ 4²\9b\88\10\92A\0J\1a\9b \19kMt¸¤&üg\93&p¨!
+hâ¤n\b\ fg"­"\19\8a\&"Ý\90NÉDÍÂ1á\99\e\92tb¢CI\\ f\88  \98\eRñ%j³¿KXÍ!Qæ\12½(O·Dú0$@-qÒ-K,Ú
+K\fOy9®\\89\ 5\13V¯y*Q6\88\91C~ñ\94h(\87ô*%:0\1a%ÀË\17JLnÕ'1²ÓI8²l\12å!\87Ð\98DÈvÈkIüp¢$æ=#%±ÕCJ\12\8e\1f¶k\\90\84\90\10\8f\7fH[\17\89\88\ 3X"\81UsH\fÙCº       \89Eÿ\902\ 5\89"!R\v\90\10/\11),¨¥\8dÈ\1c##\89<\97#*Ò\12 ÜÚ´\1fÁØD8wDÜO¤MGÈ8å\88\95F\8a\b}77Â\14\15\11mhE\1a\ 2\ 51c\91m\1aqyÀwFhÓG\ 5¶PF$m"\8dò¤i\1cFÈ/"\8a\86\8cÌ\99\86if\ 4\89EØ,\1a     ³"úW#é+\92i#ê("¸72\9c2\8ex}"¸ç\88+\1e\82\80\1d1Y"\88\86\91\bêÔ#\1eG\ 4U>âNDPÞ\8fØ\15"¨'\90\18\ e\f\12\9f>\ 4W\85Ä\19\ fAyHì\95\89¤\98C\88û"©Ü\1038\922\rQç I]\ 2À°\92\84\0C\84LIö-Ä \97¤r\85¸Q& _!\8e¤)ÄÈMRvBì½\93t\94\10õ\80\92\b\ 4!\B\94t\1eDûHIÁA\84Ñ\94¬/G%Þ3\b\8eUâò\82 j%¦*\b"_\89\9d  \82ú±ÄËì\11\15Zâî@PÎ\96Ø2\10\14q\89+\ 5\82"A \­K²\v\88\18½äq\808H\19@ÌÛ/iù\1f\96\1fZ\a\13W\7fË\88Iu{oL\826³¢*M
+\a \14ÄíÃ\96óCò]R\15?\L\r0Áp8f3ñ\r\1fÄ\82\9b\9f\ f\831\ù0F\9a\98\8b\ f¤¨\89!øÀW­\89§÷À>£p\ f\89Óg\ f|-\13Óõ@å7ñS\ f\f\87\13\93ô@(äÄ\ 1=P`N|\9b\av\0»åÁ<q\9de\ ewv\ 2\ 2ú#+\9c,\90\0À´\a\0Ð}¿uk\18\84\81¾ÐÑaà\87\9a\8b¤Ã\88þV\92ÝäMrT\1cKÍ"\0\0\0\ 1\0\0@\9f\b:        \94
+\1dÚwÆ\1dç\9b¯Þû~k³·vóþ³¶\17ÿû3çºó\8aGý¿\95\ eµúÞ^½µVï\9dïµùwnûå×Zk·Æ÷ÚÍÿ¾ÿî\8c;ÞÝû[sÆ\95\ eÅùWK5Çx{8ã\9b¯þ»âQÞïö¿âÎ\7fç\98ó½q·¿oÍw¶¹âÑ®¯þxçj\7fí×ZooÇØrÿ«¥ÿb»«µ\17[k«ý\95\ e½:W»õÝýân1¾\1c\7f_íýþvËïÿ\9dç\8aG=®thϸ²3¾\17gl·÷Öv\8fïÎ\19ÿÛ\7fµvwÞ}µØn»uÅ£?W:4ÿ[!=ª¥;{\8c?îØw¼;æ½_­5§<÷û=¿|\7fÞ¹å·s̯Æ\97ÛÛ18\13½ïoÖ<ÿm±õÝgï¿\02\9aßë³í\e_\8fóþÞú»e Xv0þ÷úÍ1¯\r¸o¬w×6×Ï\7fï{ï\8fýå¶²@\12õ:¤\87ö¡¼¶]ç\f[}¢÷Ð>Ôj¤i\ 3\11x\9e ø\8dX²Mê\7f0ÜÅ\90¬HÆÂRÄ)ξ\16¨yÀö$é¦\0\18Å\ e-Ás&ºÞW^¿å\19{¾­¿¾sÛ½ö_oﯶ9W\92F|Üý¥ÜæL-íºÞ\8eÚ\aj©¨ÔI\81\ 1Â\ 3Xù±À\0\91\1e¨4\ 2ÍÙ\80r|õ\8f\1c\1fT\\99\1fJ\13MX2Qµµ\ 1
+Y\95æÊ,Á\13\ 5˱\ 5z\94%ûH\ 1\eÊ/9\96\1aJ\8e¥ÆblW \80ÍD\9b\88bÈa\89d`\80\rh.XQ\f9g8cÉÆÌY~£    Õ\bh\0\8f\92F/¥LBSö\19 ¥HÄgh\9a´Z\e1äL(\84\f¿ú¸\14\84\8dåYZ\85æçÁVßY\12\19\9e&ôj\ 3tBe!\85\0á¹\ 2c_Â\84B4
+\95\ 1`\94!L4óÛLóÖô¡A.µÔÒKédb©¥\13:¡ø¡A\1e\1aä\94ÍD/õÐ:\9aÂ\96îR&\15@ù©B\10(\9efXz©\ f\86fzéî»WK5µ\ f\ròРø¾L»/Ý\97ÒL³ø\ 5\10Y{é}h\90\87V)dR\82\ 1İD'"I\86g\89U\82¯ó\ 39´£â7®Êï\95y\99¯Õl4\89_\0\11­'I³½tòÐ:
+\99°d³\91DëIÒL'\14R\82¬RDKÐõɾ\10}\99³Ró\98jL±ç\9cÛ{ïµ3Rö¹\9fþO¹íÛZl\82:P§Å|×\0@57A\1d¨öîwÆ è¥8W»¹Ç?w\9boþÞ{ëýŤ\ f,1§\0Ðdï­ûn\8bµåYç|¯¾Úîëý\8b¯¿\9dwÏuõ\7fëÎñÕuw¿w\fõuå\9dwÚsö¼wyß\7f¿ßÞÞ|\7fí>û\9ewÍ9×Kóýuo\8có¥Øj|ëïô¾9_þ3ßõ~Þ)î\16ë_óö¼Öýw»½Í\e\7fË1Æ\99k1\14½þâÞiç¹ß\9f{æÝfmûÕ{W~;Í;ï8wößϵ½½âýñÆÝ_\8fy½¹^ì1õýöÌõõ]×ûÿÚñ{»\8aïÆÕ^mÅñ¥øã_/÷6güëö¼S|óöVÞÅÿwªùß\9b[\9dq¯ßß\8eíßWÛ¿±ý?[\7fsÕ¸÷\?çÝoÞsß~Û}kÎ\9dÍ\16ï®ûý|ÿNõÞ5ón÷ì5í¹»üÞÎ×{»\8b;»ñõ\9d\7fL/îþ½\9eßî^Ü«¾Ú\8a~ÜÝmµÕÇ^wÜi+|»ÏwÖuwÚ\8aWÜÑk;ÚQ~;ʹͺj\9e?¶¶n¾;º;\9a¯Ç\98wßóÜíÎk+þõÕbùþ\8bi\8aKq)nã\185WÔZ\9dõµxëî«õÜóh¿;óëoÏ\9dÞίþ\1e÷¯³ÏZ\fE7ö\9ewÜÿ÷_Wÿùõ8÷¯o¶ÝæÌ{Ö\98s̳­º~ÝQëkî(D\83>×@üg:ݼ£¹ÓÛ;õ\9dv¯¡v\865\95\16óèÅ\9eß}·æ\9bßz;ï\9dþ\9com¯Ïþç¬w·¶ZPÆ\7f\r¤eîÖ¶£\k\99Îo\8fkï(ßZFwÿâ«e2å¼×Lï×2ùæ\8f=ß¶Ú\8a;-ã+î(ïwï\9a»Ý\7fÕ\9dí·î®ëÎß\ e{-f½¼/ƶóÛQ¼;ï;\8a\9fú­eèÝ[ßú©¿6×\8bµ\f½:ß®ÃXËhÜåK7îîÝøz\¿\16Û¸Óµk.j1$j»6\8bÈF\19æA¯&ÛÙV\7f\7fÍ÷Þ_Å\14§­R\9c\16ó)\8e\85Z\0alëï4Ю½z\9a;ê)ÿ[k¼kö9o®o§;Æ\9d\ 6Âõ_\8f¿ý\9d\83\1d®1|¯ÆÑ2·ÃÙÞÍ÷θ£ûf_­¯\19ãNËôνç\9agÜ;Ý5\ 6]ýoŽêmë§\19g~Õ\9fWÝѼµî¼Wý;Ê=¯¿Ë\9dr\8a¯Ï9gû­÷Øö\9f?Ö¹ZÌûõÜ{Üï÷Ù_\ùç½ë2î[çìíÕ\\1eµ¶£\90}3]þ Ü3¼~úéåÝãª;Z?ý¸ÓV¿zÿ¯æÕÓ¬;º½ç¹z\9a9θj\7f7í¸£\98jÛ}Ý3¯¿ÓVù×ßí\8a鶸zª/½\19Ûj¯Õ¹bÌëÎ\97ö¼qÕ¸«üV\8d3æ>ãúogë¿]¯þúÛá«\91\1c³PôR\9b\ 2Å\0ÎÿÁ¤\bR\9c6\10\96©óÁdX «\1cW é\1c\13&4æÑþy¶Û請\9c\9dsûïÖ\9cîÞ/®\95¿<\95§­l¿ôïU×ýN[Y®\89^«ò\ 3KýR\v\12)¦»Z-F¿Þ¹Z\8e9®öoìýýw_½ïö\9f{þ¹öúb^-Þ\98cOïí´\fí»Òê\7f÷»{o¿¶âÛwݵó«ñÏP{»]ÿ®\7f×O­çöv\1a(Fy\17Q;\130z£*6fXá¬\ 3\8aªOv\96#)`Ã
\8eK\16\86bé§8\8dúK-§:Å\99òý\9cãÛ3îèý\9ewÊ9卑wEííDj/ÈcпÚBDó<jµ\96çÜ[ytß¾qGq\fEíç½£ÚzÞQ\8c;z«Õ\\1e½¿£\96^Måi \fµ·Ó@Ôv\9d½\1díøæîþ_?Å}óú­½ö~ìéÍZ\8cvz³¦¡¶¥eè½\9d\ 6¢½£8k\19ê?½\97n\ f¢\1ewôÒk)Î\14ãú;\8as×i \8f;º­æ¢V\13Qk¯l<Ï\99÷ÐÄQ\15\v@_\96l\93²÷\83á0dlÌ´LÙW\9aN\19(ónÇÒ^ñJ6ã\9cð\ 3\97\ 4[(26fê5\953Ñ#cc¦\13       \10p\ 3øÊ\8e½2\19¾Øæ{3&\1eG\91C     à\fW\1f9R\ 2Øê\13U¬q\14[#\8b%@ÀíöýJ\17k\1c\19tµû\14 àV»Ú«ïô\9e\v\10°o\97/¾ø\ 6\10\0\v,1¦\ 10o\82Cx\9d\bjll*0\8bF"Qáª\ fN\e0@3&\e¯qa\910$\87\ 6¯sk\ 2\97\92\82×I\1fǶ¥DÛ¶\11P\16!lÛ6    \ 4Ƕ\95\a\ 2Û6\80ÓR\92mÛD\vƶåRÀ\ 1\16i-@¶mÀ\80\ 1\ 3\ 6p\9aÄ\12{M¼nÛ`\87\86ÎÄ]á\ 1ç\ 6¥\0Ù\180\80tO\13\96ò  Á¡ü\rendstream\rendobj\r19 0 obj\r<</Length 32300>>stream\r
+ÑàׯÀH8-Kä\19\82\86ó8Z\9a\a\8a\80j\13ñ\10Q\fpÄÛp8³Â\84\19u\13/G. \13M\ 1gaMªÍ\8bä\ e|@%¢\95áÄ67\19ì_ª^ØÛ\7fÛ¶ïQa\99Øt\v\15%\98áln·m\9bÙ\91ªf\97\13\93\19f6Û¶m \ 3Û¶å\ 4\18×!-¶m##Û¶\r`ª£Ãi¦
+dÛ¶\16ÅÈc
+\16Û¶-\1eÛ¶\91YÁcV\94\95\83É@t!ðÙ#8ø¬&6\ eǶm\90\8a\88\93ÁÞ¶m{5: \81×ñ\8b\14¸mÛDWDÇ\98¶mÛJ\81mÛîG¡4ÀÛ¶m\ 3D\eÐö\9c¶8xlÛÂ\11Ù6Í\ 4\ 6\f\18@\82:\rÎkÖ ò\ 3 B\9cð\9f\ 6"\8a\ 1É£\e\9be(·-\81 \83\18¡VÉ«\94ÜÇ!ø\1eÑD\93-\96\86\1d\8cþl³m\e§\rP\905®@Íö\9f\84\99P
+\r üd¡71ÝK?\18Ê­G'¥Ñ\86D\ 5\80"\19\8a\19ó\vE\f\rO\19\86~0\94ß\ f\86b*\vé(£\7fß\ f\ 6\14Éð\14g!0ÀWú`B\ f\0Æ\17\10Da²\ f½wUOS\84ÉB+ûHò\93\952'G3zP\82\8cCòËlî
+\14ÅqE\1f\1e°ò\v\95`øÉT±ÙË\ 4\9e_   ÊÀÎ5]14\81æB\0_Ù±ú\ 6ð\95\1dP\fM\eÏÄ\95ìÓ:e\9fóS\8då
+\ 3ÆÆòµ\1aecHc\\82a+<e ë\13ÀWvdcxù\19"ÜQ\85\91\ 1\8c²1´5\ 3®!K6fdái\82\9a\0\1e°r\ 4ÀYbbcÉY\85â8
\e38\16\96¦±%û\80®oD\8e&Xù\85\ é\92.\19\96+\13Ôà*\ 3À(\83ÉfÔ\f[#\ 5Í\19\15?\99Ì\15\9a Fö¡æG_«\99¹
+E\92üè9\e\ 3øDúQYHÏ\90Òñ¤,\10\94ÑÙ\18@9Ò\81\90ÊÂÏå\92\85\ 2©l¤²O$él\f\0\ 5Z9\9a\91ì£æGA1lQÙG]²0ÀgR\19ø\ 2\05)\8b\82¯\93\82åGA\13|\99\1e\0\0Ã\93
+d8Í\8f\ 3\93\85 k\96\9fwIò+M«Q£[ è²Ê\8f%ûÎR\8a£\19áûÁL&å\a\92$F\14g\1c°\14\0\b+A\8b] ù:?2å\92\85\ 1Æ\10\0¾R\ 3\8aá\8b\81üd¥    % Ç\11\ 5]ßÌ%û@ç\8c<g"ú?\98\97    \86èÿ`.=K\90Ò{?\1146\vY`èáñ\81%\86\1cËL\8a\váîk>\v\v¶{\90\e\9a#i4\89   c~.9\9aX (zâ\8c\ 4Iâ§\1aÅÎþ`²ÏüÒS\0h\1aÑ{ï\rMZ\82äGÒÿÁ¨J\8a=Öx»è¥\94U~£ê,?úAQEÁó\13G34)+,]4\80\95\f,?Ò\94}åIÿ\aã¢çl\84­F\19\8cÒK¢ã9ÃÐ\ fæ#yNqãê\1cI3\14¿\1a\92¬\ e3¿\98y\82¦\89\ 1EÕ79W¡æA    Ê\0áù\89 iwÔ\8e¡\v\0P$Cq%~*\1a +ÁÓüÊ\9eµ\1f)\18 \ 4M°$ÇðüHæ)\e9'hªf%{o'GÓïã
+,\89"\98á÷÷Ó,C\8e\0\90%û¸dáË\f\89ÞÎýY:[ ¨û­[ ¨\ 5\82.æ-\10t\86²\85Sk¿rÉB\0\80áI\9f<\16\b\8a^érð\14°9[ È¿Vá\8b!6f@1l\8då\88\ 5ªb\e1T\85çGÆÆ\fG32Kð\ 4c_ù\8d>\18\18(ºd\18põqÎ\97+$\9d#YJáûÁ\b\0O\v\ e\b\b\17\8a\1f\rOÙÇÏ\92(Î8\1f\fÌV[õ}\84\1aPT}&0ö%\88ßj\ 4\99\9aO  \9e²ÏjÔ\9c\9fG\ 4K\ fJ`RP\16\8açl¤%Ø¢V\ 4\ 3\80 \1aÀ\19\8aßL\81ºd!ý¢Ù\98\11E0seã\80°\1c=\98\ 5\92Êq\149\1e+,;þû\1d\96d    \ 6\10\f_\fÔ4Á\92$g%Úï\0\8bñ¿óc}'\18\ 3@˼6ã¯ùîZ\80\80\0\ 2øÿ{}uÍÜ\9f-\10\14\eÏsT­BѼ\0h\99÷\ 4K'XúÎO\ 3\8adì3)\ 1nl<ÍÙ*\0\85å\17à\82°Õ(\ e\9c`©ü\ 2ÜPe¦8\ 2³ü\ 2¤LYã\91âRÜ$Åißùi>>Í\10ä\8d°Æ\1aë_-õùÿm=æ\1a[«ÿ¿úwÛ³­¸âQk«÷ûîíïö\98ó\8dû¶\97Ûû»¾»ãÿµ·^\87j\8b¿Î|ßn³¿\1eÿ~í¾ÚþËõ¿¿ÿþûæöwîÿî½o˽¿\1aû­ûïÚîÏmÎ\9bo\7f}Ö>÷«»î\ek|ñÝÕ~ëï½]ïn·ÖÝ⬽ÇÞbî·å¿cÌïÆØ^m{ηoë¯Ï¾w¿õ½·÷¿{¯x´÷J\87öþýæ\99Û\8c=ßöZ¿{þ×úݱç}ó]ñèÝ\15\8fr\8c·ÎØ÷\8a\7fÿÿc\8d÷Çÿöíýõ\9cs\8c-öÜÿÏ-ÇÝ£\96Þ«+!Êq%£1ÆûÚþ1Æ\99ãJ\ 3ͺ\12¢\97oü»¾¿sÛ³íöÞ]A \16W\1a¨­\84\95L®Ö~üq×þÿ\7f¹ÿøj®\11½\14Â\12ÇÌ\83¤\11«\91F±¦òòîY_Ï1·Ø÷}{î:wίÍ]W:\94\7f\9c±ÎvûÞ·ÍXßÜyç·ï«ë½¸Ú­sÎWã½±å\1eç\7f±öÛf{³å\1cãíqþ?{«»Õ\9ckÌ3ö·Ò¡\9cß\9f­æ¼{{­íß\7f[í·|g½íÕ½Zoy·ùëûußßz~óçûV:Ôÿ¾uµ4sþíõyóÌ«í\97û¬¹å¼âÑÛ+\1d\9a=ÎÕz\9b¯Æ_oÜóö\9ck­-Ï\7fç\8d\96w_ñèÿ\95\ eÝ·ë\½Õ\9bcËsþþgÜmÞÕÒßí¾·âQ\9do¥Có¾{[Ï­ßÚî\8d·¶7\7f\8fuµ|oÿsöÿsî1÷\1a_\8cõþ?W\9b»÷ßþ\9f;®vóî±ÆÞc|q¶y_ì·Ï\16W\9byÞ}{oûÿøzk/çÿúj)ï|ÿ\7f\7fÅ£¶Ò¡~soõÍÝçl½íùs|/ö\97S­ý½voíuÖ·ï½o¾\9e[\9fõÅùZ­½ç\98ëËñÿÕónuηâÑ­+\1d\8aíý¹Z]-Åý{ï1ιoß÷Öþ\7fmõÞº[{+\1eµ¸BzTKy¿×Ú\7fµÆ\1cç͵®t(×ûöûµÝVçûuç¸Û\8bõõý÷¼5ÿÕfïoÅ£ù^\9b³×\96s¼«åöëÎ1®xôöËoÍßzï\7fïúnÍû¾\15\8f~Î;Õ7Ûß¹öwã¾uµøú|mîöÛ\9b÷½Úß«³çØâ¯{ý\1dgÌûÞ\15\8fjk­®\96v¬wÿVk˱ÆÜï\9f±½Þê\9c·õÚfïq¶ÿs}±ïys{\7fÆôr¯qÎÙ[Ìq·\9a{Ý+\1e½þV\ 2.rl\95¤Èª§¬\ 5\9e²°ÆVXT}2pÆ"ÇJ
+\18W+Ù¬\15\8a.RÀ\95É>R@5¿ð\94}\95\14`\82²ó\13['h\9aäX\96\95\14`VR\06KVyÊÆU        ²¾\97YM2¶\82\ 5\10\92¬±\8a»ÌæC½\ eÉ|¬®XMòs\81²j\92ªj\92ä'\96`\80S¶Z\99\95U®Dre\ 6\0Åoe\ 6xUWe\95+2\14[20,ÇÊ*GÒ<Wµ\14\14\91"v\86*óS©F
+VU\8d\14/\0¬\ 2\84¥\86\ 6 ¢,P\16¶@ÍCu­/û>Å
+º¾XxkI\92¾\96$ùwI\92%I²H\11d\8d1\16YÅÓ¬âi\964\14ß\ fæA   R\9cf     Àoq\10³Ó#©ò\14Q\rJ°æ­\|\1f\86\8am\99ð\15\9cv°IFr"U\1a\91\f\91Åd\81\1a\19²ç`<k\1f\18+v²\92A\ÇFæø\ f\87ì\80\83%b±R\81\12C-bà\9d5\88^aS ~$\85        ë\18Í     Æ\12\e\1fVù¸H\8a\98\ 4¢DñY\8d8\ 5§9@   ²ð\81² \10\12@ tX\960ñu\8aMF/\ 2\99B~m£       s¥\1a%\91ë\93qve\83\16¬5C1\88
+On\91\b2"è9TFà¶\a\1a\84<\9cb¬Ò®\14X\14®\ 1Îú>\bãêá\9a¥\15§\9dÎ\ 4¿"©"¥jtb\9d\11\89@¥0ú̾ÒÈÀác8\19\>\bÕGà[\9d\ f\12\13°+ËLÌ>\1a2!y¡V©~\1f\9fÔfa¡¦\16"=\94h9l"     \ 6ÿ´D\17Mc\ 4¨¤°\10¡¢$\10DpZ£Fl\11\16R\ 5\ 1á\10r\19\88mU\81@XT\12¬\a       WFx\88\98­û\0\82lb\ e#eÀäp\ 1½(\ e­ðÛ\1c<~\88hP-Dh\1aºÀ\84¤a\15\82¹P\ 4\ f\89\bE\11áá¨\8d¥U2,8ïÀ°Ðra\188M\97<\b\ 3ŦÑ:\85,¯ÐéV$ö     F`*\17\14\fJ\ e\v\14\84\ao\81qZE\16T­Óe\12=(#SÁÅäM\12\88Åf"!"\89\92\8a\94\16\1aà¤t°\90\10#]&þDê\14ùB²£É\83\ 4á\92\96\ 2§q\8f/RX\8c\1c¯0kEl
+§Ä\99\1aÍ .\9f\11ã{á\91\ 3¶©\10\rÌ\16\ f"l%4"\ 2\8a4\10\ 5±\84\ 4ÆfHxØpLÂËÕ%        \e\81G\11Âá\82)\94ñBKè´]H\88âáô\ 2E0\8e\12\88Ó<\9cª\80\1aJÿ\0\9d¡À\vá\7f       á$áPA0\1fD\ f\ 4\vxz\1dD¼L¥\ 3     \ 3´\1c\19ä ì|\8aOfõ°ð¡\80@0\1f\v\82iàã\12#1\8feóBy`åHãÉ |ë)!\92\8aNhÅEt8M\92\0ùt$|·;\15\b\98§HÅY\80\81        \9cÿ\9a\10pL
+\ 6\a§!\16  7\98\rba\ 3\89xo\13Z\1a\93M)4Aj0/\86\bM­¢\ 3\8d\99 ê\1aÖ\f% 9uT­ÌÁy\962\16\10Ædr$¡f8M²*I\8fÑñ$¼Ò\92\b^l¦ð=
+X\81Ã{}\ e
+L\8bÁÅ\80q5°6\98ðáË\18X\84Ä\86!a1\96ÁÆ=J\ 6\8eÜ1\ 6\93\8ehbð?²¼h\ 68ße\ 4"E\97\882Ár\81eºîÒ CÒÂi=ä\90²|"\b  \96\b\95¦b)\11:\ 3\96¼\ fÈ
+\82À)UY½¾\84
+\84\15±T2\r\97®2áЪ(\80@ø¯à³z\8d
+B\8a\8cAÁf<l\ 1\83ýN\ 2Ç\ 1\ 3\8b\0\14¡1\11\98\ e\8d\86\80ÓÉh\82QD\10 à4MÅ\14\17Ø@é\\16\a\94mÁ¡P\14\1aÂ\be À\93?B\0\9cø\ 5¯\8dÂ'O\rï\8f\10@ü±\81\88ñ)\f\10B\9f@`qðÚË xÒã)ð\f¢Pç1*\96Ù#cÉê0l9u\14\82D§s\1a\87\ 5ù\9dk\88Ho4ü
+.>D\15O\95H&^\9ax\1cî\99¸\9e_¼H\84÷È@Ŷ®nµ!¢ÉÂæ2\99Î^t\86¿Ï\bL²M\81ljS \ 1Ô§@\ 4¥\17\92\86\ 3Ýè\ 5\15\9c\13ÍiVİÐÞ\ 5¢È\ 6\ 2?"\1fx}\94\17&v&O@4ϲ\92\ 6\92\1d\fP\ 5î%\90\85;5\82Â\r\12\19\ 4,nF\v\968*\18
+\ e\9fF\1eÙ\1d3Wuq\1f\17nÈ~\9fû\82\94*w\ 2\97Ó@\8f\ fwa]HfwVPY\ 6\8dëd\19£óÀr¾}±0ÆB¶\ 5\98Çê$F\15\93í\10hM$\ e\16\1c&ù¤\88&\12\9eYf²\19,?Q\91Hݤ \1f,&¢ì@¬\9e\ 5\84¯
+\14\80N\95áqB¨\9cÖÉ\97A\15U\r^C\ f\9e¤Z\a׬{\91\v1@Lt\19b\9fº±%"t\f\15   \98\ eÓQz'±p]\a\16\1d\ 3L\15\eØä\89Õ@\1eE4\f\95h ä\98\9b\81\87±+\18Høpð\80ÇH=\ 6\93\16§¤ú\10\85\843\17\9f¤D\85\18$¢f AÒ²\13\1a\89já!\90¤F\8f%\11.\b\90\1aÏÈCD\b\8b@|¢*"\ 1\8e\r\91ol(D@\81ì\89À´ç\12©ÐDð\bã¡Q#\92
+\r\17Ù^¬\80pÚÅd     !\bÛ8\ 1\1c  ,X\1dALME\aRM\89\vÄ\ 2\ 2uÈH\92\99@V ç\80,\10¼óÁ­'>@ä\ 1ë±ú  \1e\8d\92Ìô°h$¡\a\8a\80³y\9c\9e¢ò ðÏ\1f¨ßª\8f­bq<8íb\0;\1d©\ f\90\96\9aI8ÈGÈà¸X F\ eVIôqè\11Ás@\10(\108jÄI;P\13°st\ffÃÁ\0éf\8dÊ \915\1e6èjèÐ~\rUGÁ¡Q\19h\98\1a2\18*Ô@8ñN\83Ó\1e\98РñpG\94\ 6Á¢ë\ 6\19\86\ 2\væhè\8fµ5b«\16É\8d&R\14\1c\ f)X\\ 5L\94àPç¢\813¨½ÄA*\b!î¥ðêp¥\96õ8K#¡\80\93`NÎɾ\84ËA8f\12\ e\94\80jp\9cV\99\11l\í\9c¤ÀÌ\9c\80     ¼\10B-\81\a\ 6å\13\18\9d&\10\ 2\1dJe\10¨\98\ 3$\81Í                t\98ì\11p\MF`#\11,\ 2\15)\88/\10[ض\0\ 5\ 2\81\15xu$$\ 2®Ì\80C u\11-\ 4\\98\86ÉxeH2\ 6§Q `
+F¬ä\ 2\19å7ú\18\vòG0\1c\10F\ 3£«P\98\18Z\ 1bĨÀ\18@\f\8e-y\18¢\83\ 4\rÃ\81\82dÀh\11L\140Ì/æ\19\92ÜØ\fß\90/ÃÃK\1d\83A\15B\18¯\8bn0\ 4ÊÒ\82Á\17\1cç\82Ó>~D."HFlQѰ\10\87 µðà\98j\91ÚJ©ÅBÄ@,\b>Û°0\9dÎ\85\85LA$-t\88%Z\88<\10 \85ø\89ø,4\82\ 4gQ"½2\8b\8a\86Ò`Qð9,\v\b\19\85`ñp$øÅ\ 1\85b/8-\16ºyAð\85ìb\82\85½d$\8b\ 5Ôë±h0¼Æ"ä\91\8cÅìûl\v\ f\1e
+\86UÅÖ©¢q«h Ä6\8fmÀ¶ó\e_\eÈÂjm\ 2$\8aµ\95H'Õ6°M\13\e\84¨ ±õ\ 5\14ÄÆi¯JÊaÛ\f\8c¨mA1;m\v(»°éЧ´\85\18\95Âöá\8dÑ\ 6\91\\12\14÷\816̬CØ\18¤è³A\90\9cg3¨\18q6\81²±ÙR\8c\87̦\89P¼Mre\ 6\9b«rºl¢\ 3\8b\f\8dÊÆiçjE°Il\v\94Í£9\7fË!\ 3¿\95©Û7      Æ\0ß\ e
+\1a\v³¼ \9c\8c¼\81ݼ\9bÂ(f·Jè\9al\90NU7\8a\r\9d$N\ 3\9b·P\90l\95\0\8d¥\rd{\10/\8f­c)\8e\8dÓ¶¨ÒضWç6\95\ 4\vl  \9a\ 1ÆF\89h,¶Æ¶m\e×mÛ6À» ¦\81\18ø\0ëÇ\a\87±mÛ\16ñØ\ 6,¶-ò)\91­\ 2\95\0Ù\16\11\11ÈbÛ¶í<¸l[¦Ül\9bfÐl\e\85\87µØb«      cë.\84±\r\18`        \85<M\86èZ\9aEí<FåÈ\18Hºòb:-¼ñ$¯mVÂ\8c \81\12æ@a±m\ 3\ 6D|\98ä~V%&·ÌIï*n\8b^\16\rD\8fÓ\1c\1fÖGó ð;OBQa´\18\r\b\98Ù\80UmD\1eóC\10\ f±®%-\84  \8c"\81bàqZ\ e\9b~1AMµ@Ä:§\9d,W\98\91\19\f\940\94\ 3Y/O\8bdC8\80M\ 6\f\ 42Oà\806\92¾ºT\18\Ph#¡x*aæ´Bà\ôá\14pf®1\86©\805X\9c&\1a0`\80\176T\18\f°(\ 1\17\89\89õ -Ü\89òpf\ 1Cy8Ó 1U\1d\8b)\81òp×\80ò°ãò2u\1f\942\959\8d¡\ 2¢\ 2¢s:\9dN¨Î·8Z\15\ e[áh\91\rd\ 6b\13±\10`"7³\80j\940\91\8ba&\b3A;\81\99ã©CÁDn\ 6²1\91ë\98p&\13Ê\84\82\84Ç\ eD\1e\90      \8fÍÄF\1dK  \85À)P2\ 299\88\1dTüÙÁ½\1cÄ\1e\9a"\90óAìàA\11È\a±Èìà^Î
+§}pHrj\1e\971ô¡\8046\8fË\87bÀñùP\9c.3\ 2\97\9aÇE§P\1eæ´\14ê\ 4R\80\96Ó<®Æåä.§\ 5{\\17{\\ 3\19ß\13LsêN\15\aæ~\a¬8pD¢âÀ§\87á\ e«30ª8phñq\9a\ 1g\91Z|w\86U\15 ÅwG¬ÚHh 67\93\ 3\r\e\89\ 6\ 3\ 2bs7\12\9b\8d\ 49Ð0VN#;C\835æèI*\1a#²ãÇØ\18Yd\12\ 3qƱp\10\1eA4\bB\13\ 1
+C!E\90e\ 2\1eßyHØ \14\12<Èz\81 \ 6\83\9bL#ÇâØC\83\86\98ñ
+\ 6)FP ©wbV>8\8d\0ôBiSB1Ëßu\16æÄ\17
+E\1c\83+x&\8e\9d°8\vs³@\8d[\ 1\17\90hE0¢(ø\87­ÀãE\8e,m\8bD\820ñ2\99Uõ2\1c{N\fjÁÆAcjà8h\1aúÅÄÉ8Î\89Áfd1q$\f\ 4>g3c14©ï$v^"KYVø­e;¤DË"$øÒ\84Ó\1e¯pÁÀ#ñÁ\98\19E\13b(@\12\ f¼À\ 2
+\ 6±WÁØÉBÛ2\86R\r5\85òzÍ´@\b\ 4\ 2ÙTuLUÇTuj\86Óf,\94\87'5Óêj¦uª8p}PZeª\ 3B¸(\14Jòð\ 6r\99ê<(­2Õ±H\14ÊT\ 5\ 4î\16·Õ-n«[ÜV\ 5\ 4\ 3\8a\81\ 1e\92\16ßÍt\8bÛ\92,nË\92"]\86\e:'Ôv\82ØÜS\ 4±¹\99
+GËf²¡C6t,\92ÉÃÃ\9c&\81\99\12\98)\81\99ã©cYX@- \f0\91\9b\91ÀL\bÌ\8c\80\14 ­¸Á²\99L\83e3\95\ 6Ëf\1e\ 3\r\96up\9aæq\b|\19\92úÀ\1c\eu,%T  UBÕ     \8fÍp\1a\816óà`YGê\ 3-\ 2)É%½¹\85\14(\bd\ 3\ 1¢@A0GOÂ9úÂ%s
+\94\v¦@¹Ì\fx\9e\1dÜ\86ÅmÙ\83\18®ø\ 2\ eîE\12R \òAìq\80p/\a \13Ø\17È\1f\8aη@òË\8cÀ¸cFl.§\9d\9aÇ\85\ 1f\82öCÁi\8e\ fé\8cà4ÆæqÉpÚgÛ<.\9b­c\91|ÌÑ«*3\ 2+d\1ej¦e=®Î·H4lZN\8b\84Ó<¦Ek,\1a@\b÷"á4\8f@\ 5Ê[\Îí\85ò°Ç\1c=Ór\96}\82,S\r\1dY©c\91ÄF\9cLàÃ:,\92èàrZ$\1dsô$\9c6\86\ 6\87'«,\92ÎùPq`ÓÃp\87%\99,\9c 50U\1dKç\|\97Ó\14D\9c\8fk l\1e\17        çá.\fÜ\81»0p\193Ôâ»\1eéS\10È\9c/r!YU\91\8c¯    §y¤Ïc=\ e\81ï\92\ 3\r\16   §iP\9fÇ6 \13¨
+GË\8e§\8eE²iÔ\11h5\89\86\14é2\92\ 6B'd:]2§5@lº\86\81Í\80E2°É\e\89η(\904àkÒ(?\10\9b«å\8d\ 4äà;xxl8<(-Ëi\8c
+\88NGÀ¡ð"w\1c\17R\1fh#\9cÆX\946\a·± x³\bü±\17\a\1e\bU\1cØ1K}>\8cAU     '\9cÆqûÀ6F\16\89\82Bd\96òX®1á±£\85ηtº\ 6\8bD#â4àkâa²\82\89\\8fôy\1e]\83E2\86\ 6¸\8dÅ"Q\bI&ùs°¬æ¡ó-\ fN3±\1e¤e\80Â\b'\ 6¥\ 6Ëf"]FRÎ8\16\89Bì1\81\81ÀD®G\1aЯ-Bm$*\18\\16\9bIÄX\ e\19È\a}h\ 2Ó\98º\b\83\8dÁ-\vfÉi\ e
+^ý\ 1:\18\9cÓN\13\ 3\1dmr\16fD\83\16;\128F\12à4\ 6\9fcqebV6@4§\89\9d\87\98@\85Åã3        |1LF£Á*y        Þ\14(iÖ*up\e¥\84\16Ç^
+ÎÂä4\87\ 6ý \92\v\f\ 6Wpá\ 2É¢ìêĬÜ,0\91\vQU #TÐ\ 2åÚX\14\94å\fU\99X\87Ì\87&\9f\82\17ÚãÍIud\86\85»fÙ\8d*\ eÌi\8b2%v¶Eà\83re i\ 6\fI3°q`\16ÉV)^\ 3\9b\89â5°5ü\83nËÀ,\92MàÄ\90\85\85\96%·<²\10Ð$t9\8d \93\f©\93\f&¯;ÖU\bs\90\91}0É"p\80\17È\83\8a\84Ox¤O\16Ú\16      Y\0!-\8d\10©¤'\964 M­\10ÓX¼\99*\98%$°\95©\9d\914¶ÔH6(\ 4\94
\1d³%ájý½»Ðª\95ûu'}-\16\82\12.        \94~H\88\1e°\bÉÃvм<\ f\b.0\12`\98e\§
+\88\8a¾p"\e\ eðÀY\8aF\92ÉÛ¼Jÿ\9fJ\96\ 26\13U\ 1í\12·Ðj\82\952\91@öôà1\0ÙRg\80U°±ec$\8e\15\8b¤û¬ò\16\euZ\9f\8f·Ø¨c\91H6eYn\a\r\96\8d\14hP\14\10ùämIOìêÌà\8dÓd'\ 6\81\16.Ùt`Zx:\84{aè&\15É\8cÓ`Ù\86þ\0\1d\e71+9­r\166\e«p@9#°*%`9\8f\97\NK&lL\83\ 6Ë\92\88ã´\89\ f\91"\19A<\ f\8b\ 3\97±\9eª`ðÈ\87\9ddwÆi\15\94\ 6Ë®
+üBb\80E^\ 2\eqÊrÛ
+&\11\89\86\ 5§=Py\82\8a\90\v\89Hc$$ì\ 5âÀ!R`\f\1eZ¨"\1e\91ÕF\ 1~\12$*\ 3\ e6|`\10<0\f\8dSÇpIØ\1e\aY\1c\12'ûyÐ\9cö\9a$\80¦ð´§þÐ\ 1\95Î\19§AJ\1f\93Õ\ f\1aAw@=\87JåX+\82\83\ 3aÁi%\91\12*\89\83­\18Èr\9a¾xºWÀ<\91ü? kqàÀ 6¤\12¬b3ø£kÈ©\8eÃä4²7X¶t\9aÀ8Ë\90à\1d\18
+\1d\vv@Q¨Áà\9cv\10\8e\1c« IÐÜ\8fq\16æ¨\0\81c\1f\1atw\98U0\18Ü\9cTNã\90\b
+$\11\ f\97\a\84»\13³²lt\87ùX\14pÚØð0jO\8eÀ\98\99;d|Å\81\94ôÄ\9e¸\86\99\ 4eÉiçB$nN\81Ĩ\e,+É\84*ú¡r\1a\0G\94\r&ÁF\85\89\\96x\12d\87cÄ?
+\bTU}\1c\ 6]garÚ\82\ 3£c'0\98Ò\88cp\r\83\89c9-\ 1\ 2\9cÅY\84"\96cQ\r:¤/\ 2\91×.Ð+\ 2    §\1d<d(\16GEaÔpb\98\ f[\81ÃD%2<\9c6rà\12\96\8c\89\95\8a(%d%Ò¨9-dbS7¶\8eE2ó \\r"\99\88òÅI\15Ñm°ìã¡`\90Q\Ç[&D\17ý(é\89Eð"Dy2 ÊÒ\ 4q\9a¦¡Á²bg[$\12\1eÆ\ 5w<\85\80ç[4\v\8b\ 3k\1c\11\9b\99\ 1S\1eÛ\80\8d\12X\ 1\83^÷<+\8d¬ÑH\90&&\87\84FN(}:\ 6\13ó@ðåª$\97Aa¥ðµÄd\1d§qóa\13ÌÑ\93`\8aB\81Ö\r\95\89%3£        \8f\8d\1dl\8b¤[I.\9a\81\8b\ 1B/á\84       ïá%¹h8Êö`<\9b㠩بÄÍi3½\0í\ 3bid\86\ 3\12  3NjÂ\84Ä ·\ 1Et\82ö\0\7f\11âB\98\11\98kb2\81ljNS\80d¶-ë\98Èý$\13\ f\e\8dø\89È\94\1a1\88Wý½\10¼.\1a\aÍ\ f\8d"(\ 5.sb@\ 2=\86M¥c\9aø\9emN*L³-\92ËÁ\84Ç.\842\17\ 6RQ\92\ 6\9bW\10\r@¶'LP\16®`\80@a `Ài\a>\16Ã$p+m`í\rÝNf\8f\1d7\1fÖZ\1alKóUH\f\ f¬ó[\1aï4]2\81B¦(\14h\1c\92Ll>_\17É$$\99Ø\89êt\91ô\89m\91ÜûÁL´S\0hº÷\83!  k\fQ*\vA,ÙGOó\ 3é\9bÇ\96ì£\1a\ f®(\8e«ª\1a)FÐ,Á\0`YU#\ 5èúDñ»\9f¨"C\98\89¡ 9«ª\91Â\8aÕ$_ç¨\9a\99õ\94µl\0Õª\9a¤=ÃS5R\84 ë#AY(¶@VY®T­ÖÈ\ 2AQÕj\8d\15\16\v\94\99¨4R\88\94¹(E\9dR
+\91È\0\0\0\90\0c\12\00((\18\91\92\91$\84\98í\ 1\14\0\ 4vV&D:>.&\10Gc¡@\18\12\85\81\14Ia\14\83Q\10\ 3a\fc\f1¤Ìé \0\e\fû8Âô[¾\12£\ eû]Þæx&SuÙôLOé+(và ]®\82&Á¥òal1\ 5\9e\94=KmpÞh3q?\91ó\16­\85\ 6\879ÄM\99hk(Å
+êÝYÐØ\99Z\ eEÃC¸\13g\1aúf]\17\92\ 3ôÄ$ú\96-»í\9f\r\0ù.\9dP÷£¾u\19<QÇ\1aØUs¿VÑ}5x\ f\91\ 5·¿\8c¼\10º9\19\ 2\14@iÂD1\1a¥É\12\9e\1e<|FP¥}Öc+Fõ\81\89\97¢+С\14ç\r{ÈÕHO\19]vʯè\86[]º\11øG\17yLÏ\96Pùè"\8aU"o\14bÒëT\88Ð\1c]\f$\88òèÚìû\90ñ*#P]£[\1an\1d0Y¤Md9º\b¾L;\14ÝÚ\v\9b\16\16¬\8a\ 3<ݮĢúNèÂA\8a\92\eþÑM=rY\ 6\1f÷&¡\ 4ÎèYZìQÅ\11¡\128Ù9\88¯Ý5QÜ2̳Ç\92+ò-¦ø³\9cü>\8aéÃxRÌ\e½\81\91d\aÏ\r\ 4p\rçcÆ\83\960?ÖH^\91û/nX\98\87\8a;ôÖ\0Ä¥{*Â\ eS,Qò\8ef'W\9f\88\eÊ`GÅ\8b\b1.ó\1aB.L\ 6\80×E>ÓP\8f4\81þpöt\9a5\ 4\85V\7f&\1f¾PÙÄcj\10¤\1fG\ 33C\94a*¾\À÷(%å"+IÐIJgÉ6©VÑ*â$«<¤ü 1\ 1Ç(\9bkgh\89§\erË©\ 5©¦\10üß\84\16]w\b}r}1\16à-\16\v)ù=¥>\v\ fæ¼\1cÄ\86À\11Öíoy³\97\93\ 6û\88ËÁþ\89mfÞ6ß¡¼(kü¸Dp@\93ö\ 5ÕCV\11,ÖöÆ\83,̸Êkê!\94­p:2\f±M2Ý\94\9fá\83ü_YsH\ 5\8d{é4\9c¬?\9d\83G\13å\a\a)~\1a1¸ð\a\ 5ñä¢lX\98¿rØ\\81Z\15Ú\ e\9e¡\aV\85\19«\1fÙ\12\B\9cñ^\9a\ 25¿          \98TÜâ-\83\88è\0\1f\ 4öâYb}ÃÚÆÿf\97Úfº\92ç}¥;µ`ºÛ.hà»t tE\8e\9dseÅ\9b\12ßÈ\98Ç©\sLéÂx®ð2Ý[8rÍ\85ê\8f$ø`ºï\ 2UöO×^¼\19û\89eºß\9b\91®\8fÆ\ 6\97ß\99®àq+Cp\1c\e\e\98®Þ{vx!\0so9H¹òÌt\8dfmC 3ëÈ\85ÂLÈ*\9f°*t\8cúòJ¥q^ "\18ý¡Ì\0¥X\98\1f\19bST\86F§Zß]dV\ 6Ê=\9e\92\96X\rª\93\8eäÍqÔ+Ca\a-=·Ê×Xe´!Q\1a6\ 3ѧ¥ã¹:q¨\1f\ eÀ\8e[ätú\1fW\80\a\90\ 3Û\UÃÒ¿Ôìt\ 3ª\8c\92KtÆÍëÞp¿q\ 5OYeÄaÁV\98 ^Æ(¥Qr9\ 6\96\1c\ 4ìt3\97\a\19*ÊÂ\v\98:\1eëK=õ\ 4{K96\1a\8a»²v%\9f\19xáÄ\83[]¾K±¤r.5k\ 6·\93\97\1f8\v\b|2åóÙ£Ñ\9f¬_Òäã#\12ã.ò'ÀÿR\16\ 3\0[W\1e:e~\80ð\18,\9fZ\92\98-w\90¤ñ$\91ªÍÌúq\vÑ>\94þM\824\82\ÿ\86ÐÇ\94\9d\ f:\8c­Ø\8c\8cI!\91Ý\92R<\ 4\8e\18Á¬é¬ÁOÑ\9cË¥\v¯ÂpqWf8v\890û³i}\15ðer\e\88Öé\87\ 1È%¦Ñ¡\8c\19\85\fÏHp\9bré\11ðQUí\1eÓ)Â^\88\91tt,~\14\1c½¤\18\81aïÌ÷Û«éZ§À!%¸éhóÒheôl\13\10§\1a°.B¨7|7Mó\9bÏ\b\84TQ\15·æ(Ã\9bà_|_«~\90¯j4ͧ\82Ü^ì¦\9f°ã'\80Å(\eNc^t\ 1Í\8c\19\91ú\ 1@\85xÖ¿À\8aÜFÒÝä~¬EY_\95\a\84\83ãÒÒ\8bµ]Úe!\19¾T\fò_\18±\1aÅ
\19ÑS%Pøe)pÇa\85þ¦\80Lc\ 1x\r\11H\8a\18Ü\v>.\95ë\8e)\10\eò®h±Ç\ eÜ\8fA\ 1dYX¹aN\963\a\97­#Bxqâ\ fÀ#$( .E\8b\a\89ûU\bÔ#í\80\8b\13úÁ\vGÓMá¹Ë]Q?ü«jh\ f±\90þmi¦!ëQƸǠ    y%õ\9e\9cbl¿.,\9fobÒ \7fßîf\8e÷1Öt\8f.\11\9a¥¦è\80ºD\92\8d;ÿ¶2Þ)ÕqpuÏ\19¤CÓ\9c\7fº\fJÃÿûõ´®°xö>òmX\9e\90\98  I@«dá:\1eø~\8b\f(\9ccÚ±EdNÊ+uÜiù£TM5F\80\90\ 5â/¨Odº\8bÄøW¡\8b8bS\9eú·Ãó\9f0coÈO\1d\ 2úR\9e 5#\84\1da\90ß»rU·PBÞ\8d£\1d×9áäè\1atf\1cì#¡670#\92Ý&Í\9d\ f0\8d¥V\ 4ÞOI`\80E=ófÊo\õ\95ÊËL«¯Ibø\f\17ývÿì·Ã\16\83¼ÖwØ÷\8c®\10q_n 8D±µo\18\f\1fø0\90&ÙøãÈ×jP7\83\ 3äTSÌÖÿ\99Í\r¢\93\ 3\ 5\97¶6\a»y}\92\eááÑ ðÁ\98icxÄÑ\12§ÐÈ\9a[·6ÝEPÒíT³*d¯Û<\09\18ï#ÿlT\ 2»A4\1e\8d      _þg·\14\82\16\83éßZ\98\17Èp!9HG\e\eÁn\8fÈÉ\96\9fn»L\8dsÝ¢
+JAë.Üô\18\16¢Á.\92×\8cÝO\13;Í)ô\9a?\8b\;\16X ¨Ä`ÍúÙe\15È_\85!\17³íBJ\87å\82_
+J\88<'ÄC\934³©\ 3-\ 1\85K\ 2¢
+jDÅ%QÊq,l,=Q½ÛöQÉ\9b\96õ\9b>\17·\90ä\14\80Ãhc«ì\7f   Ç\80ÅÐ$ ã,\1f\\84     ÞkzáPC-\83-\ 3l³_^\7f{=Á+\ 6:î·Â}\17Æ¥Ë
+S\16(í<\94XA\11ù\99®¾]\ 5u\9e,\16\98&\15}ëÆªf,³¼Ø¹øè[x! \e\ fs\0\1c\1a\9bQÂÃ\1d´ï\92\80\97\16øÎ\b\1a\9e2/B"°µ\16\ 1Û\87Â\8bgI\ f\9a\8a\ 1{ ¢[Ä\87ù»g±èP8w6\8f\98@Xä\86\0\98\1f>|\ 4ßrÄ×-#á\ f\93Wô~2¾¼ùqH\ 6AB\18\8fOoá§>PÄ    \ 1¨·ù\9aÉ"æa6²n\1cÇw¯\16\89X&\95\87§¯e\87¯\8f¯_4=¬ÑÆìúJ/|I«Dv||Ò÷Àæ`Ë\9f}´ÝÏ­\8a«\1c\89§ã#\97+Äs-iÜÏ*Õ§Q\9c·\ 6¡V\vi\18´\95\82:ï¹sQ\83\1dg]\86^\83Mþò\0ݤð\bQ\1fÿ\9fö?Ðí\ 1\81
+p\97JqJ´\90T-ÒÒ_x\19\93\bZ¾N!\92ý\8aPzWøï\94³\13\8ej\11ó~\1cØÃ\ 6M¤b-× ðHñ\98\ f\93/\aär¡§ÕS\82ü\0ûi\1fèr\9aËPTX5\9aä\eû×|ia¯gqy\85{ëH(HZ5\16²ÿ\11\90\1að·$aÊ5ÕHaHÚ\14í«Éöð@Í\0\96l\8c\9c»×º¹\1cÛú\86 Âã»r\13Ê\9bäª&Ðèa~!Z\83Ó\16¤\ 3·õ½©æ7eFÖ\16\9cÁTG'´+\1a£6\eÜ\82Ñ\94Þ3PîKv`NCVãªT\8d\83\9e\1aéa)a\97Éeß/\92ö%ï\82¬I>Cu\15ÇpùDøÖñ\14ÇÂ
+\9d±\94\1af\93³`P\99ÜÎê\fø\86\1c·\9aM\9dgëiI.»o£bW\97­úx\19\1c\ 1\ 2xËÍ\95Æ\99x\8a+/\99+{â={ÞÀäY\97ár¼: \ 2If
+\93\88½¢ò\9eñì*÷¶Ýµß\8e¡À#Í\9f?ð!o\9e]ôaÃsq7\1dÕ3\88\87\839»}5(aÂÑíÌ8¼<{WL\80ï[\8aõóLu\93û¢\8f$\ 4|\93E[\81e\9bÑke\1döÌdîMR(,\\86¯?RAÎ\ 5\88 E½l:\ 4\16<\ 5¡\96bkØçeH[!c&J%¿\8a­\f6\ 5YÌ!)OqQ\12í\88ÛR;\8dÄ6(¶\13í\9a\81\9cý\11\19¿\96W\1fã,lÇ\9c\1f¹È\98·\eßø~\14ß\ f\ 3\8c¨!§<¤ÿÌ\15\879a(4¯\19ä [&@\ 3X^»{Jä4UyÜ¥?PÒè^ïrâ×ÅkäÏDQÞ\98Éfdå[Vû>\81\8584´×ä\92zG\8ec\84Þ®\92\88y
+vÖ¤\9e\11\ f\98ziægPFS«özò.\16¬\86ùp\96â]\8bvWQ\11äl}]~\9e\9f0hÌ\ 1ß\19\19X²4\90ñõ\82ZB­°ÙçåUD¨
+\15Þ\16Ì xnykQ\95ç\98â\8b\80ùË![\86ÕÁDD"nhí^ò\1f\90ñÜqe\b\ 1\13Õx`ÿêºÉ\96\15Ï\15bµÏ\ fÝz(\98ä   !Æ\1aÜõ1ìÂ\ 6\11\ fA
+\9d6ùÃ\97\ 6\a\12>gyÞ\15Lå·ñÃ\95­`ð¨\7f\84\8c\7f\18ª\93\80b\1dN\1cÒw1Y¨æeP\86G5\1a\84\9bÉM\ e\915\ fè/Û\8eæ\17-d¤\1fýõ¹\10þ\93ò-\ 5¿j\96úF\94Ì9³n&×Ñ\93\8d\ e
+\16\97     \8ar¶÷BH\ e®\1fõi\bßËJRcJd°\19jÚ-°\8e\88ÝÁ+¼þ\14\83Bmz5(:Ú\9f¢¶#¨q\87M\ 5\81L\8d+Èráø¤\ 6yCF¥³Ð%\80!\94Íþ~§$\81´%aÐÅé\93aWE-ÎÁý\18 \1fÅ\ 5}=?\90M\81   ¼L\1f¨3ÞN¤ÖYÑè\0\97¦Ö\896?`\85¶9u\10k+ãc \9aW\18ª\822?Ô©(6Ç\89³\8eW\7fA\82¿\15\91\88¬\8a}ÃZÌ))"rc²Ëù\11+/8\9c\e[v[Ó?\1c\1aIÌ,\1d½N4r:eZtJüA\89\1fX÷&G\80U.M\rùJ\ e\92á[\83Áo0Úâ\ 3Ebïg\97®ë¯¶ï\aD3Öí\95¯\}\9db  )[¤\95*íÛÓ\91×b±|Àà\90Á\1cú!ÆK" ±*ï%2\15\1fG\87Ù¨£\89=ÿô$Óvo«\9c\ 1\10Ô8VÒLx\96¦\91\ 1fÛÞÓ qðix]B£-ë4\8a±\8c\ 3y\90Y å$oþ\1d\19É¡#÷    YÁN\99Ñ)ô\eÊfö\892ÌQ#Ù\v\b\ e|\ 4µ\97\8aû!âÀÑ\9b\18àöA M\97\vü\ fCõ H_\83.#ó\9e¬»'$]ø9ùµå|÷®g#\ 2­5Ì\vä\19\f©ú\14^\f\10Î\839\9b\95²*n\82ý\9c\87éq0\ 5\1d\ fðËåp£Øá-Åü\86tìAù©Éºç8\91â\97Çþ¾:Þ\86Z*vÉ\ 3\8cl\w\8b70ß\11\8bÔH\89Ú{ \88\ 2!\84Ä)Ýà,ä7\88À̹\91\9b\85\a\99\9f\ e\86µÇ\1f\0\86¸\99{\81Úh|h\89ó\16ù[H<7©P¸%Ui$[C\ 1ù~^d(S\b\v\8d*\19t?ªo@ûÁ\96ï3µt@e\bÈ\1e*F÷WÖýl#_¢ÿ\9a\18\99YU×h\ 3\93&\ 3D±7É\18Å9\bnÛo}b\85¿ãkö\86\9fì\ e\9cåd¤ÿ·NfT\1a\1d>\8b\ f   ø\91ÌzÓüß²X#(\17~åô)\8f\ 6Ä\ 3§aý~ò^|~«¦PÖ\96\82     °ê×\91x×ÛÀËo¤gi\eÙr\1fµó,M\87or\98צ®Ör\ f$&I>\rø¸¬¢­pRS
+\f\9e\8añ\93 ¯Oºê±ø>b&×T\8fIuö\föh\0\98\9a\12\a\90`0ø×\8b¬       ¡ÅszÂw$VRÍ\9aàF\ fÿ\ 3\11Ã\1a6Ëì\0cæ>ô\1e\v+\(qvLh\9c\7f\86}D"Ð7#Ry!u\b\16\9c\84$\93\80\9e\a="Ø\85ׯ\9f\10H5i\92Ìõã¶¾<;Ú\8c\øt¬W¯­\91põê³þ\ 6¡ð8Éó6YòêQx¶e\v\8fxQåÈté£\18¤zíìU¼,\14h\9eÖ²Þ   <~\16Ù\9d\94\14ín³Õ\19%-´G~\9c"\87\9c\0¿V4\13ÂõÓêic9X\8e\96\ 1éL\95\ 4Ùp\9fôZN`l\8fì¨N5Ã\1f\8b\83K\16»ÔcÞ+}fûF\9f\97\ 5í\81ª1¨fè÷ýÌ2+'G\v\18\96b\É|\ 4\bµÙiKW-p:¦ëÉV   $âÛ/\8e\ e¢Á³þ\ÆÑ<:\1f\13ûS5\8bQ\9fþÓ\ 48\ 1\81î{.®ÓÄ\8a§\99^³/>ÍÃz¨Î>c\97\87÷
+þ¼]\90Éê&\87êàø5Y\86÷îsce÷Í\r]ãË×õ>£\ 4Ìl\e+"!`Hù\fä¡\1e\18\8a¾|¦\97\bê&GÏÎ\1fC\97}'üË2·×\\99Ðàlë6\15Û\1av·C¾VÆ!\1aô,Qx½ôD+N\ e¬d´\8fbçë\14¦c\8aÜ=2\0dF\17´¥\f\7f78ÚW\ 3I5Bê#ö\821W/vÌó\87Dr\81=¡u¿\15K{©+gíU\8bÐ&éG1c\83d©å)\12n\ 1p\13 \8fãÃÖ\12tN~oro÷×ë37*¶<FJÆ\aÓ-w\8a\Ûõ=\b\bðd\10Ò?\11Fu\99ª\85\rZ\ 6¢\96ÏÁÛ\1d\8aÊ×Í?ÄþÓVp\ 1l\9eb¶ÀÞMC\ 3ý¿-nhÞ<\vk\14*%\80\b\8d6\ 5\ 3ew×\\920·       Æ%\93~(Hx%â{V\8fÒF\e\1f\9btubwâ)r"\99HǼÕMÞ\86þ\98Ò\ 5ÏÅ^¹&*C3\8f\vQÅU\8a\0&\1fTÐÀìÝ2\8c"\9dà\ 27:\8að*\b|Y\1e\97mÐË\8fø\83\1c\11X°Ó\ 5-Ð\ã'(iz(3\9dº\8a\1a\8f;û¼Ëï1ÔØ.ï\ 1\e\ 6ê z¦_'\9aþ íàÙO\13Á¡æ,Èû$ßz}ý:\ 4»\8aäN\ fC\8cÃx\86\9cê\e¥\90\ 3\15]8ÑðTËi µ'zÿq;º8]\96d;.\85\8e\9eü#¨\13¤«Q\1aT\eu«c´ÛÑ?°\9d§\9a\ 41à9\87ý5\11Ç\ 3&ô°\86\96ëà«¿®n\97\98Ç\8b\97ÍxÔí\13É\1fcdí¶\1ah\vuDÖn\10Ð\90k\9fEé¥\83ZL!!G¤XU(íðýê5ö\8f\84\ 5Á\12ô\1c\8b¯cF5Ë3iÈ~5Ö\8fÈèn\867~¤\93\83õ\ 2\83\95Üü°mdÚüÃFsuu+ò\ 4\99(pã`ds\ fWàP\9a­7\8d\8dêZ<:o¯îi;÷e ½°«\12\10\89 g\92ê¿\96L~º©\ 1\96ù\93E(.\ eì\9c\92ò¬\94\16^\86\90X-¼!U!\8b)\1cF"@§YGD¦îiBøÏUµ×2-\ 6Wæ?C<¦    p\9e\80: g£erIwiÕE-\85*\b¯\15\0\vHU[àUW4ðv\89\11ùa°ÝAKaì)|#øþ\12Ì@\9bÓ\17O.
+B[y\ 5R\ 3E=n±n-Zè[0(ýÄÌ\8f\95\0ÚÏK\14D0!¦³é9ÎO¯.6\9c\12Lú÷!Ò\b\952æfúþ\ 3)Îï1AZ\ 3 \9aºÙïÛ\1e¿t?ñJÏ1'\86ÑSf;x÷ÎÑKã`«uâöüç\9c:=¾ê:\96óùCØÔ:ðýF\9eæÇ\92-\ 2Üy+ÑL÷åî\bbì~Ç\82ºÑì\7ftB[ÂZ 0Å\9b×9øä\99\ 1O¨¸JÛ\b\81\ fàSõ³[\18\ e\83(A\1c\88\8f`ÇÐ\1fá¯o\10jr=¡\1aLeï\85É\81åÇùíªDe´\bÞ0ø¿VÒ¿\8dÿÖàú\ 2\ 1\85?\v\8a¯&ÌícG?\81TÍ4*\aàú\ e\10nÀ)h²^\r\88Ôû^\15¹õC±\1c\ 3´  _!xõ\91U­&\1fC"fK\10\99¿\83¿ð°¬íQñsn\95#\16|°¼ñè;º\8f\15\13°UÀ\7f×y\9b0\92\84È\8c\8aÔàõt?Y\ 6¯\17¤\12zâ^QH+Àn\ 1Àߪ\0ùu8\ 2éFDÆ\9bHûiu\8dæ\8b\87¼V\94h=ÆR\10\ 4s\95MåCʬ\ 4Ú\vþù\ 6pkén©»A\82\ 3é¼Ö\f¥Ð\99\83\ 1\81Á<¶¶-1!ü\9f\8eZD»ã}\fÓ\1c
+g\90f\ 2\84\1fÀ¶ <ÊÅ\r­ éD\99¿J\189\91\fw\v\86Z\9a8JìîÇé%ifm\9c×ÿ?&2D±ð/ò,\98/Â4¢¡\895İ}\8c\bV\1e\84\14ð\14\vù°.\12\1aán.ÄL ]\vÂî,@MÿÐ/m²ôÑ·4\16\91      `Å6?uÅq~ç²\98³\ 2w\85Ãä\99o\86A@|¢Äð\91\1cK)=¿¨·Z¤¸´VÊï\85û\f\1eùª¶ÙmÑ´\ f\8c>FSpiÝ\19Ñ\9còRuS&Kø\95\ 1VcC)ÛD@\ 3»¨F \96\11ï\91\10ÁÅ@\ e`$¨e)³®DLK\r\8béåëÜ?\ 6Á\8a\8a
+PIc¦³´ºì(ií\ 1\80\91\9a\f,N\eçKñ\b\179ãûQþ?'þ&õTanÜÂܯ7\193]\ eÄ­dÜl\96©s½+\84údp8Â\ 6
+\8d)òR\8e\b\ f\88²x\86+\99¡ñ©ÔjÎ\81?\8c\18Ò=n\96#
\93\9b\9bZ®?x÷©L8öI!f\973íB¹\99U\8e\r\8f\85×Z\83ÊLNº\ 4ÊÜjÛ\8f§T\ f\9a\85¯¾Îií\81K8#E\1câ³\b¸bÜ\adcµ¸\18D;\15\b\9dÑ\89º\86T¾n´ðe\ 4\86bmV\94J¯Ø&ý\ f)"µ(ݰ_K\14µþ_\ f\91Óz©Ùoe\96-\ f¸éD\15Ñå3u7@X\10íÅ*Õ\bÞÔ!;ãhEÝy\bìõ\11\ 3¨\18\ 6\0\16ôÁ\98Y\95Ñ@ÛÀåÊØ?\rÈf&]\e¥o«;\15}R\v²³é\ 2bL\8f\7f4ÄYÞÑ&N\19\1a.§ÔÄ^ z\1c\11ð\95:p\1af\88\82ó·2Â\ 2R\90²&âM¸É{U\19ud\98\80\19º\ 2HêT\16ý7\90ÌR ó¤þê\8c\88q£0ß-á\8a^f\8c\7fÃ\98ÔQÞA+\88cNÂR\945âµìÖÔ·\9aȲd\86oèðtÇÑk\800!' ISM2ýs\ e\82üna\ 6_\92¯ÑRÑ\1a°Ç³¿\19§er\88t\11í\10\9cQ\81¥\84á\ 1ý\80Ì                à\96ä\8b\9e1"l\9d\8els\18\88!´ÈÃ\1a\b´9[\87ª\8eË\15åqó0Áº\9fo&vr騫p\1cÑ\en0ëÌ\14P¾HòFÇ1P \ fi\90\14Þ\15{\1eàk\92Ô\9c>ó£þ"\§ÛÚÌu\86!\13\92\1f\15\95\88\8c"\1a\8c\14°¶Çn¸5ûóK&pJ´\9dB\83ë\ 5Æ9\8f\17F\89u\bÚÂ\87Ü\95ÞOS7?·\16OÓ]\9fs\90*\ 3/\1e\91Rç(á)\97µ\13Õ.\f\e\13\8f¹|¹OqôÒr\80u'\f¹{~e\99ä[]"¬Ä\1d½ê2JöC\b¼VÉ\8e£¤øáÏ#nìvCTL%Óv\9c¯ëªDç\15Z\9b# ­»\1a·\80\1fîw\ 2±<8ZÝ\91(¾TÏqør{u÷¹µ\94\ 2Cc\9d\90\86\9fW\85,Ö2l\86Ñ\16úú=\0ÂÐ"ëÔN2Üý?gÿI#\1e\14Âåi\vp\96Vçé,ôöÃ\ fMéd\F \14\9c\9b\ 6\18<éz\ 5\17ÊU5Ux\83Û\1c=\1eê«é¶(â³B\12¨Ë¬\e\97¤Ý®ëä\19û\9ek£p6\ 1Áï0B\9cÂgÏf\9b¶QGF*<2c\85
+¿åC4S
+FEN\10\15\84õ$PK\9d¦/rxû\82-SÆ75\1a\1d\b\ f\8fjGx\89¿       Æùæ\9e\88,\vîy«\1e£\11»$îä/ \80\95\8c\9fbu%;\88  @é\ 4=
+ÁÐ\ 5*\8cÃû'©®ûõÅ\17\0ãÿüOãê J\9bð\14²f\ 5f:˧\1c+Dp\17_\9bî\8e°­ä.Lñ¦\96ñ\13\98L\vR¥Ý¸Q»è\v<lb\8b®¸Ä¿ú\v\13fF\17\93ñ\11\149N\8f
+xO\9c\17%\r\ 5o\97\f\90\8e\14\13é\a{\16í\9e\8aجÝY@½;Mn.%N\v\8cÁ\80½fðɪCcÿ\91Ò¬W\a[OV@PúfæÈÚ\13D\97\9e_\85\1e¼©a
+õ³N\89\1aÜÕ±×A\10\ 4l\10¨ Ë\9f§\11X\17óá¼j! :án\12­\ 6FôÖ\8ddË¢      ôÈ(k\89»=\85\9a\8apI\91¨ìÛ-ÃD{:\86\ 3\89áÁ0ybóTܪ\8b×-\aèèqwÕ3\92'\81w+E[ï\ 6+G;7\1c\81\ 3y=QsH\9c\894>*2¦ór\90 \ 6çu.¿\ 3Îv'Ã\e\9aU\80¿\9c¬A×þËä<%\87Û%N§¿Çg\9aa´U.@\ 1²ÉBßû0Ö$M\ 5=㮬~îõ\92§aÁhò\99\1ajGÀ\ 1¤õ©÷X¬È³B\10\9d\ 3ÑÐ>\86̤\8cTªI\ 5D\94ñ\8a AnZ\91'\11·\1e,Mxcö\80\83Ì\8a\9c\8d¿ã&TÎ-ig¶`á¾C27»\99}ºL\18St\rì,U*ÿÀ\1d\802|Ée¿#v\96Ð\9aÿhGñ;\aó\81Pu¿4X\14Ð\94\1e;~Ï#C\10\1a¶0À¼ë\A\7f\18KÃ&\ 5ÙÇ [ Ò\1cT\98\88$K²Ì7Ë|Åï |\90u\8dO\8e¯KÞã\10\98,\99`iE\1a×MCZ÷\9cT^§µþó»÷¸C\92\18Ú\13ë\87=¨CZû·gF©É3q\ 4\8cKL\8c«\13\ 2\11\99à?:ô!²²/ú\8cAüi\b0VR\96lB\9e\1a~U:"II\0\8eX¥G*õ-0½_>\90\88c\15°{©\92U\9e\18ç\14>h$\87ÑRÃG×ç<      ºÌ¼Í{Öpü¦WÙ\95\80\10\ e?\1f q\1cê¤\ 6Ë\1eIô×}Ò\8d)í¢']\ 1â\10\8e\91yÙmQ5O\99\16C\1d\bÇeWÐu\8aûg\8f¬u×ýÃ\1cûG\18Í÷Ë"\86/ÐtKòF\ 1%ª´å\8f\1a!rÃ_ÿ×\82D¦èÑ´\e\86\ 6\91ÝÌ\8f\r\1c\84û \ 4$\1f<\ 6¡\8a\89?\855Vñ\ e¯ò%Íà5ZdÆØPý\9e3\83{é*ÁTÜ#\18?b\8cÉ_M\92\15âQ\xJfZqñ\92ìi:äë\84BÍþ\85*ûVåöÐûIà7/ùºw±L\89!4Å\17µeL·GsR,äã!\94dCà_\87\10\ e´í>ªpX¢MPÔ\8c÷¹\9ej½nþB©\97RYÞ4Y\ eöÚX§ !± ) ÆÇ\95«\89R|F9<Ppóa9\16\16\ 1É\98\v>2qÅìéþÉ\13 -*ûí\83\¡Ú_¶a\84Y\e#¢%ò~}ð*hZÉscó\ f\12\91-\fð\r\9b\9eòê        !¼^AxGÜ*1\8a8\85E!¹~/# l¨\93\81
+¥h\1a\8dº\aó>"Õ\97ØÁ.\1c+\r÷(§<\84\1cµ\f\1fr\14é\86.%\1fF\16\12\vt\r\84ä\13+ºéÎÆ\1c\8eàü\9a\8fGj?½³ò"\a{\9e\8e\8b3j\93"\89\10äO'5\f\1fS>¸zR´:\f\88\ 1!T¦\ 6pFÑ\ 5ë¶q#þ\1fq\91\85#¶aøÑZK¥%1\17\8c\1cÔv\10j\v\7f
+\88\96o¬.\ 5 P\85T\aòF\r\90v\1f2\18¬Á7¸GC>fS4½\97Z70_!fÆààþ¨>Ò\92§-ü$\92\12¾\v\91F\ 3¦ír\19\19ã\r¢Ý¤Û
\97o\85øÄNE¢»\93fj(Î\84\ 2èd\ 4'WYÊ£ÇD\ 6¾Óèqu?K²+ü\0\ 5X\18\ 6ìf«ÁC®a¹:í{hÍ2M>\89:\96Ü)\97\7f
+o9\8e/\9f\99\\fÆÆ(þ«\98\ e\ f\v\ e\18׸ÐË0´´XUKþìmvÝXÀÎbâÂÒÞ¿\80\e\94\1f\f{âL`¼(\eß½jf[püòLJT\ 3Y\9a!\ 6v¶¯ì$ì\vÍ\r\10Ç\10êD{£÷ï»ÌFÀ\85ÑrÇKî\898l`\87¨,3O\rAISó\r\90³óÇ\ f\7f¹\85Éëb¤xÛ»9®\13#L¦\eµ\13¯;\ f¥L\82\12þ²m\16_¼5BÖ\v\1d\84OLl \ 3îwõ½õ\ 6C.ö\93(a\8cƪ7\163£S\92¯Vëâ^\9b-\9b\a\ 6þ{Ð+q\b\80ûÒÝ\109OBf¨Ô\a!\8e\92ÛÈ\95z\9d-\ 2©\9eFE\16åáÅG0ì¼\9b°\80e4'\94\12.\13É|\8c5\89{«­µW\eT$\18?ÒLôØÐÁ\ 3\94ÎñÖ®\8c\1f6\98\16èµ\vðå¥Dw\992ôeÃik\1e\10e\r'\13ç\90\Dj¸ïI\94Øl5¯ÛþbÝ9,z^éôáúê}ó\ 3\88£\ 5Ù¯«Gbø9¾ô\16f\8f#^s\8dúJü|.CN\ 2\8bæZ    \ 5G\92\1aê\88Öʵ¤\15\14d\eÿr°¿ÉMz>\13\86 ï?\11\ fæÂ\ fÛjϹËðµq{V¦\ 5\90\ e\83\99\1a\80\1a\e%@¬\99Q)\82\bzu×\81{VÄ\9bÌ\13¡Üá@xRÁqlÉò`\ro\1aa\17üá\eZ\9cn%'\83Õùå\a\f¦m\86,Þ±:}ä\8cØUR\9dq\0Wkq\9d\8d\96ìi\12¢\92\9aâvÇ}"l¸\8dð׿_¶µÑÊy!@\ 6¹\17q¿&!¼1Û\99#¹°Û_\8f©Ýýéñ\ 6\16ëà<\8c\v/j\92\88\9c;RÞ\8eI\8d\10µÜ³Ñ Õ&\ 3JºÇÈ\87Æÿ
+ÿJâm\1eer&
\89\8bìzA¡Èr8\f(\ f\ 5ò=a² H"änT?\11Òq|%^;\1f\a$ÙØÚlÒ\15¡\ 3ò7\ 6\85H7\ 5õ©\1a.T\12\116Ña"\18Z%\86zZ\ 5\ 4É\19\ 2»\8b\97\8b]r\b=d\84Êõ\91H\t\9e\95­'V\965¬ÐÆ\81v\1e®iåK\10\88E\bË©B\96®²\9cÎÙuf\ e¨¡pàÖ$\86Y©²"¥Ç\7f
+Ò|m(À\ 2r\9dfÈT\80/ëklxÛùî<=\1am{\19\8c{N\80\væ\ eäü\r¯E¶dè\93¨G\8a\85Ó ¿»G¸«\ eËÛÐG´ý´ël\14\150\9d°#oÑ\ 4xb\17\85\ 6ëêrWkKE\83\ 5V\9a\ 5Õ|\9eI=H\9f
\88\9eã\f\930\90SÕÈZº%O<\1fÃÞ\ 3!|,²\1e2§I3Ç\90\8bSC8\8e\12\98HáV\96uþK\92,\97\84\10Ê\14-\\1cÔ\12æ5\8f\8cÙ\ eßÍF*\15)\9bx\82ø\9dÿ\0eaXÄr\8b\9b¢\1f\95ÂØ©Ñ\ 5îÊÜí\8eOI\\aÈ\86\8f\17Màò\91u0 FS/ \ 5oݱ©\95\8cP\ f÷ÇOß2JÑ>ZÉ\89\13>n>ýQ\ 4\99z`\9dG\17£¥\15åå?ãYQð
+ï+dò=¢U\ 2F\140L(ÉððM\ eùR\15¢nþ3\8eI)~KQS%\ 2p\v#8Oë\7fÚ\eIÊ8\15¯\0Y\95ºq\9bÓä\97\91ó¤Ë\83çN\ 3jÒ¥®$4¸×\v\8aïù\f\ 4¡V\85ý\16\87\82\ 5¬­\85GßZ\ 1¡¿+h&ð¯¡c\9b33øC3Q­²»Û\87Cî!Æ\15_97~\99á;\9añW¯¡\9dÄ\80Ùcç\94\9eeåíAßï¨Ú«*\86[èª-¤]y©á\9eÄj)ÖÚ\1a1RXÂôSâ"­¥\9c®{ZDÉ\88\18I=\8d}0\1f±\8d\1d+ù/\1dIhX\ 2ù\19Ö©á¥E\82QhÆBÉe\f\1a«ð¨!\rZ$Wë\r&*ûýÌs\f~ùà\80\888ýPN\0\9aì+j ¡\9f\ f¬nbÆ\88\1f\7fq\13~\18\8c\13Ð;X»¿\94ÐF\ f ëaܽÍY\ 1¢Ì\akÉÛÒ\ 2Ú<p,/\vb¡]ÜåÐFȨ\92\8açj\90³nâÃð[L/Þ-b¾ü­\8f/\1dðsL²Ì\12#óI\83 \95\1e4P\95\8dcº°\85þ<·\8a¯ +r\8ei\13\93o÷H\1aú³Û\ e\8cÑãT\fUz¸\r4V­$x]\839ô8À \aÃÇ)dpÕ\8e/\13\94\87\95«´1\10¾\18\9f\11Çôä·rP\8aü«Ã\12jÃݲ\e5\ 6\86ýl';ØCÁó\ 5*ÃnÒy1FEîÿ\85.\8d^=\8fy\99\97\ 6\8dKÂ~ï¿n(®Ì\0ñ\81\82"?×q\ 4 ({\8aDa@gjìwwO§   \8bÁÌ]\9d\1e7\91)^\16H\a­ôÙÀ ïLzüë°\8d©÷\92_H{ýyäǦVÊ*?Å\0\13ÐÕ;Ø7CÛ^Xõ?\9cl\8b\ 2h#\1dS-Z\b\10Ð\ 5ð©»\90\11~âEr¹\ 2\9a\8a\1cÚÇç)JW©åKg­\13\86ì\95\8bb»Û-$\9c\ e\83áV\83û\91\8d\b®\ 6\1e)HZê'À³îì(=4I8¿m.\ 1(Ö c B»\r©¶z\97ü«#]\87H°Ìãv\8e©Î\9aª^ØAC%\9d\e\9a3Ï«\a\1c©ZìB¼\\§
+\17L0\f `ÐC\91³Ï'\82¢íW\99{Úørïøö\90ä´\87¸t\10ú\9aH?0\9eb=QgüüµlÖ¾\ 4\1dð\99\10
+\ fÑÏ\11¿#é6 Tä·»\84j\9a&]*ãëS\12\97\1c\87\8f\1eCÙWì`ßi¦\89\17Xz\9a\94ÿ¹û\ 6\85â%¢s\1d\ 2ôHãø]°\12¾\9b\88\99µî\15ÆÁ¸\82üçÜÑÕ\9ez\ 2\ 6m\85&-\99öÙΩøàÒØ]Àj\9ed\97¥^4*Bk'+\88|:\ e*ɼs®Í1Sg\1c\1e\asçÇßýB8\8c±â\88ø\1d\8e±ÿa.\1c\14°1\ 1ZRÀÝ9Ò¨Í2³Jr*\ìÏ\ e\1eö\arC\80Ce8zø#¨öÂÊþ`ðµwÀ\19\atu}/-$e\9aÜú\8b\a\ 6¥)\19«SÓ\91Û1XÛ\99\9aë\8b´\ 3¢*Ͻ\1fÄÓ\ 6\0Å×ðµ\85%k\1d66==ÒD\8a\13\86n¥p\8b±à\99*7\ e9\ 3\0\92²\ 1\fwPñÁ0UZ8Z¡\ 6\8eA>±'«F-\84Sð7       \v       hÄ5`] 6¼q¿¨±\18H6F\9bË\16ÜàS×\8dñ'\17Z=¬ÀZ{KØ9\ f\94\8dúÕQëCZÖ\80\8c\ 6j}Ö ú¾í(\ eø"<Ò:\88±®\ f«\1a\1c\8b/\8e\15h¶¤\0úq`\a\vÚ
+b\ 4}\8f+Oßì_è\e\1a\18r,Óè}ýýrYÕhÓ¯×o\1ð\85u/c!\89edíxu},
\83,\14\12:à[l¸§ã\98q\8dJ\14\1awòC\9fyªBø\8bQÆüu8\10\9b\87\1e½Áb\8eeL\ f_\9dÔ\84    +ÞBê\8cx¨o?ÖT\14`\1cÍÖ¹X$bzVv8\açD³\97uÄàXxÝ+ÅÜ\15\87\8eb\94P8e¼\87êr¡AÞë\87î\13\94C\88,\amå¨ß    \1dé\8ca³RZý¿\89óØ1&Røms§\ fF\87Þ¹}U\1f{>îr\9b[\86h\vºW3eë\rÕߣh\vÐæ\12¤m\f\1c\88äàã\86\84ÎB\13tåx\97kóÝ\10\9f"×˦b"/TÜ\90/\9fü¹\ 2zïf\1c~7¹ÔôÛ¤\88Á¥Ê2Ðú\r_*µë\90\9c\fñ\rKËôM\96µÂÅEZ\95\8ej,ÿâ>\ 3\94)ÑN¶óFKøµÔ²Í¿\14ïîhGôE>¼<RÝü\ fò\95è 0\92O'\e$\99\fG lÔÛ7cÔ«ôgGDEP,-\14fXÞÖýØ_\ fóG\a\89\eXPWA\¹¯g\0ò/¬C¦z\r("p\10ã
+P\b\1c\ 2\8dO=Oª[¹\97\88+^ø_öë®C7\9c\0\1cPuw5\89Ò?\97Ï\80<ÏL%÷¬
+:\88ð[Ç\ fðÓÌ.)¹   \9b:\8a:mYX=\ 4²\920±«\87æÉ]q<ð\87VÍ\ÃJÿ"\92.$w\1f{>d\82°b²î Óü\95\1dØ,Ôõmª\r\11db\ 2ù\ fê&\89t\9bSÀê\½i ¹Â\82aÚ£äÜ\1f\95)\b\9c'%ÑÆÐ¦ªÝYV4\89X\ f&i\12,´mæ6Uj\15Ãð<âÀ\8d.P"\9aÚ¢ÃqÉ(W\92É)v\1d\9bqq
+\ 1,@\8e\ 2\17³\ fé7\ 1\1cL|ëú\84j\14;2@\84\8aøB[÷C¯îÅlé¾¶EöD{W½U\112¥<\ 3ð\ 6;\1cè\ f\11\987ø¨/&<\1dò\14_^q|A        \95D\8a?ÀfÔh;\1en\ 4÷\112!\85\88\937Hõë\87Ok\84©ÏneÁä%à}0Ö¬mj\e\e J\80Ý\b½#á)D$ab\83½58À\11\84;\ 5r\12\80ùTLá'yϯ¨Ô.þ'ú¡ÿF\ 5\9b\ e\82t\86\14u\99
+\94}-\98TãÆE\91\17*\fiÙ³\88\81\84[Iò×â\a#\9eÈVN\ 6ð9¿\ 1G¡TÚÇFßw]Ð\16jæ¢Kâ]ü®Öø\ 4nt|\16ßÁWc²VI n~ÙoJäÔ\ fp´6»\86¼\ eclL@z~I\18|­'\r£B\94ë ü7ôä\ ez\11\9dô?©´oEu~6\9c~¾(\1d°?wÏyY\8ey\9d\98â\ 1\ 3\v\17}þNëº]\81º¢sÞ\ 1MC\9dî×òmaØÛ³\8eÔÍ\18M\18GHÈ
+               \94R\14ÃiÚgg\94\0\14æ&4P\8cïWã\9f±¢ÌÌ\13\1eñ\17\ 6\18°w&iU2È\9cÌÂñ\93d\86ì!Û90;akW½î¬\8a¯\8a·»h\8dJÎIò?Ö_^èÞ\9aÇæy¹\93g¯2J{\85\91~>¼8ü¼o\98hN\7fÁ0\9c#ïÖ^%Áo\9d\1f%2p÷\ 20Ù`ïñUE\12\89X:\83\91aù¥\[Õ\93bÛ¬uj2F´\ 2Jeywk\83\82\82)\99I6UX¨\9a#D!¶NxÞ+2K.\90\17³ÅQ\1a¯t¿°WÔKÎ\9aýUí©\82ÀÂþC#\17\90~¹ !W²#x\96\8c\b/ZØzXȦ\91\8bñ\ 1Þæ\ 5´\7fJV½\13®P\81 \14®¿\9czûúz«Ñ\vfëm8\94\ f\19Nk\82áÖIÏav\nB\81ËF\fdWTQ§\96\ 6\97\ 6\13\81\18_É ÅG÷\0Ã>¼\9f\9d\9b$Óó³«:ö¹'×W ³9&\13¦oº(lE÷Ë\92é\85w\93\ 1áÆà¤ÄÊ.ó\11\81\r\9fÏ\95½_èk²\9a^.¨ï>`ÈÃB?çN/É\ 2\88RîþÒ\8bPU¢\13%¿ñG¦\97W\9bû7*(h\85Ç)L\90\ 4\12\vp\ e\82\81SgÎ\ 4\96%Ô      \12®Þó²Ów\19+æCÛ\9b\8d\97@ïã\82\9c\89\8b\1aV&±Ö²êØ=6nÏÀ\8e\18Ü.QÆ\ 3ÎãÞ\ 4*\88\8aÚÇ%÷¯
+Ûß\80¶¢\9b"\8a#9c;\147\80Û\14¡¥×÷Ý[Ó.N*`¡\98ó\18t2Çú\\82ç+\815\86\båüÐ\9eY\13^ h|Pv{\1f\12\98\99­.ýR ü\b;0\ 1\9dóHC~¥Ì\82 #0CS£"gts¡\1csc£)26Á\91\8d\9c}:£     B\1cà@\89`ØK\10\ 1¡C\9byÔ'\fÌÕ¥\8b4\ 2>]õ=Óz\1eiBºQ\8cG$=¸,Ç\89\ 5áv\1f\92fª¦\18Ý\913tpNÐ7À\1dQå8~/H\97nýºÜ\17eíT\8b`\14\ 4¡\ 3QlLÃ'wVÅ\95^ :l)ÐæAYí\8dÕZÁL\86ͧ$\0ì\17è´\ 3ñÂ\9dÑ\806Í£ÅA.ZÑ·!Ø?Ë\1e<Vc\12/Wÿ\bç\18\9fð~\85ME~s'¤?\ 6|\12\10\ 5¼ª\99õ\94\84VuåfT¡È²:Íl\ 1\9fØ)ã14Ìî\86ÑÇ\0Ä[á\14\búM\bâéÍ3
+`EìD\8f%~\ 4\94Ç\81\a\1f¤+¢\8bTe\10Þ·¹Ñ\aIN´\9fϯù{¨?3«w\ 6£þ?8\91ò§\9a\ 1Ïj5\0þ×ÔL\9e&<4\82\8d\83ðM\98¡\81\eêâ,_hs××\f\ 66\94\aõ\1d|^ôëu\8dèé>Ã=­­ï¤ôVÂ\9f;¡{­ñ\9c´\90\94äû`    ©öQ\1fû\ 1/¬Ù\9e\10NYû¡Î\8d0\85ãø\1cåâ\apV\99TëA\19î)ÒÎ$,³¶e{\ f\84\13\1d8îõ¿k¨ß|8)@Ðv\8c\vD\88\92ºÿ\f\16\84/ò¤§rCëÉNÜ"Ä=\8eë§\11§°\11©<ô\9fø\13\1dNÓdÌGýªõn   \9b\1f³\\94ã«`iÕ?D\88\15\1f\9b\81«qns\9f\9d\a$R_`\1d\93\8cç\17ïÚ¿ð¹êè\95\80\10°VÑy\84\ 3\13iLqá@Ì¢<«\97ËD¿"Ä]üËÈ\ e\19à!ÒÄoyWj\85®x³\ 15\83\88+\18¹xu-X.7\ 5Áy\1a\98kB:KßFô3»-,ZP,Ô\fdÙLîߺÿH\10:¢ê·¥«~ÏËså\15þÚ¸¨\96b1ù´b&o9p\17ßzÊf¥ôÆ Y¾\1e'J\bÃÚ×\94r\16\17ÿ\8b\f[å´Æ>æi]]è¥d\f»þ\9aÇ\9a\86£\0ÎóÒ|µãý#4\87A¿ø¸å\80AD¾O«÷\8cbÚ«8JR«lÍÇ¡·¸k}ñÌ\12¹m\eÖT\89¦úLX¹µyÞ>OäüøÕi\9e\16(\ 5\ 2bh0ÇKö\8cçk£ÐÇ_\ 2\8bA[\ e®\ eÇU/\96\91ÍGSäÔ°[\9dÙE:\ 3\HJdtÅÛ\8cÑ\96\11\10\83§´vë/¸\8f{òg\1fÐþ\82\85ÝÀ-C\94ßT¤¨×*MøiÞV\8dî\ 6x}\11\9bO É\e\ 6\a\ 5d^(\95\19_Ð2\a\98Pe`Þ'ø     Ù¥®m¼9(\93\a\r1¨r¿E\8bÇ\82hU¾\r':s\19´\921ûBHZÒhõ\15W\17\eÝB\15ôò\9d¹\14*y(¤\11\15yéWhæs0ät¨¦¿[¤hÂD\16Súxà8L1­\7fT\81oð¸êÑ\9b\ 6Ó?\9d×X´þYÃ\17\¢å¦&\ 5Î\12bpþiQ0f3%sy¯\8eM\95\1ewM\15¡3ÕáîÍ1\15#`d­\8bÈ\87\1c       \81\15m¯|\85Çka\16z\8fýaNb¤ôÕ\18é\87\80\88ó½\83ê¢\95óK¡\a\9bã¶oY\9d\90\ 2Á¿çüçµ-³as\ fÛ9\v½ú6\9bÁ)ë<¼\90ÌBJ|«r´oEï\98Il\11        ­?Ôì7\10C.\9aò\8cØ?\e\85^T«¹ªQÕ£·¼sâ\89\94V¦É\ 6ðªi*[OözI\f\0h|Qg\ 1\ e      \1c\ 2\9e\bíI'\80À|nûVÅ\90ï¬àuÄë\98(Oè¸\ 6o_X\89Ò\85õZ\88ÕD\85è}\1aîn\ 1¿ú=¢\85â|öæ?\15\ e6 ¤¨æBÓâ+ûF\93\9c( Á\81ÐB}\14<\81KÉñÝQ´Qù\9c\15l4cu^¤P\9c\9a>\ 6w@¦-¸5\8c\96\85¬Ñ(æ\97\19Î\ 2ZVËJ/ìu-OEç
+vJ{äF¸(\19\ 3Ý­ËÁ\12ýµ\82tFÒ\v\995\ 5P(á¥[ÿ7\ e¯\85j\12î6¥^f\88¨\90sYÙè©\ 3\92ë\v\ 4\8agsÝbÃ\18E9\96S=\91»k;{N\1c\1eà\8aJ\9aU»ÒO\93ÿ·Ì?\17¯e\17/\83S7\ 4z¯ådæÚõ¥mºâ}\9c\86ú\8cÐï    §1\ 1¤·#\8b\91
\91
+M«X\85&Ú~ѹ\vm|ÍWòÏT\15æK\14Cá±»¾A\1f:\8bÒçhe\16\9b=\8dÒR\99\1d¶ñç\8e!\8e³Ôºí
+·;µJ\þ\81íx¾\r@\89í¿1      \1a\10:aGê¯D´,{Í3ï15Ð\ eÎX¼`-ËÓ\aîóê-\b\96\94\92f¨ÂE\851ît\\97ú\8bã'\99Ý4Öu\18$ý!9\16¬¬P'\rYl,g1e-ó\ 3:\10\90\18+M\aò\IéewVÄ\95[TS\1aÀ/ÓK£è;\19\9c\88\8aX\97³ÄbHµê9\9e\1f¤\19ðå\8a\v
+î¡M\8a¿½¾Ü¥+´úòG\1f\93\9e6¡QÝ\97w\91\93ÔE\1aâù¿Ä¥\ ezª{8ü\17¼Hzáþkû#Ï\ 23°(*^\95¢\98ï\ 2R\9a\8c{q?Ì\14ó°Ñ°o½C2°\8fhîU±\13/Múö\99ê\91#2¯Ù\a\rX?ÚÃÁ¾f\ f~[¤],ßP\10¬3\r\93l¢ÝuÍv»\18\11h\8fã¿NzÇ\9bW\1fÆkAø\982kµT\9a\83hk±\ e\83\84H\90zF^Wþt3z\9a½\9b\1f\1av\15ê¸t)#\88+\eÌ;ï\93¸3½K:8    çN%\936\/jÄ\19òÑ\1cïO\ 6\94\98ÞÃ÷\98@ëJO\10EoP\ 6z\ 4'F\9a\ 2±ë¹ ï\18O\19ÖÅ\89Dr4«Ü©«\ f-1l\8c\8d>\13æ¶\ 30\1cc\8b\1dô\94²1ÓÛD\83\ 4å\a¤blϰ\9fð4uXI¥ÀÀå¨.`\16{¦º\14ì&_Í ®ªì´¾p\e\88Ø'Ó\84,\81Y\11\9cõò/§\fD\ 1ÛÔ9Ú5Ñy\95æx=-&¥ATåì\8c\97wu`ÑÎÌþ=\13Æ^>&\ 4k\aß\80½!\7f$6Ë'\7f}\80e\9aШq\eY>ú\\röt8\9b\82À\84¹eÏßþMéñ2Ý/V0Ê­\14-ÀÚíIþ3\18Y\17óH£È/GGî.ØØ6\8aF5×a\95(z \9a\89}\1c§\1e\91jfÙZAé\15Ö\1c£+¥¿\ f\ e®\bÙü2\88\94r<\11PnD¨â\92$b7wÜd\92©ô\ f\9cW\801IÉ:\92\ 44Ò¤\7fú\90\8c"½Ä±ñô5äìÞ6{\1a-Ô·\ 4Aÿh5\18øý!ëÁ\1dÅ\8d\b\96\97³\ e:E§Þ\bþJkN\1d:c#XÓÔæ\81QâVt×4eöi©fï5ئf\7fX7ÐZ3Ò\8f>¦§\98£\83låý\92\82\ 3½a\15í·\15\81\97\88?_Ç\92-`\ 1^t\9d\ 2½¨
+\18Òû\võox\82í?¥\90\ 6¤\98\92ôÌH\91,¹H\ 5ÚìÒ\\12\95Ý\92Ö¸\0\9eç:.§\r\89wFFå(Án×I\1f\1arC\12Ä.Ñ\84Ñ\97óò¼dÕ\99R\85Ï@\b\úb³h\82
+îj#­ÛE\9dÁEîehAþG\89²\9f'?\84¶kM¯\e\8b\96ä§^k8ë[@
+'\85²\16\1a±\1f\ 5O\90\9b\86\80q\1c\18\1d\1c2µ÷0à\84tÔ,S\14©\91\ 40\f\86¹µ¤­\94\ 4üÓýã&¦I>iÍÊDP\9aúÇjL!ZÕ¤4j\ 2ÕÙùg<9\19\1aîtÒ§6zz Ìb\15j\vwÌÝ¿)õµ¼ 2\83@
+  h:CÏÞú"w¥*Þx*\8f×7¸\1c-bØ%À\ 6 \ eܯúK\ 2\ 1ôq\99Ý\9f\9fá¿Û\16¡úÀ}÷\b4\19\rÙ\89·OQ\84@,à®øI\102\83\b\9f|ÝÁ[°5\ eå'@®\8c£\eWãýÃ\8f*8älM«®uóÞ«)>Í+N«Ý\8f×2\82\ e\vÂÂPèK%\82Ò\18ÚøÀb±µ×"a\ 4]\e|XcÙï\1dÄ[2\96¥°Êx\84×ò\10·Ô5\8bLO&\f\94Å2Ǭ\93ót{\877Þt#\93º\8ab5\15¢°\1eÚrå\86à2ÓÌæ©¼Çn\91 R\16H½(̧R@Ô\e¸èâº0\¦Dd²L%]|ñâõhl2Çä\ e\85R\ 1Ê5Ý<) \0`X\aÜ¿Ë3\ 2\94\ 4×uÅuG]·zÝì°'ef¦dÖ5\83¡À{j\9e\b^\8b¯\vô\ 3ã\ 3Û\ 3 \8e«pµÅ\ 3f#   $4f\19\10\81\ 1\81\92ÃÈ\b\11\83-D8Í\81\11\18\8cöfàõ\bÍ@\92UN5ú[ËLI²lNW.5/(Íp\1a\84ël\12jÀ©AÈj\87\17ëômÉ\ ew\0½\bG¦Z     N¢\b\82\11útT\ 2\18¬8ß
+\æW[Øò\82à\14\88\1fÆ \aºVC\b6&\vÎ\9d\95ô\116Ô 2 ¥\1c\13ôVÚ­õ\9dS\98bNGÄ\\91u*¯H\91q\88{eóh4ÜÜ\ 4p5±\9c*/) ¥\1dµ\10Ð\9bäZ墱ªRÒÌ¡¸àÁÀ¡¸\93\96CA«*\r9\14\18\8d\100\ 3ë'\86\8faÃÇp§\14\9dà\14±\11§\88á[I\14\8a&Ø&J`\91(EÅÚ\0\f\ 1fa\b\80!À,Í\93Ò<4O\8a\ e\90t\8e\95j'`®±Rí$¯T;Q±`v\80´à`èñ}\1a\ fïVJÁÐ\ 3ãïÓÈ|\1a\ fÑ\96\96ù4\1e\1f\18z`\9d§ñ\0=\f®#0Þaþ\81¡ap\1d\81¿\81À\99\7f`\fÍÐ@`̽è(÷¢£,\1e
+Qw0àr¨Ë½ ¨H\92«"IT\99JU\9fä90\9fäyèP\1dèáP]zH\17¹s\86\8a \87A¯R\eK¡Î)kb\96R\10`PxPÑ\13a¼BáIx(\ 5´\84\87\86\ 1gªÝú9:\ 6Ø¡óÚqNòCã\eV\95\9a¸X\fã'\10Ú\87ÓwÀÈrkæ¬\96È\9c\81*Êb­ÌbÈ\95JùÆ\18A\18\ 6\9a\13J\b\10A\90Ï\89ú\ 4Ô\13\97Ö4Õ_\9a*\1dvgK,\96LY\f§0Ï@\88ÖÂ@Û\10Öô\9c\8bO`fs |F2-èiUÆóR\8dß\8e\100>\82\97\ 6R¢ñ\e\81(ã÷\ 1\19Ƨ³ ×'0\97\13\10,øð\87Z\ 4\19D 9\13\88UEÉ1¿TÇ\82I\b\ 6Ì5\15              \ 6=Re¹\95v9\89Ùr\82ËIÌ\96@\8fDZ,H$î4:´\f¬W\19X?1|Ì\8e\8f,åT1)§Ê\84rªüD\11³·\12¾\95n%\11N\11³\f\9c"f¯Y\ 60¼YÎ&²\89Ò\10        ô\ 6h\1e\9a'³ÁÐ\ 3gn\190ôÀ\8dÐ\ 3+>\8d\968\88¡\aÎX\1dÁ\ 3ch\98\8cë\88\1dæ14Ì"ó\98DÙ@ 2ÿÀ`\f­\84¥¨xAuê\ 5=ÄCG0¢â\13¨2U¦ÊR\8b\98\1aX·±t\eKh%U¡\9c*\8foc©b K¸\92ª\8c%Ы\8d%ÔF¡\[ÂCÑ$<ë\84òxBRD\1a\8c\95½v\82w+è]ÓÁØ­$âZB\95\8a\15e8'¨d:|Ò\8dH\rª\15\85\93ÁÃ.Y\16\ 3*Ì    \ 5\8fEh ¯ö\9c¹ð\13\90\95­\8b"d:¤øf1äN¥¼® \87
+A\1cqØßXíVRX*\984Põ\ 4=8g\ eô\14\87\95j_\96\13É\93\8a\ fÊ\16W6\aÁ\80ø \f``\aÊ\bcJ&?£\108T\8eÔZÑHt&d@d1Q@\8fÇ
+b\Õ\93Xç?B2\12X=\99:V­]\8få¸P\1fÑ%p\e\93aAk\11\fª²º\9e\17O\80\88\9b\1cê\ 6äZ%Q\94\1aø²´\88\9aË\94\91\85îË\9c®DîêT\ 5ñqÄ\95j\19\87\95jo("\v@àð°R­í¤¦µ6\ 1\fÅ\84 ÔçhT,³,åhTìÈ>\ 2ù\\84Ò?¹ææòfÕyä°\91Jn¢\a~Ef«\89*â¨h30\9e\1aßR3$Hf­\1cê.&¨io\17\ 3ëE\a\1a\8f0@/äh赸¡\19\8eè\811\95\0\ 4\16\eãA©#\1d\98\17\81\1dê\8e¨\ f¢¸¶\12*\8a8EÌ\86ªFE\11\86\0S¨:\95FÅr¡3í"{`v-iT$q¬Û\80fDN\95EÉaöÒ%~§O\8düÐ\84\83ð#x\84ã§6vâ\87Q\98ä·0qÂ\8f\8c_%%\1a?\12\82Áø\81ÞÎ\822Àf\18;¨"\ 6!\ 5\94»[Õ.7³Þn\10\b\v\13ËÈ1¿L"¼\1f\e\8c"\ 1o\ eÔ´\e-\98Õ4\9diOѦb±\84§H\99\94D+Ë'£²ls\1f¥Qq1*¡¢EiT´\9d0\81K\94F\11"\e\0I\85\80\ 3      ×\9e\88p\9b\f1£`ÓAê®ÞdM¦É¥2iTÜ´\80JÆ#\8d\8a\91þ\91\10ÕBE;Ò¨92'\1fÊ%G.þ d\ 2\8d\8açæV,8U\82¤v¨»z\ 2\8d\8aÖó2U\ e\10»\81\88ì4¡R\18£ӠçÐ|Â+\11°¨á\95\80\93\81ï\92¡hb.O\84!+\13\0È#¼$\81FE2\93áE¬âa¥Ú\83À\ 1\15ñG£"\ e}\\1f\8d\8açåázZÂ\83\8aæG£â;H×K6#Úà\b×\8f\1f\8d\8a¥(k}4è¡þs4*b\v©¾\85 Ô/_Y6rZ\8bPÊàhTdà$)èýä6¾
+\7f©Ò\82j\1e\8a;BÐ\9cÆF\8b0\1a(è5\16\8b\97E\8dF\99\88J\12UÄEF£âúi\ 2 2H*f3\ 5¡Ê²\12\10\11\96C\91\10mZ\1cÈ¡¸bC\9bÖ\ 69U>ÌÚ´\8aCi\b=pyX©\964È¡.\82\ 230I\1cË´ãKU]rF2mÇÍ\\95\1a¬cÚ7Y\a\13\81Fªò\97\8bº°ìÀ\91".\ e+Õ.F)Z\11K\92«9`P\93\17\bÑ-\ f\87î"gµÕ\b\87 \14\83`6\92Q\ 5¢Þ\8aÄlå.R\18:\13"ÂIF\95|m\89\86\82?tâébÃ\10\93\89\eÈ|E\97`Ыµº\86Ø\14«æ?\a\87Md$rY0\8d£:Úb5Â:¦UqQÅ~Jy]?\95Å´\ 5\9cÓ!Vph\80øu\r.i\9c\ e)Ìëª\ 3\9dªÝ
+z"ÉY×0%°²¸\9d\15ÙÜø¤Vs`³XÊ'c±\r\12¡b%\8d\84\01\97$ä§A0\18¿\nÑÑÄ,\88\1aÅ,襹Gxm\96Eú AÊ11\ 2\ 5®_Ku\13¹áô\aÒ\89e\8f%áÌ¡kp\19`;åV\13¡R±\86\ ez\ 4\9e\82\96εvê\90»\8cÎܺè«u\ 5%vj1®\98ÅJ2\12\8b\85\80(ÂÉî\aI\89å'\1a \b¡\rØÉ\96\v\ e\ 6»ðr)\88\81;]`\84âÁ\19} ÇÙ5È\1a©ï vr{dZÚ\9a\17\14ôÊ\8c\9aöCJ;j/Ú´è\90ÔI;J\8e\ emZ±\80¤\\86ªQq\9cå`v¡jT,U,\98eUF\ fг:ÂøqÀ¡¸\fX§¶Ñ    Sï\9bÎ4\10ÐÜ\\1eAÈVEq"\0E\\86\ 4\8a\ 5E0éDh"\8cbQ\12¸  \81sè&°\89\82]v N$&ßhÕÊ&\84WÀê\9a
+´S]M\82êÚn\v\15K\93\12bR]=Ò¨¨e·rU¬°rS\ 5»\eJ \ÝqQîÅD¹#\8d\8a¥C¥ÜÑìµ\vïê\16\94¾\ 1Sx\17/\14\8fpr\bÝk@H\14È\1dÌ·&\81W\124vx  4*âÙÀÆ\14-¥/0¹:ªëí\9dlWùA\90\1f\8d\8aäßZâ\aLµ.G£âÕlõ-\87£QÑ6n)§L¥\1c\83\90cpA\90\90\8dåëCc\ 6\9c\8cÏȬjv|Ð\ 3½×l\15ôr\8aÃJ\ 5½\9d\ 5Åøt'Áå,/ÈrÌl\88;\bA\12ì\81æ3ûcÜ\87£%¾í\80Û\98\8b\80Òêz\ eoð7\a
+zÖô²ÉÍ$]¢Fdéz\98\ 1=\95\81b|kZÊ\896íZ@\92\ÅèÐ\f®M»xE©ÍD9&xPQUÛ¤J\ eÓ*øLü\ 5N¤Q±õm5\ 2z'\92(!Ek\1aS@
+CF\15ÏìÐ-\ 1¯\9c     Á\bèL\88á5ál\12(EMH0\8b\89²\9b\80\eUsßAäSWé\e´z#)®$°íÀH\7f·»mÌ\ 4È0³ \973XÇßp\ eZ_nº\ 6uR'\94\8f\0ÔׯHä³YIZ\b¢\84´ÆB×\15ô&0U\ 6\aT{]\91f\81ÝZkL\80èÒ\88ê¦\13ÛÆT\8c\ 42V\8d\80@\11]êÇ'mr¨\9bË\15\ 1K\88 Õ\89|§46YKö?Ô!¾\ 2RàzqÀ`\ 6IA#ÇDL\10¢ñAoÅé\ fä;0Dp\86\ 4Õÿf\ f\1d\f¶Zl¯Z(À\e\v\1e\1a\0[BsA\ fô@\ fô\ 4,*è\81\95\13       Ñ\87\8eAM4)kG!©Ä\a%»>ò\¼\96¤\12"$\17\ 4dzh>áE-jx\1d\90Gx\e\ 1\99l\94\88ðJ
+L\91Ð\aÒQ\1f\97\87Ë\9clW&\94¬\ eÒõ\1cá\1aÿö&º\8a¢¬Å\0\17\b\95º¬¾\89®\17ô\0½×lõ­\85T!\bµqK\1fô²,ý±L¥\8bPú3
+àIAÏtÈÆ/yJÔ\8c\1fÖìÂ@a!©\98ýF\995!N\92âðZÀ\0½Ã\96¨©!÷\17\ 4ùåÛÉmüó\13
+0G\80\ 5NÆgèúh6Bã¢\11³3\8ahxУÔ@²üF\bÁP¢T\9d      %¤DA.\7fß\ e¤s\90 £6k<D3¯>\ 1\10Cnç\f5}d7uû\95\9af\ 3ëO\ 5%ɺ\82^Å´}$\ 3¬cÚßÝY\87cгy4j\11O\95gQjà¡\83h\ 1\ 2§\ 40#Ö:\aæZÂ\89ÐÆx`VBè\81I+\13/+ù\94dyS\92pQ\10\12ðÃ¥¾¸\eRÀæX×\9e¥S\ 1A\10ô`2Ö-\80Í W\80­6]\ e¶Ê
+0\19ë\ 6Ó±
\0X9\99·Â\12\ eX+\ 1Ij¶îwg]îË÷©±Åz\7f>3æü¼»Äß/>1ïX\83{Æ·ÿî¸s\9eOËíÝûįõ\9fXküÛêÿ³ìún|w¶\99\97ù?\9f¶ìøZüü´\9cVèç¾Úfί%Ïþ\9cÿãò^¬1ïùr\9d?k~ZÝOþúí÷2\9f\18ãû\16ç·ö$\vÝö·¸ë\13ÿ\97Øb/@áÞ~ÿnû¥|\92.×¹w¾ñÖvc~9é\ 5\8b3¾Ûâ¿Ö\96\9bïÎyɵ}ýý{þ]Þs\178Ͻã\8cÿÞû\97\9f\9d÷\9c]vã½ÿ´åÞ»ð'YÈ\9a?¿9ëî¹xÇoõ[ûûsÞ\8fÏ·\96ÿk[ê¼\vXgÝ1YÀ\16?þ³ìüæû¿qçøË\7f|Þ­1Ö§µÿûæüÖfι¶\9fy?uïÛ>æeçÛ£å|ÚÞñµûä¯Ë}nÛ¯í\8fϳ\9fùËóK\97ßl?óç÷î\9cï÷\8bË,ñ4\ 5ÝOÎÉ}÷c}\96:ë¼ÿ¼¸_Ýû¦\15\19\93\ 5|ïÅ\sÌs.ïß\8dñÞ\\9f{Ûþ6ãKÒ\9d¿&ïK\16ö¹½\0\ 5û-\8d\96\9fV\9f{{\9aÞ9ßÞä÷Û\8bí-³Þ\85ÜOû]ÿw{\96ç\99ÉBþ?»íùñ.à^n®ûåÿ;¿þÝ5ÖçYÚ\13Ó
+ºÜüÞí\ 5(ì÷X¤ÿ\8bo>Ï­o\7f[ÚÂÞûÌ\7f\9fcls¿\9c\9f[kÍïî'ß\7ffÞïYv|\92\85\8d3\7fÎ˼7î]{´Âi{y~'\v=ç?ó$\9f¹\7f'ùÍ\wû\97Û|\92\ 5}\92\ 5»ïɱ\97\8b\14îB#«Á4»ë[Òy¿ÍçYî~ORÎøl4`µ\ 3\rÞ\9d[®Ë\1fð4\85Þµí\99VÈy{\ 1
+7ßVX«ÆR\e\rX\0\a\9a\80Þûí=ónñ½åãÇ\97Ä;¿ú>î\9c\97\13\97V\98®\ 6ÃýOίµ\16_Yí\80ëÇ\ f»\ 1\80 \81\15@í²°\8d\ 6h\85ÕVÛA\80\99Ë\960a­/Öî\93À:Ð\1dÔ.\8d\ 6,AVcé\0P£qÀ\8aáý\1a\8e7çûK«÷¶§-5~~\7f\9f¶ãòÏÍmaw{?óÜûÅúÚ|­Íwk\8bµí^G\ 5z\ 1\1aQÙBøªB£@¹\844\e\92Y\89\14Þ«i
\17\16^KS°\ 5«\v¶P°\85\7fÕ* è½j\15Õ¿\87\ 6 Ç\80xL»ûB\ f\fJM\v3\e·ôIN*}\91£Q\11E@¨Ïp¤\ 1\8aW¨T4\16ºl\13:\84\10\89\0\8c\0\ 1\fÃ\12H08(\14\8f\bäRòª\97ó\14\0\ 3X8&@@>88(\93Ë¢\910$
+\ 6\ 4r\18\85a\1c\ 4A\18È1å\90dH1Èù~#°~ßjm|EÁ\95`®j\b0¥?7=,¢Í`+«B\8ap\7fòÓÒ&\ 1ç\82\96Áº\88²\eI
+Û·c\96|Að\ fÜ\9aª\92*  n\16\17ý¾6\83¹\94\12ÑN\92=\99\90o\17]\94»\12ÂM\b\92\rÁ¶¼L¶ÏÀmî>lÂ34¡)Oip\80\vº®4ÐçW\7f
+@î4Lj9·ÿí\81\12m\9cE+ÓëÑÚ\ f8áºým2yþþ1¸Ô\99§¢d­\aM\vú;À¤ky\9ex\8cȲC1Pf8
+Áe\94\97\16\89Ã\8eSorÜ\ 6²\84\8eY\ 4?lºGP¡ª~xûÑ\b¾\8b\82Z<TUqºéRJ\ 5\91Þ¿ÿ\18z\ 2'LÈ#]\ e~­ü ºd6
+\89\9fï\87OÂù\ 39\15Ñ\8c\90\vp\ e\1eôg\9fçuµ\80h\13T3\88ï\1ck\90G\92N\ 47ÀAç)ÞLa\7fÊù\86T¥e«\9bä·\ 5 \9f#\ 1\ 2Ç\13à\13­»Nu\91\1f\ 6ðöYqHqá¨/\87\8c\19\18ÒÍ\89rézæS};ÖlMï2\91}XN\8c\95`1ö\f.\8bàÚH.\10ÉÙM>\9cÕ\8e®W°\9c\8dyOÛh\ 6þù*E\15\ 1ãz¡ô,Dõ?\ 5bµ+\16ÁÂÌ=ë\10ͱ\ 2\ 3üR©ûÓ\88\e\93åñ;ª\1a4
\98}¨@äÃz)=´yBK`è1ír\9f\eõ7?dô\85\83Q\vm\93©\9f¯^\8fÑyôÂkD^²\891Âê2B\95ZQC\16 \10ùrKdì\19Ã\ 2'BßíXº\99z%ÂлKÉÖ¢Ý-M7D\9a4_\9fø2¬ \99w\10 ðÈ";à\1fPIê!ñ\9f6p\13IJ\12òµe\b\88¶P£»ëf\bê5½\84ü\16ý¤\99\81\88¡c\85ЬëÎu\0u]\89nrÖ\h\9f½\vÔW\8b\87Rh\14¡Úö©<\84X"A´Þ»é¥Nñ\87¶Ôã\87ãÅïÕ\eý\9e\13O\93\90gé4\99I\1e* ×V3\0©û\v\90\94%H\12öª\80\98rmä\80\ 6\18\15¥ªb\89GíÌÐ\9bk¶:ýõ¦\ eðÉ~ÞÄÒß\16O\v¬NxÜ\ 1¤a\92ò7\7f\19r8=Ñ㩦\95­nÚ2F`e,ìp\82¨<öItõ¾D\8a«+\11R"\91÷\1cÊj\1f}\ 34¡(¦\88\e\ 2\9a\89û\14\7f7\13Î\83è´]\rvL\91é\13\1f\7f\9cyùÿÎT6\90à\89÷\17¢ºè½=¹Ci\85åM««HË\93I{Í,­\8b³\15Ò°\97\98é7oªª\81\7f©¹ô\8c%©Ã\17­Yfg\8eª>\rP@Q\ 6¯¶Kª\19ê°\9eÙ:%ô´/Q×/¸v^ËN£\88Ú3U0Ó\8a\87²À´\97ÓQ`|k\1fVrï\82\14äç:<ís\ 69w¢od7\8b·\8c¢ö\1e\ 3ÁäºcßYãíÊ\ 3#ê4¤\96\17\13¨\ 5ÝÙ\88D¸\19\99¡]ÊG|§\ 3\rÚ²áI¢s¢ù´xiê\84¯.Q9:r"n\v\96\r>S.Ê]ªØëÏC¬am¿yºÈÃÉ2z°Ö¢\87JªRWÏá\87ï÷$\84&Ó¹÷t|®û\9cÆ*p(®\1c\0\9bÐ7`¬â
+GáF\ 3»v:x©^\95\8c\9c1Ãùì¼\12#\ac¾~# ¦\80á϶1^Ej"\14÷8-\8aù\f\86 Ô\93¤C2úS\ fFúq¢Î²\11,7\10âÓá)ÅL] dp\99±\9cæÀ\rÛ6Ù­5º\13\ 1-\87¬ÆM\8f%\ 2\8bÆ\14\85%)¼\10o\1fàñÁjÜy@\1fɱqÙÙÓgæ\7fW
+\88Ë\90é\90\ fíw\ 6Ák\rÍ\14´\133°Ð\98\10b8/L\90õ\16æ\9eæy\91LL@÷Îx\92\1e\rÀ\88\99I?îÝ,\96\81\88\92ÿ\86ÑZøZO\84dOçf(¢t\8d\96CãíüѲò\94\v&j\85hRf¢\9bsæ~\89\88\93ÉþÝ1¹r\9a\va\9b\8a"(¢Ö\9ai\85\fùÃS;Ðñ\1c{\87iÔô\9b+J\99%z\95+ÔѪ\ 5\13±ù-ÈÒÍ\12l\ 4ä\ f2\7f\b!+#¾`px\r±.\ê\89`A\8dkWÙÛöºjuE\13$2³jL®
+Ït\9fè\97­\9d¤'\84|¿QL\ fÑ\8d0wo~¼º\88D\16¼Ú\11\92X"\99ñ1íf\95\e\1f.u5Ö£:N\91ð÷Î\ 3øfr´é)¥\9f7\97\89Äu¼\ 5(ï3o\1dýcá8îÛS¶å¿»/ÒáWÞ\89çdÓ\0!y°V&êL\82÷Í\ 3\f\19>$>7 \81ï<¬\13ª"{\93¯\16\a|úÕÈ,©7Ý»$;='+\84O\9e\8dÞ)½Søp\98X¯4Ø\94\ 2ç\80N¯é\9eöÅy ii<v"\8b;|²ñTV   Ö\8f{8ÊÌg±Èlh8òÄ3Ë2\91K£Hs¬ý\92ä"\8a¤v¶æ¨e\8aÜoG,Ýå\88is\85\9eµ\9f6egJBD
+BÕp&/à7j§
+G/Q£$x\8cÁCÂ.ñaW«2%«à\ 1È¡`L\81\ 4Î)´]£\r9cÌ4Ý{¥Ð\1ev\8a\1c\10=\1dm\ 6\846    \8fE\8aL\1eÓ\80Ä®=N\81î8'\93¿7¦`Ë\8eG{\1c
+\12¤ú\8egï¶ÃU>\85:\1d\10$¸²\1dï½Ê+ô\ 2s\98&¶²rÇý=\92BÄþ
+\12\14ë\8e3(\91\93\1a\nDZ¦Î]B\9e\88yôçÌ\1eì¸T@#ÿéñØN.L\9eA«ìx¤ÇÁ\915\ e½\1dÏ\12éñ©?\ 2\7fÇ#ü \95\92\99\1eÚÅtÛì¸)Q\1a23³ãOfuòYãá\8eÐã¶F*ýÝq\ 4U&ú£ÞdÇ\e=>©\9b\80Oðèñ\b~Çõ\81èÌ®ô§Ë;n  ô \11Iùì\8eû:`ºcÜmË\8eGz\1c\185\ ev\1c\8f|\1c§£ß¬\8f\82VTâ\8e»Ì0¯Çû7«ê\1d\7f\9a\96ÝãE\82A`;\9eL¿Çz¼\0={é\8e\86s\9d_\ 1w7Úñ\99\1egz¢(¢ßã:É\8e\8fôx½\14\88ì8B\8f£Êã\0tÇ÷\19ÀëñÎ\99dDÙñ\9b\96ÍZ*Cw\9cÞÿ\07¼Ö\85;n{\e#kd\fb\ frc\f    dظÇ%q\8c!?ÎGHc.Üÿ\18Ã\162bz|]Cë1Æ\1e2À{¼\8d\90\9d\92\8aX2ÖMR\8e1\8eCƾÇ{éÛÆ\18BÈ0ïñD!Lå\1d\8f¹¹K×\9cð"\ 2|ð¸;#\13\0\9dæd]#Ø{\vÉ£óÚm\ 5\ 4¡ÌX\86ê
+\1d\9fë¡h\84Ôr`£Æ#   íù\89\98ÑÞrÄ?\ 6FÜ»ý(d\8a\10kLï0`\ 5R\92ÀP\92\86(\16\81\92+ðUZÖ\96öÐÙ\17"¹n?QÆ\87@ɰæÉ·oÅ\ 1ÛúÎþ¦¡·Gíp\8e\98\1d\8e\16^:O\bE\87¡ºKÑÏcÀ\183è7¼Òk\ 4s¶+\92\86W\89}\ 5=\93ÂË\7fÁ«Çm±àÕq-\12¼RlWëxU¹\ 2\85ýõM0)\e>^ÑÍîù[Á«ÐvÕóðjË`xÛU\8d\81Wd\1d«\9b?2»ªíxµYÚmWö\1e¯@\8b±µ«Ê0#\1dÆÜ\1dvQ2Pwç#*ÑÜ»b½½¼Ò\15Abd\86\17\8a)\7f\89ÿøö\87¿åÁX$´X½`eZ¡Ü'LE£\ 2qÀìD­<î\e\83e{L¤Ùó?4Hº\8d\92\93É;©à._.SåFóº:<:\81:.¯ÔFe2&9NW @\8b¹H³6\80\82ŵ]ÿz\86\81¡\ 4"0J\98lçÐ'RH©5Ó¶\97QBÒØ\17ÎS¾:3Æå­yðX\85ðâ*/g8Ð\ 6\84uÀQöûüâ7¥ÊR\1aZ\ 5\1dÐá:íð\82!'grÆUI\9c¦a\84ìÿÿëÜߦÚÎqiæ\ 2_Õè4\16#4%ó\14\9e\1a}¡,/
+þJt¤|D\8d\9cuò$×ò^â¼ÌãåE\ e\f\7fcÕ¢©VÀjÈÀØ!2¥*Qþ¢;è\82«A²#\ 1ú~;XõåÄÈ\19\9dhÙ/I>SL¢\ 5g\b´½v4¿\80"\0Ð\f¸iº!\10©â?ku\14 @¿øc1¸k\19\92g¸Ö2x\1c\bZ\8d\18Y1\90T\10X\12]àÈøµ\ 1\16\ 4N{õ>¦iºé\932P\1e\bùpE³êPq¢­\0ª\97à"o\9cçx\17×§\86rh\rÃii j»\87U\1eyy     î\88\0Ü\ 3ôZYfª!\8c\19:3æ§_\ 3\84\15/JÃ\15\8f\87¯ãÐ2\aò%õS\8c'\ 4KPvºA\ 2\99GRé³íããÛF+½vÑiþPMD\18\ 22\18TM]\82ºaKW\89¤        9ï·õ\9b\1a3\82ÀNî\f±\8fò¶Ø-*'\ eï\8eb\95Q\12^\11þ\92\97XÁâEø\94\93\8eÚê\88ËÏIL\13\d\1e\9bvq\ 3\a\13Û'ò\16j5±\98\1aïRâqõº·\927o,ÀÆØùj\1a\83u\0bôhK\96°ieAÈ\94^\8a\855>ÿº4¥\r ü^Ò\97Ðiý\1aöMlKöì\152\99\80Ȥ;\18\83åwå¨\85]\92c`Ë#\81¡\ 6Ë\9dT$tÐ_\85A\9a~\82ú\ 5ÿ!L9­o\8d\e«\1f\89ÑO-@EÀì±í?¬\10ÅË-{·|Â\1aÏþ¾ò\14\8a\ 6ë8ßñ\9c\95\11`GB\99Î\ 2ƲÌþ#v£5*\83Íyê\9eÌf:&\f\8fOX¥\1cj\83Þo\0~o°Ê±\1a¨q6ìéâ\95$\1dÊ\1e]â³ñG´ÃGi¯8ðϯ.f@\aCôxêe<9=Ö;\9a«è\9fM{ñ\8d\eÈÜ\10*5\85ª\ 46ELzY\14õ\7f\98!k[\ 5wôÒv\a\87N}¿òj²Là\vF{Ø%¿üGÌ~\94ù\14\9f\1e^õ7ä\b\19\86èp\f¦\81\ eÏ\99± {\98.&Z¼\92â§\1c\10K\9f\1ap\ 3ÍB¤Ã{µ±=\1eµ\14»\11\17s<÷A;wE
+#Ð4    \83õ\86\v×Ê£ÉéÁ;\ f\8e_å2lV\eæg\99ÞÏâ:è\12\9d±\rË\83\17\1a8\1dvÇúÌÐu/K3.E̸£\v6Á0\10»ôCÎ\11\9cæ\89Y\13üdK\90Õï~\8aR¢R+\83ã\9cJf\0\10\18-ÿ\e\97\94
+wÆ\18>e!òÓü¢ÌÞÞa.§c±\8e\9c÷XÀ\84_¾÷%y\157\11\8d»°­â]\9f÷H6K¡\8bàùi\ e!Éê>~\ 3¢.Ïu\0\15Oe\11IæAü¶÷î\8a§lO\9aø>5\19ñ\ 4®9î\1d¯W\7f\8eÈY\9e\1aÇ \9e´+\84L\ f£¡xÚ\7f\1cAïÌ\83x¿\16¤\9d\9d0\14O\0\8eÏ\92o\8a\93u«¹#mZ\8ex\12\9dÌ7Í\9a\1fR<Å\9fo\8cG+a--\86\8e\ 2ÙW¶\9bo^\15°¹¶ÑZ    \13óM\12?+àÖrÁÖU\17ó\12m\ 2\9e\8a9í ö\87\9b{ý­\83?­àsD\86Í.}ä2OHÞÇb\7f\8f8¤Í\83Ì\90±B{µöM1Çä^})\80£BAm\v\81h=«LR@dFqSÛÄUø®°\8e|6;&\16c\1a\b\b;{/äyÈRÝwLâE\9c\8fè\88;;\8eù±øì¹L\16ìB/FÃw\1dó/ü\8aH\8eÔRîÂE:ùD\0\\8f\96\ 6Ì\13_tm7\8eÛj5¤-ôûT\18\8d\92\87DMrf\16Ì\ 6ª&ÎUG{x?ä\ 2éä\15\98\90³¥Tô\85\fa'(&O\7f\99}\14ïD\8c¥_­.ÜÚp%NË\9d\12\1az5% Ó­¾WüZ\ 3\0\ e\a`\vq\82Ñd]¬½A      8-¡\ 2£[\19ÌW\8eâ{è \97þ        ¥C)\9d\13D^/\89\1c\97ØÁ@y=ÜóÙä\91\93Zß·¢8{vÉð\ 5+X=\9bÙðè\1aE k}Ëh\8d\99M\9d7\17¸Î\8b\9f\131m\89\1a\8aÃG\19\ 64Dîw\b\13ûaH6uj\86\b\8d§Ç(\16"¶ô`\ e\84æ¨Uu\eýÅÍ\8a\90} øg~<E¼p\8d§\97ò\9dU\89Æù\1a]\95Ä\82ÿ&¶Ë§Ì\11 \0^
+Òæ6<ÛóxBPñDb\9d(Ãó\88Ëüú\87\8b-oRÙµ\88ìã\14bûx²í   \vE4\9eþ\1c\84\96¬aòö    /ÕxZÄ~ ÜÓw-ã´\87\94%O6T\8dPXÅ\98Lؼu\ 2ªØì\7fª­_\1f\1a\9a\83Ð)¸5Ä\1ckÿ[ð\98U®Ö^\ 2\9eÜÕÙ\e\92ø\ exPí\85¹nB_\10-1ÁÌü×HÆ\82Q
+FR\13ÅØ\85I\83ü`?¸\ 1
+\9b¾\vILÀñöZc\8cÌ\95\18;\1a\12wÐxÙ  k\10çCÀ\1aª>3Ê¥´4\8d\r¶~\9dc\ 2]\876E\f\95gAì½aĬÎÍp-u\ 1\92Ý\15\8c\18\ 3\87/\eÕ,ø
+,Ê\bKïùës\85U®4h\91L׸Q\97/áEcì\18§Ú+ît\93t\1dNp®ÄÛ(|Êð\9c©G)ñÿå\18G\9a
+¯mÁ\\96\9c\10\84¶LÌ7W²ÏFþºã\86\84ë\90.k¹
+\eó}n¿¨¼\81\98\86\11\12õ\b\ 5Q×A)\0e³sÑÂ\19bÕ[q"x\ 1\0\94Ì9ç\ 3³\8e\1e\14Q\8b÷\1dÿ\97\92\90q\1c\95!\ 6ÿ\9e\1e]EíS\8fJDÐI=z\f\94\ 1\18\85¦\87Ït
+o{+\9c*¯°TÝðÌ-È\9bh\108L\97@sçÞÎ\98k~ï{í\85# SH{Þé\8fÃ\91tͼ+Pà\8fLk)O®\v\99îzúN\13Øq\99.ÓBA,. @\eF·DG\92áw\7fVcSb&¹ \84\80ë¿ ÃFa?cõ|íÊ\12\17\ 1ãg
+ñ¾[ö\f\90çB£YO}4\bÖÉeyP¯e¢Rb¦ÆW\14º6m\9dú\1d\a%q~Ï\91^§Ãæ\ 3öLïß¹Þ\1fQÿ3¹;\15Û5tÔf?@ð½'ÞZvÚv\17ÙMw%áMÕ j_«\ 5\82\812\Û²ÍÉ'5è\96¨ªÚª\16W¢rõÑ\\7f\7fCìú°»¶\98Uö B\89²*b²éÍr"N»â§W®³o#9u\14ëj)"\14VX\1c¿Ô\ 5;H\1a\9a)\a6\8d ÝFL¨ý\12­\1f\81ã\b\a±\a%ïe\ 6\80RMËíJ'\86ö\9bÜ¡¶f)§~÷$æ\11½\1d\10ö)4ï\10å\87E¨­T]ÁøÍÈn\ 4Ö9\86\93\87HcX¶oÿÛ\18>Þr³Ë\87\7f\1aw\ 6¡d\a±\ 5)](oÜØ\1aÛôÓ\19òð\94\18ì´pQ¥n\9fE`\ 5\12Í.\8e\98!?g¨Jt\8e\19õ¯ØÏ\97\87\9d¬¹IïOQ\rßУç;\8be^Mm\7fþ¿LnÒ¸\11wÌÀ\15\80Ã*ýË\9b\80@ògãÀô\15\98\9b\14\r\11ʳ iüûe¶IÊ\14Û\92\ 68Òh»Ï\84¥ÅÞl\15,ý«k2\81(\19¨\7fo
\85\83\9dk*ï\10À¿\81\82¸\f÷
+óy\8f\9aéß_£\9f"öÿKÿªñ\8c\b\f\ fö\86\rE%\0sH¬¼\9b2xøWç²BÃÚ\91Õ¿AK\v?ý¢äÕÕÒæñîp-A\fÿR\19¡p¦\7fé\9e2v\85\7fINe\82d\1f¨®µ\f\11ð/^Üù\9bB£¬Ñ\94\9fÜA]\91\81ô/Óõ\9d\91\91Ü®,Wø÷\85\8a&Kê¿~ètuÂ\ 5\95ËúÁ\94\8c\8cûÛ\1c\ e1éà\8fW@EujQMa\ eA\ 6Êm%´\1c\133\9d\87B\11°Ac[¡Ë.cS©©f®Æ\91îÊÞ£eu\f\1dÔwJ\16\v\9c\94\8eë\87Vp \10Aå8\f\ f[ºbY\80h¹¡KÀ\1d×\19´\9dF~aï,Ö\9eÖ4xjæ×ò\13\98@c¤Dá    \98\85mì"U`\8f\9dB\8cÕnE]f>Û.úÂ\fl(G|Ä+é¨am~PYêÌ8U\9e\14m¡@ȤDWàæ\13\13H[Ñ\1e\8bõS\90ßkö\86\91\9aÕ@°}ú\98¥\ 2aZ¹t^_Wêf$¸tÚå¹\7f\17yÁå~»\82wk§LMu\81\12k\8a\ f\98|{^\8aòÜ\90ÚÍ1Õ\88óÔP5\ 6&\1dÜÿ\a\16²6´¡zª\10\96a7Xn\aô°êÕº4à\7f\92<ëMÈÌB\9bÚnÒ\9c餣¶\85Ú*D%\94*\ e¤Á\96\e¦Ûè\93¥\88õ`\86¤,®ÞeZBø`\9c©\82\88\fª\1aiµÀ\ 1      ¡\82\12/\87\1a»D\94\8eyßR:8,\10Ç\11wø1fß\ 6\7f\9d½\ fz{Ó\ 2RÙ9G»\9eïR¯\\K\88"\aßn\az{g\ e\83ôJà\10
+\1eX¯¤^\9fÊÿ\8cåSlR/ì^Yw\91P\84\98x\b\13\ 2ê½ÿ\96õ'\r\9aý\17J|&Ñ5\97HKo\10õ\89¹Ù5é#Þÿc\1cêµf\17\8b\e$ÐM\8d Þ8qªÝ\1cC~R/h²6©6 Z°q\ 3S@)M¤=\9c\94z5®7YW\1dÇ\11Sm¸\9cU15wAÚ\r&\98×hs\8a\86\19\ 2î¤qd}Ñ6\91\94M:¨r'Ó\8b´ejª>gÁî\9f¹\12rWR¸\96\8f\82\13ï·\18\82\9bëE>\8aÅn\19`þt¯\17=\9aþa$vY\1fZ¹ÉÂ5¸øI6Ð"Ú°}\19iB\89\8cÃ\16~]%É\eÕ)2FÉè`çâ\92$eL\91\8a&\84Söw(?ÞxÅf]\8c&ÄÔ\8e%SL¿â\950v,L¨\17\ 20¹8Àj\94\ 5õ>\82\9a%%}Uä´@\rHÇ   ½3^á?áxÌs\11w\8c\13Å,¥<JQIv\11âIP¬(ï{\ 6ìñ\ f\v±ì¸3Åæ+\82ï¥8¥­ ©\ 5\8dò6D~\ac\ e¾ë¨mV\9d¢$Û\92m/_$ùʺ¸\195X\809T\ f\1c'¹D\91Ç8AXv)\v-\8c^ªn\ 6Ĥ\16\12?j\ f¦\83\ 1\12µý\ 2Uú?        ÕNZ\9dJ\fñ\18\7f·%dG\8f\bü£§ÇIC÷mE\03|w­ÿì\ 6Ìv'³&U½è½t\8b\ 5\8cmdÜ}õ:iGD\9cæ\b¾S\90Þ\82\81\7f\870Qõ.Û\88Â\9f4\0W½`ÝÄ_Ы1íjÕ{+4ê\99\93ÎÒ\94'hl\99\1e\9cÃ\15Få¯û$´1h¯òò2\ el?ÀÀª7År}÷O¸|õj0\8cöÖ\99ãªÞ\ egW\b¼zA\8b\83$à&¤A£#VT½\90>×öª»W'¬(»¼CÚÍb\8c'¨ù¿\87Æ\bÛ_q\16\8cZuBã½ov¾\92\10³\86\81       ò\v\8f°G\ 1ì'öðH!\84Îí\96Ñs'95áÐÅ\11aGÄR¹|\81\97CÅxÁ\e\12ô0m\83\99\br)ðv¾I÷)b\16ard\877t4x\88wSIüZEÇü¼ÄÀ0\ 4\ 4H=^\8a\80ØJFø\8f¾òý\8dÊ+æ\19Þ'É3Eû¼mÒ\97ø\91\b\8b\fõþº3µnìDíúÜêi+\8a¬ÈúÊèÕ\12·\18`\8f\86Ã\97ïx\ 3#8\ f\84p\94²\85IAm°\97Ô×\88q\ 3   ¦@°\178ò;g\ 4\81+\90ú\ f#åEXî\ 4\86许|¡\85å|ÃF}\1aÍ.þ\94ÙÝ\19}Ë|| ®À Ëè9`¬\f&§ð
+{cÀ¹\8cmI\9bo?£Tåaý½\1cøÇ|/\ 1¬\8dc\b¢\9d\13\9f{áî^:â\97\1eî\87ywq\8d\95\8aûÍ¡3(v$8«Fb\bí\18ÅvúEOF\ f\ 6Ä\8f¿AÓøR'$¤ë¬³¢\84,)\94¦\94\9fGG\12\7f½~l\1aÞ]Ò\1aµ\99,{Ï|~w\8bý¤÷j\186-Þ­s\86Â/ð°ï®\ 2\7fã\ 5\7f1KÒóÇuêÝ%Ï\11ðµÝfpä\13Ç\97=^ýëÕÃCIº*¶ùü©     \8cðFrÇéÝ\8d´lóìÅ\eèݵÿÝ¡\ 3T:äÒÆ\87GÝÞÝ=³ÀoÀ´c²DÅ»ü/+ß$a\16ù¢\9ex7¨®Ú_æbzw\15D\9b\17\88uÝ|\8d\ f\ 5\19kªô4$ùé2g   N\92o\10\8e2\80Ý\8bø= o²â¨\80!Å«_´\88\83ÅÔ[<[à®Ç\94\ e\13è}&î> \7f[d\12\1c\82\13\88KEm)\0-R~kGÍ\96ÉÜò\86\8bk\19º¢5qQ9ñ\1dsÌÏ\ 5Ôý\12R\9a\99\8a&IM¬I§\19\ fÏ\83v\80 ß¨\8ag\19ú\96öÿñ\a|VÉ\8c\13-kÌ¥99ÂFp\a6âÃ\95ï\88äf\98\ eI\ 6Óê¨mª?&\8b\81\ 6®î\14\f\17Ãu)Î\8aëÝ(üwÒ Ê8ð¡\a\b\82¹*o,ì\87©\805\86Z\8fÁöÌ ´l-\96Â\¢µ\0FYL§\9c\1e½®ÑMXöY÷h³Ñ¡Û¤\19\v\b\8eó\0?ÿ<³¦\e\99KoyÂ\9dÈÒ7'ÚæÇ,s\ 6\18í\19\86S¸¬\8cÕúd\0\88\92A.KiJ\9a@À¡i\96eÎ$k³ß\98k~\8aGs\0´y¾±\9fÂU¡|û\1aëSï\99¶3xNð\94ö©r¼'¯\ 3<\9dr$\:õºÚÕÕ¬Êëh}tÂ=\89­jål&þ#n$¥\89óÎfn\99\9dXÂ{Gö»\85ÜÝéÙÄáeùyõÞ/RÚ\95h¢VtXy\15¶ÜÆã´üé \81Ý¥Þ9¨s\85\9e%j~\14ø\87\92ûØõ\rĶb\búé±\ 2\90îAîî«ø\14\19¿¼\94
+\7fLA5NRh\86È\174    ñzÛ²$ \14q&þS\ f\19¼\ 1fÇÐJ\ f®\r  \ 3\0\ 2®\ 4\rendstream\rendobj\r22 0 obj\r[21 0 R]\rendobj\r32 0 obj\r<</CreationDate(D:20200725234456+10'00')/Creator(Adobe Illustrator 24.2 \(Macintosh\))/ModDate(D:20200725234456+10'00')/Producer(Adobe PDF library 15.00)/Title(Jacktrip)>>\rendobj\rxref\r
+0 33\r
+0000000004 65535 f\r
+0000000016 00000 n\r
+0000000147 00000 n\r
+0000038245 00000 n\r
+0000000000 00000 f\r
+0000038296 00000 n\r
+0000000000 00000 f\r
+0000043346 00000 n\r
+0000000000 00000 f\r
+0000000000 00000 f\r
+0000000000 00000 f\r
+0000000000 00000 f\r
+0000000000 00000 f\r
+0000000000 00000 f\r
+0000000000 00000 f\r
+0000000000 00000 f\r
+0000043419 00000 n\r
+0000043593 00000 n\r
+0000044772 00000 n\r
+0000110360 00000 n\r
+0000000000 00000 f\r
+0000040363 00000 n\r
+0000142712 00000 n\r
+0000038693 00000 n\r
+0000040663 00000 n\r
+0000040550 00000 n\r
+0000039334 00000 n\r
+0000039802 00000 n\r
+0000039850 00000 n\r
+0000040434 00000 n\r
+0000040465 00000 n\r
+0000040698 00000 n\r
+0000142737 00000 n\r
+trailer\r<</Size 33/Root 1 0 R/Info 32 0 R/ID[<0736C03EA6374B77AEB4921C0FCAF2A6><B3D402B8E9994E6585EF6BDAA695FC42>]>>\rstartxref\r142925\r%%EOF\r
\ No newline at end of file
diff --git a/src/gui/alt/about.png b/src/gui/alt/about.png
new file mode 100644 (file)
index 0000000..99d8c77
Binary files /dev/null and b/src/gui/alt/about.png differ
diff --git a/src/gui/alt/about@2x.png b/src/gui/alt/about@2x.png
new file mode 100644 (file)
index 0000000..0b2f82c
Binary files /dev/null and b/src/gui/alt/about@2x.png differ
diff --git a/src/gui/alt/icon.png b/src/gui/alt/icon.png
new file mode 100644 (file)
index 0000000..d6a2d90
Binary files /dev/null and b/src/gui/alt/icon.png differ
diff --git a/src/gui/micoff.svg b/src/gui/micoff.svg
new file mode 100644 (file)
index 0000000..e827d6f
--- /dev/null
@@ -0,0 +1,17 @@
+<svg width="19" height="28" viewBox="0 0 19 28" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_1_2)">
+<g clip-path="url(#clip1_1_2)">
+<path d="M14.7516 5.43539C14.7516 2.43351 12.3181 0 9.31624 0C6.31436 0 3.88086 2.43351 3.88086 5.43539V13.4077C3.88086 16.4096 6.31436 18.8431 9.31624 18.8431C12.3181 18.8431 14.7516 16.4096 14.7516 13.4077V5.43539Z" fill="#0F0D0D"/>
+<path d="M0.906172 12.2445C0.66584 12.2445 0.435352 12.34 0.265412 12.5099C0.0954714 12.6799 0 12.9104 0 13.1507C0 17.9818 3.69688 21.9658 8.41039 22.4224V26.1882H4.7868C4.66596 26.1852 4.54575 26.2065 4.43324 26.2507C4.32074 26.2949 4.21821 26.3611 4.1317 26.4455C4.04518 26.5299 3.97643 26.6308 3.92949 26.7422C3.88255 26.8536 3.85837 26.9732 3.85837 27.0941C3.85837 27.215 3.88255 27.3346 3.92949 27.446C3.97643 27.5574 4.04518 27.6583 4.1317 27.7427C4.21821 27.8271 4.32074 27.8934 4.43324 27.9375C4.54575 27.9817 4.66596 28.003 4.7868 28H13.8463C14.0827 27.9942 14.3075 27.8962 14.4727 27.7269C14.6378 27.5577 14.7302 27.3306 14.7302 27.0941C14.7302 26.8576 14.6378 26.6305 14.4727 26.4613C14.3075 26.292 14.0827 26.194 13.8463 26.1882H10.2227V22.4219C14.9363 21.9647 18.6331 17.9813 18.6331 13.1502C18.6273 12.9138 18.5293 12.689 18.3601 12.5238C18.1908 12.3587 17.9637 12.2663 17.7272 12.2663C17.4908 12.2663 17.2636 12.3587 17.0944 12.5238C16.9251 12.689 16.8271 12.9138 16.8213 13.1502C16.8213 17.2878 13.4548 20.6544 9.31711 20.6544C5.17945 20.6544 1.81234 17.2884 1.81234 13.1507C1.81234 12.9104 1.71687 12.6799 1.54693 12.5099C1.37699 12.34 1.1465 12.2445 0.906172 12.2445Z" fill="#0F0D0D"/>
+<line x1="1.38898" y1="2.26597" x2="17.111" y2="25.4353" stroke="#0F0D0D" stroke-width="2" stroke-linecap="round"/>
+</g>
+</g>
+<defs>
+<clipPath id="clip0_1_2">
+<rect width="19" height="28" fill="white"/>
+</clipPath>
+<clipPath id="clip1_1_2">
+<rect width="19" height="28" fill="white"/>
+</clipPath>
+</defs>
+</svg>
index c685a7d6b0b63be83f580310a0411a4804522d64..191d544fc27166866a653b4cd5de6d1f6b679602 100644 (file)
 #ifndef NO_VS
 #include "virtualstudio.h"
 #endif
-#ifdef PSI
-#include "ui_qjacktrip_novs.h"
-#else
 #include "ui_qjacktrip.h"
-#endif
 #ifdef USE_WEAK_JACK
 #include "weak_libjack.h"
 #endif
 
 QJackTrip::QJackTrip(int argc, bool suppressCommandlineWarning, QWidget* parent)
     : QMainWindow(parent)
-#ifdef PSI
     , m_ui(new Ui::QJackTrip)
-#else
-    , m_ui(new Ui::QJackTripVS)
-#endif
     , m_netManager(new QNetworkAccessManager(this))
     , m_statsDialog(new MessageDialog(this, QStringLiteral("Stats")))
     , m_debugDialog(new MessageDialog(this, QStringLiteral("Debug"), 2))
@@ -69,6 +61,7 @@ QJackTrip::QJackTrip(int argc, bool suppressCommandlineWarning, QWidget* parent)
     , m_realCerr(std::cerr.rdbuf())
     , m_jackTripRunning(false)
     , m_isExiting(false)
+    , m_exitSent(false)
     , m_hasIPv4Reply(false)
     , m_argc(argc)
     , m_hideWarning(false)
@@ -107,7 +100,12 @@ QJackTrip::QJackTrip(int argc, bool suppressCommandlineWarning, QWidget* parent)
         About about(this);
         about.exec();
     });
-#ifndef NO_VS
+#ifdef NO_VS
+    m_ui->authNotVSLabel->setText(
+        QStringLiteral("(This is for JackTrip's inbuilt authentication system. To easily "
+                       "connect to a Virtual Studio server, download a Virtual Studio "
+                       "enabled version of JackTrip.)"));
+#else
     connect(m_ui->vsModeButton, &QPushButton::clicked, this,
             &QJackTrip::virtualStudioMode);
 #endif
@@ -314,7 +312,9 @@ QJackTrip::QJackTrip(int argc, bool suppressCommandlineWarning, QWidget* parent)
     // Check if Jack is actually available
     if (have_libjack() != 0) {
 #ifdef RT_AUDIO
+#ifdef PSI
         bool usingRtAudioAlready = m_ui->backendComboBox->currentIndex() == 1;
+#endif  // PSI
         m_ui->backendComboBox->setCurrentIndex(1);
         m_ui->backendComboBox->setEnabled(false);
         m_ui->backendLabel->setEnabled(false);
@@ -382,9 +382,11 @@ QJackTrip::QJackTrip(int argc, bool suppressCommandlineWarning, QWidget* parent)
 
 void QJackTrip::closeEvent(QCloseEvent* event)
 {
-    // Ignore the close event so that we can override the handling of it.
-    event->ignore();
-    exit();
+    if (!m_exitSent) {
+        // Ignore the close event so that we can override the handling of it.
+        event->ignore();
+        exit();
+    }
 }
 
 void QJackTrip::resizeEvent(QResizeEvent* event)
@@ -417,6 +419,15 @@ void QJackTrip::resizeEvent(QResizeEvent* event)
     rect = metrics.boundingRect(0, 0, width, 0, Qt::TextWordWrap,
                                 m_ui->authDisclaimerLabel->text());
     m_ui->authDisclaimerLabel->setMinimumHeight(rect.height());
+
+    width = m_ui->authGroupBox->contentsRect().width()
+            - m_ui->authGroupBox->contentsMargins().left()
+            - m_ui->authGroupBox->contentsMargins().right()
+            - m_ui->authGroupBox->layout()->contentsMargins().left()
+            - m_ui->authGroupBox->contentsMargins().right();
+    rect = metrics.boundingRect(0, 0, width, 0, Qt::TextWordWrap,
+                                m_ui->authNotVSLabel->text());
+    m_ui->authNotVSLabel->setMinimumHeight(rect.height());
 }
 
 void QJackTrip::showEvent(QShowEvent* event)
@@ -467,6 +478,7 @@ void QJackTrip::processFinished()
         m_jackTrip.reset();
     }
     if (m_isExiting) {
+        m_exitSent = true;
         emit signalExit();
     } else {
         enableUi(true);
@@ -722,6 +734,17 @@ void QJackTrip::start()
 
     // Start the appropriate JackTrip process.
     try {
+        AudioInterface::audioBitResolutionT resolution;
+        if (m_ui->resolutionComboBox->currentIndex() == 0) {
+            resolution = AudioInterface::BIT8;
+        } else if (m_ui->resolutionComboBox->currentIndex() == 1) {
+            resolution = AudioInterface::BIT16;
+        } else if (m_ui->resolutionComboBox->currentIndex() == 2) {
+            resolution = AudioInterface::BIT24;
+        } else {
+            resolution = AudioInterface::BIT32;
+        }
+
         if (m_ui->typeComboBox->currentIndex() == HUB_SERVER) {
             m_udpHub.reset(new UdpHubListener(m_ui->localPortSpinBox->value(),
                                               m_ui->basePortSpinBox->value()));
@@ -745,6 +768,7 @@ void QJackTrip::start()
                 // Set buffers to zero when underrun
                 m_udpHub->setUnderRunMode(JackTrip::ZEROS);
             }
+            m_udpHub->setAudioBitResolution(resolution);
 
             if (!m_ui->jitterCheckBox->isChecked()) {
                 m_udpHub->setBufferStrategy(-1);
@@ -797,17 +821,6 @@ void QJackTrip::start()
                 jackTripMode = JackTrip::CLIENTTOPINGSERVER;
             }
 
-            AudioInterface::audioBitResolutionT resolution;
-            if (m_ui->resolutionComboBox->currentIndex() == 0) {
-                resolution = AudioInterface::BIT8;
-            } else if (m_ui->resolutionComboBox->currentIndex() == 1) {
-                resolution = AudioInterface::BIT16;
-            } else if (m_ui->resolutionComboBox->currentIndex() == 2) {
-                resolution = AudioInterface::BIT24;
-            } else {
-                resolution = AudioInterface::BIT32;
-            }
-
             m_jackTrip.reset(new JackTrip(jackTripMode, JackTrip::UDP,
                                           m_ui->channelSendSpinBox->value(),
                                           m_ui->channelRecvSpinBox->value(),
@@ -975,6 +988,7 @@ void QJackTrip::exit()
     if (m_jackTripRunning) {
         stop();
     } else {
+        m_exitSent = true;
         emit signalExit();
     }
 }
index 3a396e54d5356a943a2a2cb3e345749f8673a2f8..4359b31dc91c929591a7ac4c689fcb2d28cce466 100644 (file)
 
 namespace Ui
 {
-#ifdef PSI
 class QJackTrip;
-#else
-class QJackTripVS;
-#endif
 }  // namespace Ui
 
 #ifndef NO_VS
@@ -76,7 +72,7 @@ class QJackTrip : public QMainWindow
     void showEvent(QShowEvent* event) override;
 
 #ifndef NO_VS
-    enum uiModeT{UNSET, VIRTUAL_STUDIO, STANDARD};
+    enum uiModeT { UNSET, VIRTUAL_STUDIO, STANDARD };
     void setVs(QSharedPointer<VirtualStudio> vs);
 #endif
 
@@ -123,11 +119,7 @@ class QJackTrip : public QMainWindow
     QString commandLineFromCurrentOptions();
     void showCommandLineMessageBox();
 
-#ifdef PSI
     QScopedPointer<Ui::QJackTrip> m_ui;
-#else
-    QScopedPointer<Ui::QJackTripVS> m_ui;
-#endif
     QScopedPointer<UdpHubListener> m_udpHub;
     QScopedPointer<JackTrip> m_jackTrip;
     QScopedPointer<QNetworkAccessManager> m_netManager;
@@ -137,6 +129,7 @@ class QJackTrip : public QMainWindow
     std::ostream m_realCerr;
     bool m_jackTripRunning;
     bool m_isExiting;
+    bool m_exitSent;
 
     QMutex m_requestMutex;
     QString m_IPv6Address;
index 286174459cf29548df179e72768e70b489e5b9f3..c34366f23dc6431de6855de8b9e0b5abc7278bc0 100644 (file)
@@ -27,6 +27,7 @@
     <file>share.svg</file>
     <file>cog.svg</file>
     <file>mic.svg</file>
+    <file>micoff.svg</file>
     <file>ethernet.png</file>
     <file>ohno.png</file>
     <file>headphones.svg</file>
index 9044e47cf64e8942c72130707ac69b3bb69604f1..9ead504e69fa9964407f0a2a83d9c5c21869e5ac 100644 (file)
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <class>QJackTripVS</class>
- <widget class="QMainWindow" name="QJackTripVS">
+ <class>QJackTrip</class>
+ <widget class="QMainWindow" name="QJackTrip">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>409</width>
-    <height>845</height>
+    <height>913</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -165,181 +165,90 @@ To connect to a hub server you need to run as a hub client.</string>
         <string>Basic options</string>
        </attribute>
        <layout class="QGridLayout" name="gridLayout_3">
-        <item row="7" column="0" colspan="2">
-         <widget class="QGroupBox" name="requireAuthGroupBox">
+        <item row="3" column="0" colspan="2">
+         <widget class="QGroupBox" name="autoPatchGroupBox">
           <property name="title">
            <string/>
           </property>
-          <layout class="QGridLayout" name="gridLayout_7">
-           <item row="3" column="2">
-            <widget class="QPushButton" name="keyBrowse">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Browse</string>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="0" colspan="3">
-            <widget class="QLabel" name="authDisclaimerLabel">
-             <property name="text">
-              <string>(This is a work in progress and needs to be manually configured outside of the app. Only use if you know what you're doing.)</string>
-             </property>
-             <property name="wordWrap">
-              <bool>true</bool>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="0">
-            <widget class="QLabel" name="certLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>&amp;Certificate File</string>
-             </property>
-             <property name="buddy">
-              <cstring>certEdit</cstring>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="0">
-            <widget class="QLabel" name="keyLabel">
-             <property name="enabled">
-              <bool>false</bool>
+          <layout class="QGridLayout" name="gridLayout_10">
+           <item row="0" column="0" rowspan="2" colspan="2">
+            <widget class="QLabel" name="autoPatchLabel">
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+               <horstretch>0</horstretch>
+               <verstretch>0</verstretch>
+              </sizepolicy>
              </property>
              <property name="text">
-              <string>&amp;Key File</string>
+              <string>Hub auto&amp;patch mode</string>
              </property>
              <property name="buddy">
-              <cstring>keyEdit</cstring>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QLineEdit" name="keyEdit">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Choose the private key that the server should use for the SSL connection.</string>
+              <cstring>autoPatchComboBox</cstring>
              </property>
             </widget>
            </item>
-           <item row="2" column="1">
-            <widget class="QLineEdit" name="certEdit">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
+           <item row="0" column="2">
+            <widget class="QComboBox" name="autoPatchComboBox">
              <property name="toolTip">
-              <string>Choose the certificate file that the server should use to establish an initial SSL connection.</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="2">
-            <widget class="QPushButton" name="certBrowse">
-             <property name="enabled">
-              <bool>false</bool>
+              <string>Select how you want audio to be routed by the hub server.</string>
              </property>
-             <property name="text">
-              <string>Browse</string>
+             <property name="currentIndex">
+              <number>0</number>
              </property>
+             <item>
+              <property name="text">
+               <string>Server to clients</string>
+              </property>
+             </item>
+             <item>
+              <property name="text">
+               <string>Client loopback</string>
+              </property>
+             </item>
+             <item>
+              <property name="text">
+               <string>Client fan out/in but no loopback</string>
+              </property>
+             </item>
+             <item>
+              <property name="text">
+               <string>Full Mix</string>
+              </property>
+             </item>
+             <item>
+              <property name="text">
+               <string>No auto patching</string>
+              </property>
+             </item>
             </widget>
            </item>
-           <item row="0" column="0" colspan="2">
-            <widget class="QCheckBox" name="requireAuthCheckBox">
+           <item row="3" column="0" colspan="3">
+            <widget class="QCheckBox" name="upmixCheckBox">
              <property name="toolTip">
-              <string>Require clients to connect with a username and password.</string>
-             </property>
-             <property name="text">
-              <string>&amp;Require Authentication</string>
-             </property>
-            </widget>
-           </item>
-           <item row="4" column="0">
-            <widget class="QLabel" name="credsLabel">
-             <property name="enabled">
-              <bool>false</bool>
+              <string>For clients that only send one channel of audio, relay their signal in stereo.</string>
              </property>
              <property name="text">
-              <string>&amp;Credentials File</string>
-             </property>
-             <property name="buddy">
-              <cstring>credsEdit</cstring>
+              <string>&amp;Upmix mono clients to stereo</string>
              </property>
             </widget>
            </item>
-           <item row="4" column="1">
-            <widget class="QLineEdit" name="credsEdit">
+           <item row="2" column="0" colspan="3">
+            <widget class="QCheckBox" name="patchServerCheckBox">
              <property name="enabled">
               <bool>false</bool>
              </property>
              <property name="toolTip">
-              <string>Choose the file containing the list of usernames and passwords.</string>
-             </property>
-            </widget>
-           </item>
-           <item row="4" column="2">
-            <widget class="QPushButton" name="credsBrowse">
-             <property name="enabled">
-              <bool>false</bool>
+              <string>Include the server in the audio patching. This allows an ensemble member to
+play from this machine. (Available in client fan out/in and full mix modes.)</string>
              </property>
              <property name="text">
-              <string>Browse</string>
+              <string>&amp;Include server in patching</string>
              </property>
             </widget>
            </item>
           </layout>
          </widget>
         </item>
-        <item row="11" column="0" colspan="2">
-         <layout class="QHBoxLayout" name="aboutLayout">
-          <item>
-           <spacer name="aboutSpacer">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>40</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item>
-           <widget class="QPushButton" name="vsModeButton">
-            <property name="text">
-             <string>Virtual Studio Mode</string>
-            </property>
-           </widget>
-          </item>
-          <item>
-           <widget class="QPushButton" name="aboutButton">
-            <property name="text">
-             <string>About</string>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </item>
-        <item row="9" column="0">
-         <spacer name="basicVerticalSpacer">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeType">
-           <enum>QSizePolicy::Expanding</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
         <item row="2" column="0" colspan="2">
          <widget class="QGroupBox" name="channelGroupBox">
           <layout class="QGridLayout" name="gridLayout_9">
@@ -420,16 +329,6 @@ To connect to a hub server you need to run as a hub client.</string>
           </layout>
          </widget>
         </item>
-        <item row="5" column="0" colspan="2">
-         <widget class="QCheckBox" name="zeroCheckBox">
-          <property name="toolTip">
-           <string>Silence the audio when there's a buffer underrun.</string>
-          </property>
-          <property name="text">
-           <string>Set buffer to &amp;zero when underrun occurs</string>
-          </property>
-         </widget>
-        </item>
         <item row="6" column="0" colspan="2">
          <widget class="QCheckBox" name="timeoutCheckBox">
           <property name="toolTip">
@@ -440,90 +339,275 @@ To connect to a hub server you need to run as a hub client.</string>
           </property>
          </widget>
         </item>
-        <item row="3" column="0" colspan="2">
-         <widget class="QGroupBox" name="autoPatchGroupBox">
+        <item row="8" column="0" colspan="2">
+         <widget class="QGroupBox" name="authGroupBox">
+          <property name="enabled">
+           <bool>true</bool>
+          </property>
           <property name="title">
            <string/>
           </property>
-          <layout class="QGridLayout" name="gridLayout_10">
-           <item row="2" column="0" colspan="2">
-            <widget class="QCheckBox" name="upmixCheckBox">
+          <layout class="QGridLayout" name="gridLayout_6">
+           <item row="4" column="1">
+            <widget class="QLineEdit" name="passwordEdit">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
              <property name="toolTip">
-              <string>For clients that only send one channel of audio, relay their signal in stereo.</string>
+              <string>Enter your password. (This will not be shown or saved.)</string>
+             </property>
+             <property name="echoMode">
+              <enum>QLineEdit::Password</enum>
+             </property>
+             <property name="cursorPosition">
+              <number>0</number>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="0" colspan="2">
+            <widget class="QCheckBox" name="authCheckBox">
+             <property name="toolTip">
+              <string>Supply a username and password to connect to the server.</string>
              </property>
              <property name="text">
-              <string>&amp;Upmix mono clients to stereo</string>
+              <string>&amp;Use Authentication</string>
              </property>
             </widget>
            </item>
-           <item row="0" column="1">
-            <widget class="QComboBox" name="autoPatchComboBox">
+           <item row="3" column="1">
+            <widget class="QLineEdit" name="usernameEdit">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
              <property name="toolTip">
-              <string>Select how you want audio to be routed by the hub server.</string>
+              <string>Enter your username for the server.</string>
              </property>
-             <property name="currentIndex">
-              <number>0</number>
+            </widget>
+           </item>
+           <item row="4" column="0">
+            <widget class="QLabel" name="passwordLabel">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="text">
+              <string>&amp;Password</string>
+             </property>
+             <property name="buddy">
+              <cstring>passwordEdit</cstring>
              </property>
-             <item>
-              <property name="text">
-               <string>Server to clients</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>Client loopback</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>Client fan out/in but no loopback</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>Full Mix</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>No auto patching</string>
-              </property>
-             </item>
             </widget>
            </item>
-           <item row="0" column="0">
-            <widget class="QLabel" name="autoPatchLabel">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
+           <item row="3" column="0">
+            <widget class="QLabel" name="usernameLabel">
+             <property name="enabled">
+              <bool>false</bool>
              </property>
              <property name="text">
-              <string>Hub auto&amp;patch mode</string>
+              <string>&amp;Username</string>
              </property>
              <property name="buddy">
-              <cstring>autoPatchComboBox</cstring>
+              <cstring>usernameEdit</cstring>
              </property>
             </widget>
            </item>
            <item row="1" column="0" colspan="2">
-            <widget class="QCheckBox" name="patchServerCheckBox">
+            <widget class="QLabel" name="authNotVSLabel">
+             <property name="text">
+              <string>(This is for JackTrip's inbuilt authentication system, not for the Virtual Studio. To connect to a Virtual Studio server, press the &quot;Virtual Studio Mode&quot; button below.)</string>
+             </property>
+             <property name="wordWrap">
+              <bool>true</bool>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </widget>
+        </item>
+        <item row="9" column="0">
+         <spacer name="basicVerticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeType">
+           <enum>QSizePolicy::Expanding</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item row="7" column="0" colspan="2">
+         <widget class="QGroupBox" name="requireAuthGroupBox">
+          <property name="title">
+           <string/>
+          </property>
+          <layout class="QGridLayout" name="gridLayout_7">
+           <item row="3" column="2">
+            <widget class="QPushButton" name="keyBrowse">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="text">
+              <string>Browse</string>
+             </property>
+            </widget>
+           </item>
+           <item row="1" column="0" colspan="3">
+            <widget class="QLabel" name="authDisclaimerLabel">
+             <property name="text">
+              <string>(This is a work in progress and needs to be manually configured outside of the app. Only use if you know what you're doing.)</string>
+             </property>
+             <property name="wordWrap">
+              <bool>true</bool>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="0">
+            <widget class="QLabel" name="certLabel">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="text">
+              <string>&amp;Certificate File</string>
+             </property>
+             <property name="buddy">
+              <cstring>certEdit</cstring>
+             </property>
+            </widget>
+           </item>
+           <item row="3" column="0">
+            <widget class="QLabel" name="keyLabel">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="text">
+              <string>&amp;Key File</string>
+             </property>
+             <property name="buddy">
+              <cstring>keyEdit</cstring>
+             </property>
+            </widget>
+           </item>
+           <item row="3" column="1">
+            <widget class="QLineEdit" name="keyEdit">
              <property name="enabled">
               <bool>false</bool>
              </property>
              <property name="toolTip">
-              <string>Include the server in the audio patching. This allows an ensemble member to
-play from this machine. (Available in client fan out/in and full mix modes.)</string>
+              <string>Choose the private key that the server should use for the SSL connection.</string>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="1">
+            <widget class="QLineEdit" name="certEdit">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="toolTip">
+              <string>Choose the certificate file that the server should use to establish an initial SSL connection.</string>
+             </property>
+            </widget>
+           </item>
+           <item row="2" column="2">
+            <widget class="QPushButton" name="certBrowse">
+             <property name="enabled">
+              <bool>false</bool>
              </property>
              <property name="text">
-              <string>&amp;Include server in patching</string>
+              <string>Browse</string>
+             </property>
+            </widget>
+           </item>
+           <item row="0" column="0" colspan="2">
+            <widget class="QCheckBox" name="requireAuthCheckBox">
+             <property name="toolTip">
+              <string>Require clients to connect with a username and password.</string>
+             </property>
+             <property name="text">
+              <string>&amp;Require Authentication</string>
+             </property>
+            </widget>
+           </item>
+           <item row="4" column="0">
+            <widget class="QLabel" name="credsLabel">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="text">
+              <string>&amp;Credentials File</string>
+             </property>
+             <property name="buddy">
+              <cstring>credsEdit</cstring>
+             </property>
+            </widget>
+           </item>
+           <item row="4" column="1">
+            <widget class="QLineEdit" name="credsEdit">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="toolTip">
+              <string>Choose the file containing the list of usernames and passwords.</string>
+             </property>
+            </widget>
+           </item>
+           <item row="4" column="2">
+            <widget class="QPushButton" name="credsBrowse">
+             <property name="enabled">
+              <bool>false</bool>
+             </property>
+             <property name="text">
+              <string>Browse</string>
              </property>
             </widget>
            </item>
           </layout>
          </widget>
         </item>
+        <item row="11" column="0" colspan="2">
+         <layout class="QHBoxLayout" name="aboutLayout">
+          <item>
+           <spacer name="aboutSpacer">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QPushButton" name="vsModeButton">
+            <property name="text">
+             <string>&amp;Virtual Studio Mode</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="aboutButton">
+            <property name="text">
+             <string>About</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item row="5" column="0" colspan="2">
+         <widget class="QCheckBox" name="zeroCheckBox">
+          <property name="toolTip">
+           <string>Silence the audio when there's a buffer underrun.</string>
+          </property>
+          <property name="text">
+           <string>Set buffer to &amp;zero when underrun occurs</string>
+          </property>
+         </widget>
+        </item>
        </layout>
       </widget>
       <widget class="QWidget" name="advancedTab">
@@ -534,8 +618,8 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
         <string>Advanced options</string>
        </attribute>
        <layout class="QGridLayout" name="gridLayout_4">
-        <item row="7" column="0">
-         <widget class="QLabel" name="resolutionLabel">
+        <item row="5" column="0">
+         <widget class="QLabel" name="queueLengthLabel">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
             <horstretch>0</horstretch>
@@ -543,87 +627,41 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
            </sizepolicy>
           </property>
           <property name="text">
-           <string>Audio &amp;Bit Resolution</string>
+           <string>&amp;Queue Buffer Length</string>
           </property>
           <property name="buddy">
-           <cstring>resolutionComboBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="7" column="1" colspan="2">
-         <widget class="QComboBox" name="resolutionComboBox">
-          <property name="toolTip">
-           <string>Select the audio bit resolution.</string>
-          </property>
-          <property name="currentIndex">
-           <number>1</number>
+           <cstring>queueLengthSpinBox</cstring>
           </property>
-          <item>
-           <property name="text">
-            <string>8</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>16</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>24</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>32</string>
-           </property>
-          </item>
          </widget>
         </item>
-        <item row="1" column="1" colspan="2">
-         <widget class="QLineEdit" name="remoteNameEdit">
+        <item row="0" column="1" colspan="2">
+         <widget class="QLineEdit" name="clientNameEdit">
           <property name="toolTip">
-           <string>Set the name of the Jack client as it will appear on the hub server.</string>
+           <string>Set the name of the Jack client.</string>
           </property>
           <property name="maxLength">
            <number>64</number>
           </property>
-         </widget>
-        </item>
-        <item row="11" column="0">
-         <widget class="QCheckBox" name="ioStatsCheckBox">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="toolTip">
-           <string>Display IO stats in another window.</string>
-          </property>
-          <property name="text">
-           <string>Display &amp;IO Stats</string>
+          <property name="placeholderText">
+           <string>JackTrip</string>
           </property>
          </widget>
         </item>
-        <item row="1" column="0">
-         <widget class="QLabel" name="remoteNameLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>Remote Client &amp;Name</string>
+        <item row="13" column="0">
+         <spacer name="advancedVerticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
           </property>
-          <property name="buddy">
-           <cstring>remoteNameEdit</cstring>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
           </property>
-         </widget>
+         </spacer>
         </item>
-        <item row="3" column="0">
-         <widget class="QLabel" name="remotePortLabel">
+        <item row="7" column="0">
+         <widget class="QLabel" name="resolutionLabel">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
             <horstretch>0</horstretch>
@@ -631,122 +669,135 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
            </sizepolicy>
           </property>
           <property name="text">
-           <string>Remote &amp;Port</string>
+           <string>Audio &amp;Bit Resolution</string>
           </property>
           <property name="buddy">
-           <cstring>remotePortSpinBox</cstring>
+           <cstring>resolutionComboBox</cstring>
           </property>
          </widget>
         </item>
-        <item row="2" column="1" colspan="2">
-         <widget class="QSpinBox" name="localPortSpinBox">
+        <item row="1" column="1" colspan="2">
+         <widget class="QLineEdit" name="remoteNameEdit">
           <property name="toolTip">
-           <string>Set the local port to use for the connection. The default is 4464.
-(Useful for running multiple hub clients behind the same router.)</string>
-          </property>
-          <property name="minimum">
-           <number>1024</number>
-          </property>
-          <property name="maximum">
-           <number>65535</number>
+           <string>Set the name of the Jack client as it will appear on the hub server.</string>
           </property>
-          <property name="value">
-           <number>4464</number>
+          <property name="maxLength">
+           <number>64</number>
           </property>
          </widget>
         </item>
-        <item row="13" column="0" colspan="3">
-         <widget class="QGroupBox" name="authGroupBox">
-          <property name="enabled">
-           <bool>true</bool>
+        <item row="7" column="1" colspan="2">
+         <widget class="QComboBox" name="resolutionComboBox">
+          <property name="toolTip">
+           <string>Select the audio bit resolution.</string>
           </property>
-          <property name="title">
-           <string/>
+          <property name="currentIndex">
+           <number>1</number>
           </property>
-          <layout class="QGridLayout" name="gridLayout_6">
-           <item row="0" column="0" colspan="2">
-            <widget class="QCheckBox" name="authCheckBox">
-             <property name="toolTip">
-              <string>Supply a username and password to connect to the server.</string>
-             </property>
-             <property name="text">
-              <string>&amp;Use Authentication</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QLineEdit" name="passwordEdit">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Enter your password. (This will not be shown or saved.)</string>
-             </property>
-             <property name="echoMode">
-              <enum>QLineEdit::Password</enum>
-             </property>
-             <property name="cursorPosition">
-              <number>0</number>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="1">
-            <widget class="QLineEdit" name="usernameEdit">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Enter your username for the server.</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="0">
-            <widget class="QLabel" name="passwordLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>&amp;Password</string>
-             </property>
-             <property name="buddy">
-              <cstring>passwordEdit</cstring>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="0">
-            <widget class="QLabel" name="usernameLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>&amp;Username</string>
-             </property>
-             <property name="buddy">
-              <cstring>usernameEdit</cstring>
-             </property>
-            </widget>
-           </item>
-          </layout>
+          <item>
+           <property name="text">
+            <string>8</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>16</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>24</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>32</string>
+           </property>
+          </item>
          </widget>
         </item>
-        <item row="2" column="0">
-         <widget class="QLabel" name="localPortLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
+        <item row="9" column="0" colspan="3">
+         <widget class="QCheckBox" name="realTimeCheckBox">
+          <property name="toolTip">
+           <string>Use real time priority for the networking threads.</string>
           </property>
           <property name="text">
-           <string>&amp;Local Port</string>
+           <string>Enable real&amp;time priority for networking threads</string>
           </property>
-          <property name="buddy">
-           <cstring>localPortSpinBox</cstring>
+          <property name="checked">
+           <bool>true</bool>
           </property>
          </widget>
         </item>
-        <item row="5" column="0">
-         <widget class="QLabel" name="queueLengthLabel">
+        <item row="11" column="1">
+         <widget class="QSpinBox" name="ioStatsSpinBox">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
+          <property name="toolTip">
+           <string>Choose how often stats should be reported.</string>
+          </property>
+          <property name="minimum">
+           <number>1</number>
+          </property>
+          <property name="maximum">
+           <number>120</number>
+          </property>
+         </widget>
+        </item>
+        <item row="4" column="1" colspan="2">
+         <widget class="QSpinBox" name="basePortSpinBox">
+          <property name="toolTip">
+           <string>Set the base UDP port to be used by connecting hub clients. The default is 61002.
+(You should manually set this if running multiple hub servers on the same machine.)</string>
+          </property>
+          <property name="minimum">
+           <number>1024</number>
+          </property>
+          <property name="maximum">
+           <number>65535</number>
+          </property>
+          <property name="value">
+           <number>61002</number>
+          </property>
+         </widget>
+        </item>
+        <item row="14" column="0" colspan="3">
+         <layout class="QHBoxLayout" name="useDefaultsLayout">
+          <item>
+           <spacer name="useDefaultsSpacer">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QPushButton" name="commandLineButton">
+            <property name="toolTip">
+             <string>Show the equivalent command line for the current settings.</string>
+            </property>
+            <property name="text">
+             <string>Get Command &amp;Line</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="useDefaultsButton">
+            <property name="text">
+             <string>Use &amp;Defaults</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item row="1" column="0">
+         <widget class="QLabel" name="remoteNameLabel">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
             <horstretch>0</horstretch>
@@ -754,28 +805,31 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
            </sizepolicy>
           </property>
           <property name="text">
-           <string>&amp;Queue Buffer Length</string>
+           <string>Remote Client &amp;Name</string>
           </property>
           <property name="buddy">
-           <cstring>queueLengthSpinBox</cstring>
+           <cstring>remoteNameEdit</cstring>
           </property>
          </widget>
         </item>
-        <item row="14" column="0">
-         <spacer name="advancedVerticalSpacer">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
+        <item row="11" column="0">
+         <widget class="QCheckBox" name="ioStatsCheckBox">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
           </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
+          <property name="toolTip">
+           <string>Display IO stats in another window.</string>
           </property>
-         </spacer>
+          <property name="text">
+           <string>Display &amp;IO Stats</string>
+          </property>
+         </widget>
         </item>
-        <item row="4" column="0">
-         <widget class="QLabel" name="basePortLabel">
+        <item row="3" column="0">
+         <widget class="QLabel" name="remotePortLabel">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
             <horstretch>0</horstretch>
@@ -783,10 +837,10 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
            </sizepolicy>
           </property>
           <property name="text">
-           <string>&amp;UDP Base Port</string>
+           <string>Remote &amp;Port</string>
           </property>
           <property name="buddy">
-           <cstring>basePortSpinBox</cstring>
+           <cstring>remotePortSpinBox</cstring>
           </property>
          </widget>
         </item>
@@ -806,11 +860,8 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
           </property>
          </widget>
         </item>
-        <item row="11" column="2">
-         <widget class="QLabel" name="ioStatsLabel">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
+        <item row="6" column="0">
+         <widget class="QLabel" name="redundancyLabel">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
             <horstretch>0</horstretch>
@@ -818,44 +869,61 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
            </sizepolicy>
           </property>
           <property name="text">
-           <string>Reporting &amp;Interval (s)</string>
+           <string>&amp;Redundancy</string>
           </property>
           <property name="buddy">
-           <cstring>ioStatsSpinBox</cstring>
+           <cstring>redundancySpinBox</cstring>
           </property>
          </widget>
         </item>
-        <item row="5" column="1" colspan="2">
-         <widget class="QSpinBox" name="queueLengthSpinBox">
+        <item row="8" column="0" colspan="3">
+         <widget class="QCheckBox" name="connectAudioCheckBox">
           <property name="toolTip">
-           <string>Set the queue buffer length, in packet size.</string>
+           <string>Connect the Jack client to the default system audio ports.</string>
+          </property>
+          <property name="text">
+           <string>&amp;Connect default audio ports</string>
+          </property>
+          <property name="checked">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1" colspan="2">
+         <widget class="QSpinBox" name="localPortSpinBox">
+          <property name="toolTip">
+           <string>Set the local port to use for the connection. The default is 4464.
+(Useful for running multiple hub clients behind the same router.)</string>
           </property>
           <property name="minimum">
-           <number>2</number>
+           <number>1024</number>
           </property>
           <property name="maximum">
-           <number>999</number>
+           <number>65535</number>
           </property>
           <property name="value">
-           <number>4</number>
+           <number>4464</number>
           </property>
          </widget>
         </item>
-        <item row="6" column="1" colspan="2">
-         <widget class="QSpinBox" name="redundancySpinBox">
+        <item row="3" column="1" colspan="2">
+         <widget class="QSpinBox" name="remotePortSpinBox">
           <property name="toolTip">
-           <string>Number of redundant packets to be sent to avoid glitches related to packet loss.</string>
+           <string>Set the remote port to use for the connection. The default is 4464.</string>
           </property>
           <property name="minimum">
-           <number>1</number>
+           <number>1024</number>
+          </property>
+          <property name="maximum">
+           <number>65535</number>
           </property>
           <property name="value">
-           <number>1</number>
+           <number>4464</number>
           </property>
          </widget>
         </item>
-        <item row="6" column="0">
-         <widget class="QLabel" name="redundancyLabel">
+        <item row="4" column="0">
+         <widget class="QLabel" name="basePortLabel">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
             <horstretch>0</horstretch>
@@ -863,92 +931,98 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
            </sizepolicy>
           </property>
           <property name="text">
-           <string>&amp;Redundancy</string>
+           <string>&amp;UDP Base Port</string>
           </property>
           <property name="buddy">
-           <cstring>redundancySpinBox</cstring>
+           <cstring>basePortSpinBox</cstring>
           </property>
          </widget>
         </item>
-        <item row="11" column="1">
-         <widget class="QSpinBox" name="ioStatsSpinBox">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="toolTip">
-           <string>Choose how often stats should be reported.</string>
+        <item row="2" column="0">
+         <widget class="QLabel" name="localPortLabel">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
           </property>
-          <property name="minimum">
-           <number>1</number>
+          <property name="text">
+           <string>&amp;Local Port</string>
           </property>
-          <property name="maximum">
-           <number>120</number>
+          <property name="buddy">
+           <cstring>localPortSpinBox</cstring>
           </property>
          </widget>
         </item>
-        <item row="3" column="1" colspan="2">
-         <widget class="QSpinBox" name="remotePortSpinBox">
+        <item row="6" column="1" colspan="2">
+         <widget class="QSpinBox" name="redundancySpinBox">
           <property name="toolTip">
-           <string>Set the remote port to use for the connection. The default is 4464.</string>
+           <string>Number of redundant packets to be sent to avoid glitches related to packet loss.</string>
           </property>
           <property name="minimum">
-           <number>1024</number>
-          </property>
-          <property name="maximum">
-           <number>65535</number>
+           <number>1</number>
           </property>
           <property name="value">
-           <number>4464</number>
+           <number>1</number>
           </property>
          </widget>
         </item>
-        <item row="8" column="0" colspan="3">
-         <widget class="QCheckBox" name="connectAudioCheckBox">
-          <property name="toolTip">
-           <string>Connect the Jack client to the default system audio ports.</string>
-          </property>
-          <property name="text">
-           <string>&amp;Connect default audio ports</string>
-          </property>
-          <property name="checked">
-           <bool>true</bool>
+        <item row="11" column="2">
+         <widget class="QLabel" name="ioStatsLabel">
+          <property name="enabled">
+           <bool>false</bool>
           </property>
-         </widget>
-        </item>
-        <item row="0" column="1" colspan="2">
-         <widget class="QLineEdit" name="clientNameEdit">
-          <property name="toolTip">
-           <string>Set the name of the Jack client.</string>
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
           </property>
-          <property name="maxLength">
-           <number>64</number>
+          <property name="text">
+           <string>Reporting &amp;Interval (s)</string>
           </property>
-          <property name="placeholderText">
-           <string>JackTrip</string>
+          <property name="buddy">
+           <cstring>ioStatsSpinBox</cstring>
           </property>
          </widget>
         </item>
-        <item row="4" column="1" colspan="2">
-         <widget class="QSpinBox" name="basePortSpinBox">
+        <item row="5" column="1" colspan="2">
+         <widget class="QSpinBox" name="queueLengthSpinBox">
           <property name="toolTip">
-           <string>Set the base UDP port to be used by connecting hub clients. The default is 61002.
-(You should manually set this if running multiple hub servers on the same machine.)</string>
+           <string>Set the queue buffer length, in packet size.</string>
           </property>
           <property name="minimum">
-           <number>1024</number>
+           <number>2</number>
           </property>
           <property name="maximum">
-           <number>65535</number>
+           <number>999</number>
           </property>
           <property name="value">
-           <number>61002</number>
+           <number>4</number>
           </property>
          </widget>
         </item>
-        <item row="15" column="0" colspan="3">
-         <layout class="QHBoxLayout" name="useDefaultsLayout">
+        <item row="12" column="0" colspan="3">
+         <widget class="QCheckBox" name="verboseCheckBox">
+          <property name="toolTip">
+           <string>Display debugging information that would normally appear on the console.</string>
+          </property>
+          <property name="text">
+           <string>Show &amp;Debug Information</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="backendTab">
+       <attribute name="title">
+        <string>Audio Backend</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout_11">
+        <item row="9" column="0" colspan="2">
+         <layout class="QHBoxLayout" name="deviceManagementLayout">
           <item>
-           <spacer name="useDefaultsSpacer">
+           <spacer name="backendTabSpacer">
             <property name="orientation">
              <enum>Qt::Horizontal</enum>
             </property>
@@ -961,54 +1035,34 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
            </spacer>
           </item>
           <item>
-           <widget class="QPushButton" name="commandLineButton">
-            <property name="toolTip">
-             <string>Show the equivalent command line for the current settings.</string>
-            </property>
-            <property name="text">
-             <string>Get Command &amp;Line</string>
+           <widget class="QPushButton" name="refreshDevicesButton">
+            <property name="enabled">
+             <bool>false</bool>
             </property>
-           </widget>
-          </item>
-          <item>
-           <widget class="QPushButton" name="useDefaultsButton">
             <property name="text">
-             <string>Use &amp;Defaults</string>
+             <string>&amp;Refresh Device List</string>
             </property>
            </widget>
           </item>
          </layout>
         </item>
-        <item row="9" column="0" colspan="3">
-         <widget class="QCheckBox" name="realTimeCheckBox">
-          <property name="toolTip">
-           <string>Use real time priority for the networking threads.</string>
-          </property>
-          <property name="text">
-           <string>Enable real&amp;time priority for networking threads</string>
-          </property>
-          <property name="checked">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-        <item row="12" column="0" colspan="3">
-         <widget class="QCheckBox" name="verboseCheckBox">
+        <item row="0" column="1">
+         <widget class="QComboBox" name="backendComboBox">
           <property name="toolTip">
-           <string>Display debugging information that would normally appear on the console.</string>
-          </property>
-          <property name="text">
-           <string>Show &amp;Debug Information</string>
+           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Choose the audio backend to use. JACK is the default and is well tested, but requires the JACK audio server to be installed.&lt;/p&gt;&lt;p&gt;RtAudio is still a work in progress, but it works with your operating system's native audio drivers and requires no additional software.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
           </property>
+          <item>
+           <property name="text">
+            <string>JACK</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>RtAudio</string>
+           </property>
+          </item>
          </widget>
         </item>
-       </layout>
-      </widget>
-      <widget class="QWidget" name="backendTab">
-       <attribute name="title">
-        <string>Audio Backend</string>
-       </attribute>
-       <layout class="QGridLayout" name="gridLayout_11">
         <item row="3" column="1">
          <widget class="QComboBox" name="inputDeviceComboBox">
           <property name="enabled">
@@ -1016,8 +1070,24 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
           </property>
          </widget>
         </item>
-        <item row="0" column="0">
-         <widget class="QLabel" name="backendLabel">
+        <item row="6" column="1">
+         <spacer name="backendSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>444</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item row="3" column="0">
+         <widget class="QLabel" name="inputDeviceLabel">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
           <property name="sizePolicy">
            <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
             <horstretch>0</horstretch>
@@ -1025,10 +1095,10 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
            </sizepolicy>
           </property>
           <property name="text">
-           <string>Audio &amp;Backend:</string>
+           <string>&amp;Input Device:</string>
           </property>
           <property name="buddy">
-           <cstring>backendComboBox</cstring>
+           <cstring>inputDeviceComboBox</cstring>
           </property>
          </widget>
         </item>
@@ -1080,6 +1150,41 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
           </item>
          </widget>
         </item>
+        <item row="0" column="0">
+         <widget class="QLabel" name="backendLabel">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="text">
+           <string>Audio &amp;Backend:</string>
+          </property>
+          <property name="buddy">
+           <cstring>backendComboBox</cstring>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="0">
+         <widget class="QLabel" name="bufferSizeLabel">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="text">
+           <string>&amp;Buffer Size:</string>
+          </property>
+          <property name="buddy">
+           <cstring>bufferSizeComboBox</cstring>
+          </property>
+         </widget>
+        </item>
         <item row="1" column="1">
          <widget class="QComboBox" name="sampleRateComboBox">
           <property name="enabled">
@@ -1131,8 +1236,8 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
           </item>
          </widget>
         </item>
-        <item row="3" column="0">
-         <widget class="QLabel" name="inputDeviceLabel">
+        <item row="1" column="0">
+         <widget class="QLabel" name="sampleRateLabel">
           <property name="enabled">
            <bool>false</bool>
           </property>
@@ -1143,50 +1248,13 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
            </sizepolicy>
           </property>
           <property name="text">
-           <string>&amp;Input Device:</string>
+           <string>&amp;Sampling Rate:</string>
           </property>
           <property name="buddy">
-           <cstring>inputDeviceComboBox</cstring>
+           <cstring>sampleRateComboBox</cstring>
           </property>
          </widget>
         </item>
-        <item row="6" column="1">
-         <spacer name="backendSpacer">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>444</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item row="9" column="0" colspan="2">
-         <layout class="QHBoxLayout" name="deviceManagementLayout">
-          <item>
-           <spacer name="backendTabSpacer">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>40</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item>
-           <widget class="QPushButton" name="refreshDevicesButton">
-            <property name="text">
-             <string>&amp;Refresh Device List</string>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </item>
         <item row="4" column="0">
          <widget class="QLabel" name="outputDeviceLabel">
           <property name="enabled">
@@ -1206,61 +1274,6 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
           </property>
          </widget>
         </item>
-        <item row="2" column="0">
-         <widget class="QLabel" name="bufferSizeLabel">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>&amp;Buffer Size:</string>
-          </property>
-          <property name="buddy">
-           <cstring>bufferSizeComboBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="0" column="1">
-         <widget class="QComboBox" name="backendComboBox">
-          <property name="toolTip">
-           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Choose the audio backend to use. JACK is the default and is well tested, but requires the JACK audio server to be installed.&lt;/p&gt;&lt;p&gt;RtAudio is still a work in progress, but it works with your operating system's native audio drivers and requires no additional software.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-          </property>
-          <item>
-           <property name="text">
-            <string>JACK</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>RtAudio</string>
-           </property>
-          </item>
-         </widget>
-        </item>
-        <item row="1" column="0">
-         <widget class="QLabel" name="sampleRateLabel">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>&amp;Sampling Rate:</string>
-          </property>
-          <property name="buddy">
-           <cstring>sampleRateComboBox</cstring>
-          </property>
-         </widget>
-        </item>
         <item row="4" column="1">
          <widget class="QComboBox" name="outputDeviceComboBox">
           <property name="enabled">
@@ -1271,7 +1284,7 @@ play from this machine. (Available in client fan out/in and full mix modes.)</st
         <item row="5" column="0" colspan="2">
          <widget class="QLabel" name="backendWarningLabel">
           <property name="text">
-           <string>These settings are ignored in Hub Server mode which requires JACK to operate.</string>
+           <string>These settings are ignored in hub server mode which requires JACK to operate.</string>
           </property>
           <property name="wordWrap">
            <bool>true</bool>
@@ -1827,6 +1840,9 @@ and wetness is the essence of beauty.</string>
   <tabstop>keyBrowse</tabstop>
   <tabstop>credsEdit</tabstop>
   <tabstop>credsBrowse</tabstop>
+  <tabstop>authCheckBox</tabstop>
+  <tabstop>usernameEdit</tabstop>
+  <tabstop>passwordEdit</tabstop>
   <tabstop>vsModeButton</tabstop>
   <tabstop>aboutButton</tabstop>
   <tabstop>clientNameEdit</tabstop>
@@ -1842,9 +1858,6 @@ and wetness is the essence of beauty.</string>
   <tabstop>ioStatsCheckBox</tabstop>
   <tabstop>ioStatsSpinBox</tabstop>
   <tabstop>verboseCheckBox</tabstop>
-  <tabstop>authCheckBox</tabstop>
-  <tabstop>usernameEdit</tabstop>
-  <tabstop>passwordEdit</tabstop>
   <tabstop>commandLineButton</tabstop>
   <tabstop>useDefaultsButton</tabstop>
   <tabstop>backendComboBox</tabstop>
diff --git a/src/gui/qjacktrip_novs.ui b/src/gui/qjacktrip_novs.ui
deleted file mode 100644 (file)
index 7aaced2..0000000
+++ /dev/null
@@ -1,1880 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>QJackTrip</class>
- <widget class="QMainWindow" name="QJackTrip">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>409</width>
-    <height>889</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>JackTrip</string>
-  </property>
-  <property name="windowIcon">
-   <iconset resource="qjacktrip.qrc">
-    <normaloff>:/qjacktrip/icon.png</normaloff>:/qjacktrip/icon.png</iconset>
-  </property>
-  <widget class="QWidget" name="centralWidget">
-   <layout class="QGridLayout" name="gridLayout">
-    <item row="0" column="1">
-     <widget class="QComboBox" name="typeComboBox">
-      <property name="toolTip">
-       <string>To connect to a p2p (peer to peer) server you need to run as a p2p client.
-To connect to a hub server you need to run as a hub client.</string>
-      </property>
-      <property name="currentIndex">
-       <number>2</number>
-      </property>
-      <item>
-       <property name="text">
-        <string>P2P Client</string>
-       </property>
-      </item>
-      <item>
-       <property name="text">
-        <string>P2P Server</string>
-       </property>
-      </item>
-      <item>
-       <property name="text">
-        <string>Hub Client</string>
-       </property>
-      </item>
-      <item>
-       <property name="text">
-        <string>Hub Server</string>
-       </property>
-      </item>
-     </widget>
-    </item>
-    <item row="6" column="0" colspan="2">
-     <layout class="QHBoxLayout" name="buttonLayout">
-      <item>
-       <widget class="QPushButton" name="connectButton">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <property name="text">
-         <string>Connect</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QPushButton" name="disconnectButton">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <property name="text">
-         <string>Disconnect</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QPushButton" name="exitButton">
-        <property name="text">
-         <string>Exit</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </item>
-    <item row="3" column="1">
-     <widget class="QLabel" name="ipLabel">
-      <property name="toolTip">
-       <string>If running as a server, this is the address you should supply to the other clients.
-(You will need to enable any port forwarding on your router manually.)</string>
-      </property>
-      <property name="text">
-       <string>Looking up external IP address...</string>
-      </property>
-     </widget>
-    </item>
-    <item row="1" column="1">
-     <widget class="QComboBox" name="addressComboBox">
-      <property name="sizePolicy">
-       <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
-        <horstretch>0</horstretch>
-        <verstretch>0</verstretch>
-       </sizepolicy>
-      </property>
-      <property name="toolTip">
-       <string>Enter the IP address or the hostname of the server you want to connect to.</string>
-      </property>
-      <property name="editable">
-       <bool>true</bool>
-      </property>
-      <property name="maxCount">
-       <number>5</number>
-      </property>
-      <property name="insertPolicy">
-       <enum>QComboBox::NoInsert</enum>
-      </property>
-     </widget>
-    </item>
-    <item row="1" column="0">
-     <widget class="QLabel" name="addressLabel">
-      <property name="enabled">
-       <bool>true</bool>
-      </property>
-      <property name="text">
-       <string>&amp;Address of server</string>
-      </property>
-      <property name="buddy">
-       <cstring>addressComboBox</cstring>
-      </property>
-     </widget>
-    </item>
-    <item row="0" column="0">
-     <widget class="QLabel" name="typeLabel">
-      <property name="text">
-       <string>&amp;Run JackTrip as</string>
-      </property>
-      <property name="buddy">
-       <cstring>typeComboBox</cstring>
-      </property>
-     </widget>
-    </item>
-    <item row="5" column="0" colspan="2">
-     <widget class="QTabWidget" name="optionsTabWidget">
-      <property name="enabled">
-       <bool>true</bool>
-      </property>
-      <property name="minimumSize">
-       <size>
-        <width>391</width>
-        <height>0</height>
-       </size>
-      </property>
-      <property name="currentIndex">
-       <number>0</number>
-      </property>
-      <property name="tabsClosable">
-       <bool>false</bool>
-      </property>
-      <property name="movable">
-       <bool>false</bool>
-      </property>
-      <widget class="QWidget" name="basicTab">
-       <property name="enabled">
-        <bool>true</bool>
-       </property>
-       <attribute name="title">
-        <string>Basic options</string>
-       </attribute>
-       <layout class="QGridLayout" name="gridLayout_3">
-        <item row="3" column="0" colspan="2">
-         <widget class="QGroupBox" name="autoPatchGroupBox">
-          <property name="title">
-           <string/>
-          </property>
-          <layout class="QGridLayout" name="gridLayout_10">
-           <item row="0" column="0" rowspan="2" colspan="2">
-            <widget class="QLabel" name="autoPatchLabel">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="text">
-              <string>Hub auto&amp;patch mode</string>
-             </property>
-             <property name="buddy">
-              <cstring>autoPatchComboBox</cstring>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="2">
-            <widget class="QComboBox" name="autoPatchComboBox">
-             <property name="toolTip">
-              <string>Select how you want audio to be routed by the hub server.</string>
-             </property>
-             <property name="currentIndex">
-              <number>0</number>
-             </property>
-             <item>
-              <property name="text">
-               <string>Server to clients</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>Client loopback</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>Client fan out/in but no loopback</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>Full Mix</string>
-              </property>
-             </item>
-             <item>
-              <property name="text">
-               <string>No auto patching</string>
-              </property>
-             </item>
-            </widget>
-           </item>
-           <item row="3" column="0" colspan="3">
-            <widget class="QCheckBox" name="upmixCheckBox">
-             <property name="toolTip">
-              <string>For clients that only send one channel of audio, relay their signal in stereo.</string>
-             </property>
-             <property name="text">
-              <string>&amp;Upmix mono clients to stereo</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="0" colspan="3">
-            <widget class="QCheckBox" name="patchServerCheckBox">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Include the server in the audio patching. This allows an ensemble member to
-play from this machine. (Available in client fan out/in and full mix modes.)</string>
-             </property>
-             <property name="text">
-              <string>&amp;Include server in patching</string>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item row="2" column="0" colspan="2">
-         <widget class="QGroupBox" name="channelGroupBox">
-          <layout class="QGridLayout" name="gridLayout_9">
-           <item row="3" column="0">
-            <widget class="QLabel" name="channelRecvLabel">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="text">
-              <string>&amp;Received from network:</string>
-             </property>
-             <property name="buddy">
-              <cstring>channelRecvSpinBox</cstring>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QSpinBox" name="channelRecvSpinBox">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="toolTip">
-              <string>Number of audio channels toaccept from the network.</string>
-             </property>
-             <property name="minimum">
-              <number>1</number>
-             </property>
-             <property name="value">
-              <number>2</number>
-             </property>
-            </widget>
-           </item>
-           <item row="4" column="1">
-            <widget class="QSpinBox" name="channelSendSpinBox">
-             <property name="toolTip">
-              <string>Number of audio channels to send to the network.</string>
-             </property>
-             <property name="minimum">
-              <number>1</number>
-             </property>
-             <property name="value">
-              <number>2</number>
-             </property>
-            </widget>
-           </item>
-           <item row="4" column="0">
-            <widget class="QLabel" name="channelSendLabel">
-             <property name="text">
-              <string>&amp;Sent to network:</string>
-             </property>
-             <property name="buddy">
-              <cstring>channelSendSpinBox</cstring>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="0" colspan="2">
-            <widget class="QLabel" name="channelLabel">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="text">
-              <string>&amp;Number of channels</string>
-             </property>
-             <property name="buddy">
-              <cstring>channelRecvSpinBox</cstring>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item row="6" column="0" colspan="2">
-         <widget class="QCheckBox" name="timeoutCheckBox">
-          <property name="toolTip">
-           <string>Stop JackTrip if no network traffic has been received for 10 seconds.</string>
-          </property>
-          <property name="text">
-           <string>&amp;Disconnect after 10 seconds of no network activity</string>
-          </property>
-         </widget>
-        </item>
-        <item row="8" column="0" colspan="2">
-         <widget class="QGroupBox" name="authGroupBox">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="title">
-           <string/>
-          </property>
-          <layout class="QGridLayout" name="gridLayout_6">
-           <item row="0" column="0" colspan="2">
-            <widget class="QCheckBox" name="authCheckBox">
-             <property name="toolTip">
-              <string>Supply a username and password to connect to the server.</string>
-             </property>
-             <property name="text">
-              <string>&amp;Use Authentication</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QLineEdit" name="passwordEdit">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Enter your password. (This will not be shown or saved.)</string>
-             </property>
-             <property name="echoMode">
-              <enum>QLineEdit::Password</enum>
-             </property>
-             <property name="cursorPosition">
-              <number>0</number>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="1">
-            <widget class="QLineEdit" name="usernameEdit">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Enter your username for the server.</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="0">
-            <widget class="QLabel" name="passwordLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>&amp;Password</string>
-             </property>
-             <property name="buddy">
-              <cstring>passwordEdit</cstring>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="0">
-            <widget class="QLabel" name="usernameLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>&amp;Username</string>
-             </property>
-             <property name="buddy">
-              <cstring>usernameEdit</cstring>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item row="9" column="0">
-         <spacer name="basicVerticalSpacer">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeType">
-           <enum>QSizePolicy::Expanding</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item row="7" column="0" colspan="2">
-         <widget class="QGroupBox" name="requireAuthGroupBox">
-          <property name="title">
-           <string/>
-          </property>
-          <layout class="QGridLayout" name="gridLayout_7">
-           <item row="3" column="2">
-            <widget class="QPushButton" name="keyBrowse">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Browse</string>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="0" colspan="3">
-            <widget class="QLabel" name="authDisclaimerLabel">
-             <property name="text">
-              <string>(This is a work in progress and needs to be manually configured outside of the app. Only use if you know what you're doing.)</string>
-             </property>
-             <property name="wordWrap">
-              <bool>true</bool>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="0">
-            <widget class="QLabel" name="certLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>&amp;Certificate File</string>
-             </property>
-             <property name="buddy">
-              <cstring>certEdit</cstring>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="0">
-            <widget class="QLabel" name="keyLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>&amp;Key File</string>
-             </property>
-             <property name="buddy">
-              <cstring>keyEdit</cstring>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QLineEdit" name="keyEdit">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Choose the private key that the server should use for the SSL connection.</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="1">
-            <widget class="QLineEdit" name="certEdit">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Choose the certificate file that the server should use to establish an initial SSL connection.</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="2">
-            <widget class="QPushButton" name="certBrowse">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Browse</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="0" colspan="2">
-            <widget class="QCheckBox" name="requireAuthCheckBox">
-             <property name="toolTip">
-              <string>Require clients to connect with a username and password.</string>
-             </property>
-             <property name="text">
-              <string>&amp;Require Authentication</string>
-             </property>
-            </widget>
-           </item>
-           <item row="4" column="0">
-            <widget class="QLabel" name="credsLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>&amp;Credentials File</string>
-             </property>
-             <property name="buddy">
-              <cstring>credsEdit</cstring>
-             </property>
-            </widget>
-           </item>
-           <item row="4" column="1">
-            <widget class="QLineEdit" name="credsEdit">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Choose the file containing the list of usernames and passwords.</string>
-             </property>
-            </widget>
-           </item>
-           <item row="4" column="2">
-            <widget class="QPushButton" name="credsBrowse">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Browse</string>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item row="11" column="0" colspan="2">
-         <layout class="QHBoxLayout" name="aboutLayout">
-          <item>
-           <spacer name="aboutSpacer">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>40</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item>
-           <widget class="QPushButton" name="vsModeButton">
-            <property name="text">
-             <string>&amp;Virtual Studio Mode</string>
-            </property>
-           </widget>
-          </item>
-          <item>
-           <widget class="QPushButton" name="aboutButton">
-            <property name="text">
-             <string>About</string>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </item>
-        <item row="5" column="0" colspan="2">
-         <widget class="QCheckBox" name="zeroCheckBox">
-          <property name="toolTip">
-           <string>Silence the audio when there's a buffer underrun.</string>
-          </property>
-          <property name="text">
-           <string>Set buffer to &amp;zero when underrun occurs</string>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </widget>
-      <widget class="QWidget" name="advancedTab">
-       <property name="enabled">
-        <bool>true</bool>
-       </property>
-       <attribute name="title">
-        <string>Advanced options</string>
-       </attribute>
-       <layout class="QGridLayout" name="gridLayout_4">
-        <item row="5" column="0">
-         <widget class="QLabel" name="queueLengthLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>&amp;Queue Buffer Length</string>
-          </property>
-          <property name="buddy">
-           <cstring>queueLengthSpinBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="0" column="1" colspan="2">
-         <widget class="QLineEdit" name="clientNameEdit">
-          <property name="toolTip">
-           <string>Set the name of the Jack client.</string>
-          </property>
-          <property name="maxLength">
-           <number>64</number>
-          </property>
-          <property name="placeholderText">
-           <string>JackTrip</string>
-          </property>
-         </widget>
-        </item>
-        <item row="13" column="0">
-         <spacer name="advancedVerticalSpacer">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item row="7" column="0">
-         <widget class="QLabel" name="resolutionLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>Audio &amp;Bit Resolution</string>
-          </property>
-          <property name="buddy">
-           <cstring>resolutionComboBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="1" column="1" colspan="2">
-         <widget class="QLineEdit" name="remoteNameEdit">
-          <property name="toolTip">
-           <string>Set the name of the Jack client as it will appear on the hub server.</string>
-          </property>
-          <property name="maxLength">
-           <number>64</number>
-          </property>
-         </widget>
-        </item>
-        <item row="7" column="1" colspan="2">
-         <widget class="QComboBox" name="resolutionComboBox">
-          <property name="toolTip">
-           <string>Select the audio bit resolution.</string>
-          </property>
-          <property name="currentIndex">
-           <number>1</number>
-          </property>
-          <item>
-           <property name="text">
-            <string>8</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>16</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>24</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>32</string>
-           </property>
-          </item>
-         </widget>
-        </item>
-        <item row="9" column="0" colspan="3">
-         <widget class="QCheckBox" name="realTimeCheckBox">
-          <property name="toolTip">
-           <string>Use real time priority for the networking threads.</string>
-          </property>
-          <property name="text">
-           <string>Enable real&amp;time priority for networking threads</string>
-          </property>
-          <property name="checked">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-        <item row="11" column="1">
-         <widget class="QSpinBox" name="ioStatsSpinBox">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="toolTip">
-           <string>Choose how often stats should be reported.</string>
-          </property>
-          <property name="minimum">
-           <number>1</number>
-          </property>
-          <property name="maximum">
-           <number>120</number>
-          </property>
-         </widget>
-        </item>
-        <item row="4" column="1" colspan="2">
-         <widget class="QSpinBox" name="basePortSpinBox">
-          <property name="toolTip">
-           <string>Set the base UDP port to be used by connecting hub clients. The default is 61002.
-(You should manually set this if running multiple hub servers on the same machine.)</string>
-          </property>
-          <property name="minimum">
-           <number>1024</number>
-          </property>
-          <property name="maximum">
-           <number>65535</number>
-          </property>
-          <property name="value">
-           <number>61002</number>
-          </property>
-         </widget>
-        </item>
-        <item row="14" column="0" colspan="3">
-         <layout class="QHBoxLayout" name="useDefaultsLayout">
-          <item>
-           <spacer name="useDefaultsSpacer">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>40</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item>
-           <widget class="QPushButton" name="commandLineButton">
-            <property name="toolTip">
-             <string>Show the equivalent command line for the current settings.</string>
-            </property>
-            <property name="text">
-             <string>Get Command &amp;Line</string>
-            </property>
-           </widget>
-          </item>
-          <item>
-           <widget class="QPushButton" name="useDefaultsButton">
-            <property name="text">
-             <string>Use &amp;Defaults</string>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </item>
-        <item row="1" column="0">
-         <widget class="QLabel" name="remoteNameLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>Remote Client &amp;Name</string>
-          </property>
-          <property name="buddy">
-           <cstring>remoteNameEdit</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="11" column="0">
-         <widget class="QCheckBox" name="ioStatsCheckBox">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="toolTip">
-           <string>Display IO stats in another window.</string>
-          </property>
-          <property name="text">
-           <string>Display &amp;IO Stats</string>
-          </property>
-         </widget>
-        </item>
-        <item row="3" column="0">
-         <widget class="QLabel" name="remotePortLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>Remote &amp;Port</string>
-          </property>
-          <property name="buddy">
-           <cstring>remotePortSpinBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="0" column="0">
-         <widget class="QLabel" name="clientNameLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>Custom Client &amp;Name</string>
-          </property>
-          <property name="buddy">
-           <cstring>clientNameEdit</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="6" column="0">
-         <widget class="QLabel" name="redundancyLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>&amp;Redundancy</string>
-          </property>
-          <property name="buddy">
-           <cstring>redundancySpinBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="8" column="0" colspan="3">
-         <widget class="QCheckBox" name="connectAudioCheckBox">
-          <property name="toolTip">
-           <string>Connect the Jack client to the default system audio ports.</string>
-          </property>
-          <property name="text">
-           <string>&amp;Connect default audio ports</string>
-          </property>
-          <property name="checked">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-        <item row="2" column="1" colspan="2">
-         <widget class="QSpinBox" name="localPortSpinBox">
-          <property name="toolTip">
-           <string>Set the local port to use for the connection. The default is 4464.
-(Useful for running multiple hub clients behind the same router.)</string>
-          </property>
-          <property name="minimum">
-           <number>1024</number>
-          </property>
-          <property name="maximum">
-           <number>65535</number>
-          </property>
-          <property name="value">
-           <number>4464</number>
-          </property>
-         </widget>
-        </item>
-        <item row="3" column="1" colspan="2">
-         <widget class="QSpinBox" name="remotePortSpinBox">
-          <property name="toolTip">
-           <string>Set the remote port to use for the connection. The default is 4464.</string>
-          </property>
-          <property name="minimum">
-           <number>1024</number>
-          </property>
-          <property name="maximum">
-           <number>65535</number>
-          </property>
-          <property name="value">
-           <number>4464</number>
-          </property>
-         </widget>
-        </item>
-        <item row="4" column="0">
-         <widget class="QLabel" name="basePortLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>&amp;UDP Base Port</string>
-          </property>
-          <property name="buddy">
-           <cstring>basePortSpinBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="2" column="0">
-         <widget class="QLabel" name="localPortLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>&amp;Local Port</string>
-          </property>
-          <property name="buddy">
-           <cstring>localPortSpinBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="6" column="1" colspan="2">
-         <widget class="QSpinBox" name="redundancySpinBox">
-          <property name="toolTip">
-           <string>Number of redundant packets to be sent to avoid glitches related to packet loss.</string>
-          </property>
-          <property name="minimum">
-           <number>1</number>
-          </property>
-          <property name="value">
-           <number>1</number>
-          </property>
-         </widget>
-        </item>
-        <item row="11" column="2">
-         <widget class="QLabel" name="ioStatsLabel">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>Reporting &amp;Interval (s)</string>
-          </property>
-          <property name="buddy">
-           <cstring>ioStatsSpinBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="5" column="1" colspan="2">
-         <widget class="QSpinBox" name="queueLengthSpinBox">
-          <property name="toolTip">
-           <string>Set the queue buffer length, in packet size.</string>
-          </property>
-          <property name="minimum">
-           <number>2</number>
-          </property>
-          <property name="maximum">
-           <number>999</number>
-          </property>
-          <property name="value">
-           <number>4</number>
-          </property>
-         </widget>
-        </item>
-        <item row="12" column="0" colspan="3">
-         <widget class="QCheckBox" name="verboseCheckBox">
-          <property name="toolTip">
-           <string>Display debugging information that would normally appear on the console.</string>
-          </property>
-          <property name="text">
-           <string>Show &amp;Debug Information</string>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </widget>
-      <widget class="QWidget" name="backendTab">
-       <attribute name="title">
-        <string>Audio Backend</string>
-       </attribute>
-       <layout class="QGridLayout" name="gridLayout_11">
-        <item row="9" column="0" colspan="2">
-         <layout class="QHBoxLayout" name="deviceManagementLayout">
-          <item>
-           <spacer name="backendTabSpacer">
-            <property name="orientation">
-             <enum>Qt::Horizontal</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>40</width>
-              <height>20</height>
-             </size>
-            </property>
-           </spacer>
-          </item>
-          <item>
-           <widget class="QPushButton" name="refreshDevicesButton">
-            <property name="text">
-             <string>&amp;Refresh Device List</string>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </item>
-        <item row="0" column="1">
-         <widget class="QComboBox" name="backendComboBox">
-          <property name="toolTip">
-           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Choose the audio backend to use. JACK is the default and is well tested, but requires the JACK audio server to be installed.&lt;/p&gt;&lt;p&gt;RtAudio is still a work in progress, but it works with your operating system's native audio drivers and requires no additional software.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-          </property>
-          <item>
-           <property name="text">
-            <string>JACK</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>RtAudio</string>
-           </property>
-          </item>
-         </widget>
-        </item>
-        <item row="3" column="1">
-         <widget class="QComboBox" name="inputDeviceComboBox">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-         </widget>
-        </item>
-        <item row="6" column="1">
-         <spacer name="backendSpacer">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>444</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item row="3" column="0">
-         <widget class="QLabel" name="inputDeviceLabel">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>&amp;Input Device:</string>
-          </property>
-          <property name="buddy">
-           <cstring>inputDeviceComboBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="2" column="1">
-         <widget class="QComboBox" name="bufferSizeComboBox">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="toolTip">
-           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set the driver's buffer size to use with the RtAudio backend.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-          </property>
-          <property name="currentIndex">
-           <number>3</number>
-          </property>
-          <item>
-           <property name="text">
-            <string>16</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>32</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>64</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>128</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>256</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>512</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>1024</string>
-           </property>
-          </item>
-         </widget>
-        </item>
-        <item row="0" column="0">
-         <widget class="QLabel" name="backendLabel">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>Audio &amp;Backend:</string>
-          </property>
-          <property name="buddy">
-           <cstring>backendComboBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="2" column="0">
-         <widget class="QLabel" name="bufferSizeLabel">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>&amp;Buffer Size:</string>
-          </property>
-          <property name="buddy">
-           <cstring>bufferSizeComboBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="1" column="1">
-         <widget class="QComboBox" name="sampleRateComboBox">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="toolTip">
-           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set the audio sample rate to use with the RtAudio backend. This setting should be the same on both ends of the connection.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-          </property>
-          <property name="currentText">
-           <string>48000</string>
-          </property>
-          <property name="currentIndex">
-           <number>3</number>
-          </property>
-          <item>
-           <property name="text">
-            <string>22050</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>32000</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>44100</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>48000</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>88200</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>96000</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>192000</string>
-           </property>
-          </item>
-         </widget>
-        </item>
-        <item row="1" column="0">
-         <widget class="QLabel" name="sampleRateLabel">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>&amp;Sampling Rate:</string>
-          </property>
-          <property name="buddy">
-           <cstring>sampleRateComboBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="4" column="0">
-         <widget class="QLabel" name="outputDeviceLabel">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>&amp;Output Device:</string>
-          </property>
-          <property name="buddy">
-           <cstring>outputDeviceComboBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="4" column="1">
-         <widget class="QComboBox" name="outputDeviceComboBox">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-         </widget>
-        </item>
-        <item row="5" column="0" colspan="2">
-         <widget class="QLabel" name="backendWarningLabel">
-          <property name="text">
-           <string>These settings are ignored in hub server mode which requires JACK to operate.</string>
-          </property>
-          <property name="wordWrap">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </widget>
-      <widget class="QWidget" name="JitterTab">
-       <attribute name="title">
-        <string>Jitter Buffer</string>
-       </attribute>
-       <layout class="QGridLayout" name="gridLayout_8">
-        <item row="10" column="2">
-         <widget class="QLabel" name="packetsLabel">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="text">
-           <string>Packets</string>
-          </property>
-         </widget>
-        </item>
-        <item row="8" column="0" colspan="3">
-         <widget class="QCheckBox" name="autoQueueCheckBox">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="text">
-           <string>Automatically set the &amp;queue length</string>
-          </property>
-          <property name="checked">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-        <item row="9" column="0" colspan="2">
-         <widget class="QLabel" name="autoQueueLabel">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>Aim to &amp;drop no more than one in every</string>
-          </property>
-          <property name="buddy">
-           <cstring>autoQueueSpinBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="5" column="0" colspan="3">
-         <widget class="Line" name="bufferLine">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-         </widget>
-        </item>
-        <item row="9" column="2">
-         <widget class="QSpinBox" name="autoQueueSpinBox">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="maximum">
-           <number>1000000</number>
-          </property>
-          <property name="singleStep">
-           <number>100</number>
-          </property>
-          <property name="value">
-           <number>500</number>
-          </property>
-         </widget>
-        </item>
-        <item row="3" column="0" colspan="3">
-         <widget class="QCheckBox" name="broadcastCheckBox">
-          <property name="toolTip">
-           <string>Enable a second, broadcast output with a higher queue length
-for better quality at the expense of latency.</string>
-          </property>
-          <property name="text">
-           <string>Enable &amp;Broadcast Output</string>
-          </property>
-         </widget>
-        </item>
-        <item row="12" column="0">
-         <spacer name="verticalSpacer">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item row="11" column="0" colspan="3">
-         <widget class="QLabel" name="autoQueueExplanationLabel">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="text">
-           <string>This will override the queue buffer length entered in the advanced options tab. (The default value is 500.)</string>
-          </property>
-          <property name="wordWrap">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-        <item row="0" column="0" colspan="2">
-         <widget class="QCheckBox" name="jitterCheckBox">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="toolTip">
-           <string>Enable the new jitter buffer. This is now the default.</string>
-          </property>
-          <property name="text">
-           <string>Enable &amp;Jitter Buffer</string>
-          </property>
-          <property name="checked">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-        <item row="2" column="1" colspan="2">
-         <widget class="QComboBox" name="bufferStrategyComboBox">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="toolTip">
-           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Buffer strategy 1 attempts to drop as little audio data as possible without exceeding the maximum queue length. It operates very similarly to the original buffer implementation with a few fixes to drop even less audio.&lt;/p&gt;&lt;p&gt;Buffer strategy 2 is optimized to keep the latency stable, so that the delay experienced over the connection doesn't fluctuate and is as predictable as possible. The trade off is that more audio might be dropped, but the difference should be negligible with the right queue length.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-          </property>
-          <property name="currentIndex">
-           <number>0</number>
-          </property>
-          <item>
-           <property name="text">
-            <string>1</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>2</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string>3 (experimental)</string>
-           </property>
-          </item>
-         </widget>
-        </item>
-        <item row="2" column="0">
-         <widget class="QLabel" name="bufferStrategyLabel">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string>Use buffer &amp;strategy</string>
-          </property>
-          <property name="buddy">
-           <cstring>bufferStrategyComboBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="4" column="0">
-         <widget class="QLabel" name="broadcastQueueLabel">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="text">
-           <string>Broadcast &amp;Queue Length</string>
-          </property>
-          <property name="buddy">
-           <cstring>broadcastQueueSpinBox</cstring>
-          </property>
-         </widget>
-        </item>
-        <item row="4" column="1" colspan="2">
-         <widget class="QSpinBox" name="broadcastQueueSpinBox">
-          <property name="enabled">
-           <bool>false</bool>
-          </property>
-          <property name="toolTip">
-           <string>Set the broadcast queue buffer length, in packet size.</string>
-          </property>
-          <property name="minimum">
-           <number>2</number>
-          </property>
-          <property name="maximum">
-           <number>999</number>
-          </property>
-          <property name="value">
-           <number>8</number>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </widget>
-      <widget class="QWidget" name="pluginsTab">
-       <attribute name="title">
-        <string>Plugins</string>
-       </attribute>
-       <layout class="QVBoxLayout" name="verticalLayout">
-        <item>
-         <widget class="QGroupBox" name="incomingGroupBox">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="title">
-           <string>Incoming</string>
-          </property>
-          <layout class="QGridLayout" name="gridLayout_5">
-           <item row="1" column="1">
-            <widget class="QSlider" name="inZitarevWetnessSlider">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Set the wet/dry mix.</string>
-             </property>
-             <property name="maximum">
-              <number>100</number>
-             </property>
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="tickPosition">
-              <enum>QSlider::TicksBelow</enum>
-             </property>
-             <property name="tickInterval">
-              <number>20</number>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="2">
-            <widget class="QLabel" name="inFreeverbLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Wetness</string>
-             </property>
-            </widget>
-           </item>
-           <item row="4" column="0">
-            <widget class="QCheckBox" name="inLimiterCheckBox">
-             <property name="toolTip">
-              <string>Enable the limiter on incoming audio.</string>
-             </property>
-             <property name="text">
-              <string>&amp;Limiter</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="0">
-            <widget class="QCheckBox" name="inFreeverbCheckBox">
-             <property name="toolTip">
-              <string>Enable the freeverb plugin on incoming audio.</string>
-             </property>
-             <property name="text">
-              <string>&amp;Freeverb</string>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="2" alignment="Qt::AlignHCenter">
-            <widget class="QLabel" name="inZitarevLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Wetness</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="0">
-            <widget class="QCheckBox" name="inCompressorCheckBox">
-             <property name="toolTip">
-              <string>Enable the compressor plugin on incoming audio.</string>
-             </property>
-             <property name="text">
-              <string>&amp;Compressor</string>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="0">
-            <widget class="QCheckBox" name="inZitarevCheckBox">
-             <property name="toolTip">
-              <string>Enable the zitarev reverb plugin on incoming audio.</string>
-             </property>
-             <property name="text">
-              <string>&amp;Zitarev</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="1">
-            <widget class="QSlider" name="inFreeverbWetnessSlider">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Set the wet/dry mix.</string>
-             </property>
-             <property name="maximum">
-              <number>100</number>
-             </property>
-             <property name="singleStep">
-              <number>1</number>
-             </property>
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="invertedAppearance">
-              <bool>false</bool>
-             </property>
-             <property name="tickPosition">
-              <enum>QSlider::TicksBelow</enum>
-             </property>
-             <property name="tickInterval">
-              <number>20</number>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item>
-         <widget class="QGroupBox" name="outgoingGroupBox">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="title">
-           <string>Outgoing</string>
-          </property>
-          <layout class="QGridLayout" name="gridLayout_2">
-           <item row="0" column="0">
-            <widget class="QCheckBox" name="outFreeverbCheckBox">
-             <property name="toolTip">
-              <string>Enable the freeverb plugin on outgoing audio.</string>
-             </property>
-             <property name="text">
-              <string>Free&amp;verb</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="1">
-            <widget class="QSlider" name="outFreeverbWetnessSlider">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Set the wet/dry mix.</string>
-             </property>
-             <property name="maximum">
-              <number>100</number>
-             </property>
-             <property name="singleStep">
-              <number>1</number>
-             </property>
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="invertedAppearance">
-              <bool>false</bool>
-             </property>
-             <property name="tickPosition">
-              <enum>QSlider::TicksBelow</enum>
-             </property>
-             <property name="tickInterval">
-              <number>20</number>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="2">
-            <widget class="QLabel" name="outFreeverbLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Wetness</string>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="0">
-            <widget class="QCheckBox" name="outZitarevCheckBox">
-             <property name="toolTip">
-              <string>Enable the zitarev reverb plugin on outgoing audio.</string>
-             </property>
-             <property name="text">
-              <string>Zi&amp;tarev</string>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="1">
-            <widget class="QSlider" name="outZitarevWetnessSlider">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Set the wet/dry mix.</string>
-             </property>
-             <property name="maximum">
-              <number>100</number>
-             </property>
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="tickPosition">
-              <enum>QSlider::TicksBelow</enum>
-             </property>
-             <property name="tickInterval">
-              <number>20</number>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="2">
-            <widget class="QLabel" name="outZitarevLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Moisture is the essence of wetness,
-and wetness is the essence of beauty.</string>
-             </property>
-             <property name="text">
-              <string>Wetness</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="0">
-            <widget class="QCheckBox" name="outCompressorCheckBox">
-             <property name="toolTip">
-              <string>Enable the compressor plugin on outgoing audio.</string>
-             </property>
-             <property name="text">
-              <string>Com&amp;pressor</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="0">
-            <widget class="QCheckBox" name="outLimiterCheckBox">
-             <property name="toolTip">
-              <string>Enable the limiter on outgoing audio.</string>
-             </property>
-             <property name="text">
-              <string>Li&amp;miter</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QSpinBox" name="outClientsSpinBox">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="toolTip">
-              <string>Enter the anticipated number of clients that will be connected to the server.</string>
-             </property>
-             <property name="minimum">
-              <number>1</number>
-             </property>
-             <property name="maximum">
-              <number>100</number>
-             </property>
-             <property name="value">
-              <number>2</number>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="2">
-            <widget class="QLabel" name="outLimiterLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Clients</string>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item>
-         <spacer name="pluginsVerticalSpacer">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
-      </widget>
-     </widget>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QMenuBar" name="menuBar">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>0</y>
-     <width>409</width>
-     <height>30</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QStatusBar" name="statusBar"/>
- </widget>
- <tabstops>
-  <tabstop>typeComboBox</tabstop>
-  <tabstop>addressComboBox</tabstop>
-  <tabstop>connectButton</tabstop>
-  <tabstop>disconnectButton</tabstop>
-  <tabstop>exitButton</tabstop>
-  <tabstop>optionsTabWidget</tabstop>
-  <tabstop>channelRecvSpinBox</tabstop>
-  <tabstop>channelSendSpinBox</tabstop>
-  <tabstop>autoPatchComboBox</tabstop>
-  <tabstop>patchServerCheckBox</tabstop>
-  <tabstop>upmixCheckBox</tabstop>
-  <tabstop>zeroCheckBox</tabstop>
-  <tabstop>timeoutCheckBox</tabstop>
-  <tabstop>requireAuthCheckBox</tabstop>
-  <tabstop>certEdit</tabstop>
-  <tabstop>certBrowse</tabstop>
-  <tabstop>keyEdit</tabstop>
-  <tabstop>keyBrowse</tabstop>
-  <tabstop>credsEdit</tabstop>
-  <tabstop>credsBrowse</tabstop>
-  <tabstop>authCheckBox</tabstop>
-  <tabstop>usernameEdit</tabstop>
-  <tabstop>passwordEdit</tabstop>
-  <tabstop>vsModeButton</tabstop>
-  <tabstop>aboutButton</tabstop>
-  <tabstop>clientNameEdit</tabstop>
-  <tabstop>remoteNameEdit</tabstop>
-  <tabstop>localPortSpinBox</tabstop>
-  <tabstop>remotePortSpinBox</tabstop>
-  <tabstop>basePortSpinBox</tabstop>
-  <tabstop>queueLengthSpinBox</tabstop>
-  <tabstop>redundancySpinBox</tabstop>
-  <tabstop>resolutionComboBox</tabstop>
-  <tabstop>connectAudioCheckBox</tabstop>
-  <tabstop>realTimeCheckBox</tabstop>
-  <tabstop>ioStatsCheckBox</tabstop>
-  <tabstop>ioStatsSpinBox</tabstop>
-  <tabstop>verboseCheckBox</tabstop>
-  <tabstop>commandLineButton</tabstop>
-  <tabstop>useDefaultsButton</tabstop>
-  <tabstop>backendComboBox</tabstop>
-  <tabstop>sampleRateComboBox</tabstop>
-  <tabstop>bufferSizeComboBox</tabstop>
-  <tabstop>inputDeviceComboBox</tabstop>
-  <tabstop>outputDeviceComboBox</tabstop>
-  <tabstop>refreshDevicesButton</tabstop>
-  <tabstop>jitterCheckBox</tabstop>
-  <tabstop>bufferStrategyComboBox</tabstop>
-  <tabstop>broadcastCheckBox</tabstop>
-  <tabstop>broadcastQueueSpinBox</tabstop>
-  <tabstop>autoQueueCheckBox</tabstop>
-  <tabstop>autoQueueSpinBox</tabstop>
-  <tabstop>inFreeverbCheckBox</tabstop>
-  <tabstop>inFreeverbWetnessSlider</tabstop>
-  <tabstop>inZitarevCheckBox</tabstop>
-  <tabstop>inZitarevWetnessSlider</tabstop>
-  <tabstop>inCompressorCheckBox</tabstop>
-  <tabstop>inLimiterCheckBox</tabstop>
-  <tabstop>outFreeverbCheckBox</tabstop>
-  <tabstop>outFreeverbWetnessSlider</tabstop>
-  <tabstop>outZitarevCheckBox</tabstop>
-  <tabstop>outZitarevWetnessSlider</tabstop>
-  <tabstop>outCompressorCheckBox</tabstop>
-  <tabstop>outLimiterCheckBox</tabstop>
-  <tabstop>outClientsSpinBox</tabstop>
- </tabstops>
- <resources>
-  <include location="qjacktrip.qrc"/>
- </resources>
- <connections/>
-</ui>
index b2ccf5208b17d881465092a24ce194291f94f73d..6b133ace6d5e37ec73d6a95f6e7129836af1abf4 100644 (file)
@@ -72,7 +72,8 @@ VirtualStudio::VirtualStudio(bool firstRun, QObject* parent)
     m_userId          = settings.value(QStringLiteral("UserId"), "").toString();
     m_uiScale         = settings.value(QStringLiteral("UiScale"), 1).toFloat();
     m_darkMode        = settings.value(QStringLiteral("DarkMode"), false).toBool();
-    m_showInactive    = settings.value(QStringLiteral("ShowInactive"), false).toBool();
+    m_testMode        = settings.value(QStringLiteral("TestMode"), false).toBool();
+    m_showInactive    = settings.value(QStringLiteral("ShowInactive"), true).toBool();
     m_showSelfHosted  = settings.value(QStringLiteral("ShowSelfHosted"), false).toBool();
     m_showDeviceSetup = settings.value(QStringLiteral("ShowDeviceSetup"), true).toBool();
     m_showWarnings    = settings.value(QStringLiteral("ShowWarnings"), true).toBool();
@@ -107,6 +108,10 @@ VirtualStudio::VirtualStudio(bool firstRun, QObject* parent)
     });
 
     settings.beginGroup(QStringLiteral("Audio"));
+    m_inMultiplier  = settings.value(QStringLiteral("InMultiplier"), 1).toFloat();
+    m_outMultiplier = settings.value(QStringLiteral("OutMultiplier"), 1).toFloat();
+    m_inMuted       = settings.value(QStringLiteral("InMuted"), false).toBool();
+    m_outMuted      = settings.value(QStringLiteral("OutMuted"), false).toBool();
 #ifdef RT_AUDIO
     m_useRtAudio     = settings.value(QStringLiteral("Backend"), 0).toInt() == 1;
     m_inputDevice    = settings.value(QStringLiteral("InputDevice"), "").toString();
@@ -118,6 +123,7 @@ VirtualStudio::VirtualStudio(bool firstRun, QObject* parent)
     m_previousOutput = m_outputDevice;
 #else
     m_selectableBackend = false;
+    m_vsAudioInterface.reset(new VsAudioInterface());
 
     // Set our combo box models to an empty list to avoid a reference error
     m_view.engine()->rootContext()->setContextProperty(
@@ -158,6 +164,8 @@ VirtualStudio::VirtualStudio(bool firstRun, QObject* parent)
                                                        this);
     m_view.engine()->rootContext()->setContextProperty(QStringLiteral("serverModel"),
                                                        QVariant::fromValue(m_servers));
+    m_view.engine()->rootContext()->setContextProperty(QStringLiteral("audioInterface"),
+                                                       m_vsAudioInterface.data());
 
     m_view.engine()->rootContext()->setContextProperty(
         QStringLiteral("inputMeterModel"), QVariant::fromValue(QVector<float>()));
@@ -270,7 +278,7 @@ void VirtualStudio::setAudioBackend(const QString& backend)
         return;
     }
     m_useRtAudio = (backend == QStringLiteral("RtAudio"));
-    emit audioBackendChanged();
+    emit audioBackendChanged(m_useRtAudio);
 }
 
 int VirtualStudio::inputDevice()
@@ -291,6 +299,7 @@ void VirtualStudio::setInputDevice([[maybe_unused]] int device)
     }
 #ifdef RT_AUDIO
     m_inputDevice = m_inputDeviceList.at(device);
+    emit inputDeviceSelected(m_inputDevice);
 #endif
 }
 
@@ -312,9 +321,70 @@ void VirtualStudio::setOutputDevice([[maybe_unused]] int device)
     }
 #ifdef RT_AUDIO
     m_outputDevice = m_outputDeviceList.at(device);
+    emit outputDeviceSelected(m_outputDevice);
 #endif
 }
 
+float VirtualStudio::inputVolume()
+{
+    return m_inMultiplier;
+}
+
+float VirtualStudio::outputVolume()
+{
+    return m_outMultiplier;
+}
+
+bool VirtualStudio::inputMuted()
+{
+    return m_inMuted;
+}
+
+bool VirtualStudio::outputMuted()
+{
+    return m_outMuted;
+}
+
+void VirtualStudio::setInputVolume(float multiplier)
+{
+    m_inMultiplier = multiplier;
+    QSettings settings;
+    settings.beginGroup(QStringLiteral("Audio"));
+    settings.setValue(QStringLiteral("InMultiplier"), m_inMultiplier);
+    settings.endGroup();
+    emit updatedInputVolume(multiplier);
+}
+
+void VirtualStudio::setOutputVolume(float multiplier)
+{
+    m_outMultiplier = multiplier;
+    QSettings settings;
+    settings.beginGroup(QStringLiteral("Audio"));
+    settings.setValue(QStringLiteral("OutMultiplier"), m_outMultiplier);
+    settings.endGroup();
+    emit updatedOutputVolume(multiplier);
+}
+
+void VirtualStudio::setInputMuted(bool muted)
+{
+    m_inMuted = muted;
+    QSettings settings;
+    settings.beginGroup(QStringLiteral("Audio"));
+    settings.setValue(QStringLiteral("InMuted"), m_inMuted ? 1 : 0);
+    settings.endGroup();
+    emit updatedInputMuted(muted);
+}
+
+void VirtualStudio::setOutputMuted(bool muted)
+{
+    m_outMuted = muted;
+    QSettings settings;
+    settings.beginGroup(QStringLiteral("Audio"));
+    settings.setValue(QStringLiteral("OutMuted"), m_outMuted ? 1 : 0);
+    settings.endGroup();
+    emit updatedOutputMuted(muted);
+}
+
 int VirtualStudio::bufferSize()
 {
 #ifdef RT_AUDIO
@@ -497,6 +567,27 @@ void VirtualStudio::setDarkMode(bool dark)
     emit darkModeChanged();
 }
 
+bool VirtualStudio::testMode()
+{
+    return m_testMode;
+}
+
+void VirtualStudio::setTestMode(bool test)
+{
+    QString userEmail = m_userMetadata[QStringLiteral("email")].toString();
+    if (m_userMetadata.isEmpty() || userEmail == ""
+        || !userEmail.endsWith("@jacktrip.org")) {
+        qDebug() << "Not allowed";
+        return;
+    }
+    m_testMode = test;
+    QSettings settings;
+    settings.beginGroup(QStringLiteral("VirtualStudio"));
+    settings.setValue(QStringLiteral("TestMode"), m_testMode);
+    settings.endGroup();
+    emit testModeChanged();
+}
+
 QUrl VirtualStudio::studioToJoin()
 {
     return m_studioToJoin;
@@ -615,11 +706,10 @@ void VirtualStudio::toVirtualStudio()
                 QByteArray code = parameters->value(QStringLiteral("code")).toByteArray();
                 (*parameters)[QStringLiteral("code")] = QUrl::fromPercentEncoding(code);
             } else if (stage == QAbstractOAuth2::Stage::RequestingAuthorization) {
-                parameters->insert(QStringLiteral("audience"),
-                                   QStringLiteral("https://api.jacktrip.org"));
+                parameters->insert(QStringLiteral("audience"), AUTH_AUDIENCE);
             }
             if (!parameters->contains("client_id")) {
-                parameters->insert("client_id", "cROUJag0UVKDaJ6jRAKRzlVjKVFNU39I");
+                parameters->insert("client_id", AUTH_CLIENT_ID);
             }
         });
 
@@ -647,12 +737,17 @@ void VirtualStudio::logout()
     settings.beginGroup(QStringLiteral("VirtualStudio"));
     settings.remove(QStringLiteral("RefreshToken"));
     settings.remove(QStringLiteral("UserId"));
+    settings.remove(QStringLiteral("ShowInactive"));
+    settings.remove(QStringLiteral("ShowSelfHosted"));
+    settings.remove(QStringLiteral("ShowDeviceSetup"));
+    settings.remove(QStringLiteral("ShowWarnings"));
     settings.endGroup();
 
     m_refreshTimer.stop();
     m_heartbeatTimer.stop();
 
     m_refreshToken.clear();
+    m_userMetadata = QJsonObject();
     m_userId.clear();
     emit hasRefreshTokenChanged();
 }
@@ -680,11 +775,16 @@ void VirtualStudio::refreshDevices()
         m_outputDevice = QStringLiteral("(default)");
     }
 
-    emit inputDeviceChanged();
-    emit outputDeviceChanged();
+    emit inputDeviceChanged(m_inputDevice);
+    emit outputDeviceChanged(m_outputDevice);
 #endif
 }
 
+void VirtualStudio::playOutputAudio()
+{
+    emit triggerPlayOutputAudio();
+}
+
 void VirtualStudio::revertSettings()
 {
     m_uiScale = m_previousUiScale;
@@ -695,10 +795,10 @@ void VirtualStudio::revertSettings()
     m_outputDevice = m_previousOutput;
     m_bufferSize   = m_previousBuffer;
     m_useRtAudio   = m_previousUseRtAudio;
-    emit inputDeviceChanged();
-    emit outputDeviceChanged();
+    emit inputDeviceChanged(m_inputDevice);
+    emit outputDeviceChanged(m_outputDevice);
     emit bufferSizeChanged();
-    emit audioBackendChanged();
+    emit audioBackendChanged(m_useRtAudio);
 #endif
 }
 
@@ -724,8 +824,8 @@ void VirtualStudio::applySettings()
     m_previousInput      = m_inputDevice;
     m_previousOutput     = m_outputDevice;
 
-    emit inputDeviceChanged();
-    emit outputDeviceChanged();
+    emit inputDeviceChanged(m_inputDevice);
+    emit outputDeviceChanged(m_outputDevice);
 #endif
 
     // attempt to join studio if requested
@@ -769,10 +869,10 @@ void VirtualStudio::connectToStudio(int studioIndex)
                                 {QLatin1String("expiresAt"), expiration}};
             QJsonDocument request = QJsonDocument(json);
 
-            QNetworkReply* reply = m_authenticator->put(
-                QStringLiteral("https://app.jacktrip.org/api/servers/%1")
-                    .arg(studioInfo->id()),
-                request.toJson());
+            QNetworkReply* reply =
+                m_authenticator->put(QStringLiteral("https://%1/api/servers/%2")
+                                         .arg(m_apiHost, studioInfo->id()),
+                                     request.toJson());
             connect(reply, &QNetworkReply::finished, this, [&, reply]() {
                 if (reply->error() != QNetworkReply::NoError) {
                     m_connectionState = QStringLiteral("Unable to Start Studio");
@@ -838,16 +938,51 @@ void VirtualStudio::completeConnection()
                          &VirtualStudio::receivedConnectionFromPeer,
                          Qt::QueuedConnection);
 
+        // Stop VsAudioInterface
+        if (!m_vsAudioInterface.isNull()) {
+            m_vsAudioInterface->closeAudio();
+        }
+
+        // Setup output volume
+        m_outputVolumePlugin = new Volume(jackTrip->getNumOutputChannels());
+        jackTrip->appendProcessPluginFromNetwork(m_outputVolumePlugin);
+        connect(this, &VirtualStudio::updatedOutputVolume, m_outputVolumePlugin,
+                &Volume::volumeUpdated);
+        connect(this, &VirtualStudio::updatedOutputMuted, m_outputVolumePlugin,
+                &Volume::muteUpdated);
+
+        // Setup input volume
+        m_inputVolumePlugin = new Volume(jackTrip->getNumInputChannels());
+        jackTrip->appendProcessPluginToNetwork(m_inputVolumePlugin);
+        connect(this, &VirtualStudio::updatedInputVolume, m_inputVolumePlugin,
+                &Volume::volumeUpdated);
+        connect(this, &VirtualStudio::updatedInputMuted, m_inputVolumePlugin,
+                &Volume::muteUpdated);
+
+        // Setup output meter
         Meter* m_outputMeter = new Meter(jackTrip->getNumOutputChannels());
         jackTrip->appendProcessPluginFromNetwork(m_outputMeter);
         connect(m_outputMeter, &Meter::onComputedVolumeMeasurements, this,
                 &VirtualStudio::updatedOutputVuMeasurements);
 
+        // Setup input meter
         Meter* m_inputMeter = new Meter(jackTrip->getNumInputChannels());
         jackTrip->appendProcessPluginToNetwork(m_inputMeter);
         connect(m_inputMeter, &Meter::onComputedVolumeMeasurements, this,
                 &VirtualStudio::updatedInputVuMeasurements);
 
+        // Grab previous levels
+        QSettings settings;
+        settings.beginGroup(QStringLiteral("Audio"));
+        m_inMultiplier  = settings.value(QStringLiteral("InMultiplier"), 1).toFloat();
+        m_outMultiplier = settings.value(QStringLiteral("OutMultiplier"), 1).toFloat();
+        m_inMuted       = settings.value(QStringLiteral("InMuted"), false).toBool();
+        m_outMuted      = settings.value(QStringLiteral("OutMuted"), false).toBool();
+        emit updatedInputVolume(m_inMultiplier);
+        emit updatedOutputVolume(m_outMultiplier);
+        emit updatedInputMuted(m_inMuted);
+        emit updatedOutputMuted(m_outMuted);
+
         m_connectionState = QStringLiteral("Connecting...");
         emit connectionStateChanged();
 #ifdef RT_AUDIO
@@ -931,6 +1066,19 @@ void VirtualStudio::disconnect()
         m_allowRefresh = true;
         m_refreshTimer.start();
     }
+
+    // Start VsAudioInterface again
+    if (!m_vsAudioInterface.isNull()) {
+        m_vsAudioInterface->setupAudio();
+        m_vsAudioInterface->setupPlugins();
+
+        m_view.engine()->rootContext()->setContextProperty(
+            QStringLiteral("inputMeterModel"),
+            QVariant::fromValue(
+                QVector<float>(m_vsAudioInterface->getNumInputChannels())));
+
+        m_vsAudioInterface->startProcess();
+    }
 }
 
 void VirtualStudio::manageStudio(int studioIndex)
@@ -939,21 +1087,21 @@ void VirtualStudio::manageStudio(int studioIndex)
         // We're here from a connected screen. Use our current studio.
         studioIndex = m_currentStudio;
     }
-    QUrl url =
-        QUrl(QStringLiteral("https://app.jacktrip.org/studios/%1")
-                 .arg(static_cast<VsServerInfo*>(m_servers.at(studioIndex))->id()));
+    QUrl url = QUrl(
+        QStringLiteral("https://%1/studios/%2")
+            .arg(m_apiHost, static_cast<VsServerInfo*>(m_servers.at(studioIndex))->id()));
     QDesktopServices::openUrl(url);
 }
 
 void VirtualStudio::createStudio()
 {
-    QUrl url = QUrl(QStringLiteral("https://app.jacktrip.org/studios/create"));
+    QUrl url = QUrl(QStringLiteral("https://%1/studios/create").arg(m_apiHost));
     QDesktopServices::openUrl(url);
 }
 
 void VirtualStudio::editProfile()
 {
-    QUrl url = QUrl(QStringLiteral("https://app.jacktrip.org/profile"));
+    QUrl url = QUrl(QStringLiteral("https://%1/profile").arg(m_apiHost));
     QDesktopServices::openUrl(url);
 }
 
@@ -983,6 +1131,12 @@ void VirtualStudio::exit()
 
 void VirtualStudio::slotAuthSucceded()
 {
+    // Determine which API host to use
+    m_apiHost = PROD_API_HOST;
+    if (m_testMode) {
+        m_apiHost = TEST_API_HOST;
+    }
+
     m_authenticated = true;
     m_refreshToken  = m_authenticator->refreshToken();
     emit hasRefreshTokenChanged();
@@ -992,9 +1146,46 @@ void VirtualStudio::slotAuthSucceded()
     settings.setValue(QStringLiteral("RefreshToken"), m_refreshToken);
     settings.endGroup();
 
-    m_device = new VsDevice(m_authenticator.data());
+    m_device = new VsDevice(m_authenticator.data(), m_testMode);
     m_device->registerApp();
 
+    if (m_vsAudioInterface.isNull()) {
+        m_vsAudioInterface.reset(new VsAudioInterface());
+        m_view.engine()->rootContext()->setContextProperty(
+            QStringLiteral("audioInterface"), m_vsAudioInterface.data());
+    }
+#ifdef RT_AUDIO
+    m_vsAudioInterface->setInputDevice(m_inputDevice);
+    m_vsAudioInterface->setOutputDevice(m_outputDevice);
+    m_vsAudioInterface->setAudioInterfaceMode(m_useRtAudio);
+#endif
+    m_vsAudioInterface->setupAudio();
+
+    connect(this, &VirtualStudio::inputDeviceChanged, m_vsAudioInterface.data(),
+            &VsAudioInterface::setInputDevice);
+    connect(this, &VirtualStudio::inputDeviceSelected, m_vsAudioInterface.data(),
+            &VsAudioInterface::setInputDevice);
+    connect(this, &VirtualStudio::outputDeviceChanged, m_vsAudioInterface.data(),
+            &VsAudioInterface::setOutputDevice);
+    connect(this, &VirtualStudio::outputDeviceSelected, m_vsAudioInterface.data(),
+            &VsAudioInterface::setOutputDevice);
+    connect(this, &VirtualStudio::audioBackendChanged, m_vsAudioInterface.data(),
+            &VsAudioInterface::setAudioInterfaceMode);
+    connect(this, &VirtualStudio::triggerPlayOutputAudio, m_vsAudioInterface.data(),
+            &VsAudioInterface::triggerPlayback);
+    connect(m_vsAudioInterface.data(), &VsAudioInterface::newVolumeMeterMeasurements,
+            this, &VirtualStudio::updatedInputVuMeasurements);
+    connect(m_vsAudioInterface.data(), &VsAudioInterface::errorToProcess, this,
+            &VirtualStudio::processError);
+
+    m_vsAudioInterface->setupPlugins();
+
+    m_view.engine()->rootContext()->setContextProperty(
+        QStringLiteral("inputMeterModel"),
+        QVariant::fromValue(QVector<float>(m_vsAudioInterface->getNumInputChannels())));
+
+    m_vsAudioInterface->startProcess();
+
     if (m_userId.isEmpty()) {
         getUserId();
     } else {
@@ -1004,7 +1195,7 @@ void VirtualStudio::slotAuthSucceded()
     if (m_regions.isEmpty()) {
         getRegions();
     }
-    if (m_userMetadata.isEmpty()) {
+    if (m_userMetadata.isEmpty() && !m_userId.isEmpty()) {
         getUserMetadata();
     }
 
@@ -1018,6 +1209,12 @@ void VirtualStudio::slotAuthSucceded()
         }
     }
     connect(m_device, &VsDevice::updateNetworkStats, this, &VirtualStudio::updatedStats);
+    connect(m_device, &VsDevice::updatedVolumeFromServer, this,
+            &VirtualStudio::setInputVolume);
+    connect(m_device, &VsDevice::updatedMuteFromServer, this,
+            &VirtualStudio::setInputMuted);
+    connect(this, &VirtualStudio::updatedInputVolume, m_device, &VsDevice::updateVolume);
+    connect(this, &VirtualStudio::updatedInputMuted, m_device, &VsDevice::updateMute);
 }
 
 void VirtualStudio::slotAuthFailed()
@@ -1058,19 +1255,30 @@ void VirtualStudio::processFinished()
 
 void VirtualStudio::processError(const QString& errorMessage)
 {
+    bool shouldSwitchToRtAudio = false;
     if (!m_retryPeriod) {
         QMessageBox msgBox;
         if (errorMessage == QLatin1String("Peer Stopped")) {
             // Report the other end quitting as a regular occurance rather than an error.
             msgBox.setText("The Studio has been stopped.");
             msgBox.setWindowTitle(QStringLiteral("Disconnected"));
+        } else if (errorMessage
+                   == QLatin1String("Maybe the JACK server is not running?")) {
+            // Report the other end quitting as a regular occurance rather than an error.
+            msgBox.setText("The JACK server is not running. Switching back to RtAudio.");
+            msgBox.setWindowTitle(QStringLiteral("No JACK server"));
+            shouldSwitchToRtAudio = true;
         } else {
             msgBox.setText(QStringLiteral("Error: ").append(errorMessage));
             msgBox.setWindowTitle(QStringLiteral("Doh!"));
         }
         msgBox.exec();
     }
-    processFinished();
+    if (shouldSwitchToRtAudio) {
+        setAudioBackend("RtAudio");
+    } else {
+        processFinished();
+    }
 }
 
 void VirtualStudio::receivedConnectionFromPeer()
@@ -1093,7 +1301,7 @@ void VirtualStudio::checkForHostname()
 
     VsServerInfo* studioInfo = static_cast<VsServerInfo*>(m_servers.at(m_currentStudio));
     QNetworkReply* reply     = m_authenticator->get(
-            QStringLiteral("https://app.jacktrip.org/api/servers/%1").arg(studioInfo->id()));
+            QStringLiteral("https://%1/api/servers/%2").arg(m_apiHost, studioInfo->id()));
     connect(reply, &QNetworkReply::finished, this, [&, reply, studioInfo]() {
         if (reply->error() != QNetworkReply::NoError) {
             m_connectionState = QStringLiteral("Unable to Start Studio");
@@ -1153,7 +1361,7 @@ void VirtualStudio::updatedStats(const QJsonObject& stats)
     return;
 }
 
-void VirtualStudio::updatedInputVuMeasurements(const QVector<float> valuesInDecibels)
+void VirtualStudio::updatedInputVuMeasurements(const QVector<float>& valuesInDecibels)
 {
     QJsonArray uiValues;
     bool detectedClip = false;
@@ -1185,7 +1393,7 @@ void VirtualStudio::updatedInputVuMeasurements(const QVector<float> valuesInDeci
                                                        QVariant::fromValue(uiValues));
 }
 
-void VirtualStudio::updatedOutputVuMeasurements(const QVector<float> valuesInDecibels)
+void VirtualStudio::updatedOutputVuMeasurements(const QVector<float>& valuesInDecibels)
 {
     QJsonArray uiValues;
     bool detectedClip = false;
@@ -1228,14 +1436,11 @@ void VirtualStudio::setupAuthenticator()
                 &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, this,
                 &VirtualStudio::launchBrowser);
 
-        const QUrl authUri(QStringLiteral("https://auth.jacktrip.org/authorize"));
-        const QString clientId = QStringLiteral("cROUJag0UVKDaJ6jRAKRzlVjKVFNU39I");
-        const QUrl tokenUri(QStringLiteral("https://auth.jacktrip.org/oauth/token"));
         const quint16 port = 52424;
 
-        m_authenticator->setAuthorizationUrl(authUri);
-        m_authenticator->setClientIdentifier(clientId);
-        m_authenticator->setAccessTokenUrl(tokenUri);
+        m_authenticator->setAuthorizationUrl(AUTH_AUTHORIZE_URI);
+        m_authenticator->setClientIdentifier(AUTH_CLIENT_ID);
+        m_authenticator->setAccessTokenUrl(AUTH_TOKEN_URI);
 
         m_authenticator->setModifyParametersFunction([](QAbstractOAuth2::Stage stage,
                                                         QVariantMap* parameters) {
@@ -1294,7 +1499,7 @@ void VirtualStudio::getServerList(bool firstLoad, bool signalRefresh, int index)
     }
 
     QNetworkReply* reply =
-        m_authenticator->get(QStringLiteral("https://app.jacktrip.org/api/servers"));
+        m_authenticator->get(QStringLiteral("https://%1/api/servers").arg(m_apiHost));
     connect(
         reply, &QNetworkReply::finished, this,
         [&, reply, topServerId, firstLoad, signalRefresh]() {
@@ -1484,6 +1689,11 @@ void VirtualStudio::getUserId()
         settings.setValue(QStringLiteral("UserId"), m_userId);
         settings.endGroup();
         getSubscriptions();
+
+        if (m_userMetadata.isEmpty() && !m_userId.isEmpty()) {
+            getUserMetadata();
+        }
+
         reply->deleteLater();
     });
 }
@@ -1491,8 +1701,7 @@ void VirtualStudio::getUserId()
 void VirtualStudio::getSubscriptions()
 {
     QNetworkReply* reply = m_authenticator->get(
-        QStringLiteral("https://app.jacktrip.org/api/users/%1/subscriptions")
-            .arg(m_userId));
+        QStringLiteral("https://%1/api/users/%2/subscriptions").arg(m_apiHost, m_userId));
     connect(reply, &QNetworkReply::finished, this, [&, reply]() {
         if (reply->error() != QNetworkReply::NoError) {
             std::cout << "Error: " << reply->errorString().toStdString() << std::endl;
@@ -1522,7 +1731,7 @@ void VirtualStudio::getSubscriptions()
 void VirtualStudio::getRegions()
 {
     QNetworkReply* reply = m_authenticator->get(
-        QStringLiteral("https://app.jacktrip.org/api/users/%1/regions").arg(m_userId));
+        QStringLiteral("https://%1/api/users/%2/regions").arg(m_apiHost, m_userId));
     connect(reply, &QNetworkReply::finished, this, [&, reply]() {
         if (reply->error() != QNetworkReply::NoError) {
             std::cout << "Error: " << reply->errorString().toStdString() << std::endl;
@@ -1540,7 +1749,7 @@ void VirtualStudio::getRegions()
 void VirtualStudio::getUserMetadata()
 {
     QNetworkReply* reply = m_authenticator->get(
-        QStringLiteral("https://app.jacktrip.org/api/users/%1").arg(m_userId));
+        QStringLiteral("https://%1/api/users/%2").arg(m_apiHost, m_userId));
     connect(reply, &QNetworkReply::finished, this, [&, reply]() {
         if (reply->error() != QNetworkReply::NoError) {
             std::cout << "Error: " << reply->errorString().toStdString() << std::endl;
@@ -1588,7 +1797,7 @@ void VirtualStudio::stopStudio()
     QJsonDocument request    = QJsonDocument(json);
     studioInfo->setHost(QLatin1String(""));
     QNetworkReply* reply = m_authenticator->put(
-        QStringLiteral("https://app.jacktrip.org/api/servers/%1").arg(studioInfo->id()),
+        QStringLiteral("https://%1/api/servers/%2").arg(m_apiHost, studioInfo->id()),
         request.toJson());
     connect(reply, &QNetworkReply::finished, this, [=]() {
         if (m_isExiting && !m_jackTripRunning) {
@@ -1606,6 +1815,7 @@ VirtualStudio::~VirtualStudio()
 
     delete m_inputMeter;
     delete m_outputMeter;
+    delete m_inputTestMeter;
 
     QDesktopServices::unsetUrlHandler("jacktrip");
 }
index 428ffa9fe5a88755a149d38908e4df8bc3fbc7e5..693b9110c593d2793d626446eb2792644e45530f 100644 (file)
@@ -49,6 +49,9 @@
 
 #include "../JackTrip.h"
 #include "../Meter.h"
+#include "../Volume.h"
+#include "vsAudioInterface.h"
+#include "vsConstants.h"
 #include "vsDevice.h"
 #include "vsQuickView.h"
 #include "vsServerInfo.h"
@@ -96,6 +99,7 @@ class VirtualStudio : public QObject
     Q_PROPERTY(float fontScale READ fontScale CONSTANT)
     Q_PROPERTY(float uiScale READ uiScale WRITE setUiScale NOTIFY uiScaleChanged)
     Q_PROPERTY(bool darkMode READ darkMode WRITE setDarkMode NOTIFY darkModeChanged)
+    Q_PROPERTY(bool testMode READ testMode WRITE setTestMode NOTIFY testModeChanged)
     Q_PROPERTY(bool showDeviceSetup READ showDeviceSetup WRITE setShowDeviceSetup NOTIFY
                    showDeviceSetupChanged)
     Q_PROPERTY(bool showWarnings READ showWarnings WRITE setShowWarnings NOTIFY
@@ -105,6 +109,12 @@ class VirtualStudio : public QObject
     Q_PROPERTY(QString failedMessage READ failedMessage NOTIFY failedMessageChanged)
     Q_PROPERTY(
         bool shouldJoin READ shouldJoin WRITE setShouldJoin NOTIFY shouldJoinChanged)
+    Q_PROPERTY(
+        float inputVolume READ inputVolume WRITE setInputVolume NOTIFY updatedInputVolume)
+    Q_PROPERTY(float outputVolume READ outputVolume WRITE setOutputVolume NOTIFY
+                   updatedOutputVolume)
+    Q_PROPERTY(
+        bool inputMuted READ inputMuted WRITE setInputMuted NOTIFY updatedInputMuted)
 
    public:
     explicit VirtualStudio(bool firstRun = false, QObject* parent = nullptr);
@@ -149,6 +159,8 @@ class VirtualStudio : public QObject
     void setUiScale(float scale);
     bool darkMode();
     void setDarkMode(bool dark);
+    bool testMode();
+    void setTestMode(bool test);
     QUrl studioToJoin();
     void setStudioToJoin(const QUrl& url);
     bool showDeviceSetup();
@@ -160,6 +172,10 @@ class VirtualStudio : public QObject
     QString failedMessage();
     bool shouldJoin();
     void setShouldJoin(bool join);
+    float inputVolume();
+    float outputVolume();
+    bool inputMuted();
+    bool outputMuted();
 
    public slots:
     void toStandard();
@@ -168,6 +184,7 @@ class VirtualStudio : public QObject
     void logout();
     void refreshStudios(int index, bool signalRefresh = false);
     void refreshDevices();
+    void playOutputAudio();
     void revertSettings();
     void applySettings();
     void connectToStudio(int studioIndex);
@@ -177,6 +194,12 @@ class VirtualStudio : public QObject
     void createStudio();
     void editProfile();
     void showAbout();
+    void updatedInputVuMeasurements(const QVector<float>& valuesInDecibels);
+    void updatedOutputVuMeasurements(const QVector<float>& valuesInDecibels);
+    void setInputVolume(float multiplier);
+    void setOutputVolume(float multiplier);
+    void setInputMuted(bool muted);
+    void setOutputMuted(bool muted);
     void exit();
 
    signals:
@@ -189,9 +212,12 @@ class VirtualStudio : public QObject
     void showFirstRunChanged();
     void hasRefreshTokenChanged();
     void logoSectionChanged();
-    void audioBackendChanged();
-    void inputDeviceChanged();
-    void outputDeviceChanged();
+    void audioBackendChanged(bool useRtAudio);
+    void inputDeviceChanged(QString device);
+    void outputDeviceChanged(QString device);
+    void inputDeviceSelected(QString device);
+    void outputDeviceSelected(QString device);
+    void triggerPlayOutputAudio();
     void bufferSizeChanged();
     void bufferStrategyChanged();
     void currentStudioChanged();
@@ -208,10 +234,15 @@ class VirtualStudio : public QObject
     void uiScaleChanged();
     void newScale();
     void darkModeChanged();
+    void testModeChanged();
     void signalExit();
     void periodicRefresh();
     void failedMessageChanged();
     void shouldJoinChanged();
+    void updatedInputVolume(float multiplier);
+    void updatedOutputVolume(float multiplier);
+    void updatedInputMuted(bool muted);
+    void updatedOutputMuted(bool muted);
 
    private slots:
     void slotAuthSucceded();
@@ -224,8 +255,6 @@ class VirtualStudio : public QObject
     void launchBrowser(const QUrl& url);
     void joinStudio();
     void updatedStats(const QJsonObject& stats);
-    void updatedInputVuMeasurements(const QVector<float> valuesInDecibels);
-    void updatedOutputVuMeasurements(const QVector<float> valuesInDecibels);
 
    private:
     void setupAuthenticator();
@@ -281,7 +310,7 @@ class VirtualStudio : public QObject
 
     bool m_onConnectedScreen = false;
     bool m_isExiting         = false;
-    bool m_showInactive      = false;
+    bool m_showInactive      = true;
     bool m_showSelfHosted    = false;
     bool m_showCreateStudio  = false;
     bool m_showDeviceSetup   = true;
@@ -290,19 +319,31 @@ class VirtualStudio : public QObject
     float m_uiScale;
     float m_previousUiScale;
     int m_bufferStrategy    = 0;
+    QString m_apiHost       = PROD_API_HOST;
     bool m_darkMode         = false;
+    bool m_testMode         = false;
     QString m_failedMessage = "";
     QUrl m_studioToJoin;
     bool m_authenticated = false;
 
     Meter* m_inputMeter;
     Meter* m_outputMeter;
+    Meter* m_inputTestMeter;
+    Volume* m_inputVolumePlugin;
+    Volume* m_outputVolumePlugin;
     QTimer m_inputClipTimer;
     QTimer m_outputClipTimer;
 
     float m_meterMax = 0.0;
     float m_meterMin = -64.0;
 
+    float m_inMultiplier  = 1.0;
+    float m_outMultiplier = 1.0;
+    bool m_inMuted        = false;
+    bool m_outMuted       = false;
+
+    QSharedPointer<VsAudioInterface> m_vsAudioInterface;
+
 #ifdef RT_AUDIO
     QStringList m_inputDeviceList;
     QStringList m_outputDeviceList;
diff --git a/src/gui/vsAudioInterface.cpp b/src/gui/vsAudioInterface.cpp
new file mode 100644 (file)
index 0000000..b21df2d
--- /dev/null
@@ -0,0 +1,383 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2008-2022 Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  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.
+*/
+//*****************************************************************
+
+/**
+ * \file vsAudioInterface.cpp
+ * \author Matt Horton
+ * \date September 2022
+ */
+
+#include "vsAudioInterface.h"
+
+#include <QDebug>
+#include <QMessageBox>
+#include <QSettings>
+
+#include "../Meter.h"
+#include "../Tone.h"
+
+// Constructor
+VsAudioInterface::VsAudioInterface(int NumChansIn, int NumChansOut,
+                                   AudioInterface::audioBitResolutionT AudioBitResolution,
+                                   QObject* parent)
+    : QObject(parent)
+    , m_numAudioChansIn(NumChansIn)
+    , m_numAudioChansOut(NumChansOut)
+    , m_audioBitResolution(AudioBitResolution)
+    , m_sampleRate(gDefaultSampleRate)
+    , m_deviceID(gDefaultDeviceID)
+    , m_inputDeviceName("")
+    , m_outputDeviceName("")
+    , m_audioBufferSize(gDefaultBufferSizeInSamples)
+    , m_audioInterfaceMode(VsAudioInterface::RTAUDIO)
+{
+    QSettings settings;
+    settings.beginGroup(QStringLiteral("Audio"));
+    m_inMultiplier       = settings.value(QStringLiteral("InMultiplier"), 1).toFloat();
+    m_outMultiplier      = settings.value(QStringLiteral("OutMultiplier"), 1).toFloat();
+    m_inMuted            = settings.value(QStringLiteral("InMuted"), false).toBool();
+    m_outMuted           = settings.value(QStringLiteral("OutMuted"), false).toBool();
+    m_audioInterfaceMode = (settings.value(QStringLiteral("Backend"), 0).toInt() == 1)
+                               ? VsAudioInterface::RTAUDIO
+                               : VsAudioInterface::JACK;
+    m_inputDeviceName =
+        settings.value(QStringLiteral("InputDevice"), "").toString().toStdString();
+    m_outputDeviceName =
+        settings.value(QStringLiteral("OutputDevice"), "").toString().toStdString();
+    settings.endGroup();
+
+    connect(this, &VsAudioInterface::settingsUpdated, this,
+            &VsAudioInterface::replaceProcess);
+    connect(this, &VsAudioInterface::modeUpdated, this,
+            &VsAudioInterface::replaceProcess);
+}
+
+VsAudioInterface::~VsAudioInterface()
+{
+    closeAudio();
+}
+
+void VsAudioInterface::setupAudio()
+{
+    try {
+        // Check if m_audioInterface has already been created or not
+        if (!m_audioInterface.isNull()) {  // if it has been created, disconnect it from
+                                           // JACK and delete it
+            std::cout << "WARNING: JackAudio interface was setup already:" << std::endl;
+            std::cout << "It will be erased and setup again." << std::endl;
+            std::cout << gPrintSeparator << std::endl;
+            closeAudio();
+        }
+
+        // Create AudioInterface Client Object
+        if (m_audioInterfaceMode == VsAudioInterface::JACK) {
+#ifndef NO_JACK
+            if (gVerboseFlag)
+                std::cout << "  JackTrip:setupAudio before new JackAudioInterface"
+                          << std::endl;
+            m_audioInterface.reset(new JackAudioInterface(
+                m_numAudioChansIn, m_numAudioChansOut, m_audioBitResolution));
+
+            m_audioInterface->setClientName(QStringLiteral("JackTrip"));
+
+            if (gVerboseFlag)
+                std::cout << "  JackTrip:setupAudio before m_audioInterface->setup"
+                          << std::endl;
+            m_audioInterface->setup();
+            if (gVerboseFlag)
+                std::cout
+                    << "  JackTrip:setupAudio before m_audioInterface->getSampleRate"
+                    << std::endl;
+            m_sampleRate = m_audioInterface->getSampleRate();
+            if (gVerboseFlag)
+                std::cout << "  JackTrip:setupAudio before m_audioInterface->getDeviceID"
+                          << std::endl;
+            m_deviceID = m_audioInterface->getDeviceID();
+            if (gVerboseFlag)
+                std::cout << "  JackTrip:setupAudio before "
+                             "m_audioInterface->getBufferSizeInSamples"
+                          << std::endl;
+            m_audioBufferSize = m_audioInterface->getBufferSizeInSamples();
+#endif          //__NON_JACK__
+#ifdef NO_JACK  /// \todo FIX THIS REPETITION OF CODE
+#ifdef RT_AUDIO
+            std::cout << "Warning: using non jack version, RtAudio will be used instead"
+                      << std::endl;
+            m_audioInterface.reset(new RtAudioInterface(
+                m_numAudioChansIn, m_numAudioChansOut, m_audioBitResolution));
+            m_audioInterface->setSampleRate(m_sampleRate);
+            m_audioInterface->setDeviceID(m_deviceID);
+            m_audioInterface->setInputDevice(m_inputDeviceName);
+            m_audioInterface->setOutputDevice(m_outputDeviceName);
+            m_audioInterface->setBufferSizeInSamples(m_audioBufferSize);
+            m_audioInterface->setup();
+            // Setup might have reduced number of channels
+            m_numAudioChansIn  = m_audioInterface->getNumInputChannels();
+            m_numAudioChansOut = m_audioInterface->getNumOutputChannels();
+            // Setup might have changed buffer size
+            m_audioBufferSize = m_audioInterface->getBufferSizeInSamples();
+#endif
+#endif
+        } else if (m_audioInterfaceMode == VsAudioInterface::RTAUDIO) {
+#ifdef RT_AUDIO
+            m_audioInterface.reset(new RtAudioInterface(
+                m_numAudioChansIn, m_numAudioChansOut, m_audioBitResolution));
+            m_audioInterface->setSampleRate(m_sampleRate);
+            m_audioInterface->setDeviceID(m_deviceID);
+            m_audioInterface->setInputDevice(m_inputDeviceName);
+            m_audioInterface->setOutputDevice(m_outputDeviceName);
+            m_audioInterface->setBufferSizeInSamples(m_audioBufferSize);
+            m_audioInterface->setup();
+            // Setup might have reduced number of channels
+            m_numAudioChansIn  = m_audioInterface->getNumInputChannels();
+            m_numAudioChansOut = m_audioInterface->getNumOutputChannels();
+            // Setup might have changed buffer size
+            m_audioBufferSize = m_audioInterface->getBufferSizeInSamples();
+#endif
+        }
+
+        std::cout << "The Sampling Rate is: " << m_sampleRate << std::endl;
+        std::cout << gPrintSeparator << std::endl;
+        int AudioBufferSizeInBytes = m_audioBufferSize * sizeof(sample_t);
+        std::cout << "The Audio Buffer Size is: " << m_audioBufferSize << " samples"
+                  << std::endl;
+        std::cout << "                      or: " << AudioBufferSizeInBytes << " bytes"
+                  << std::endl;
+        std::cout << gPrintSeparator << std::endl;
+        std::cout << "The Number of Channels is: "
+                  << m_audioInterface->getNumInputChannels() << std::endl;
+        std::cout << gPrintSeparator << std::endl;
+        QThread::usleep(100);
+    } catch (const std::exception& e) {
+        emit errorToProcess(QString::fromUtf8(e.what()));
+    }
+}
+
+void VsAudioInterface::closeAudio()
+{
+    if (!m_audioInterface.isNull()) {
+        try {
+            if (m_audioActive) {
+                m_audioInterface->stopProcess();
+                m_audioActive = false;
+            }
+        } catch (const std::exception& e) {
+            emit errorToProcess(QString::fromUtf8(e.what()));
+        }
+        m_audioInterface.clear();
+        m_numAudioChansIn  = gDefaultNumInChannels;
+        m_numAudioChansOut = gDefaultNumOutChannels;
+        m_deviceID         = gDefaultDeviceID;
+    }
+}
+
+void VsAudioInterface::replaceProcess()
+{
+    if (m_hasBeenActive) {
+        closeAudio();
+        setupAudio();
+        setupPlugins();
+        startProcess();
+    }
+}
+
+void VsAudioInterface::processMeterMeasurements(QVector<float> values)
+{
+    emit newVolumeMeterMeasurements(values);
+}
+
+void VsAudioInterface::addInputPlugin(ProcessPlugin* plugin)
+{
+    m_audioInterface->appendProcessPluginToNetwork(plugin);
+}
+
+void VsAudioInterface::addOutputPlugin(ProcessPlugin* plugin)
+{
+    m_audioInterface->appendProcessPluginFromNetwork(plugin);
+}
+
+void VsAudioInterface::setInputDevice(QString deviceName)
+{
+    m_inputDeviceName = deviceName.toStdString();
+    if (m_inputDeviceName == "(default)") {
+        m_inputDeviceName = "";
+    }
+
+    if (!m_audioInterface.isNull()) {
+        m_audioInterface->setInputDevice(m_inputDeviceName);
+        if (m_audioActive) {
+            emit settingsUpdated();
+        }
+    }
+}
+
+void VsAudioInterface::setOutputDevice(QString deviceName)
+{
+    m_outputDeviceName = deviceName.toStdString();
+    if (m_outputDeviceName == "(default)") {
+        m_outputDeviceName = "";
+    }
+
+    if (!m_audioInterface.isNull()) {
+        m_audioInterface->setOutputDevice(m_outputDeviceName);
+        if (m_audioActive) {
+            emit settingsUpdated();
+        }
+    }
+}
+
+void VsAudioInterface::setAudioInterfaceMode(bool useRtAudio)
+{
+    if (useRtAudio) {
+        m_audioInterfaceMode = VsAudioInterface::RTAUDIO;
+    } else {
+        m_audioInterfaceMode = VsAudioInterface::JACK;
+    }
+    if (!m_audioInterface.isNull() || m_hasBeenActive) {
+        emit modeUpdated();
+    }
+}
+
+int VsAudioInterface::getNumInputChannels()
+{
+    return m_audioInterface->getNumInputChannels();
+}
+
+int VsAudioInterface::getNumOutputChannels()
+{
+    return m_audioInterface->getNumOutputChannels();
+}
+
+void VsAudioInterface::setupPlugins()
+{
+    // Create plugins
+    m_inputMeter         = new Meter(getNumInputChannels());
+    m_inputVolumePlugin  = new Volume(getNumInputChannels());
+    m_outputVolumePlugin = new Volume(getNumOutputChannels());
+    m_outputTonePlugin   = new Tone(getNumOutputChannels());
+
+    // Add plugins to chains
+    addOutputPlugin(m_outputTonePlugin);
+    addInputPlugin(m_inputVolumePlugin);
+    addOutputPlugin(m_outputVolumePlugin);
+    addInputPlugin(m_inputMeter);
+
+    // Connect plugins for communication with UI
+    connect(m_inputMeter, &Meter::onComputedVolumeMeasurements, this,
+            &VsAudioInterface::processMeterMeasurements);
+    connect(this, &VsAudioInterface::updatedInputVolume, m_inputVolumePlugin,
+            &Volume::volumeUpdated);
+    connect(this, &VsAudioInterface::updatedOutputVolume, m_outputVolumePlugin,
+            &Volume::volumeUpdated);
+    connect(this, &VsAudioInterface::updatedInputMuted, m_inputVolumePlugin,
+            &Volume::muteUpdated);
+    connect(this, &VsAudioInterface::updatedOutputMuted, m_outputVolumePlugin,
+            &Volume::muteUpdated);
+    connect(this, &VsAudioInterface::triggerPlayback, m_outputTonePlugin,
+            &Tone::triggerPlayback);
+}
+
+void VsAudioInterface::startProcess()
+{
+    if (!m_audioInterface.isNull() && !m_audioActive) {
+        try {
+            m_audioInterface->initPlugins();
+            m_audioInterface->startProcess();
+            if (m_audioInterfaceMode == VsAudioInterface::JACK) {
+                m_audioInterface->connectDefaultPorts();
+            }
+        } catch (const std::exception& e) {
+            emit errorToProcess(QString::fromUtf8(e.what()));
+        }
+        m_audioActive   = true;
+        m_hasBeenActive = true;
+    }
+}
+
+float VsAudioInterface::inputVolume()
+{
+    return m_inMultiplier;
+}
+
+float VsAudioInterface::outputVolume()
+{
+    return m_outMultiplier;
+}
+
+bool VsAudioInterface::inputMuted()
+{
+    return m_inMuted;
+}
+
+bool VsAudioInterface::outputMuted()
+{
+    return m_outMuted;
+}
+
+void VsAudioInterface::setInputVolume(float multiplier)
+{
+    m_inMultiplier = multiplier;
+    QSettings settings;
+    settings.beginGroup(QStringLiteral("Audio"));
+    settings.setValue(QStringLiteral("InMultiplier"), m_inMultiplier);
+    settings.endGroup();
+    emit updatedInputVolume(multiplier);
+}
+
+void VsAudioInterface::setOutputVolume(float multiplier)
+{
+    m_outMultiplier = multiplier;
+    QSettings settings;
+    settings.beginGroup(QStringLiteral("Audio"));
+    settings.setValue(QStringLiteral("OutMultiplier"), m_outMultiplier);
+    settings.endGroup();
+    emit updatedOutputVolume(multiplier);
+}
+
+void VsAudioInterface::setInputMuted(bool muted)
+{
+    m_inMuted = muted;
+    QSettings settings;
+    settings.beginGroup(QStringLiteral("Audio"));
+    settings.setValue(QStringLiteral("InMuted"), m_inMuted ? 1 : 0);
+    settings.endGroup();
+    emit updatedInputMuted(muted);
+}
+
+void VsAudioInterface::setOutputMuted(bool muted)
+{
+    m_outMuted = muted;
+    QSettings settings;
+    settings.beginGroup(QStringLiteral("Audio"));
+    settings.setValue(QStringLiteral("OutMuted"), m_outMuted ? 1 : 0);
+    settings.endGroup();
+    emit updatedOutputMuted(muted);
+}
diff --git a/src/gui/vsAudioInterface.h b/src/gui/vsAudioInterface.h
new file mode 100644 (file)
index 0000000..507bd16
--- /dev/null
@@ -0,0 +1,143 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2008-2022 Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  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.
+*/
+//*****************************************************************
+
+/**
+ * \file vsAudioInterface.h
+ * \author Matt Horton
+ * \date September 2022
+ */
+
+#ifndef VSDAUDIOINTERFACE_H
+#define VSDAUDIOINTERFACE_H
+
+#include <QDebug>
+#include <QObject>
+#include <QSharedPointer>
+#include <QString>
+
+#ifndef NO_JACK
+#include "../JackAudioInterface.h"
+#endif
+#ifdef RT_AUDIO
+#include "../RtAudioInterface.h"
+#endif
+
+#include "../Meter.h"
+#include "../Tone.h"
+#include "../Volume.h"
+#include "../jacktrip_globals.h"
+
+class VsAudioInterface : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(
+        float inputVolume READ inputVolume WRITE setInputVolume NOTIFY updatedInputVolume)
+    Q_PROPERTY(float outputVolume READ outputVolume WRITE setOutputVolume NOTIFY
+                   updatedOutputVolume)
+
+   public:
+    // Constructor
+    explicit VsAudioInterface(
+        int NumChansIn = gDefaultNumInChannels, int NumChansOut = gDefaultNumOutChannels,
+        AudioInterface::audioBitResolutionT AudioBitResolution = AudioInterface::BIT16,
+        QObject* parent                                        = nullptr);
+    ~VsAudioInterface();
+
+    // Public functions
+    void setupAudio();
+    void closeAudio();
+    void startProcess();
+    void addInputPlugin(ProcessPlugin* plugin);
+    void addOutputPlugin(ProcessPlugin* plugin);
+    int getNumInputChannels();
+    int getNumOutputChannels();
+    void setupPlugins();
+    float inputVolume();
+    float outputVolume();
+    bool inputMuted();
+    bool outputMuted();
+
+    enum audiointerfaceModeT {
+        JACK,    ///< Jack Mode
+        RTAUDIO  ///< RtAudio Mode
+    };
+
+   public slots:
+    void setInputDevice(QString deviceName);
+    void setOutputDevice(QString deviceName);
+    void setAudioInterfaceMode(bool useRtAudio);
+    void setInputVolume(float multiplier);
+    void setOutputVolume(float multiplier);
+    void setInputMuted(bool muted);
+    void setOutputMuted(bool muted);
+
+   signals:
+    void updatedInputVolume(float multiplier);
+    void updatedOutputVolume(float multiplier);
+    void updatedInputMuted(bool muted);
+    void updatedOutputMuted(bool muted);
+    void triggerPlayback();
+    void settingsUpdated();
+    void modeUpdated();
+    void newVolumeMeterMeasurements(QVector<float> values);
+    void errorToProcess(const QString& errorMessage);
+
+   private slots:
+    // void refreshAudioStream();
+    void replaceProcess();
+    void processMeterMeasurements(QVector<float> values);
+
+   private:
+    float m_inMultiplier  = 1.0;
+    float m_outMultiplier = 1.0;
+    bool m_inMuted        = false;
+    bool m_outMuted       = false;
+    bool m_audioActive    = false;
+    bool m_hasBeenActive  = false;
+
+    // Needed in constructor
+    int m_numAudioChansIn;   ///< Number of Audio Input Channels
+    int m_numAudioChansOut;  ///< Number of Audio Output Channels
+    AudioInterface::audioBitResolutionT m_audioBitResolution;  ///< Audio Bit Resolutions
+
+    QSharedPointer<AudioInterface> m_audioInterface;
+    uint32_t m_sampleRate;                              ///< Sample Rate
+    uint32_t m_deviceID;                                ///< RTAudio DeviceID
+    std::string m_inputDeviceName, m_outputDeviceName;  ///< RTAudio device names
+    uint32_t m_audioBufferSize;  ///< Audio buffer size to process on each callback
+    VsAudioInterface::audiointerfaceModeT m_audioInterfaceMode;
+    Meter* m_inputMeter;
+    Volume* m_inputVolumePlugin;
+    Volume* m_outputVolumePlugin;
+    Tone* m_outputTonePlugin;
+};
+
+#endif  // VSDAUDIOINTERFACE_H
diff --git a/src/gui/vsConstants.h b/src/gui/vsConstants.h
new file mode 100644 (file)
index 0000000..b700015
--- /dev/null
@@ -0,0 +1,50 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2008-2022 Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  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.
+*/
+//*****************************************************************
+
+/**
+ * \file vsConstants.h
+ * \author Nelson Wang
+ * \date Oct 2022
+ */
+
+#ifndef VSCONSTANTS_H
+#define VSCONSTANTS_H
+
+#include <QString>
+
+const QString AUTH_AUTHORIZE_URI = QStringLiteral("https://auth.jacktrip.org/authorize");
+const QString AUTH_TOKEN_URI = QStringLiteral("https://auth.jacktrip.org/oauth/token");
+const QString AUTH_AUDIENCE  = QStringLiteral("https://api.jacktrip.org");
+const QString AUTH_CLIENT_ID = QStringLiteral("cROUJag0UVKDaJ6jRAKRzlVjKVFNU39I");
+const QString PROD_API_HOST  = QStringLiteral("app.jacktrip.org");
+const QString TEST_API_HOST  = QStringLiteral("test.jacktrip.org");
+
+#endif  // VSCONSTANTS_H
index 0f1468fb4c28fe3907023100fe2fdb3b9f873b9c..9b39725b787f46498ed01adcd49e6c1d302e9d66 100644 (file)
@@ -40,7 +40,8 @@
 #include <QDebug>
 
 // Constructor
-VsDevice::VsDevice(QOAuth2AuthorizationCodeFlow* authenticator, QObject* parent)
+VsDevice::VsDevice(QOAuth2AuthorizationCodeFlow* authenticator, bool testMode,
+                   QObject* parent)
     : QObject(parent), m_authenticator(authenticator)
 {
     QSettings settings;
@@ -49,6 +50,69 @@ VsDevice::VsDevice(QOAuth2AuthorizationCodeFlow* authenticator, QObject* parent)
     m_apiSecret = settings.value(QStringLiteral("ApiSecret"), "").toString();
     m_appUUID   = settings.value(QStringLiteral("AppUUID"), "").toString();
     m_appID     = settings.value(QStringLiteral("AppID"), "").toString();
+    settings.endGroup();
+    settings.beginGroup(QStringLiteral("Audio"));
+    m_captureVolume =
+        (float)settings.value(QStringLiteral("InMultiplier"), 1.0).toDouble();
+    m_captureMute = settings.value(QStringLiteral("InMuted"), false).toBool();
+    settings.endGroup();
+
+    m_sendVolumeTimer = new QTimer(this);
+    m_sendVolumeTimer->setSingleShot(true);
+    connect(m_sendVolumeTimer, &QTimer::timeout, this, &VsDevice::sendLevels);
+
+    // Determine which API host to use
+    m_apiHost = PROD_API_HOST;
+    if (testMode) {
+        m_apiHost = TEST_API_HOST;
+    }
+
+    // Set server levels to stored versions
+    QJsonObject json = {
+        {QLatin1String("captureVolume"), m_captureVolume * 100.0},
+        {QLatin1String("captureMute"), m_captureMute},
+    };
+    QJsonDocument request = QJsonDocument(json);
+
+    QNetworkReply* reply = m_authenticator->put(
+        QStringLiteral("https://%1/api/devices/%2").arg(m_apiHost, m_appID),
+        request.toJson());
+    connect(reply, &QNetworkReply::finished, this, [=]() {
+        // Got error
+        if (reply->error() != QNetworkReply::NoError) {
+            QVariant statusCode =
+                reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
+            if (!statusCode.isValid()) {
+                std::cout << "Error: " << reply->errorString().toStdString() << std::endl;
+                // TODO: Fix me
+                // emit authFailed();
+                reply->deleteLater();
+                return;
+            }
+        } else {
+            QByteArray response       = reply->readAll();
+            QJsonDocument deviceState = QJsonDocument::fromJson(response);
+            float deviceCaptureVol =
+                (float)(deviceState.object()[QStringLiteral("captureVolume")].toDouble()
+                        / 100.0);
+            float deviceCaptureMute =
+                deviceState.object()[QStringLiteral("captureMute")].toBool();
+
+            m_captureVolume = deviceCaptureVol;
+            emit updatedVolumeFromServer(m_captureVolume);
+
+            m_captureMute = deviceCaptureMute;
+            emit updatedMuteFromServer(m_captureMute);
+        }
+
+        QSettings settings;
+        settings.beginGroup(QStringLiteral("Audio"));
+        settings.setValue(QStringLiteral("InMultiplier"), m_captureVolume);
+        settings.setValue(QStringLiteral("InMuted"), m_captureMute);
+        settings.endGroup();
+
+        reply->deleteLater();
+    });
 }
 
 // registerApp idempotently registers an emulated device belonging to the current user
@@ -60,7 +124,7 @@ void VsDevice::registerApp()
 
     // check if device exists
     QNetworkReply* reply = m_authenticator->get(
-        QStringLiteral("https://app.jacktrip.org/api/devices/%1").arg(m_appID));
+        QStringLiteral("https://%1/api/devices/%2").arg(m_apiHost, m_appID));
     connect(reply, &QNetworkReply::finished, this, [=]() {
         // Got error
         if (reply->error() != QNetworkReply::NoError) {
@@ -116,7 +180,7 @@ void VsDevice::removeApp()
     }
 
     QNetworkReply* reply = m_authenticator->deleteResource(
-        QStringLiteral("https://app.jacktrip.org/api/devices/%1").arg(m_appID));
+        QStringLiteral("https://%1/api/devices/%2").arg(m_apiHost, m_appID));
     connect(reply, &QNetworkReply::finished, this, [=]() {
         if (reply->error() != QNetworkReply::NoError) {
             std::cout << "Error: " << reply->errorString().toStdString() << std::endl;
@@ -147,10 +211,10 @@ void VsDevice::removeApp()
 void VsDevice::sendHeartbeat()
 {
     if (m_webSocket == nullptr) {
-        m_webSocket = new VsWebSocket(
-            QUrl(QStringLiteral("wss://app.jacktrip.org/api/devices/%1/heartbeat")
-                     .arg(m_appID)),
-            m_authenticator->token(), m_apiPrefix, m_apiSecret);
+        m_webSocket =
+            new VsWebSocket(QUrl(QStringLiteral("wss://%1/api/devices/%2/heartbeat")
+                                     .arg(m_apiHost, m_appID)),
+                            m_authenticator->token(), m_apiPrefix, m_apiSecret);
         connect(m_webSocket, &VsWebSocket::textMessageReceived, this,
                 &VsDevice::onTextMessageReceived);
     }
@@ -211,8 +275,7 @@ void VsDevice::sendHeartbeat()
     } else {
         // Send heartbeat via POST API
         QNetworkReply* reply = m_authenticator->post(
-            QStringLiteral("https://app.jacktrip.org/api/devices/%1/heartbeat")
-                .arg(m_appID),
+            QStringLiteral("https://%1/api/devices/%2/heartbeat").arg(m_apiHost, m_appID),
             request.toJson());
         connect(reply, &QNetworkReply::finished, this, [=]() {
             if (reply->error() != QNetworkReply::NoError) {
@@ -239,7 +302,30 @@ void VsDevice::setServerId(QString serverId)
     };
     QJsonDocument request = QJsonDocument(json);
     QNetworkReply* reply  = m_authenticator->put(
-         QStringLiteral("https://app.jacktrip.org/api/devices/%1").arg(m_appID),
+         QStringLiteral("https://%1/api/devices/%2").arg(m_apiHost, m_appID),
+         request.toJson());
+    connect(reply, &QNetworkReply::finished, this, [=]() {
+        if (reply->error() != QNetworkReply::NoError) {
+            std::cout << "Error: " << reply->errorString().toStdString() << std::endl;
+            // TODO: Fix me
+            // emit authFailed();
+            reply->deleteLater();
+            return;
+        }
+        reply->deleteLater();
+    });
+}
+
+void VsDevice::sendLevels()
+{
+    // Add latest volume and mute values to heartbeat body
+    QJsonObject json = {
+        {QLatin1String("captureVolume"), (int)(m_captureVolume * 100)},
+        {QLatin1String("captureMute"), m_captureMute},
+    };
+    QJsonDocument request = QJsonDocument(json);
+    QNetworkReply* reply  = m_authenticator->put(
+         QStringLiteral("https://%1/api/devices/%2").arg(m_apiHost, m_appID),
          request.toJson());
     connect(reply, &QNetworkReply::finished, this, [=]() {
         if (reply->error() != QNetworkReply::NoError) {
@@ -279,7 +365,13 @@ JackTrip* VsDevice::initJackTrip([[maybe_unused]] bool useRtAudio,
     m_jackTrip->setRemoteClientName(m_appID);
     // increment m_bufferStrategy by 1 for array-index mapping
     m_jackTrip->setBufferStrategy(bufferStrategy + 1);
-    m_jackTrip->setBufferQueueLength(-500);
+    if (bufferStrategy == 2) {
+        // use -q auto3 for loss concealment
+        m_jackTrip->setBufferQueueLength(-3);
+    } else {
+        // use -q auto
+        m_jackTrip->setBufferQueueLength(-500);
+    }
     m_jackTrip->setPeerAddress(studioInfo->host());
     m_jackTrip->setPeerPorts(studioInfo->port());
     m_jackTrip->setPeerHandshakePort(studioInfo->port());
@@ -353,6 +445,32 @@ void VsDevice::stopPinger()
     }
 }
 
+// updateVolume sets VsDevice's capture volume to the provided float
+void VsDevice::updateVolume(float multiplier)
+{
+    if (multiplier == m_captureVolume) {
+        return;
+    }
+    m_captureVolume = multiplier;
+
+    if (m_sendVolumeTimer) {
+        m_sendVolumeTimer->start(200);
+    }
+}
+
+// updateMute sets VsDevice's capture mute to the provided boolean
+void VsDevice::updateMute(bool muted)
+{
+    if (muted == m_captureMute) {
+        return;
+    }
+    m_captureMute = muted;
+
+    if (m_sendVolumeTimer) {
+        m_sendVolumeTimer->start(200);
+    }
+}
+
 // terminateJackTrip is a slot intended to be triggered on jacktrip process signals
 void VsDevice::terminateJackTrip()
 {
@@ -375,6 +493,19 @@ void VsDevice::onTextMessageReceived(const QString& message)
         m_pinger->start();
     }
 
+    bool newMute           = newState["captureMute"].toBool();
+    float newCaptureVolume = (float)(newState["captureVolume"].toDouble() / 100.0);
+
+    if (newCaptureVolume != m_captureVolume) {
+        m_captureVolume = newCaptureVolume;
+        emit updatedVolumeFromServer(m_captureVolume);
+    }
+
+    if (newMute != m_captureMute) {
+        m_captureMute = newMute;
+        emit updatedMuteFromServer(m_captureMute);
+    }
+
     reconcileAgentConfig(newState);
 }
 
@@ -440,7 +571,7 @@ void VsDevice::registerJTAsDevice()
     QJsonDocument request = QJsonDocument(json);
 
     QNetworkReply* reply = m_authenticator->post(
-        QStringLiteral("https://app.jacktrip.org/api/devices"), request.toJson());
+        QStringLiteral("https://%1/api/devices").arg(m_apiHost), request.toJson());
     connect(reply, &QNetworkReply::finished, this, [=]() {
         if (reply->error() != QNetworkReply::NoError) {
             std::cout << "Error: " << reply->errorString().toStdString() << std::endl;
index 59b53412680db5c5e99acff34181b16d1f8e0c96..760756bee27b05557020b26116097dd5c4e287ff 100644 (file)
 
 #include <QObject>
 #include <QString>
+#include <QTimer>
 #include <QUuid>
 #include <QtNetworkAuth>
 #include <QtWebSockets>
 
 #include "../JackTrip.h"
 #include "../jacktrip_globals.h"
+#include "vsConstants.h"
 #include "vsPinger.h"
 #include "vsServerInfo.h"
 #include "vsWebSocket.h"
@@ -56,7 +58,7 @@ class VsDevice : public QObject
 
    public:
     // Constructor
-    explicit VsDevice(QOAuth2AuthorizationCodeFlow* authenticator,
+    explicit VsDevice(QOAuth2AuthorizationCodeFlow* authenticator, bool testMode,
                       QObject* parent = nullptr);
 
     // Public functions
@@ -75,10 +77,17 @@ class VsDevice : public QObject
 
    signals:
     void updateNetworkStats(QJsonObject stats);
+    void updatedVolumeFromServer(float multiplier);
+    void updatedMuteFromServer(bool muted);
+
+   public slots:
+    void updateVolume(float multiplier);
+    void updateMute(bool muted);
 
    private slots:
     void terminateJackTrip();
     void onTextMessageReceived(const QString& message);
+    void sendLevels();
 
    private:
     void registerJTAsDevice();
@@ -92,11 +101,15 @@ class VsDevice : public QObject
     QString m_token;
     QString m_apiPrefix;
     QString m_apiSecret;
+    QString m_apiHost = PROD_API_HOST;
     QJsonObject m_deviceAgentConfig;
     VsWebSocket* m_webSocket = NULL;
     QScopedPointer<JackTrip> m_jackTrip;
     QOAuth2AuthorizationCodeFlow* m_authenticator;
     QRandomGenerator m_randomizer;
+    float m_captureVolume = 1.0;
+    bool m_captureMute    = false;
+    QTimer* m_sendVolumeTimer;
 };
 
 #endif  // VSDEVICE_H
index f099b8f005fce0e4d8a935967cdb367a3a508c09..fa7b5f72e9a4c1944cb40f5d7aeac982ccadb478 100644 (file)
@@ -98,7 +98,7 @@ void VsWebSocket::onClosed()
     m_connected = false;
 }
 
-void VsWebSocket::onError(QAbstractSocket::SocketError error)
+void VsWebSocket::onError(QAbstractSocket::SocketError /*error*/)
 {
     // qDebug() << error;
     m_error = true;
index 03f51c89f4622dd89bf8b1e50f349874495ea352..64b553a9a4a402f8800684458ecb9b5c639dd0ed 100644 (file)
@@ -40,7 +40,7 @@
 
 #include "AudioInterface.h"
 
-constexpr const char* const gVersion = "1.6.4";  ///< JackTrip version
+constexpr const char* const gVersion = "1.6.6";  ///< JackTrip version
 
 //*******************************************************************************
 /// \name Default Values
index fc6f39ee12927740e3fcc9d99d2eb92d0d6c31f9..6e942cdb7c0d635767bfaa2900b5d58e959112ab 100644 (file)
@@ -1,7 +1,8 @@
 /* ------------------------------------------------------------
 name: "limiterdsp"
-Code generated with Faust 2.28.6 (https://faust.grame.fr)
-Compilation options: -lang cpp -inpl -scal -ftz 0
+Code generated with Faust 2.41.1 (https://faust.grame.fr)
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn limiterdsp -es 1 -mcd 16
+-single -ftz 0
 ------------------------------------------------------------ */
 
 #ifndef __limiterdsp_H__
@@ -14,23 +15,23 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 // aimed at creating a simple C++ header file (.h) containing a Faust DSP.
 // See the Makefile for how to use it.
 
-/************************** BEGIN dsp.h **************************/
-/************************************************************************
+/************************** BEGIN dsp.h ********************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -44,29 +45,111 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 #include <string>
 #include <vector>
 
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __export__
+#define __export__
+
+#define FAUSTVERSION "2.41.1"
+
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
+
+#ifdef _WIN32
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API    __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
+#else
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#else
+#define FAUST_API    __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
+#endif
+
+#endif
+
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
 
-struct UI;
-struct Meta;
+struct FAUST_API UI;
+struct FAUST_API Meta;
 
 /**
  * DSP memory manager.
  */
 
-struct dsp_memory_manager {
+struct FAUST_API dsp_memory_manager {
     virtual ~dsp_memory_manager() {}
 
+    /**
+     * Inform the Memory Manager with the number of expected memory zones.
+     * @param count - the number of expected memory zones
+     */
+    virtual void begin(size_t /*count*/) {}
+
+    /**
+     * Give the Memory Manager information on a given memory zone.
+     * @param size - the size in bytes of the memory zone
+     * @param reads - the number of Read access to the zone used to compute one frame
+     * @param writes - the number of Write access to the zone used to compute one frame
+     */
+    virtual void info(size_t /*size*/, size_t /*reads*/, size_t /*writes*/) {}
+
+    /**
+     * Inform the Memory Manager that all memory zones have been described,
+     * to possibly start a 'compute the best allocation strategy' step.
+     */
+    virtual void end() {}
+
+    /**
+     * Allocate a memory zone.
+     * @param size - the memory zone size in bytes
+     */
     virtual void* allocate(size_t size) = 0;
-    virtual void destroy(void* ptr)     = 0;
+
+    /**
+     * Destroy a memory zone.
+     * @param ptr - the memory zone pointer to be deallocated
+     */
+    virtual void destroy(void* ptr) = 0;
 };
 
 /**
  * Signal processor definition.
  */
 
-class dsp
+class FAUST_API dsp
 {
    public:
     dsp() {}
@@ -86,7 +169,7 @@ class dsp
      */
     virtual void buildUserInterface(UI* ui_interface) = 0;
 
-    /* Returns the sample rate currently used by the instance */
+    /* Return the sample rate currently used by the instance */
     virtual int getSampleRate() = 0;
 
     /**
@@ -94,28 +177,28 @@ class dsp
      * - static class 'classInit': static tables initialization
      * - 'instanceInit': constants and instance state initialization
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void init(int sample_rate) = 0;
 
     /**
      * Init instance state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceInit(int sample_rate) = 0;
 
     /**
      * Init instance constant state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceConstants(int sample_rate) = 0;
 
     /* Init default control parameters values */
     virtual void instanceResetUserInterface() = 0;
 
-    /* Init instance state (delay lines...) */
+    /* Init instance state (like delay lines...) but keep the control parameter values */
     virtual void instanceClear() = 0;
 
     /**
@@ -167,7 +250,7 @@ class dsp
  * Generic DSP decorator.
  */
 
-class decorator_dsp : public dsp
+class FAUST_API decorator_dsp : public dsp
 {
    protected:
     dsp* fDSP;
@@ -206,10 +289,11 @@ class decorator_dsp : public dsp
 };
 
 /**
- * DSP factory class.
+ * DSP factory class, used with LLVM and Interpreter backends
+ * to create DSP instances from a compiled DSP program.
  */
 
-class dsp_factory
+class FAUST_API dsp_factory
 {
    protected:
     // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
@@ -229,75 +313,114 @@ class dsp_factory
     virtual dsp_memory_manager* getMemoryManager()             = 0;
 };
 
-/**
- * On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
- * flags to avoid costly denormals.
- */
+// Denormal handling
 
-#ifdef __SSE__
+#if defined(__SSE__)
 #include <xmmintrin.h>
-#ifdef __SSE2__
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
+#endif
+
+class FAUST_API ScopedNoDenormals
+{
+   private:
+    intptr_t fpsr;
+
+    void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("msr fpcr, %0" : : "ri"(fpsr_aux));
+#elif defined(__SSE__)
+        _mm_setcsr(static_cast<uint32_t>(fpsr_aux));
+#endif
+    }
+
+    void getFpStatusRegister() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("mrs %0, fpcr" : "=r"(fpsr));
+#elif defined(__SSE__)
+        fpsr          = static_cast<intptr_t>(_mm_getcsr());
+#endif
+    }
+
+   public:
+    ScopedNoDenormals() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        intptr_t mask = (1 << 24 /* FZ */);
+#else
+#if defined(__SSE__)
+#if defined(__SSE2__)
+        intptr_t mask = 0x8040;
 #else
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
+        intptr_t mask = 0x8000;
 #endif
 #else
-#define AVOIDDENORMALS
+        intptr_t mask = 0x0000;
 #endif
-
 #endif
-/**************************  END  dsp.h **************************/
+        getFpStatusRegister();
+        setFpStatusRegister(fpsr | mask);
+    }
 
-/************************** BEGIN APIUI.h **************************/
-/************************************************************************
- FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
- ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
+    ~ScopedNoDenormals() noexcept { setFpStatusRegister(fpsr); }
+};
 
- This program 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 General Public License for more details.
+#define AVOIDDENORMALS ScopedNoDenormals();
 
- You should have received a copy of the GNU General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+#endif
 
- EXCEPTION : As a special exception, you may create a larger work
- that contains this FAUST architecture section and distribute
- that work under terms of your choice, so long as this FAUST
- architecture section is not modified.
- ************************************************************************/
+/************************** END dsp.h **************************/
+/************************** BEGIN APIUI.h *****************************
+FAUST Architecture File
+Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+---------------------------------------------------------------------
+This program 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 program 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 program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+EXCEPTION : As a special exception, you may create a larger work
+that contains this FAUST architecture section and distribute
+that work under terms of your choice, so long as this FAUST
+architecture section is not modified.
+************************************************************************/
 
 #ifndef API_UI_H
 #define API_UI_H
 
-#include <iostream>
+#include <stdio.h>
+
 #include <map>
 #include <sstream>
 #include <string>
 #include <vector>
 
-/************************** BEGIN meta.h **************************/
-/************************************************************************
+/************************** BEGIN meta.h *******************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -308,36 +431,40 @@ class dsp_factory
 #ifndef __meta__
 #define __meta__
 
-struct Meta {
-    virtual ~Meta(){};
+/**
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
+ (key, value) metadata.
+ */
+struct FAUST_API Meta {
+    virtual ~Meta() {}
     virtual void declare(const char* key, const char* value) = 0;
 };
 
 #endif
 /**************************  END  meta.h **************************/
-/************************** BEGIN UI.h **************************/
-/************************************************************************
+/************************** BEGIN UI.h *****************************
  FAUST Architecture File
- Copyright (C) 2003-2020 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __UI_H__
 #define __UI_H__
@@ -356,7 +483,7 @@ struct Meta {
 struct Soundfile;
 
 template<typename REAL>
-struct UIReal {
+struct FAUST_API UIReal {
     UIReal() {}
     virtual ~UIReal() {}
 
@@ -387,38 +514,41 @@ struct UIReal {
 
     // -- soundfiles
 
-    virtual void addSoundfile(const char* label, const char* filename,
-                              Soundfile** sf_zone) = 0;
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+                              Soundfile** /*sf_zone*/) = 0;
 
     // -- metadata declarations
 
     virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
+
+    // To be used by LLVM client
+    virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
 };
 
-struct UI : public UIReal<FAUSTFLOAT> {
+struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
     UI() {}
     virtual ~UI() {}
 };
 
 #endif
 /**************************  END  UI.h **************************/
-/************************** BEGIN PathBuilder.h **************************/
-/************************************************************************
+/************************** BEGIN PathBuilder.h **************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -426,10 +556,13 @@ struct UI : public UIReal<FAUSTFLOAT> {
  architecture section is not modified.
  ************************************************************************/
 
-#ifndef FAUST_PATHBUILDER_H
-#define FAUST_PATHBUILDER_H
+#ifndef __PathBuilder__
+#define __PathBuilder__
 
 #include <algorithm>
+#include <map>
+#include <regex>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -438,113 +571,266 @@ struct UI : public UIReal<FAUSTFLOAT> {
  * Helper class to build complete hierarchical path for UI items.
  ******************************************************************************/
 
-class PathBuilder
+class FAUST_API PathBuilder
 {
    protected:
     std::vector<std::string> fControlsLevel;
+    std::vector<std::string> fFullPaths;
+    std::map<std::string, std::string> fFull2Short;  // filled by computeShortNames()
+
+    /**
+     * @brief check if a character is acceptable for an ID
+     *
+     * @param c
+     * @return true is the character is acceptable for an ID
+     */
+    bool isIDChar(char c) const
+    {
+        return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+               || ((c >= '0') && (c <= '9'));
+    }
+
+    /**
+     * @brief remove all "/0x00" parts
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string remove0x00(const std::string& src) const
+    {
+        return std::regex_replace(src, std::regex("/0x00"), "");
+    }
+
+    /**
+     * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string str2ID(const std::string& src) const
+    {
+        std::string dst;
+        bool need_underscore = false;
+        for (char c : src) {
+            if (isIDChar(c) || (c == '/')) {
+                if (need_underscore) {
+                    dst.push_back('_');
+                    need_underscore = false;
+                }
+                dst.push_back(c);
+            } else {
+                need_underscore = true;
+            }
+        }
+        return dst;
+    }
+
+    /**
+     * @brief Keep only the last n slash-parts
+     *
+     * @param src
+     * @param n : 1 indicates the last slash-part
+     * @return modified string
+     */
+    std::string cut(const std::string& src, int n) const
+    {
+        std::string rdst;
+        for (int i = int(src.length()) - 1; i >= 0; i--) {
+            char c = src[i];
+            if (c != '/') {
+                rdst.push_back(c);
+            } else if (n == 1) {
+                std::string dst;
+                for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+                    dst.push_back(rdst[j]);
+                }
+                return dst;
+            } else {
+                n--;
+                rdst.push_back(c);
+            }
+        }
+        return src;
+    }
+
+    void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+    /**
+     * @brief Compute the mapping between full path and short names
+     */
+    void computeShortNames()
+    {
+        std::vector<std::string>
+            uniquePaths;  // all full paths transformed but made unique with a prefix
+        std::map<std::string, std::string>
+            unique2full;  // all full paths transformed but made unique with a prefix
+        char num_buffer[16];
+        int pnum = 0;
+
+        for (const auto& s : fFullPaths) {
+            sprintf(num_buffer, "%d", pnum++);
+            std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+            uniquePaths.push_back(u);
+            unique2full[u] = s;  // remember the full path associated to a unique path
+        }
+
+        std::map<std::string, int> uniquePath2level;  // map path to level
+        for (const auto& s : uniquePaths)
+            uniquePath2level[s] = 1;  // we init all levels to 1
+        bool have_collisions = true;
+
+        while (have_collisions) {
+            // compute collision list
+            std::set<std::string> collisionSet;
+            std::map<std::string, std::string> short2full;
+            have_collisions = false;
+            for (const auto& it : uniquePath2level) {
+                std::string u         = it.first;
+                int n                 = it.second;
+                std::string shortName = cut(u, n);
+                auto p                = short2full.find(shortName);
+                if (p == short2full.end()) {
+                    // no collision
+                    short2full[shortName] = u;
+                } else {
+                    // we have a collision, add the two paths to the collision set
+                    have_collisions = true;
+                    collisionSet.insert(u);
+                    collisionSet.insert(p->second);
+                }
+            }
+            for (const auto& s : collisionSet)
+                uniquePath2level[s]++;  // increase level of colliding path
+        }
+
+        for (const auto& it : uniquePath2level) {
+            std::string u               = it.first;
+            int n                       = it.second;
+            std::string shortName       = replaceCharList(cut(u, n), {'/'}, '_');
+            fFull2Short[unique2full[u]] = shortName;
+        }
+    }
+
+    std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+                                char ch2)
+    {
+        auto beg        = ch1.begin();
+        auto end        = ch1.end();
+        std::string res = str;
+        for (size_t i = 0; i < str.length(); ++i) {
+            if (std::find(beg, end, str[i]) != end)
+                res[i] = ch2;
+        }
+        return res;
+    }
 
    public:
     PathBuilder() {}
     virtual ~PathBuilder() {}
 
+    // Return true for the first level of groups
+    bool pushLabel(const std::string& label)
+    {
+        fControlsLevel.push_back(label);
+        return fControlsLevel.size() == 1;
+    }
+
+    // Return true for the last level of groups
+    bool popLabel()
+    {
+        fControlsLevel.pop_back();
+        return fControlsLevel.size() == 0;
+    }
+
     std::string buildPath(const std::string& label)
     {
         std::string res = "/";
         for (size_t i = 0; i < fControlsLevel.size(); i++) {
-            res += fControlsLevel[i];
-            res += "/";
+            res = res + fControlsLevel[i] + "/";
         }
         res += label;
-        std::replace(res.begin(), res.end(), ' ', '_');
-        return res;
-    }
-
-    std::string buildLabel(std::string label)
-    {
-        std::replace(label.begin(), label.end(), ' ', '_');
-        return label;
+        return replaceCharList(
+            res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
     }
-
-    void pushLabel(const std::string& label) { fControlsLevel.push_back(label); }
-    void popLabel() { fControlsLevel.pop_back(); }
 };
 
-#endif  // FAUST_PATHBUILDER_H
+#endif  // __PathBuilder__
 /**************************  END  PathBuilder.h **************************/
-/************************** BEGIN ValueConverter.h **************************/
-/************************************************************************
+/************************** BEGIN ValueConverter.h ********************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __ValueConverter__
 #define __ValueConverter__
 
 /***************************************************************************************
                                                               ValueConverter.h
                           (GRAME, Copyright 2015-2019)
+ ValueConverter.h
+ (GRAME, Copyright 2015-2019)
 
-Set of conversion objects used to map user interface values (for example a gui slider
-delivering values between 0 and 1) to faust values (for example a vslider between
-20 and 20000) using a log scale.
+ Set of conversion objects used to map user interface values (for example a gui slider
+ delivering values between 0 and 1) to faust values (for example a vslider between
+ 20 and 20000) using a log scale.
 
--- Utilities
+ -- Utilities
 
-Range(lo,hi) : clip a value x between lo and hi
-Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
+ Range(lo,hi) : clip a value x between lo and hi
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
 v2 Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1
 vm v2
 
--- Value Converters
+ -- Value Converters
 
-ValueConverter::ui2faust(x)
-ValueConverter::faust2ui(x)
+ ValueConverter::ui2faust(x)
+ ValueConverter::faust2ui(x)
 
--- ValueConverters used for sliders depending of the scale
+ -- ValueConverters used for sliders depending of the scale
 
-LinearValueConverter(umin, umax, fmin, fmax)
-LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
-LogValueConverter(umin, umax, fmin, fmax)
-ExpValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
+ LogValueConverter(umin, umax, fmin, fmax)
+ ExpValueConverter(umin, umax, fmin, fmax)
 
--- ValueConverters used for accelerometers based on 3 points
+ -- ValueConverters used for accelerometers based on 3 points
 
-AccUpConverter(amin, amid, amax, fmin, fmid, fmax)             -- curve 0
-AccDownConverter(amin, amid, amax, fmin, fmid, fmax)   -- curve 1
-AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 2
-AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 3
+ AccUpConverter(amin, amid, amax, fmin, fmid, fmax)        -- curve 0
+ AccDownConverter(amin, amid, amax, fmin, fmid, fmax)      -- curve 1
+ AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 2
+ AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 3
 
--- lists of ZoneControl are used to implement accelerometers metadata for each axes
+ -- lists of ZoneControl are used to implement accelerometers metadata for each axes
 
-ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
+ ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
 
--- ZoneReader are used to implement screencolor metadata
+ -- ZoneReader are used to implement screencolor metadata
 
-ZoneReader(zone, valueConverter) : a zone with a data converter
+ ZoneReader(zone, valueConverter) : a zone with a data converter
 
 ****************************************************************************************/
 
+#include <assert.h>
+#include <float.h>
+
 #include <algorithm>  // std::max
-#include <cassert>
-#include <cfloat>
 #include <cmath>
 #include <vector>
 
@@ -552,12 +838,12 @@ ZoneReader(zone, valueConverter) : a zone with a data converter
 // Interpolator(lo,hi,v1,v2)
 // Maps a value x between lo and hi to a value y between v1 and v2
 // y = v1 + (x-lo)/(hi-lo)*(v2-v1)
-// y = v1 + (x-lo) * coef              with coef = (v2-v1)/(hi-lo)
+// y = v1 + (x-lo) * coef           with coef = (v2-v1)/(hi-lo)
 // y = v1 + x*coef - lo*coef
 // y = v1 - lo*coef + x*coef
-// y = offset + x*coef                         with offset = v1 - lo*coef
+// y = offset + x*coef              with offset = v1 - lo*coef
 //--------------------------------------------------------------------------------------
-class Interpolator
+class FAUST_API Interpolator
 {
    private:
     //--------------------------------------------------------------------------------------
@@ -608,7 +894,7 @@ class Interpolator
 // Interpolator3pt(lo,mi,hi,v1,vm,v2)
 // Map values between lo mid hi to values between v1 vm v2
 //--------------------------------------------------------------------------------------
-class Interpolator3pt
+class FAUST_API Interpolator3pt
 {
    private:
     Interpolator fSegment1;
@@ -632,19 +918,19 @@ class Interpolator3pt
 //--------------------------------------------------------------------------------------
 // Abstract ValueConverter class. Converts values between UI and Faust representations
 //--------------------------------------------------------------------------------------
-class ValueConverter
+class FAUST_API ValueConverter
 {
    public:
     virtual ~ValueConverter() {}
-    virtual double ui2faust(double x) = 0;
-    virtual double faust2ui(double x) = 0;
+    virtual double ui2faust(double x) { return x; };
+    virtual double faust2ui(double x) { return x; };
 };
 
 //--------------------------------------------------------------------------------------
 // A converter than can be updated
 //--------------------------------------------------------------------------------------
 
-class UpdatableValueConverter : public ValueConverter
+class FAUST_API UpdatableValueConverter : public ValueConverter
 {
    protected:
     bool fActive;
@@ -664,7 +950,7 @@ class UpdatableValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter : public ValueConverter
+class FAUST_API LinearValueConverter : public ValueConverter
 {
    private:
     Interpolator fUI2F;
@@ -684,7 +970,7 @@ class LinearValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Two segments linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter2 : public UpdatableValueConverter
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fUI2F;
@@ -720,7 +1006,7 @@ class LinearValueConverter2 : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Logarithmic conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LogValueConverter : public LinearValueConverter
+class FAUST_API LogValueConverter : public LinearValueConverter
 {
    public:
     LogValueConverter(double umin, double umax, double fmin, double fmax)
@@ -742,7 +1028,7 @@ class LogValueConverter : public LinearValueConverter
 //--------------------------------------------------------------------------------------
 // Exponential conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class ExpValueConverter : public LinearValueConverter
+class FAUST_API ExpValueConverter : public LinearValueConverter
 {
    public:
     ExpValueConverter(double umin, double umax, double fmin, double fmax)
@@ -765,7 +1051,7 @@ class ExpValueConverter : public LinearValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up curve (curve 0)
 //--------------------------------------------------------------------------------------
-class AccUpConverter : public UpdatableValueConverter
+class FAUST_API AccUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -801,7 +1087,7 @@ class AccUpConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down curve (curve 1)
 //--------------------------------------------------------------------------------------
-class AccDownConverter : public UpdatableValueConverter
+class FAUST_API AccDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -837,7 +1123,7 @@ class AccDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up-Down curve (curve 2)
 //--------------------------------------------------------------------------------------
-class AccUpDownConverter : public UpdatableValueConverter
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -874,7 +1160,7 @@ class AccUpDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down-Up curve (curve 3)
 //--------------------------------------------------------------------------------------
-class AccDownUpConverter : public UpdatableValueConverter
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -910,7 +1196,7 @@ class AccDownUpConverter : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Base class for ZoneControl
 //--------------------------------------------------------------------------------------
-class ZoneControl
+class FAUST_API ZoneControl
 {
    protected:
     FAUSTFLOAT* fZone;
@@ -939,7 +1225,7 @@ class ZoneControl
 //--------------------------------------------------------------------------------------
 //  Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class ConverterZoneControl : public ZoneControl
+class FAUST_API ConverterZoneControl : public ZoneControl
 {
    protected:
     ValueConverter* fValueConverter;
@@ -954,7 +1240,10 @@ class ConverterZoneControl : public ZoneControl
         delete fValueConverter;
     }  // Assuming fValueConverter is not kept elsewhere...
 
-    virtual void update(double v) const { *fZone = fValueConverter->ui2faust(v); }
+    virtual void update(double v) const
+    {
+        *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v));
+    }
 
     ValueConverter* getConverter() { return fValueConverter; }
 };
@@ -963,7 +1252,7 @@ class ConverterZoneControl : public ZoneControl
 // Association of a zone and a four value converter, each one for each possible curve.
 // Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class CurveZoneControl : public ZoneControl
+class FAUST_API CurveZoneControl : public ZoneControl
 {
    private:
     std::vector<UpdatableValueConverter*> fValueConverters;
@@ -986,15 +1275,14 @@ class CurveZoneControl : public ZoneControl
     }
     virtual ~CurveZoneControl()
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            delete (*it);
+        for (const auto& it : fValueConverters) {
+            delete it;
         }
     }
     void update(double v) const
     {
         if (fValueConverters[fCurve]->getActive())
-            *fZone = fValueConverters[fCurve]->ui2faust(v);
+            *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v));
     }
 
     void setMappingValues(int curve, double amin, double amid, double amax, double min,
@@ -1011,16 +1299,15 @@ class CurveZoneControl : public ZoneControl
 
     void setActive(bool on_off)
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            (*it)->setActive(on_off);
+        for (const auto& it : fValueConverters) {
+            it->setActive(on_off);
         }
     }
 
     int getCurve() { return fCurve; }
 };
 
-class ZoneReader
+class FAUST_API ZoneReader
 {
    private:
     FAUSTFLOAT* fZone;
@@ -1040,6 +1327,8 @@ class ZoneReader
 #endif
 /**************************  END  ValueConverter.h **************************/
 
+typedef unsigned int uint;
+
 class APIUI
     : public PathBuilder
     , public Meta
@@ -1055,22 +1344,42 @@ class APIUI
         kHBargraph,
         kVBargraph
     };
+    enum Type { kAcc = 0, kGyr = 1, kNoType };
 
    protected:
-    enum { kLin = 0, kLog = 1, kExp = 2 };
-
-    int fNumParameters;
-    std::vector<std::string> fPaths;
-    std::vector<std::string> fLabels;
-    std::map<std::string, int> fPathMap;
-    std::map<std::string, int> fLabelMap;
-    std::vector<ValueConverter*> fConversion;
-    std::vector<FAUSTFLOAT*> fZone;
-    std::vector<FAUSTFLOAT> fInit;
-    std::vector<FAUSTFLOAT> fMin;
-    std::vector<FAUSTFLOAT> fMax;
-    std::vector<FAUSTFLOAT> fStep;
-    std::vector<ItemType> fItemType;
+    enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+    struct Item {
+        std::string fLabel;
+        std::string fShortname;
+        std::string fPath;
+        ValueConverter* fConversion;
+        FAUSTFLOAT* fZone;
+        FAUSTFLOAT fInit;
+        FAUSTFLOAT fMin;
+        FAUSTFLOAT fMax;
+        FAUSTFLOAT fStep;
+        ItemType fItemType;
+
+        Item(const std::string& label, const std::string& short_name,
+             const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+             FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+             ItemType item_type)
+            : fLabel(label)
+            , fShortname(short_name)
+            , fPath(path)
+            , fConversion(conversion)
+            , fZone(zone)
+            , fInit(init)
+            , fMin(min)
+            , fMax(max)
+            , fStep(step)
+            , fItemType(item_type)
+        {
+        }
+    };
+    std::vector<Item> fItems;
+
     std::vector<std::map<std::string, std::string> > fMetaData;
     std::vector<ZoneControl*> fAcc[3];
     std::vector<ZoneControl*> fGyr[3];
@@ -1097,33 +1406,31 @@ class APIUI
                               ItemType type)
     {
         std::string path = buildPath(label);
-        fPathMap[path] = fLabelMap[label] = fNumParameters++;
-        fPaths.push_back(path);
-        fLabels.push_back(label);
-        fZone.push_back(zone);
-        fInit.push_back(init);
-        fMin.push_back(min);
-        fMax.push_back(max);
-        fStep.push_back(step);
-        fItemType.push_back(type);
+        fFullPaths.push_back(path);
 
         // handle scale metadata
+        ValueConverter* converter = nullptr;
         switch (fCurrentScale) {
         case kLin:
-            fConversion.push_back(new LinearValueConverter(0, 1, min, max));
+            converter = new LinearValueConverter(0, 1, min, max);
             break;
         case kLog:
-            fConversion.push_back(new LogValueConverter(0, 1, min, max));
+            converter = new LogValueConverter(0, 1, min, max);
             break;
         case kExp:
-            fConversion.push_back(new ExpValueConverter(0, 1, min, max));
+            converter = new ExpValueConverter(0, 1, min, max);
             break;
         }
         fCurrentScale = kLin;
 
+        fItems.push_back(
+            Item(label, "", path, converter, zone, init, min, max, step, type));
+
         if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
-            std::cerr << "warning : 'acc' and 'gyr' metadata used for the same " << label
-                      << " parameter !!\n";
+            fprintf(
+                stderr,
+                "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n",
+                label);
         }
 
         // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
@@ -1138,7 +1445,7 @@ class APIUI
                 fAcc[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect acc metadata : " << fCurrentAcc << std::endl;
+                fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
             }
             fCurrentAcc = "";
         }
@@ -1155,31 +1462,31 @@ class APIUI
                 fGyr[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect gyr metadata : " << fCurrentGyr << std::endl;
+                fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
             }
             fCurrentGyr = "";
         }
 
         // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
         if (fCurrentColor.size() > 0) {
-            if ((fCurrentColor == "red") && (fRedReader == 0)) {
+            if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "green") && (fGreenReader == 0)) {
+            } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "blue") && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "white") && (fRedReader == 0)
-                       && (fGreenReader == 0) && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "white") && (fRedReader == nullptr)
+                       && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
             } else {
-                std::cerr << "incorrect screencolor metadata : " << fCurrentColor
-                          << std::endl;
+                fprintf(stderr, "incorrect screencolor metadata : %s \n",
+                        fCurrentColor.c_str());
             }
         }
         fCurrentColor = "";
@@ -1190,7 +1497,7 @@ class APIUI
 
     int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
     {
-        FAUSTFLOAT* zone = fZone[p];
+        FAUSTFLOAT* zone = fItems[uint(p)].fZone;
         for (size_t i = 0; i < table[val].size(); i++) {
             if (zone == table[val][i]->getZone())
                 return int(i);
@@ -1207,11 +1514,11 @@ class APIUI
 
         // Deactivates everywhere..
         if (id1 != -1)
-            table[0][id1]->setActive(false);
+            table[0][uint(id1)]->setActive(false);
         if (id2 != -1)
-            table[1][id2]->setActive(false);
+            table[1][uint(id2)]->setActive(false);
         if (id3 != -1)
-            table[2][id3]->setActive(false);
+            table[2][uint(id3)]->setActive(false);
 
         if (val == -1) {  // Means: no more mapping...
             // So stay all deactivated...
@@ -1219,14 +1526,16 @@ class APIUI
             int id4 = getZoneIndex(table, p, val);
             if (id4 != -1) {
                 // Reactivate the one we edit...
-                table[val][id4]->setMappingValues(curve, amin, amid, amax, fMin[p],
-                                                  fInit[p], fMax[p]);
-                table[val][id4]->setActive(true);
+                table[val][uint(id4)]->setMappingValues(
+                    curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit,
+                    fItems[uint(p)].fMax);
+                table[val][uint(id4)]->setActive(true);
             } else {
                 // Allocate a new CurveZoneControl which is 'active' by default
-                FAUSTFLOAT* zone = fZone[p];
-                table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax,
-                                                          fMin[p], fInit[p], fMax[p]));
+                FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+                table[val].push_back(new CurveZoneControl(
+                    zone, curve, amin, amid, amax, fItems[uint(p)].fMin,
+                    fItems[uint(p)].fInit, fItems[uint(p)].fMax));
             }
         }
     }
@@ -1240,16 +1549,16 @@ class APIUI
 
         if (id1 != -1) {
             val   = 0;
-            curve = table[val][id1]->getCurve();
-            table[val][id1]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id1)]->getCurve();
+            table[val][uint(id1)]->getMappingValues(amin, amid, amax);
         } else if (id2 != -1) {
             val   = 1;
-            curve = table[val][id2]->getCurve();
-            table[val][id2]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id2)]->getCurve();
+            table[val][uint(id2)]->getMappingValues(amin, amid, amax);
         } else if (id3 != -1) {
             val   = 2;
-            curve = table[val][id3]->getCurve();
-            table[val][id3]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id3)]->getCurve();
+            table[val][uint(id3)]->getMappingValues(amin, amid, amax);
         } else {
             val   = -1;  // No mapping
             curve = 0;
@@ -1260,26 +1569,23 @@ class APIUI
     }
 
    public:
-    enum Type { kAcc = 0, kGyr = 1, kNoType };
-
     APIUI()
-        : fNumParameters(0)
-        , fHasScreenControl(false)
-        , fRedReader(0)
-        , fGreenReader(0)
-        , fBlueReader(0)
+        : fHasScreenControl(false)
+        , fRedReader(nullptr)
+        , fGreenReader(nullptr)
+        , fBlueReader(nullptr)
         , fCurrentScale(kLin)
     {
     }
 
     virtual ~APIUI()
     {
-        for (auto& it : fConversion)
-            delete it;
+        for (const auto& it : fItems)
+            delete it.fConversion;
         for (int i = 0; i < 3; i++) {
-            for (auto& it : fAcc[i])
+            for (const auto& it : fAcc[i])
                 delete it;
-            for (auto& it : fGyr[i])
+            for (const auto& it : fGyr[i])
                 delete it;
         }
         delete fRedReader;
@@ -1292,7 +1598,18 @@ class APIUI
     virtual void openTabBox(const char* label) { pushLabel(label); }
     virtual void openHorizontalBox(const char* label) { pushLabel(label); }
     virtual void openVerticalBox(const char* label) { pushLabel(label); }
-    virtual void closeBox() { popLabel(); }
+    virtual void closeBox()
+    {
+        if (popLabel()) {
+            // Shortnames can be computed when all fullnames are known
+            computeShortNames();
+            // Fill 'shortname' field for each item
+            for (const auto& it : fFull2Short) {
+                int index                = getParamIndex(it.first.c_str());
+                fItems[index].fShortname = it.second;
+            }
+        }
+    }
 
     // -- active widgets
 
@@ -1329,13 +1646,13 @@ class APIUI
     virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone,
                                        FAUSTFLOAT min, FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kHBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kHBargraph);
     }
 
     virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min,
                                      FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kVBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kVBargraph);
     }
 
     // -- soundfiles
@@ -1378,23 +1695,25 @@ class APIUI
     //-------------------------------------------------------------------------------
     // Simple API part
     //-------------------------------------------------------------------------------
-    int getParamsCount() { return fNumParameters; }
-    int getParamIndex(const char* path)
+    int getParamsCount() { return int(fItems.size()); }
+
+    int getParamIndex(const char* path_aux)
     {
-        if (fPathMap.find(path) != fPathMap.end()) {
-            return fPathMap[path];
-        } else if (fLabelMap.find(path) != fLabelMap.end()) {
-            return fLabelMap[path];
-        } else {
-            return -1;
-        }
+        std::string path = std::string(path_aux);
+        auto it          = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+            return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+                 });
+        return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
     }
-    const char* getParamAddress(int p) { return fPaths[p].c_str(); }
-    const char* getParamLabel(int p) { return fLabels[p].c_str(); }
+
+    const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
+    const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
+    const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+
     std::map<const char*, const char*> getMetadata(int p)
     {
         std::map<const char*, const char*> res;
-        std::map<std::string, std::string> metadata = fMetaData[p];
+        std::map<std::string, std::string> metadata = fMetaData[uint(p)];
         for (const auto& it : metadata) {
             res[it.first.c_str()] = it.second.c_str();
         }
@@ -1403,26 +1722,62 @@ class APIUI
 
     const char* getMetadata(int p, const char* key)
     {
-        return (fMetaData[p].find(key) != fMetaData[p].end()) ? fMetaData[p][key].c_str()
-                                                              : "";
+        return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end())
+                   ? fMetaData[uint(p)][key].c_str()
+                   : "";
     }
-    FAUSTFLOAT getParamMin(int p) { return fMin[p]; }
-    FAUSTFLOAT getParamMax(int p) { return fMax[p]; }
-    FAUSTFLOAT getParamStep(int p) { return fStep[p]; }
-    FAUSTFLOAT getParamInit(int p) { return fInit[p]; }
+    FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
+    FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
+    FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
+    FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
+
+    FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
 
-    FAUSTFLOAT* getParamZone(int p) { return fZone[p]; }
-    FAUSTFLOAT getParamValue(int p) { return *fZone[p]; }
-    void setParamValue(int p, FAUSTFLOAT v) { *fZone[p] = v; }
+    FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
+    FAUSTFLOAT getParamValue(const char* path)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            return getParamValue(index);
+        } else {
+            fprintf(stderr, "getParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+            return FAUSTFLOAT(0);
+        }
+    }
 
-    double getParamRatio(int p) { return fConversion[p]->faust2ui(*fZone[p]); }
-    void setParamRatio(int p, double r) { *fZone[p] = fConversion[p]->ui2faust(r); }
+    void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+    void setParamValue(const char* path, FAUSTFLOAT v)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            setParamValue(index, v);
+        } else {
+            fprintf(stderr, "setParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+        }
+    }
 
-    double value2ratio(int p, double r) { return fConversion[p]->faust2ui(r); }
-    double ratio2value(int p, double r) { return fConversion[p]->ui2faust(r); }
+    double getParamRatio(int p)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone);
+    }
+    void setParamRatio(int p, double r)
+    {
+        *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r));
+    }
+
+    double value2ratio(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(r);
+    }
+    double ratio2value(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->ui2faust(r);
+    }
 
     /**
-     * Return the control type (kAcc, kGyr, or -1) for a given parameter
+     * Return the control type (kAcc, kGyr, or -1) for a given parameter.
      *
      * @param p - the UI parameter index
      *
@@ -1444,13 +1799,13 @@ class APIUI
 
     /**
      * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry,
-     * kHBargraph, kVBargraph) for a given parameter
+     * kHBargraph, kVBargraph) for a given parameter.
      *
      * @param p - the UI parameter index
      *
      * @return the Item type
      */
-    ItemType getParamItemType(int p) { return fItemType[p]; }
+    ItemType getParamItemType(int p) { return fItems[uint(p)].fItemType; }
 
     /**
      * Set a new value coming from an accelerometer, propagate it to all relevant
@@ -1490,7 +1845,7 @@ class APIUI
      * given UI parameter.
      *
      * @param p - the UI parameter index
-     * @param acc - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+     * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
      * mapping")
      * @param curve - between 0 and 3
      * @param amin - mapping 'min' point
@@ -1555,7 +1910,7 @@ class APIUI
     }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer
+     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
      *
      * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
      * @return the number of zones
@@ -1564,7 +1919,7 @@ class APIUI
     int getAccCount(int acc) { return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0; }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope
+     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
      *
      * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
      * @param the number of zones
@@ -1601,8 +1956,11 @@ class APIUI
 #define FAUSTFLOAT float
 #endif
 
+#include <math.h>
+
 #include <algorithm>
 #include <cmath>
+#include <cstdint>
 
 #ifndef FAUSTCLASS
 #define FAUSTCLASS limiterdsp
@@ -1613,20 +1971,24 @@ class APIUI
 #define exp10  __exp10
 #endif
 
+#if defined(_WIN32)
+#define RESTRICT __restrict
+#else
+#define RESTRICT __restrict__
+#endif
+
 class limiterdsp : public dsp
 {
    private:
     int fSampleRate;
-    float fConst0;
     float fConst1;
     float fConst2;
-    float fConst3;
-    int iRec5[2];
     FAUSTFLOAT fHslider0;
-    int IOTA;
+    int IOTA0;
     float fVec0[32];
-    float fRec4[2];
+    float fConst3;
     int iRec2[2];
+    float fRec3[2];
     float fRec1[2];
     float fConst4;
     float fConst5;
@@ -1637,9 +1999,16 @@ class limiterdsp : public dsp
     void metadata(Meta* m)
     {
         m->declare("analyzers.lib/name", "Faust Analyzer Library");
-        m->declare("analyzers.lib/version", "0.1");
+        m->declare("analyzers.lib/version", "0.2");
         m->declare("basics.lib/name", "Faust Basic Element Library");
-        m->declare("basics.lib/version", "0.1");
+        m->declare("basics.lib/peakholder:author", "Dario Sanfilippo");
+        m->declare("basics.lib/peakholder:copyright",
+                   "Copyright (C) 2022 Dario Sanfilippo <sanfilippo.dario@gmail.com>");
+        m->declare("basics.lib/peakholder:license", "MIT-style STK-4.3 license");
+        m->declare("basics.lib/version", "0.8");
+        m->declare("compile_options",
+                   "-a faust2header.cpp -lang cpp -i -inpl -cn limiterdsp -es 1 -mcd 16 "
+                   "-single -ftz 0");
         m->declare("compressors.lib/limiter_lad_N:author", "Dario Sanfilippo");
         m->declare(
             "compressors.lib/limiter_lad_N:copyright",
@@ -1651,91 +2020,59 @@ class limiterdsp : public dsp
             "Copyright (C) 2020 Dario Sanfilippo       <sanfilippo.dario@gmail.com>");
         m->declare("compressors.lib/limiter_lad_mono:license", "GPLv3 license");
         m->declare("compressors.lib/name", "Faust Compressor Effect Library");
-        m->declare("compressors.lib/version", "0.0");
+        m->declare("compressors.lib/version", "0.2");
         m->declare("filename", "limiterdsp.dsp");
         m->declare("maths.lib/author", "GRAME");
         m->declare("maths.lib/copyright", "GRAME");
         m->declare("maths.lib/license", "LGPL with exception");
         m->declare("maths.lib/name", "Faust Math Library");
-        m->declare("maths.lib/version", "2.3");
+        m->declare("maths.lib/version", "2.5");
         m->declare("name", "limiterdsp");
         m->declare("platform.lib/name", "Generic Platform Library");
-        m->declare("platform.lib/version", "0.1");
+        m->declare("platform.lib/version", "0.2");
         m->declare("routes.lib/name", "Faust Signal Routing Library");
         m->declare("routes.lib/version", "0.2");
         m->declare("signals.lib/name", "Faust Signal Routing Library");
-        m->declare("signals.lib/version", "0.0");
+        m->declare("signals.lib/version", "0.3");
     }
 
     virtual int getNumInputs() { return 1; }
     virtual int getNumOutputs() { return 1; }
-    virtual int getInputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
-    virtual int getOutputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
 
     static void classInit(int /*sample_rate*/) {}
 
     virtual void instanceConstants(int sample_rate)
     {
         fSampleRate = sample_rate;
-        fConst0 = std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
-        fConst1 = std::exp((0.0f - (100000.0f / fConst0)));
-        fConst2 = (1.0f - fConst1);
-        fConst3 = (0.100000001f * fConst0);
-        fConst4 = std::exp((0.0f - (4.0f / fConst0)));
-        fConst5 = (1.0f - fConst4);
-        iConst6 = int((9.99999975e-05f * fConst0));
+        float fConst0 =
+            std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
+        fConst1 = std::exp(0.0f - 100000.0f / fConst0);
+        fConst2 = 1.0f - fConst1;
+        fConst3 = 0.100000001f * fConst0;
+        fConst4 = std::exp(0.0f - 4.0f / fConst0);
+        fConst5 = 1.0f - fConst4;
+        iConst6 = int(9.99999975e-05f * fConst0);
     }
 
     virtual void instanceResetUserInterface() { fHslider0 = FAUSTFLOAT(2.0f); }
 
     virtual void instanceClear()
     {
-        for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
-            iRec5[l0] = 0;
-        }
-        IOTA = 0;
-        for (int l1 = 0; (l1 < 32); l1 = (l1 + 1)) {
-            fVec0[l1] = 0.0f;
+        IOTA0 = 0;
+        for (int l0 = 0; l0 < 32; l0 = l0 + 1) {
+            fVec0[l0] = 0.0f;
         }
-        for (int l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
-            fRec4[l2] = 0.0f;
+        for (int l1 = 0; l1 < 2; l1 = l1 + 1) {
+            iRec2[l1] = 0;
         }
-        for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) {
-            iRec2[l3] = 0;
+        for (int l2 = 0; l2 < 2; l2 = l2 + 1) {
+            fRec3[l2] = 0.0f;
         }
-        for (int l4 = 0; (l4 < 2); l4 = (l4 + 1)) {
-            fRec1[l4] = 0.0f;
+        for (int l3 = 0; l3 < 2; l3 = l3 + 1) {
+            fRec1[l3] = 0.0f;
         }
-        for (int l5 = 0; (l5 < 2); l5 = (l5 + 1)) {
-            fRec0[l5] = 0.0f;
+        for (int l4 = 0; l4 < 2; l4 = l4 + 1) {
+            fRec0[l4] = 0.0f;
         }
     }
 
@@ -1759,8 +2096,9 @@ class limiterdsp : public dsp
     {
         ui_interface->openVerticalBox("limiterdsp");
         ui_interface->declare(&fHslider0, "0", "");
-        ui_interface->addHorizontalSlider("NumClientsAssumed", &fHslider0, 2.0f, 1.0f,
-                                          64.0f, 1.0f);
+        ui_interface->addHorizontalSlider("NumClientsAssumed", &fHslider0,
+                                          FAUSTFLOAT(2.0f), FAUSTFLOAT(1.0f),
+                                          FAUSTFLOAT(64.0f), FAUSTFLOAT(1.0f));
         ui_interface->closeBox();
     }
 
@@ -1768,28 +2106,25 @@ class limiterdsp : public dsp
     {
         FAUSTFLOAT* input0  = inputs[0];
         FAUSTFLOAT* output0 = outputs[0];
-        float fSlow0        = (1.0f / std::sqrt(float(fHslider0)));
-        for (int i = 0; (i < count); i = (i + 1)) {
-            float fTemp0       = float(input0[i]);
-            iRec5[0]           = ((iRec5[1] + 1)
-                        % int(std::max<float>(1.0f, (fConst3 * float(iRec2[1])))));
-            float fTemp1       = (fSlow0 * fTemp0);
-            fVec0[(IOTA & 31)] = fTemp1;
-            float fTemp2       = std::fabs(fTemp1);
-            fRec4[0]     = std::max<float>((float((iRec5[0] > 0)) * fRec4[1]), fTemp2);
-            iRec2[0]     = (fRec4[0] >= fTemp2);
-            float fRec3  = fRec4[0];
-            fRec1[0]     = ((fConst1 * fRec1[1]) + (fConst2 * fRec3));
-            float fTemp3 = std::fabs(fRec1[0]);
-            fRec0[0] =
-                std::max<float>(fTemp3, ((fConst4 * fRec0[1]) + (fConst5 * fTemp3)));
-            output0[i] = FAUSTFLOAT(
-                (std::min<float>(1.0f, (0.5f / std::max<float>(fRec0[0], 1.1920929e-07f)))
-                 * fVec0[((IOTA - iConst6) & 31)]));
-            iRec5[1] = iRec5[0];
-            IOTA     = (IOTA + 1);
-            fRec4[1] = fRec4[0];
+        float fSlow0        = 1.0f / std::sqrt(float(fHslider0));
+        for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+            float fTemp0      = float(input0[i0]);
+            float fTemp1      = fSlow0 * fTemp0;
+            fVec0[IOTA0 & 31] = fTemp1;
+            float fTemp2      = std::fabs(std::fabs(fTemp1));
+            int iTemp3        = (fTemp2 >= fRec3[1]) | (float(iRec2[1]) >= fConst3);
+            int iThen0        = iRec2[1] + 1;
+            iRec2[0]          = ((iTemp3) ? 0 : iThen0);
+            fRec3[0]          = ((iTemp3) ? fTemp2 : fRec3[1]);
+            fRec1[0]          = fConst2 * fRec3[0] + fConst1 * fRec1[1];
+            float fTemp4      = std::fabs(fRec1[0]);
+            fRec0[0]    = std::max<float>(fTemp4, fConst4 * fRec0[1] + fConst5 * fTemp4);
+            output0[i0] = FAUSTFLOAT(
+                std::min<float>(1.0f, 0.5f / std::max<float>(fRec0[0], 1.1920929e-07f))
+                * fVec0[(IOTA0 - iConst6) & 31]);
+            IOTA0    = IOTA0 + 1;
             iRec2[1] = iRec2[0];
+            fRec3[1] = fRec3[0];
             fRec1[1] = fRec1[0];
             fRec0[1] = fRec0[0];
         }
index 80554d4ee0b17ad08a9863ce621f6c29f6122b02..9bf27f518b7a3339b663b1e539c7a8afa3317547 100644 (file)
@@ -139,7 +139,9 @@ QCoreApplication* createApplication(int& argc, char* argv[])
 #endif
 #if defined(Q_OS_MACOS) && !defined(NO_VS)
         // Turn on high DPI support.
+#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
         JTApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+#endif
         // Fix for display scaling like 125% or 150% on Windows
 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
         QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
@@ -148,11 +150,18 @@ QCoreApplication* createApplication(int& argc, char* argv[])
         return new JTApplication(argc, argv);
 #else
         // Turn on high DPI support.
+#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
         QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+#endif
         // Fix for display scaling like 125% or 150% on Windows
 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
+#if defined(NO_VS) && defined(_WIN32)
+        QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
+            Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor);
+#else
         QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
             Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
+#endif  // NO_VS
 #endif  // QT_VERSION
         return new QApplication(argc, argv);
 #endif  // Q_OS_MACOS
@@ -327,11 +336,6 @@ int main(int argc, char* argv[])
         // Check if we need to show our first run window.
         QSettings settings;
         int uiMode = settings.value(QStringLiteral("UiMode"), QJackTrip::UNSET).toInt();
-#ifndef __unix__
-        QString updateChannel = settings.value(QStringLiteral("UpdateChannel"), "stable")
-                                    .toString()
-                                    .toLower();
-#endif
 #ifdef _WIN32
         // Set url scheme in registry
         QString path = QDir::toNativeSeparators(qApp->applicationFilePath());
@@ -486,20 +490,29 @@ int main(int argc, char* argv[])
         window->show();
 #endif  // NO_VS
 
-#ifndef NO_UPDATER
-        // Setup auto-update feed
-        dblsqd::Feed* feed = 0;
+#if !defined(NO_UPDATER) && !defined(__unix__)
+#ifndef PSI
+#if defined(NO_VS)
+        // This wasn't set up earlier in NO_VS builds. Create it here.
+        QSettings settings;
+#endif
+        QString updateChannel = settings.value(QStringLiteral("UpdateChannel"), "stable")
+                                    .toString()
+                                    .toLower();
         QString baseUrl =
-            "https://raw.githubusercontent.com/jacktrip/jacktrip/dev/releases";
+            QStringLiteral(
+                "https://raw.githubusercontent.com/jacktrip/jacktrip/dev/releases/%1")
+                .arg(updateChannel);
+#else
+        QString baseUrl = QStringLiteral("https://nuages.psi-borg.org/jacktrip");
+#endif  // PSI
+        // Setup auto-update feed
+        dblsqd::Feed* feed = new dblsqd::Feed();
 #ifdef Q_OS_WIN
-        feed = new dblsqd::Feed();
-        feed->setUrl(
-            QUrl(QString("%1/%2/%3-manifests.json").arg(baseUrl, updateChannel, "win")));
+        feed->setUrl(QUrl(QString("%1/%2-manifests.json").arg(baseUrl, "win")));
 #endif
 #ifdef Q_OS_MACOS
-        feed = new dblsqd::Feed();
-        feed->setUrl(
-            QUrl(QString("%1/%2/%3-manifests.json").arg(baseUrl, updateChannel, "mac")));
+        feed->setUrl(QUrl(QString("%1/%2-manifests.json").arg(baseUrl, "mac")));
 #endif
         if (feed) {
             dblsqd::UpdateDialog* updateDialog = new dblsqd::UpdateDialog(feed);
index eb2faff1b2fd983d9c93f88e30fccfdc3e92b1e1..24dff345704941a2d07df4b52743d2a773ac4de7 100644 (file)
@@ -3,13 +3,13 @@ author: "Dominick Hing"
 license: "MIT Style STK-4.2"
 name: "meter"
 version: "1.0"
-Code generated with Faust 2.40.0 (https://faust.grame.fr)
+Code generated with Faust 2.41.1 (https://faust.grame.fr)
 Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn meterdsp -es 1 -mcd 16
 -single -ftz 0
 ------------------------------------------------------------ */
 
-#ifndef __METERDSP_H__
-#define __METERDSP_H__
+#ifndef __meterdsp_H__
+#define __meterdsp_H__
 
 // NOTE: ANY INCLUDE-GUARD HERE MUST BE DERIVED FROM THE CLASS NAME
 //
@@ -48,18 +48,71 @@ Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn meterdsp -es 1 -
 #include <string>
 #include <vector>
 
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __export__
+#define __export__
+
+#define FAUSTVERSION "2.41.1"
+
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
+
+#ifdef _WIN32
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API    __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
+#else
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#else
+#define FAUST_API    __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
+#endif
+
+#endif
+
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
 
-struct UI;
-struct Meta;
+struct FAUST_API UI;
+struct FAUST_API Meta;
 
 /**
  * DSP memory manager.
  */
 
-struct dsp_memory_manager {
+struct FAUST_API dsp_memory_manager {
     virtual ~dsp_memory_manager() {}
 
     /**
@@ -99,7 +152,7 @@ struct dsp_memory_manager {
  * Signal processor definition.
  */
 
-class dsp
+class FAUST_API dsp
 {
    public:
     dsp() {}
@@ -200,7 +253,7 @@ class dsp
  * Generic DSP decorator.
  */
 
-class decorator_dsp : public dsp
+class FAUST_API decorator_dsp : public dsp
 {
    protected:
     dsp* fDSP;
@@ -243,7 +296,7 @@ class decorator_dsp : public dsp
  * to create DSP instances from a compiled DSP program.
  */
 
-class dsp_factory
+class FAUST_API dsp_factory
 {
    protected:
     // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
@@ -269,7 +322,7 @@ class dsp_factory
 #include <xmmintrin.h>
 #endif
 
-class ScopedNoDenormals
+class FAUST_API ScopedNoDenormals
 {
    private:
     intptr_t fpsr;
@@ -385,7 +438,7 @@ architecture section is not modified.
  The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
  (key, value) metadata.
  */
-struct Meta {
+struct FAUST_API Meta {
     virtual ~Meta() {}
     virtual void declare(const char* key, const char* value) = 0;
 };
@@ -433,7 +486,7 @@ struct Meta {
 struct Soundfile;
 
 template<typename REAL>
-struct UIReal {
+struct FAUST_API UIReal {
     UIReal() {}
     virtual ~UIReal() {}
 
@@ -464,8 +517,8 @@ struct UIReal {
 
     // -- soundfiles
 
-    virtual void addSoundfile(const char* label, const char* filename,
-                              Soundfile** sf_zone) = 0;
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+                              Soundfile** /*sf_zone*/) = 0;
 
     // -- metadata declarations
 
@@ -475,7 +528,7 @@ struct UIReal {
     virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
 };
 
-struct UI : public UIReal<FAUSTFLOAT> {
+struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
     UI() {}
     virtual ~UI() {}
 };
@@ -506,10 +559,13 @@ struct UI : public UIReal<FAUSTFLOAT> {
  architecture section is not modified.
  ************************************************************************/
 
-#ifndef FAUST_PATHBUILDER_H
-#define FAUST_PATHBUILDER_H
+#ifndef __PathBuilder__
+#define __PathBuilder__
 
 #include <algorithm>
+#include <map>
+#include <regex>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -518,46 +574,190 @@ struct UI : public UIReal<FAUSTFLOAT> {
  * Helper class to build complete hierarchical path for UI items.
  ******************************************************************************/
 
-class PathBuilder
+class FAUST_API PathBuilder
 {
    protected:
     std::vector<std::string> fControlsLevel;
+    std::vector<std::string> fFullPaths;
+    std::map<std::string, std::string> fFull2Short;  // filled by computeShortNames()
+
+    /**
+     * @brief check if a character is acceptable for an ID
+     *
+     * @param c
+     * @return true is the character is acceptable for an ID
+     */
+    bool isIDChar(char c) const
+    {
+        return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+               || ((c >= '0') && (c <= '9'));
+    }
+
+    /**
+     * @brief remove all "/0x00" parts
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string remove0x00(const std::string& src) const
+    {
+        return std::regex_replace(src, std::regex("/0x00"), "");
+    }
+
+    /**
+     * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string str2ID(const std::string& src) const
+    {
+        std::string dst;
+        bool need_underscore = false;
+        for (char c : src) {
+            if (isIDChar(c) || (c == '/')) {
+                if (need_underscore) {
+                    dst.push_back('_');
+                    need_underscore = false;
+                }
+                dst.push_back(c);
+            } else {
+                need_underscore = true;
+            }
+        }
+        return dst;
+    }
+
+    /**
+     * @brief Keep only the last n slash-parts
+     *
+     * @param src
+     * @param n : 1 indicates the last slash-part
+     * @return modified string
+     */
+    std::string cut(const std::string& src, int n) const
+    {
+        std::string rdst;
+        for (int i = int(src.length()) - 1; i >= 0; i--) {
+            char c = src[i];
+            if (c != '/') {
+                rdst.push_back(c);
+            } else if (n == 1) {
+                std::string dst;
+                for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+                    dst.push_back(rdst[j]);
+                }
+                return dst;
+            } else {
+                n--;
+                rdst.push_back(c);
+            }
+        }
+        return src;
+    }
+
+    void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+    /**
+     * @brief Compute the mapping between full path and short names
+     */
+    void computeShortNames()
+    {
+        std::vector<std::string>
+            uniquePaths;  // all full paths transformed but made unique with a prefix
+        std::map<std::string, std::string>
+            unique2full;  // all full paths transformed but made unique with a prefix
+        char num_buffer[16];
+        int pnum = 0;
+
+        for (const auto& s : fFullPaths) {
+            sprintf(num_buffer, "%d", pnum++);
+            std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+            uniquePaths.push_back(u);
+            unique2full[u] = s;  // remember the full path associated to a unique path
+        }
+
+        std::map<std::string, int> uniquePath2level;  // map path to level
+        for (const auto& s : uniquePaths)
+            uniquePath2level[s] = 1;  // we init all levels to 1
+        bool have_collisions = true;
+
+        while (have_collisions) {
+            // compute collision list
+            std::set<std::string> collisionSet;
+            std::map<std::string, std::string> short2full;
+            have_collisions = false;
+            for (const auto& it : uniquePath2level) {
+                std::string u         = it.first;
+                int n                 = it.second;
+                std::string shortName = cut(u, n);
+                auto p                = short2full.find(shortName);
+                if (p == short2full.end()) {
+                    // no collision
+                    short2full[shortName] = u;
+                } else {
+                    // we have a collision, add the two paths to the collision set
+                    have_collisions = true;
+                    collisionSet.insert(u);
+                    collisionSet.insert(p->second);
+                }
+            }
+            for (const auto& s : collisionSet)
+                uniquePath2level[s]++;  // increase level of colliding path
+        }
+
+        for (const auto& it : uniquePath2level) {
+            std::string u               = it.first;
+            int n                       = it.second;
+            std::string shortName       = replaceCharList(cut(u, n), {'/'}, '_');
+            fFull2Short[unique2full[u]] = shortName;
+        }
+    }
+
+    std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+                                char ch2)
+    {
+        auto beg        = ch1.begin();
+        auto end        = ch1.end();
+        std::string res = str;
+        for (size_t i = 0; i < str.length(); ++i) {
+            if (std::find(beg, end, str[i]) != end)
+                res[i] = ch2;
+        }
+        return res;
+    }
 
    public:
     PathBuilder() {}
     virtual ~PathBuilder() {}
 
-    std::string replaceCharList(std::string str, const std::vector<char>& ch1, char ch2)
+    // Return true for the first level of groups
+    bool pushLabel(const std::string& label)
     {
-        std::vector<char>::const_iterator beg = ch1.begin();
-        std::vector<char>::const_iterator end = ch1.end();
-        for (size_t i = 0; i < str.length(); ++i) {
-            if (std::find(beg, end, str[i]) != end) {
-                str[i] = ch2;
-            }
-        }
-        return str;
+        fControlsLevel.push_back(label);
+        return fControlsLevel.size() == 1;
+    }
+
+    // Return true for the last level of groups
+    bool popLabel()
+    {
+        fControlsLevel.pop_back();
+        return fControlsLevel.size() == 0;
     }
 
     std::string buildPath(const std::string& label)
     {
         std::string res = "/";
         for (size_t i = 0; i < fControlsLevel.size(); i++) {
-            res += fControlsLevel[i];
-            res += "/";
+            res = res + fControlsLevel[i] + "/";
         }
         res += label;
-        std::vector<char> rep = {' ', '#', '*', ',', '/', '?',
-                                 '[', ']', '{', '}', '(', ')'};
-        replaceCharList(res, rep, '_');
-        return res;
+        return replaceCharList(
+            res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
     }
-
-    void pushLabel(const std::string& label) { fControlsLevel.push_back(label); }
-    void popLabel() { fControlsLevel.pop_back(); }
 };
 
-#endif  // FAUST_PATHBUILDER_H
+#endif  // __PathBuilder__
 /**************************  END  PathBuilder.h **************************/
 /************************** BEGIN ValueConverter.h ********************
  FAUST Architecture File
@@ -646,7 +846,7 @@ vm v2
 // y = v1 - lo*coef + x*coef
 // y = offset + x*coef              with offset = v1 - lo*coef
 //--------------------------------------------------------------------------------------
-class Interpolator
+class FAUST_API Interpolator
 {
    private:
     //--------------------------------------------------------------------------------------
@@ -697,7 +897,7 @@ class Interpolator
 // Interpolator3pt(lo,mi,hi,v1,vm,v2)
 // Map values between lo mid hi to values between v1 vm v2
 //--------------------------------------------------------------------------------------
-class Interpolator3pt
+class FAUST_API Interpolator3pt
 {
    private:
     Interpolator fSegment1;
@@ -721,7 +921,7 @@ class Interpolator3pt
 //--------------------------------------------------------------------------------------
 // Abstract ValueConverter class. Converts values between UI and Faust representations
 //--------------------------------------------------------------------------------------
-class ValueConverter  // Identity by default
+class FAUST_API ValueConverter
 {
    public:
     virtual ~ValueConverter() {}
@@ -733,7 +933,7 @@ class ValueConverter  // Identity by default
 // A converter than can be updated
 //--------------------------------------------------------------------------------------
 
-class UpdatableValueConverter : public ValueConverter
+class FAUST_API UpdatableValueConverter : public ValueConverter
 {
    protected:
     bool fActive;
@@ -753,7 +953,7 @@ class UpdatableValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter : public ValueConverter
+class FAUST_API LinearValueConverter : public ValueConverter
 {
    private:
     Interpolator fUI2F;
@@ -773,7 +973,7 @@ class LinearValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Two segments linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter2 : public UpdatableValueConverter
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fUI2F;
@@ -809,7 +1009,7 @@ class LinearValueConverter2 : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Logarithmic conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LogValueConverter : public LinearValueConverter
+class FAUST_API LogValueConverter : public LinearValueConverter
 {
    public:
     LogValueConverter(double umin, double umax, double fmin, double fmax)
@@ -831,7 +1031,7 @@ class LogValueConverter : public LinearValueConverter
 //--------------------------------------------------------------------------------------
 // Exponential conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class ExpValueConverter : public LinearValueConverter
+class FAUST_API ExpValueConverter : public LinearValueConverter
 {
    public:
     ExpValueConverter(double umin, double umax, double fmin, double fmax)
@@ -854,7 +1054,7 @@ class ExpValueConverter : public LinearValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up curve (curve 0)
 //--------------------------------------------------------------------------------------
-class AccUpConverter : public UpdatableValueConverter
+class FAUST_API AccUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -890,7 +1090,7 @@ class AccUpConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down curve (curve 1)
 //--------------------------------------------------------------------------------------
-class AccDownConverter : public UpdatableValueConverter
+class FAUST_API AccDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -926,15 +1126,15 @@ class AccDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up-Down curve (curve 2)
 //--------------------------------------------------------------------------------------
-class AccUpDownConverter : public UpdatableValueConverter
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccUpDownConverter(double amin, double amid, double amax, double fmin,
-                       double /*fmid*/, double fmax)
+    AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
+                       double fmax)
         : fA2F(amin, amid, amax, fmin, fmax, fmin)
         , fF2A(fmin, fmax, amin,
                amax)  // Special, pseudo inverse of a non monotonic function
@@ -963,15 +1163,15 @@ class AccUpDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down-Up curve (curve 3)
 //--------------------------------------------------------------------------------------
-class AccDownUpConverter : public UpdatableValueConverter
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccDownUpConverter(double amin, double amid, double amax, double fmin,
-                       double /*fmid*/, double fmax)
+    AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
+                       double fmax)
         : fA2F(amin, amid, amax, fmax, fmin, fmax)
         , fF2A(fmin, fmax, amin,
                amax)  // Special, pseudo inverse of a non monotonic function
@@ -999,7 +1199,7 @@ class AccDownUpConverter : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Base class for ZoneControl
 //--------------------------------------------------------------------------------------
-class ZoneControl
+class FAUST_API ZoneControl
 {
    protected:
     FAUSTFLOAT* fZone;
@@ -1010,9 +1210,8 @@ class ZoneControl
 
     virtual void update(double /*v*/) const {}
 
-    virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
-                                  double /*amax*/, double /*min*/, double /*init*/,
-                                  double /*max*/)
+    virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
+                                  double /*min*/, double /*init*/, double /*max*/)
     {
     }
     virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
@@ -1028,7 +1227,7 @@ class ZoneControl
 //--------------------------------------------------------------------------------------
 //  Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class ConverterZoneControl : public ZoneControl
+class FAUST_API ConverterZoneControl : public ZoneControl
 {
    protected:
     ValueConverter* fValueConverter;
@@ -1055,7 +1254,7 @@ class ConverterZoneControl : public ZoneControl
 // Association of a zone and a four value converter, each one for each possible curve.
 // Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class CurveZoneControl : public ZoneControl
+class FAUST_API CurveZoneControl : public ZoneControl
 {
    private:
     std::vector<UpdatableValueConverter*> fValueConverters;
@@ -1110,7 +1309,7 @@ class CurveZoneControl : public ZoneControl
     int getCurve() { return fCurve; }
 };
 
-class ZoneReader
+class FAUST_API ZoneReader
 {
    private:
     FAUSTFLOAT* fZone;
@@ -1153,8 +1352,9 @@ class APIUI
     enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
 
     struct Item {
-        std::string fPath;
         std::string fLabel;
+        std::string fShortname;
+        std::string fPath;
         ValueConverter* fConversion;
         FAUSTFLOAT* fZone;
         FAUSTFLOAT fInit;
@@ -1162,6 +1362,23 @@ class APIUI
         FAUSTFLOAT fMax;
         FAUSTFLOAT fStep;
         ItemType fItemType;
+
+        Item(const std::string& label, const std::string& short_name,
+             const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+             FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+             ItemType item_type)
+            : fLabel(label)
+            , fShortname(short_name)
+            , fPath(path)
+            , fConversion(conversion)
+            , fZone(zone)
+            , fInit(init)
+            , fMin(min)
+            , fMax(max)
+            , fStep(step)
+            , fItemType(item_type)
+        {
+        }
     };
     std::vector<Item> fItems;
 
@@ -1191,6 +1408,7 @@ class APIUI
                               ItemType type)
     {
         std::string path = buildPath(label);
+        fFullPaths.push_back(path);
 
         // handle scale metadata
         ValueConverter* converter = nullptr;
@@ -1207,7 +1425,8 @@ class APIUI
         }
         fCurrentScale = kLin;
 
-        fItems.push_back({path, label, converter, zone, init, min, max, step, type});
+        fItems.push_back(
+            Item(label, "", path, converter, zone, init, min, max, step, type));
 
         if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
             fprintf(
@@ -1381,7 +1600,18 @@ class APIUI
     virtual void openTabBox(const char* label) { pushLabel(label); }
     virtual void openHorizontalBox(const char* label) { pushLabel(label); }
     virtual void openVerticalBox(const char* label) { pushLabel(label); }
-    virtual void closeBox() { popLabel(); }
+    virtual void closeBox()
+    {
+        if (popLabel()) {
+            // Shortnames can be computed when all fullnames are known
+            computeShortNames();
+            // Fill 'shortname' field for each item
+            for (const auto& it : fFull2Short) {
+                int index                = getParamIndex(it.first.c_str());
+                fItems[index].fShortname = it.second;
+            }
+        }
+    }
 
     // -- active widgets
 
@@ -1469,26 +1699,19 @@ class APIUI
     //-------------------------------------------------------------------------------
     int getParamsCount() { return int(fItems.size()); }
 
-    int getParamIndex(const char* path)
+    int getParamIndex(const char* path_aux)
     {
-        auto it1 = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
-            return it.fPath == std::string(path);
-        });
-        if (it1 != fItems.end()) {
-            return int(it1 - fItems.begin());
-        }
-
-        auto it2 = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
-            return it.fLabel == std::string(path);
-        });
-        if (it2 != fItems.end()) {
-            return int(it2 - fItems.begin());
-        }
-
-        return -1;
+        std::string path = std::string(path_aux);
+        auto it          = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+            return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+                 });
+        return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
     }
-    const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+
     const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
+    const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
+    const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+
     std::map<const char*, const char*> getMetadata(int p)
     {
         std::map<const char*, const char*> res;
@@ -1516,7 +1739,13 @@ class APIUI
     FAUSTFLOAT getParamValue(const char* path)
     {
         int index = getParamIndex(path);
-        return (index >= 0) ? getParamValue(index) : FAUSTFLOAT(0);
+        if (index >= 0) {
+            return getParamValue(index);
+        } else {
+            fprintf(stderr, "getParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+            return FAUSTFLOAT(0);
+        }
     }
 
     void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
@@ -1618,7 +1847,7 @@ class APIUI
      * given UI parameter.
      *
      * @param p - the UI parameter index
-     * @param acc - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+     * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
      * mapping")
      * @param curve - between 0 and 3
      * @param amin - mapping 'min' point
@@ -1761,7 +1990,7 @@ class meterdsp : public dsp
     {
         m->declare("author", "Dominick Hing");
         m->declare("basics.lib/name", "Faust Basic Element Library");
-        m->declare("basics.lib/version", "0.5");
+        m->declare("basics.lib/version", "0.8");
         m->declare("compile_options",
                    "-a faust2header.cpp -lang cpp -i -inpl -cn meterdsp -es 1 -mcd 16 "
                    "-single -ftz 0");
diff --git a/src/tonedsp.h b/src/tonedsp.h
new file mode 100644 (file)
index 0000000..e999299
--- /dev/null
@@ -0,0 +1,2237 @@
+/* ------------------------------------------------------------
+name: "tonedsp"
+Code generated with Faust 2.50.6 (https://faust.grame.fr)
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn tonedsp -es 1 -mcd 16 -single -ftz 0
+------------------------------------------------------------ */
+
+#ifndef  __tonedsp_H__
+#define  __tonedsp_H__
+
+// NOTE: ANY INCLUDE-GUARD HERE MUST BE DERIVED FROM THE CLASS NAME
+//
+// faust2header.cpp - FAUST Architecture File
+// This is a simple variation of matlabplot.cpp in the Faust distribution
+// aimed at creating a simple C++ header file (.h) containing a Faust DSP.
+// See the Makefile for how to use it.
+
+/************************** BEGIN dsp.h ********************************
+ FAUST Architecture File
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ ************************************************************************/
+
+#ifndef __dsp__
+#define __dsp__
+
+#include <string>
+#include <vector>
+
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __export__
+#define __export__
+
+#define FAUSTVERSION "2.50.6"
+
+// Use FAUST_API for code that is part of the external API but is also compiled in faust and libfaust
+// Use LIBFAUST_API for code that is compiled in faust and libfaust
+
+#ifdef _WIN32
+    #pragma warning (disable: 4251)
+    #ifdef FAUST_EXE
+        #define FAUST_API
+        #define LIBFAUST_API
+    #elif FAUST_LIB
+        #define FAUST_API __declspec(dllexport)
+        #define LIBFAUST_API __declspec(dllexport)
+    #else
+        #define FAUST_API
+        #define LIBFAUST_API 
+    #endif
+#else
+    #ifdef FAUST_EXE
+        #define FAUST_API
+        #define LIBFAUST_API
+    #else
+        #define FAUST_API __attribute__((visibility("default")))
+        #define LIBFAUST_API __attribute__((visibility("default")))
+    #endif
+#endif
+
+#endif
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+struct FAUST_API UI;
+struct FAUST_API Meta;
+
+/**
+ * DSP memory manager.
+ */
+
+struct FAUST_API dsp_memory_manager {
+    
+    virtual ~dsp_memory_manager() {}
+    
+    /**
+     * Inform the Memory Manager with the number of expected memory zones.
+     * @param count - the number of expected memory zones
+     */
+    virtual void begin(size_t /*count*/) {}
+    
+    /**
+     * Give the Memory Manager information on a given memory zone.
+     * @param size - the size in bytes of the memory zone
+     * @param reads - the number of Read access to the zone used to compute one frame
+     * @param writes - the number of Write access to the zone used to compute one frame
+     */
+    virtual void info(size_t /*size*/, size_t /*reads*/, size_t /*writes*/) {}
+    
+    /**
+     * Inform the Memory Manager that all memory zones have been described,
+     * to possibly start a 'compute the best allocation strategy' step.
+     */
+    virtual void end() {}
+    
+    /**
+     * Allocate a memory zone.
+     * @param size - the memory zone size in bytes
+     */
+    virtual void* allocate(size_t size) = 0;
+    
+    /**
+     * Destroy a memory zone.
+     * @param ptr - the memory zone pointer to be deallocated
+     */
+    virtual void destroy(void* ptr) = 0;
+    
+};
+
+/**
+* Signal processor definition.
+*/
+
+class FAUST_API dsp {
+
+    public:
+
+        dsp() {}
+        virtual ~dsp() {}
+
+        /* Return instance number of audio inputs */
+        virtual int getNumInputs() = 0;
+    
+        /* Return instance number of audio outputs */
+        virtual int getNumOutputs() = 0;
+    
+        /**
+         * Trigger the ui_interface parameter with instance specific calls
+         * to 'openTabBox', 'addButton', 'addVerticalSlider'... in order to build the UI.
+         *
+         * @param ui_interface - the user interface builder
+         */
+        virtual void buildUserInterface(UI* ui_interface) = 0;
+    
+        /* Return the sample rate currently used by the instance */
+        virtual int getSampleRate() = 0;
+    
+        /**
+         * Global init, calls the following methods:
+         * - static class 'classInit': static tables initialization
+         * - 'instanceInit': constants and instance state initialization
+         *
+         * @param sample_rate - the sampling rate in Hz
+         */
+        virtual void init(int sample_rate) = 0;
+
+        /**
+         * Init instance state
+         *
+         * @param sample_rate - the sampling rate in Hz
+         */
+        virtual void instanceInit(int sample_rate) = 0;
+    
+        /**
+         * Init instance constant state
+         *
+         * @param sample_rate - the sampling rate in Hz
+         */
+        virtual void instanceConstants(int sample_rate) = 0;
+    
+        /* Init default control parameters values */
+        virtual void instanceResetUserInterface() = 0;
+    
+        /* Init instance state (like delay lines...) but keep the control parameter values */
+        virtual void instanceClear() = 0;
+        /**
+         * Return a clone of the instance.
+         *
+         * @return a copy of the instance on success, otherwise a null pointer.
+         */
+        virtual dsp* clone() = 0;
+    
+        /**
+         * Trigger the Meta* parameter with instance specific calls to 'declare' (key, value) metadata.
+         *
+         * @param m - the Meta* meta user
+         */
+        virtual void metadata(Meta* m) = 0;
+    
+        /**
+         * DSP instance computation, to be called with successive in/out audio buffers.
+         *
+         * @param count - the number of frames to compute
+         * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
+         * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
+         *
+         */
+        virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
+    
+        /**
+         * DSP instance computation: alternative method to be used by subclasses.
+         *
+         * @param date_usec - the timestamp in microsec given by audio driver.
+         * @param count - the number of frames to compute
+         * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
+         * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
+         *
+         */
+        virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { compute(count, inputs, outputs); }
+       
+};
+
+/**
+ * Generic DSP decorator.
+ */
+
+class FAUST_API decorator_dsp : public dsp {
+
+    protected:
+
+        dsp* fDSP;
+
+    public:
+
+        decorator_dsp(dsp* dsp = nullptr):fDSP(dsp) {}
+        virtual ~decorator_dsp() { delete fDSP; }
+
+        virtual int getNumInputs() { return fDSP->getNumInputs(); }
+        virtual int getNumOutputs() { return fDSP->getNumOutputs(); }
+        virtual void buildUserInterface(UI* ui_interface) { fDSP->buildUserInterface(ui_interface); }
+        virtual int getSampleRate() { return fDSP->getSampleRate(); }
+        virtual void init(int sample_rate) { fDSP->init(sample_rate); }
+        virtual void instanceInit(int sample_rate) { fDSP->instanceInit(sample_rate); }
+        virtual void instanceConstants(int sample_rate) { fDSP->instanceConstants(sample_rate); }
+        virtual void instanceResetUserInterface() { fDSP->instanceResetUserInterface(); }
+        virtual void instanceClear() { fDSP->instanceClear(); }
+        virtual decorator_dsp* clone() { return new decorator_dsp(fDSP->clone()); }
+        virtual void metadata(Meta* m) { fDSP->metadata(m); }
+        // Beware: subclasses usually have to overload the two 'compute' methods
+        virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(count, inputs, outputs); }
+        virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(date_usec, count, inputs, outputs); }
+    
+};
+
+/**
+ * DSP factory class, used with LLVM and Interpreter backends
+ * to create DSP instances from a compiled DSP program.
+ */
+
+class FAUST_API dsp_factory {
+    
+    protected:
+    
+        // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
+        virtual ~dsp_factory() {}
+    
+    public:
+    
+        virtual std::string getName() = 0;
+        virtual std::string getSHAKey() = 0;
+        virtual std::string getDSPCode() = 0;
+        virtual std::string getCompileOptions() = 0;
+        virtual std::vector<std::string> getLibraryList() = 0;
+        virtual std::vector<std::string> getIncludePathnames() = 0;
+    
+        virtual dsp* createDSPInstance() = 0;
+    
+        virtual void setMemoryManager(dsp_memory_manager* manager) = 0;
+        virtual dsp_memory_manager* getMemoryManager() = 0;
+    
+};
+
+// Denormal handling
+
+#if defined (__SSE__)
+#include <xmmintrin.h>
+#endif
+
+class FAUST_API ScopedNoDenormals {
+    
+    private:
+    
+        intptr_t fpsr = 0;
+        
+        void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+        {
+        #if defined (__arm64__) || defined (__aarch64__)
+            asm volatile("msr fpcr, %0" : : "ri" (fpsr_aux));
+        #elif defined (__SSE__)
+            // The volatile keyword here is needed to workaround a bug in AppleClang 13.0
+            // which aggressively optimises away the variable otherwise
+            volatile uint32_t fpsr_w = static_cast<uint32_t>(fpsr_aux);
+            _mm_setcsr(fpsr_w);
+        #endif
+        }
+        
+        void getFpStatusRegister() noexcept
+        {
+        #if defined (__arm64__) || defined (__aarch64__)
+            asm volatile("mrs %0, fpcr" : "=r" (fpsr));
+        #elif defined (__SSE__)
+            fpsr = static_cast<intptr_t>(_mm_getcsr());
+        #endif
+        }
+    
+    public:
+    
+        ScopedNoDenormals() noexcept
+        {
+        #if defined (__arm64__) || defined (__aarch64__)
+            intptr_t mask = (1 << 24 /* FZ */);
+        #elif defined (__SSE__)
+        #if defined (__SSE2__)
+            intptr_t mask = 0x8040;
+        #else
+            intptr_t mask = 0x8000;
+        #endif
+        #else
+            intptr_t mask = 0x0000;
+        #endif
+            getFpStatusRegister();
+            setFpStatusRegister(fpsr | mask);
+        }
+        
+        ~ScopedNoDenormals() noexcept
+        {
+            setFpStatusRegister(fpsr);
+        }
+
+};
+
+#define AVOIDDENORMALS ScopedNoDenormals ftz_scope;
+
+#endif
+
+/************************** END dsp.h **************************/
+/************************** BEGIN APIUI.h *****************************
+FAUST Architecture File
+Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+---------------------------------------------------------------------
+This program 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 program 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 program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+EXCEPTION : As a special exception, you may create a larger work
+that contains this FAUST architecture section and distribute
+that work under terms of your choice, so long as this FAUST
+architecture section is not modified.
+************************************************************************/
+
+#ifndef API_UI_H
+#define API_UI_H
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <stdio.h>
+#include <map>
+
+/************************** BEGIN meta.h *******************************
+ FAUST Architecture File
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ ************************************************************************/
+
+#ifndef __meta__
+#define __meta__
+
+
+/**
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve (key, value) metadata.
+ */
+struct FAUST_API Meta {
+    virtual ~Meta() {}
+    virtual void declare(const char* key, const char* value) = 0;
+};
+
+#endif
+/**************************  END  meta.h **************************/
+/************************** BEGIN UI.h *****************************
+ FAUST Architecture File
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ ********************************************************************/
+
+#ifndef __UI_H__
+#define __UI_H__
+
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+/*******************************************************************************
+ * UI : Faust DSP User Interface
+ * User Interface as expected by the buildUserInterface() method of a DSP.
+ * This abstract class contains only the method that the Faust compiler can
+ * generate to describe a DSP user interface.
+ ******************************************************************************/
+
+struct Soundfile;
+
+template <typename REAL>
+struct FAUST_API UIReal {
+    
+    UIReal() {}
+    virtual ~UIReal() {}
+    
+    // -- widget's layouts
+    
+    virtual void openTabBox(const char* label) = 0;
+    virtual void openHorizontalBox(const char* label) = 0;
+    virtual void openVerticalBox(const char* label) = 0;
+    virtual void closeBox() = 0;
+    
+    // -- active widgets
+    
+    virtual void addButton(const char* label, REAL* zone) = 0;
+    virtual void addCheckButton(const char* label, REAL* zone) = 0;
+    virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
+    virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
+    virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
+    
+    // -- passive widgets
+    
+    virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
+    virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
+    
+    // -- soundfiles
+    
+    virtual void addSoundfile(const char* label, const char* filename, Soundfile** sf_zone) = 0;
+    
+    // -- metadata declarations
+    
+    virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
+    
+    // To be used by LLVM client
+    virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
+};
+
+struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
+    UI() {}
+    virtual ~UI() {}
+};
+
+#endif
+/**************************  END  UI.h **************************/
+/************************** BEGIN PathBuilder.h **************************
+ FAUST Architecture File
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ ************************************************************************/
+
+#ifndef __PathBuilder__
+#define __PathBuilder__
+
+#include <vector>
+#include <set>
+#include <map>
+#include <string>
+#include <algorithm>
+#include <regex>
+
+
+/*******************************************************************************
+ * PathBuilder : Faust User Interface
+ * Helper class to build complete hierarchical path for UI items.
+ ******************************************************************************/
+
+class FAUST_API PathBuilder {
+
+    protected:
+    
+        std::vector<std::string> fControlsLevel;
+        std::vector<std::string> fFullPaths;
+        std::map<std::string, std::string> fFull2Short;  // filled by computeShortNames()
+    
+        /**
+         * @brief check if a character is acceptable for an ID
+         *
+         * @param c
+         * @return true is the character is acceptable for an ID
+         */
+        bool isIDChar(char c) const
+        {
+            return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9'));
+        }
+    
+        /**
+         * @brief remove all "/0x00" parts
+         *
+         * @param src
+         * @return modified string
+         */
+        std::string remove0x00(const std::string& src) const
+        {
+            return std::regex_replace(src, std::regex("/0x00"), "");
+        }
+    
+        /**
+         * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+         *
+         * @param src
+         * @return modified string
+         */
+        std::string str2ID(const std::string& src) const
+        {
+            std::string dst;
+            bool need_underscore = false;
+            for (char c : src) {
+                if (isIDChar(c) || (c == '/')) {
+                    if (need_underscore) {
+                        dst.push_back('_');
+                        need_underscore = false;
+                    }
+                    dst.push_back(c);
+                } else {
+                    need_underscore = true;
+                }
+            }
+            return dst;
+        }
+    
+        /**
+         * @brief Keep only the last n slash-parts
+         *
+         * @param src
+         * @param n : 1 indicates the last slash-part
+         * @return modified string
+         */
+        std::string cut(const std::string& src, int n) const
+        {
+            std::string rdst;
+            for (int i = int(src.length())-1; i >= 0; i--) {
+                char c = src[i];
+                if (c != '/') {
+                    rdst.push_back(c);
+                } else if (n == 1) {
+                    std::string dst;
+                    for (int j = int(rdst.length())-1; j >= 0; j--) {
+                        dst.push_back(rdst[j]);
+                    }
+                    return dst;
+                } else {
+                    n--;
+                    rdst.push_back(c);
+                }
+            }
+            return src;
+        }
+    
+        void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+    
+        /**
+         * @brief Compute the mapping between full path and short names
+         */
+        void computeShortNames()
+        {
+            std::vector<std::string>           uniquePaths;  // all full paths transformed but made unique with a prefix
+            std::map<std::string, std::string> unique2full;  // all full paths transformed but made unique with a prefix
+            char num_buffer[16];
+            int pnum = 0;
+        
+            for (const auto& s : fFullPaths) {
+                sprintf(num_buffer, "%d", pnum++);
+                std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+                uniquePaths.push_back(u);
+                unique2full[u] = s;  // remember the full path associated to a unique path
+            }
+        
+            std::map<std::string, int> uniquePath2level;                // map path to level
+            for (const auto& s : uniquePaths) uniquePath2level[s] = 1;   // we init all levels to 1
+            bool have_collisions = true;
+        
+            while (have_collisions) {
+                // compute collision list
+                std::set<std::string>              collisionSet;
+                std::map<std::string, std::string> short2full;
+                have_collisions = false;
+                for (const auto& it : uniquePath2level) {
+                    std::string u = it.first;
+                    int n = it.second;
+                    std::string shortName = cut(u, n);
+                    auto p = short2full.find(shortName);
+                    if (p == short2full.end()) {
+                        // no collision
+                        short2full[shortName] = u;
+                    } else {
+                        // we have a collision, add the two paths to the collision set
+                        have_collisions = true;
+                        collisionSet.insert(u);
+                        collisionSet.insert(p->second);
+                    }
+                }
+                for (const auto& s : collisionSet) uniquePath2level[s]++;  // increase level of colliding path
+            }
+        
+            for (const auto& it : uniquePath2level) {
+                std::string u = it.first;
+                int n = it.second;
+                std::string shortName = replaceCharList(cut(u, n), {'/'}, '_');
+                fFull2Short[unique2full[u]] = shortName;
+            }
+        }
+    
+        std::string replaceCharList(const std::string& str, const std::vector<char>& ch1, char ch2)
+        {
+            auto beg = ch1.begin();
+            auto end = ch1.end();
+            std::string res = str;
+            for (size_t i = 0; i < str.length(); ++i) {
+                if (std::find(beg, end, str[i]) != end) res[i] = ch2;
+            }
+            return res;
+        }
+     
+    public:
+    
+        PathBuilder() {}
+        virtual ~PathBuilder() {}
+    
+        // Return true for the first level of groups
+        bool pushLabel(const std::string& label) { fControlsLevel.push_back(label); return fControlsLevel.size() == 1;}
+    
+        // Return true for the last level of groups
+        bool popLabel() { fControlsLevel.pop_back(); return fControlsLevel.size() == 0; }
+    
+        std::string buildPath(const std::string& label)
+        {
+            std::string res = "/";
+            for (size_t i = 0; i < fControlsLevel.size(); i++) {
+                res = res + fControlsLevel[i] + "/";
+            }
+            res += label;
+            return replaceCharList(res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
+        }
+    
+};
+
+#endif  // __PathBuilder__
+/**************************  END  PathBuilder.h **************************/
+/************************** BEGIN ValueConverter.h ********************
+ FAUST Architecture File
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ ********************************************************************/
+
+#ifndef __ValueConverter__
+#define __ValueConverter__
+
+/***************************************************************************************
+ ValueConverter.h
+ (GRAME, Copyright 2015-2019)
+ Set of conversion objects used to map user interface values (for example a gui slider
+ delivering values between 0 and 1) to faust values (for example a vslider between
+ 20 and 20000) using a log scale.
+ -- Utilities
+ Range(lo,hi) : clip a value x between lo and hi
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and v2
+ Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1 vm v2
+ -- Value Converters
+ ValueConverter::ui2faust(x)
+ ValueConverter::faust2ui(x)
+ -- ValueConverters used for sliders depending of the scale
+ LinearValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
+ LogValueConverter(umin, umax, fmin, fmax)
+ ExpValueConverter(umin, umax, fmin, fmax)
+ -- ValueConverters used for accelerometers based on 3 points
+ AccUpConverter(amin, amid, amax, fmin, fmid, fmax)        -- curve 0
+ AccDownConverter(amin, amid, amax, fmin, fmid, fmax)      -- curve 1
+ AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 2
+ AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 3
+ -- lists of ZoneControl are used to implement accelerometers metadata for each axes
+ ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
+ -- ZoneReader are used to implement screencolor metadata
+ ZoneReader(zone, valueConverter) : a zone with a data converter
+
+****************************************************************************************/
+
+#include <float.h>
+#include <algorithm>    // std::max
+#include <cmath>
+#include <vector>
+#include <assert.h>
+
+
+//--------------------------------------------------------------------------------------
+// Interpolator(lo,hi,v1,v2)
+// Maps a value x between lo and hi to a value y between v1 and v2
+// y = v1 + (x-lo)/(hi-lo)*(v2-v1)
+// y = v1 + (x-lo) * coef           with coef = (v2-v1)/(hi-lo)
+// y = v1 + x*coef - lo*coef
+// y = v1 - lo*coef + x*coef
+// y = offset + x*coef              with offset = v1 - lo*coef
+//--------------------------------------------------------------------------------------
+class FAUST_API Interpolator {
+    
+    private:
+
+        //--------------------------------------------------------------------------------------
+        // Range(lo,hi) clip a value between lo and hi
+        //--------------------------------------------------------------------------------------
+        struct Range
+        {
+            double fLo;
+            double fHi;
+
+            Range(double x, double y) : fLo(std::min<double>(x,y)), fHi(std::max<double>(x,y)) {}
+            double operator()(double x) { return (x<fLo) ? fLo : (x>fHi) ? fHi : x; }
+        };
+
+
+        Range fRange;
+        double fCoef;
+        double fOffset;
+
+    public:
+
+        Interpolator(double lo, double hi, double v1, double v2) : fRange(lo,hi)
+        {
+            if (hi != lo) {
+                // regular case
+                fCoef = (v2-v1)/(hi-lo);
+                fOffset = v1 - lo*fCoef;
+            } else {
+                // degenerate case, avoids division by zero
+                fCoef = 0;
+                fOffset = (v1+v2)/2;
+            }
+        }
+        double operator()(double v)
+        {
+            double x = fRange(v);
+            return  fOffset + x*fCoef;
+        }
+
+        void getLowHigh(double& amin, double& amax)
+        {
+            amin = fRange.fLo;
+            amax = fRange.fHi;
+        }
+};
+
+//--------------------------------------------------------------------------------------
+// Interpolator3pt(lo,mi,hi,v1,vm,v2)
+// Map values between lo mid hi to values between v1 vm v2
+//--------------------------------------------------------------------------------------
+class FAUST_API Interpolator3pt {
+
+    private:
+
+        Interpolator fSegment1;
+        Interpolator fSegment2;
+        double fMid;
+
+    public:
+
+        Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2) :
+            fSegment1(lo, mi, v1, vm),
+            fSegment2(mi, hi, vm, v2),
+            fMid(mi) {}
+        double operator()(double x) { return  (x < fMid) ? fSegment1(x) : fSegment2(x); }
+
+        void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fSegment1.getLowHigh(amin, amid);
+            fSegment2.getLowHigh(amid, amax);
+        }
+};
+
+//--------------------------------------------------------------------------------------
+// Abstract ValueConverter class. Converts values between UI and Faust representations
+//--------------------------------------------------------------------------------------
+class FAUST_API ValueConverter {
+
+    public:
+
+        virtual ~ValueConverter() {}
+        virtual double ui2faust(double x) { return x; };
+        virtual double faust2ui(double x) { return x; };
+};
+
+//--------------------------------------------------------------------------------------
+// A converter than can be updated
+//--------------------------------------------------------------------------------------
+
+class FAUST_API UpdatableValueConverter : public ValueConverter {
+    
+    protected:
+        
+        bool fActive;
+        
+    public:
+        
+        UpdatableValueConverter():fActive(true)
+        {}
+        virtual ~UpdatableValueConverter()
+        {}
+        
+        virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max) = 0;
+        virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
+        
+        void setActive(bool on_off) { fActive = on_off; }
+        bool getActive() { return fActive; }
+    
+};
+
+//--------------------------------------------------------------------------------------
+// Linear conversion between ui and Faust values
+//--------------------------------------------------------------------------------------
+class FAUST_API LinearValueConverter : public ValueConverter {
+    
+    private:
+        
+        Interpolator fUI2F;
+        Interpolator fF2UI;
+        
+    public:
+        
+        LinearValueConverter(double umin, double umax, double fmin, double fmax) :
+            fUI2F(umin,umax,fmin,fmax), fF2UI(fmin,fmax,umin,umax)
+        {}
+        
+        LinearValueConverter() : fUI2F(0.,0.,0.,0.), fF2UI(0.,0.,0.,0.)
+        {}
+        virtual double ui2faust(double x) { return fUI2F(x); }
+        virtual double faust2ui(double x) { return fF2UI(x); }
+    
+};
+
+//--------------------------------------------------------------------------------------
+// Two segments linear conversion between ui and Faust values
+//--------------------------------------------------------------------------------------
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter {
+    
+    private:
+    
+        Interpolator3pt fUI2F;
+        Interpolator3pt fF2UI;
+        
+    public:
+    
+        LinearValueConverter2(double amin, double amid, double amax, double min, double init, double max) :
+            fUI2F(amin, amid, amax, min, init, max), fF2UI(min, init, max, amin, amid, amax)
+        {}
+        
+        LinearValueConverter2() : fUI2F(0.,0.,0.,0.,0.,0.), fF2UI(0.,0.,0.,0.,0.,0.)
+        {}
+    
+        virtual double ui2faust(double x) { return fUI2F(x); }
+        virtual double faust2ui(double x) { return fF2UI(x); }
+    
+        virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max)
+        {
+            fUI2F = Interpolator3pt(amin, amid, amax, min, init, max);
+            fF2UI = Interpolator3pt(min, init, max, amin, amid, amax);
+        }
+
+        virtual void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fUI2F.getMappingValues(amin, amid, amax);
+        }
+    
+};
+
+//--------------------------------------------------------------------------------------
+// Logarithmic conversion between ui and Faust values
+//--------------------------------------------------------------------------------------
+class FAUST_API LogValueConverter : public LinearValueConverter {
+
+    public:
+
+        LogValueConverter(double umin, double umax, double fmin, double fmax) :
+            LinearValueConverter(umin, umax, std::log(std::max<double>(DBL_MIN, fmin)), std::log(std::max<double>(DBL_MIN, fmax)))
+        {}
+
+        virtual double ui2faust(double x) { return std::exp(LinearValueConverter::ui2faust(x)); }
+        virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::log(std::max<double>(x, DBL_MIN))); }
+
+};
+
+//--------------------------------------------------------------------------------------
+// Exponential conversion between ui and Faust values
+//--------------------------------------------------------------------------------------
+class FAUST_API ExpValueConverter : public LinearValueConverter {
+
+    public:
+
+        ExpValueConverter(double umin, double umax, double fmin, double fmax) :
+            LinearValueConverter(umin, umax, std::min<double>(DBL_MAX, std::exp(fmin)), std::min<double>(DBL_MAX, std::exp(fmax)))
+        {}
+
+        virtual double ui2faust(double x) { return std::log(LinearValueConverter::ui2faust(x)); }
+        virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::min<double>(DBL_MAX, std::exp(x))); }
+
+};
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using an Up curve (curve 0)
+//--------------------------------------------------------------------------------------
+class FAUST_API AccUpConverter : public UpdatableValueConverter {
+
+    private:
+
+        Interpolator3pt fA2F;
+        Interpolator3pt fF2A;
+
+    public:
+
+        AccUpConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
+            fA2F(amin,amid,amax,fmin,fmid,fmax),
+            fF2A(fmin,fmid,fmax,amin,amid,amax)
+        {}
+
+        virtual double ui2faust(double x) { return fA2F(x); }
+        virtual double faust2ui(double x) { return fF2A(x); }
+
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
+        {
+            //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
+            fF2A = Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
+        }
+
+        virtual void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+
+};
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using a Down curve (curve 1)
+//--------------------------------------------------------------------------------------
+class FAUST_API AccDownConverter : public UpdatableValueConverter {
+
+    private:
+
+        Interpolator3pt        fA2F;
+        Interpolator3pt        fF2A;
+
+    public:
+
+        AccDownConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
+            fA2F(amin,amid,amax,fmax,fmid,fmin),
+            fF2A(fmin,fmid,fmax,amax,amid,amin)
+        {}
+
+        virtual double ui2faust(double x) { return fA2F(x); }
+        virtual double faust2ui(double x) { return fF2A(x); }
+
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
+        {
+             //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
+            fF2A = Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
+        }
+
+        virtual void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+};
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using an Up-Down curve (curve 2)
+//--------------------------------------------------------------------------------------
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter {
+
+    private:
+
+        Interpolator3pt        fA2F;
+        Interpolator fF2A;
+
+    public:
+
+        AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax) :
+            fA2F(amin,amid,amax,fmin,fmax,fmin),
+            fF2A(fmin,fmax,amin,amax)                          // Special, pseudo inverse of a non monotonic function
+        {}
+
+        virtual double ui2faust(double x) { return fA2F(x); }
+        virtual double faust2ui(double x) { return fF2A(x); }
+
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax)
+        {
+            //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
+            fF2A = Interpolator(fmin, fmax, amin, amax);
+        }
+
+        virtual void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+};
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using a Down-Up curve (curve 3)
+//--------------------------------------------------------------------------------------
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter {
+
+    private:
+
+        Interpolator3pt        fA2F;
+        Interpolator fF2A;
+
+    public:
+
+        AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax) :
+            fA2F(amin,amid,amax,fmax,fmin,fmax),
+            fF2A(fmin,fmax,amin,amax)                          // Special, pseudo inverse of a non monotonic function
+        {}
+
+        virtual double ui2faust(double x) { return fA2F(x); }
+        virtual double faust2ui(double x) { return fF2A(x); }
+
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax)
+        {
+            //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
+            fF2A = Interpolator(fmin, fmax, amin, amax);
+        }
+
+        virtual void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+};
+
+//--------------------------------------------------------------------------------------
+// Base class for ZoneControl
+//--------------------------------------------------------------------------------------
+class FAUST_API ZoneControl {
+
+    protected:
+
+        FAUSTFLOAT*    fZone;
+
+    public:
+
+        ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
+        virtual ~ZoneControl() {}
+
+        virtual void update(double /*v*/) const {}
+
+        virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/, double /*min*/, double /*init*/, double /*max*/) {}
+        virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
+
+        FAUSTFLOAT* getZone() { return fZone; }
+
+        virtual void setActive(bool /*on_off*/) {}
+        virtual bool getActive() { return false; }
+
+        virtual int getCurve() { return -1; }
+
+};
+
+//--------------------------------------------------------------------------------------
+//  Useful to implement accelerometers metadata as a list of ZoneControl for each axes
+//--------------------------------------------------------------------------------------
+class FAUST_API ConverterZoneControl : public ZoneControl {
+
+    protected:
+
+        ValueConverter* fValueConverter;
+
+    public:
+
+        ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* converter) : ZoneControl(zone), fValueConverter(converter) {}
+        virtual ~ConverterZoneControl() { delete fValueConverter; } // Assuming fValueConverter is not kept elsewhere...
+
+        virtual void update(double v) const { *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v)); }
+
+        ValueConverter* getConverter() { return fValueConverter; }
+
+};
+
+//--------------------------------------------------------------------------------------
+// Association of a zone and a four value converter, each one for each possible curve.
+// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
+//--------------------------------------------------------------------------------------
+class FAUST_API CurveZoneControl : public ZoneControl {
+
+    private:
+
+        std::vector<UpdatableValueConverter*> fValueConverters;
+        int fCurve;
+
+    public:
+
+        CurveZoneControl(FAUSTFLOAT* zone, int curve, double amin, double amid, double amax, double min, double init, double max) : ZoneControl(zone), fCurve(0)
+        {
+            assert(curve >= 0 && curve <= 3);
+            fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
+            fValueConverters.push_back(new AccDownConverter(amin, amid, amax, min, init, max));
+            fValueConverters.push_back(new AccUpDownConverter(amin, amid, amax, min, init, max));
+            fValueConverters.push_back(new AccDownUpConverter(amin, amid, amax, min, init, max));
+            fCurve = curve;
+        }
+        virtual ~CurveZoneControl()
+        {
+            for (const auto& it : fValueConverters) { delete it; }
+        }
+        void update(double v) const { if (fValueConverters[fCurve]->getActive()) *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v)); }
+
+        void setMappingValues(int curve, double amin, double amid, double amax, double min, double init, double max)
+        {
+            fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
+            fCurve = curve;
+        }
+
+        void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+        }
+
+        void setActive(bool on_off)
+        {
+            for (const auto& it : fValueConverters) { it->setActive(on_off); }
+        }
+
+        int getCurve() { return fCurve; }
+};
+
+class FAUST_API ZoneReader {
+
+    private:
+
+        FAUSTFLOAT* fZone;
+        Interpolator fInterpolator;
+
+    public:
+
+        ZoneReader(FAUSTFLOAT* zone, double lo, double hi) : fZone(zone), fInterpolator(lo, hi, 0, 255) {}
+
+        virtual ~ZoneReader() {}
+
+        int getValue()
+        {
+            return (fZone != nullptr) ? int(fInterpolator(*fZone)) : 127;
+        }
+
+};
+
+#endif
+/**************************  END  ValueConverter.h **************************/
+
+typedef unsigned int uint;
+
+class APIUI : public PathBuilder, public Meta, public UI
+{
+    public:
+        enum ItemType { kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph };
+        enum Type { kAcc = 0, kGyr = 1, kNoType };
+
+    protected:
+
+        enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+        struct Item {
+            std::string fLabel;
+            std::string fShortname;
+            std::string fPath;
+            ValueConverter* fConversion;
+            FAUSTFLOAT* fZone;
+            FAUSTFLOAT fInit;
+            FAUSTFLOAT fMin;
+            FAUSTFLOAT fMax;
+            FAUSTFLOAT fStep;
+            ItemType fItemType;
+            
+            Item(const std::string& label,
+                 const std::string& short_name,
+                 const std::string& path,
+                 ValueConverter* conversion,
+                 FAUSTFLOAT* zone,
+                 FAUSTFLOAT init,
+                 FAUSTFLOAT min,
+                 FAUSTFLOAT max,
+                 FAUSTFLOAT step,
+                 ItemType item_type)
+            :fLabel(label), fShortname(short_name), fPath(path), fConversion(conversion),
+            fZone(zone), fInit(init), fMin(min), fMax(max), fStep(step), fItemType(item_type)
+            {}
+        };
+        std::vector<Item> fItems;
+
+        std::vector<std::map<std::string, std::string> > fMetaData;
+        std::vector<ZoneControl*> fAcc[3];
+        std::vector<ZoneControl*> fGyr[3];
+
+        // Screen color control
+        // "...[screencolor:red]..." etc.
+        bool fHasScreenControl;      // true if control screen color metadata
+        ZoneReader* fRedReader;
+        ZoneReader* fGreenReader;
+        ZoneReader* fBlueReader;
+
+        // Current values controlled by metadata
+        std::string fCurrentUnit;
+        int fCurrentScale;
+        std::string fCurrentAcc;
+        std::string fCurrentGyr;
+        std::string fCurrentColor;
+        std::string fCurrentTooltip;
+        std::map<std::string, std::string> fCurrentMetadata;
+
+        // Add a generic parameter
+        virtual void addParameter(const char* label,
+                                  FAUSTFLOAT* zone,
+                                  FAUSTFLOAT init,
+                                  FAUSTFLOAT min,
+                                  FAUSTFLOAT max,
+                                  FAUSTFLOAT step,
+                                  ItemType type)
+        {
+            std::string path = buildPath(label);
+            fFullPaths.push_back(path);
+
+            // handle scale metadata
+            ValueConverter* converter = nullptr;
+            switch (fCurrentScale) {
+                case kLin:
+                    converter = new LinearValueConverter(0, 1, min, max);
+                    break;
+                case kLog:
+                    converter = new LogValueConverter(0, 1, min, max);
+                    break;
+                case kExp:
+                    converter = new ExpValueConverter(0, 1, min, max);
+                    break;
+            }
+            fCurrentScale = kLin;
+
+            fItems.push_back(Item(label, "", path, converter, zone, init, min, max, step, type));
+       
+            if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
+                fprintf(stderr, "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n", label);
+            }
+
+            // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
+            if (fCurrentAcc.size() > 0) {
+                std::istringstream iss(fCurrentAcc);
+                int axe, curve;
+                double amin, amid, amax;
+                iss >> axe >> curve >> amin >> amid >> amax;
+
+                if ((0 <= axe) && (axe < 3) &&
+                    (0 <= curve) && (curve < 4) &&
+                    (amin < amax) && (amin <= amid) && (amid <= amax))
+                {
+                    fAcc[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+                } else {
+                    fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
+                }
+                fCurrentAcc = "";
+            }
+
+            // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
+            if (fCurrentGyr.size() > 0) {
+                std::istringstream iss(fCurrentGyr);
+                int axe, curve;
+                double amin, amid, amax;
+                iss >> axe >> curve >> amin >> amid >> amax;
+
+                if ((0 <= axe) && (axe < 3) &&
+                    (0 <= curve) && (curve < 4) &&
+                    (amin < amax) && (amin <= amid) && (amid <= amax))
+                {
+                    fGyr[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+                } else {
+                    fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
+                }
+                fCurrentGyr = "";
+            }
+
+            // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
+            if (fCurrentColor.size() > 0) {
+                if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
+                    fRedReader = new ZoneReader(zone, min, max);
+                    fHasScreenControl = true;
+                } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
+                    fGreenReader = new ZoneReader(zone, min, max);
+                    fHasScreenControl = true;
+                } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
+                    fBlueReader = new ZoneReader(zone, min, max);
+                    fHasScreenControl = true;
+                } else if ((fCurrentColor == "white") && (fRedReader == nullptr) && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
+                    fRedReader = new ZoneReader(zone, min, max);
+                    fGreenReader = new ZoneReader(zone, min, max);
+                    fBlueReader = new ZoneReader(zone, min, max);
+                    fHasScreenControl = true;
+                } else {
+                    fprintf(stderr, "incorrect screencolor metadata : %s \n", fCurrentColor.c_str());
+                }
+            }
+            fCurrentColor = "";
+
+            fMetaData.push_back(fCurrentMetadata);
+            fCurrentMetadata.clear();
+        }
+
+        int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
+        {
+            FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+            for (size_t i = 0; i < table[val].size(); i++) {
+                if (zone == table[val][i]->getZone()) return int(i);
+            }
+            return -1;
+        }
+
+        void setConverter(std::vector<ZoneControl*>* table, int p, int val, int curve, double amin, double amid, double amax)
+        {
+            int id1 = getZoneIndex(table, p, 0);
+            int id2 = getZoneIndex(table, p, 1);
+            int id3 = getZoneIndex(table, p, 2);
+
+            // Deactivates everywhere..
+            if (id1 != -1) table[0][uint(id1)]->setActive(false);
+            if (id2 != -1) table[1][uint(id2)]->setActive(false);
+            if (id3 != -1) table[2][uint(id3)]->setActive(false);
+
+            if (val == -1) { // Means: no more mapping...
+                // So stay all deactivated...
+            } else {
+                int id4 = getZoneIndex(table, p, val);
+                if (id4 != -1) {
+                    // Reactivate the one we edit...
+                  table[val][uint(id4)]->setMappingValues(curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax);
+                  table[val][uint(id4)]->setActive(true);
+                } else {
+                    // Allocate a new CurveZoneControl which is 'active' by default
+                    FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+                    table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax));
+                }
+            }
+        }
+
+        void getConverter(std::vector<ZoneControl*>* table, int p, int& val, int& curve, double& amin, double& amid, double& amax)
+        {
+            int id1 = getZoneIndex(table, p, 0);
+            int id2 = getZoneIndex(table, p, 1);
+            int id3 = getZoneIndex(table, p, 2);
+
+            if (id1 != -1) {
+                val = 0;
+                curve = table[val][uint(id1)]->getCurve();
+                table[val][uint(id1)]->getMappingValues(amin, amid, amax);
+            } else if (id2 != -1) {
+                val = 1;
+                curve = table[val][uint(id2)]->getCurve();
+                table[val][uint(id2)]->getMappingValues(amin, amid, amax);
+            } else if (id3 != -1) {
+                val = 2;
+                curve = table[val][uint(id3)]->getCurve();
+                table[val][uint(id3)]->getMappingValues(amin, amid, amax);
+            } else {
+                val = -1; // No mapping
+                curve = 0;
+                amin = -100.;
+                amid = 0.;
+                amax = 100.;
+            }
+        }
+
+    public:
+
+        APIUI() : fHasScreenControl(false), fRedReader(nullptr), fGreenReader(nullptr), fBlueReader(nullptr), fCurrentScale(kLin)
+        {}
+
+        virtual ~APIUI()
+        {
+            for (const auto& it : fItems) delete it.fConversion;
+            for (int i = 0; i < 3; i++) {
+                for (const auto& it : fAcc[i]) delete it;
+                for (const auto& it : fGyr[i]) delete it;
+            }
+            delete fRedReader;
+            delete fGreenReader;
+            delete fBlueReader;
+        }
+
+        // -- widget's layouts
+
+        virtual void openTabBox(const char* label) { pushLabel(label); }
+        virtual void openHorizontalBox(const char* label) { pushLabel(label); }
+        virtual void openVerticalBox(const char* label) { pushLabel(label); }
+        virtual void closeBox()
+        {
+            if (popLabel()) {
+                // Shortnames can be computed when all fullnames are known
+                computeShortNames();
+                // Fill 'shortname' field for each item
+                for (const auto& it : fFull2Short) {
+                    int index = getParamIndex(it.first.c_str());
+                    fItems[index].fShortname = it.second;
+                }
+            }
+        }
+
+        // -- active widgets
+
+        virtual void addButton(const char* label, FAUSTFLOAT* zone)
+        {
+            addParameter(label, zone, 0, 0, 1, 1, kButton);
+        }
+
+        virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+        {
+            addParameter(label, zone, 0, 0, 1, 1, kCheckButton);
+        }
+
+        virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addParameter(label, zone, init, min, max, step, kVSlider);
+        }
+
+        virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addParameter(label, zone, init, min, max, step, kHSlider);
+        }
+
+        virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addParameter(label, zone, init, min, max, step, kNumEntry);
+        }
+
+        // -- passive widgets
+
+        virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        {
+            addParameter(label, zone, min, min, max, (max-min)/1000.0f, kHBargraph);
+        }
+
+        virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        {
+            addParameter(label, zone, min, min, max, (max-min)/1000.0f, kVBargraph);
+        }
+
+        // -- soundfiles
+
+        virtual void addSoundfile(const char* /*label*/, const char* /*filename*/, Soundfile** /*sf_zone*/) {}
+
+        // -- metadata declarations
+
+        virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
+        {
+            // Keep metadata
+            fCurrentMetadata[key] = val;
+
+            if (strcmp(key, "scale") == 0) {
+                if (strcmp(val, "log") == 0) {
+                    fCurrentScale = kLog;
+                } else if (strcmp(val, "exp") == 0) {
+                    fCurrentScale = kExp;
+                } else {
+                    fCurrentScale = kLin;
+                }
+            } else if (strcmp(key, "unit") == 0) {
+                fCurrentUnit = val;
+            } else if (strcmp(key, "acc") == 0) {
+                fCurrentAcc = val;
+            } else if (strcmp(key, "gyr") == 0) {
+                fCurrentGyr = val;
+            } else if (strcmp(key, "screencolor") == 0) {
+                fCurrentColor = val; // val = "red", "green", "blue" or "white"
+            } else if (strcmp(key, "tooltip") == 0) {
+                fCurrentTooltip = val;
+            }
+        }
+
+        virtual void declare(const char* /*key*/, const char* /*val*/)
+        {}
+
+        //-------------------------------------------------------------------------------
+        // Simple API part
+        //-------------------------------------------------------------------------------
+    
+        /**
+         * Return the number of parameters in the UI.
+         *
+         * @return the number of parameters
+         */
+        int getParamsCount() { return int(fItems.size()); }
+
+        /**
+         * Return the param index.
+         *
+         * @param str - the UI parameter label/shortname/path
+         *
+         * @return the param index
+         */
+        int getParamIndex(const char* str)
+        {
+            std::string path = std::string(str);
+            auto it = find_if(fItems.begin(), fItems.end(),
+                              [=](const Item& it) { return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path); });
+            return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
+        }
+    
+        /**
+         * Return the param label.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the param label
+         */
+        const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
+    
+        /**
+         * Return the param shortname.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the param shortname
+         */
+        const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
+    
+        /**
+         * Return the param path.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the param path
+         */
+        const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+    
+        /**
+         * Return the param metadata.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the param metadata as a map<key, value>
+         */
+        std::map<const char*, const char*> getMetadata(int p)
+        {
+            std::map<const char*, const char*> res;
+            std::map<std::string, std::string> metadata = fMetaData[uint(p)];
+            for (const auto& it : metadata) {
+                res[it.first.c_str()] = it.second.c_str();
+            }
+            return res;
+        }
+
+        /**
+         * Return the param metadata value.
+         *
+         * @param p - the UI parameter index
+         * @param key - the UI parameter index
+         *
+         * @return the param metadata value associate to the key
+         */
+        const char* getMetadata(int p, const char* key)
+        {
+            return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end()) ? fMetaData[uint(p)][key].c_str() : "";
+        }
+    
+        /**
+         * Return the param minimum value.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the param minimum value
+         */
+        FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
+    
+        /**
+         * Return the param maximum value.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the param maximum value
+         */
+        FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
+    
+        /**
+         * Return the param step value.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the param step value
+         */
+        FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
+    
+        /**
+         * Return the param init value.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the param init value
+         */
+        FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
+
+        /**
+         * Return the param memory zone.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the param memory zone.
+         */
+        FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
+
+        /**
+         * Return the param value.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the param value.
+         */
+        FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
+    
+        /**
+         * Return the param value.
+         *
+         * @param str - the UI parameter label/shortname/path
+         *
+         * @return the param value.
+         */
+        FAUSTFLOAT getParamValue(const char* str)
+        {
+            int index = getParamIndex(str);
+            if (index >= 0) {
+                return getParamValue(index);
+            } else {
+                fprintf(stderr, "getParamValue : '%s' not found\n", (str == nullptr ? "NULL" : str));
+                return FAUSTFLOAT(0);
+            }
+        }
+
+        /**
+         * Set the param value.
+         *
+         * @param p - the UI parameter index
+         * @param v - the UI parameter value
+         *
+         */
+        void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+        
+        /**
+         * Set the param value.
+         *
+         * @param p - the UI parameter label/shortname/path
+         * @param v - the UI parameter value
+         *
+         */
+        void setParamValue(const char* path, FAUSTFLOAT v)
+        {
+            int index = getParamIndex(path);
+            if (index >= 0) {
+                setParamValue(index, v);
+            } else {
+                fprintf(stderr, "setParamValue : '%s' not found\n", (path == nullptr ? "NULL" : path));
+            }
+        }
+
+        double getParamRatio(int p) { return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone); }
+        void setParamRatio(int p, double r) { *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r)); }
+
+        double value2ratio(int p, double r)    { return fItems[uint(p)].fConversion->faust2ui(r); }
+        double ratio2value(int p, double r)    { return fItems[uint(p)].fConversion->ui2faust(r); }
+
+        /**
+         * Return the control type (kAcc, kGyr, or -1) for a given parameter.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the type
+         */
+        Type getParamType(int p)
+        {
+            if (p >= 0) {
+                if (getZoneIndex(fAcc, p, 0) != -1
+                    || getZoneIndex(fAcc, p, 1) != -1
+                    || getZoneIndex(fAcc, p, 2) != -1) {
+                    return kAcc;
+                } else if (getZoneIndex(fGyr, p, 0) != -1
+                           || getZoneIndex(fGyr, p, 1) != -1
+                           || getZoneIndex(fGyr, p, 2) != -1) {
+                    return kGyr;
+                }
+            }
+            return kNoType;
+        }
+
+        /**
+         * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph) for a given parameter.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the Item type
+         */
+        ItemType getParamItemType(int p)
+        {
+            return fItems[uint(p)].fItemType;
+        }
+
+        /**
+         * Set a new value coming from an accelerometer, propagate it to all relevant FAUSTFLOAT* zones.
+         *
+         * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+         * @param value - the new value
+         *
+         */
+        void propagateAcc(int acc, double value)
+        {
+            for (size_t i = 0; i < fAcc[acc].size(); i++) {
+                fAcc[acc][i]->update(value);
+            }
+        }
+
+        /**
+         * Used to edit accelerometer curves and mapping. Set curve and related mapping for a given UI parameter.
+         *
+         * @param p - the UI parameter index
+         * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer (-1 means "no mapping")
+         * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
+         * @param amin - mapping 'min' point
+         * @param amid - mapping 'middle' point
+         * @param amax - mapping 'max' point
+         *
+         */
+        void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
+        {
+            setConverter(fAcc, p, acc, curve, amin, amid, amax);
+        }
+
+        /**
+         * Used to edit gyroscope curves and mapping. Set curve and related mapping for a given UI parameter.
+         *
+         * @param p - the UI parameter index
+         * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no mapping")
+         * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
+         * @param amin - mapping 'min' point
+         * @param amid - mapping 'middle' point
+         * @param amax - mapping 'max' point
+         *
+         */
+        void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax)
+        {
+            setConverter(fGyr, p, gyr, curve, amin, amid, amax);
+        }
+
+        /**
+         * Used to edit accelerometer curves and mapping. Get curve and related mapping for a given UI parameter.
+         *
+         * @param p - the UI parameter index
+         * @param acc - the acc value to be retrieved (-1 means "no mapping")
+         * @param curve - the curve value to be retrieved (between 0 and 3)
+         * @param amin - the amin value to be retrieved
+         * @param amid - the amid value to be retrieved
+         * @param amax - the amax value to be retrieved
+         *
+         */
+        void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid, double& amax)
+        {
+            getConverter(fAcc, p, acc, curve, amin, amid, amax);
+        }
+
+        /**
+         * Used to edit gyroscope curves and mapping. Get curve and related mapping for a given UI parameter.
+         *
+         * @param p - the UI parameter index
+         * @param gyr - the gyr value to be retrieved (-1 means "no mapping")
+         * @param curve - the curve value to be retrieved (between 0 and 3)
+         * @param amin - the amin value to be retrieved
+         * @param amid - the amid value to be retrieved
+         * @param amax - the amax value to be retrieved
+         *
+         */
+        void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid, double& amax)
+        {
+            getConverter(fGyr, p, gyr, curve, amin, amid, amax);
+        }
+
+        /**
+         * Set a new value coming from an gyroscope, propagate it to all relevant FAUSTFLOAT* zones.
+         *
+         * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+         * @param value - the new value
+         *
+         */
+        void propagateGyr(int gyr, double value)
+        {
+            for (size_t i = 0; i < fGyr[gyr].size(); i++) {
+                fGyr[gyr][i]->update(value);
+            }
+        }
+
+        /**
+         * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
+         *
+         * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+         * @return the number of zones
+         *
+         */
+        int getAccCount(int acc)
+        {
+            return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0;
+        }
+
+        /**
+         * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
+         *
+         * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+         * @param the number of zones
+         *
+         */
+        int getGyrCount(int gyr)
+        {
+            return (gyr >= 0 && gyr < 3) ? int(fGyr[gyr].size()) : 0;
+        }
+
+        /**
+         * Get the requested screen color.
+         *
+         * -1 means no screen color control (no screencolor metadata found)
+         * otherwise return 0x00RRGGBB a ready to use color
+         *
+         */
+        int getScreenColor()
+        {
+            if (fHasScreenControl) {
+                int r = (fRedReader) ? fRedReader->getValue() : 0;
+                int g = (fGreenReader) ? fGreenReader->getValue() : 0;
+                int b = (fBlueReader) ? fBlueReader->getValue() : 0;
+                return (r<<16) | (g<<8) | b;
+            } else {
+                return -1;
+            }
+        }
+
+};
+
+#endif
+/**************************  END  APIUI.h **************************/
+
+// NOTE: "faust -scn name" changes the last line above to
+// #include <faust/name/name.h>
+
+//----------------------------------------------------------------------------
+//  FAUST Generated Code
+//----------------------------------------------------------------------------
+
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif 
+
+#include <algorithm>
+#include <cmath>
+#include <cstdint>
+#include <math.h>
+
+#ifndef FAUSTCLASS 
+#define FAUSTCLASS tonedsp
+#endif
+
+#ifdef __APPLE__ 
+#define exp10f __exp10f
+#define exp10 __exp10
+#endif
+
+#if defined(_WIN32)
+#define RESTRICT __restrict
+#else
+#define RESTRICT __restrict__
+#endif
+
+class tonedspSIG0 {
+       
+  private:
+       
+       int iVec0[2];
+       int iRec0[2];
+       
+  public:
+       
+       int getNumInputstonedspSIG0() {
+               return 0;
+       }
+       int getNumOutputstonedspSIG0() {
+               return 1;
+       }
+       
+       void instanceInittonedspSIG0(int /*sample_rate*/) {
+               for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
+                       iVec0[l0] = 0;
+               }
+               for (int l1 = 0; l1 < 2; l1 = l1 + 1) {
+                       iRec0[l1] = 0;
+               }
+       }
+       
+       void filltonedspSIG0(int count, float* table) {
+               for (int i1 = 0; i1 < count; i1 = i1 + 1) {
+                       iVec0[0] = 1;
+                       iRec0[0] = (iVec0[1] + iRec0[1]) % 65536;
+                       table[i1] = std::sin(9.58738e-05f * float(iRec0[0]));
+                       iVec0[1] = iVec0[0];
+                       iRec0[1] = iRec0[0];
+               }
+       }
+
+};
+
+static tonedspSIG0* newtonedspSIG0() { return (tonedspSIG0*)new tonedspSIG0(); }
+static void deletetonedspSIG0(tonedspSIG0* dsp) { delete dsp; }
+
+static float ftbl0tonedspSIG0[65536];
+
+class tonedsp : public dsp {
+       
+ private:
+       
+       int fSampleRate;
+       float fConst0;
+       float fConst1;
+       FAUSTFLOAT fHslider0;
+       FAUSTFLOAT fHslider1;
+       float fRec1[2];
+       float fConst2;
+       float fConst3;
+       FAUSTFLOAT fButton0;
+       float fVec1[2];
+       int iRec2[2];
+       float fConst4;
+       FAUSTFLOAT fHslider2;
+       float fConst5;
+       float fRec3[2];
+       float fRec4[2];
+       float fConst6;
+       float fRec5[2];
+       float fConst7;
+       float fRec6[2];
+       float fConst8;
+       float fRec7[2];
+       float fConst9;
+       float fRec8[2];
+       float fConst10;
+       
+ public:
+       
+       void metadata(Meta* m) { 
+               m->declare("basics.lib/name", "Faust Basic Element Library");
+               m->declare("basics.lib/version", "0.8");
+               m->declare("compile_options", "-a faust2header.cpp -lang cpp -i -inpl -cn tonedsp -es 1 -mcd 16 -single -ftz 0");
+               m->declare("envelopes.lib/ar:author", "Yann Orlarey, Stéphane Letz");
+               m->declare("envelopes.lib/author", "GRAME");
+               m->declare("envelopes.lib/copyright", "GRAME");
+               m->declare("envelopes.lib/license", "LGPL with exception");
+               m->declare("envelopes.lib/name", "Faust Envelope Library");
+               m->declare("envelopes.lib/version", "0.2");
+               m->declare("filename", "tonedsp.dsp");
+               m->declare("maths.lib/author", "GRAME");
+               m->declare("maths.lib/copyright", "GRAME");
+               m->declare("maths.lib/license", "LGPL with exception");
+               m->declare("maths.lib/name", "Faust Math Library");
+               m->declare("maths.lib/version", "2.5");
+               m->declare("name", "tonedsp");
+               m->declare("oscillators.lib/name", "Faust Oscillator Library");
+               m->declare("oscillators.lib/version", "0.3");
+               m->declare("platform.lib/name", "Generic Platform Library");
+               m->declare("platform.lib/version", "0.2");
+               m->declare("signals.lib/name", "Faust Signal Routing Library");
+               m->declare("signals.lib/version", "0.3");
+               m->declare("synths.lib/additiveDrum:author", "Romain Michon");
+               m->declare("synths.lib/name", "Faust Synthesizer Library");
+               m->declare("synths.lib/version", "0.1");
+       }
+
+       virtual int getNumInputs() {
+               return 0;
+       }
+       virtual int getNumOutputs() {
+               return 1;
+       }
+       
+       static void classInit(int sample_rate) {
+               tonedspSIG0* sig0 = newtonedspSIG0();
+               sig0->instanceInittonedspSIG0(sample_rate);
+               sig0->filltonedspSIG0(65536, ftbl0tonedspSIG0);
+               deletetonedspSIG0(sig0);
+       }
+       
+       virtual void instanceConstants(int sample_rate) {
+               fSampleRate = sample_rate;
+               fConst0 = std::min<float>(1.92e+05f, std::max<float>(1.0f, float(fSampleRate)));
+               fConst1 = 1.0f / fConst0;
+               fConst2 = std::max<float>(1.0f, 0.001f * fConst0);
+               fConst3 = 1.0f / fConst2;
+               fConst4 = 44.1f / fConst0;
+               fConst5 = 1.0f - fConst4;
+               fConst6 = 0.8666667f * fConst0;
+               fConst7 = 0.73333335f * fConst0;
+               fConst8 = 0.6f * fConst0;
+               fConst9 = 0.46666667f * fConst0;
+               fConst10 = 0.33333334f * fConst0;
+       }
+       
+       virtual void instanceResetUserInterface() {
+               fHslider0 = FAUSTFLOAT(4e+02f);
+               fHslider1 = FAUSTFLOAT(0.0f);
+               fButton0 = FAUSTFLOAT(0.0f);
+               fHslider2 = FAUSTFLOAT(2.5f);
+       }
+       
+       virtual void instanceClear() {
+               for (int l2 = 0; l2 < 2; l2 = l2 + 1) {
+                       fRec1[l2] = 0.0f;
+               }
+               for (int l3 = 0; l3 < 2; l3 = l3 + 1) {
+                       fVec1[l3] = 0.0f;
+               }
+               for (int l4 = 0; l4 < 2; l4 = l4 + 1) {
+                       iRec2[l4] = 0;
+               }
+               for (int l5 = 0; l5 < 2; l5 = l5 + 1) {
+                       fRec3[l5] = 0.0f;
+               }
+               for (int l6 = 0; l6 < 2; l6 = l6 + 1) {
+                       fRec4[l6] = 0.0f;
+               }
+               for (int l7 = 0; l7 < 2; l7 = l7 + 1) {
+                       fRec5[l7] = 0.0f;
+               }
+               for (int l8 = 0; l8 < 2; l8 = l8 + 1) {
+                       fRec6[l8] = 0.0f;
+               }
+               for (int l9 = 0; l9 < 2; l9 = l9 + 1) {
+                       fRec7[l9] = 0.0f;
+               }
+               for (int l10 = 0; l10 < 2; l10 = l10 + 1) {
+                       fRec8[l10] = 0.0f;
+               }
+       }
+       
+       virtual void init(int sample_rate) {
+               classInit(sample_rate);
+               instanceInit(sample_rate);
+       }
+       virtual void instanceInit(int sample_rate) {
+               instanceConstants(sample_rate);
+               instanceResetUserInterface();
+               instanceClear();
+       }
+       
+       virtual tonedsp* clone() {
+               return new tonedsp();
+       }
+       
+       virtual int getSampleRate() {
+               return fSampleRate;
+       }
+       
+       virtual void buildUserInterface(UI* ui_interface) {
+               ui_interface->openVerticalBox("tonedsp");
+               ui_interface->addHorizontalSlider("freq", &fHslider0, FAUSTFLOAT(4e+02f), FAUSTFLOAT(5e+01f), FAUSTFLOAT(2e+03f), FAUSTFLOAT(0.01f));
+               ui_interface->addButton("gate", &fButton0);
+               ui_interface->declare(&fHslider2, "acc", "0 0 -10 0 10");
+               ui_interface->addHorizontalSlider("res", &fHslider2, FAUSTFLOAT(2.5f), FAUSTFLOAT(0.01f), FAUSTFLOAT(5.0f), FAUSTFLOAT(0.01f));
+               ui_interface->addHorizontalSlider("y", &fHslider1, FAUSTFLOAT(0.0f), FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f), FAUSTFLOAT(0.01f));
+               ui_interface->closeBox();
+       }
+       
+       virtual void compute(int count, FAUSTFLOAT** /*inputs*/, FAUSTFLOAT** outputs) {
+               FAUSTFLOAT* output0 = outputs[0];
+               float fSlow0 = float(fHslider0);
+               float fSlow1 = float(fHslider1);
+               float fSlow2 = fConst1 * fSlow0 * (0.8333333f * fSlow1 + 1.0f);
+               float fSlow3 = float(fButton0);
+               float fSlow4 = fConst4 * float(fHslider2);
+               float fSlow5 = fConst1 * fSlow0 * (1.6666666f * fSlow1 + 1.0f);
+               float fSlow6 = fConst1 * fSlow0 * (2.5f * fSlow1 + 1.0f);
+               float fSlow7 = fConst1 * fSlow0 * (3.3333333f * fSlow1 + 1.0f);
+               float fSlow8 = fConst1 * fSlow0 * (4.1666665f * fSlow1 + 1.0f);
+               float fSlow9 = fConst1 * fSlow0 * (5.0f * fSlow1 + 1.0f);
+               for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+                       fRec1[0] = fSlow2 + (fRec1[1] - std::floor(fSlow2 + fRec1[1]));
+                       fVec1[0] = fSlow3;
+                       iRec2[0] = (iRec2[1] + (iRec2[1] > 0)) * (fSlow3 <= fVec1[1]) + (fSlow3 > fVec1[1]);
+                       float fTemp0 = float(iRec2[0]);
+                       float fTemp1 = fConst3 * fTemp0;
+                       float fTemp2 = fConst2 - fTemp0;
+                       fRec3[0] = fSlow4 + fConst5 * fRec3[1];
+                       fRec4[0] = fSlow5 + (fRec4[1] - std::floor(fSlow5 + fRec4[1]));
+                       fRec5[0] = fSlow6 + (fRec5[1] - std::floor(fSlow6 + fRec5[1]));
+                       fRec6[0] = fSlow7 + (fRec6[1] - std::floor(fSlow7 + fRec6[1]));
+                       fRec7[0] = fSlow8 + (fRec7[1] - std::floor(fSlow8 + fRec7[1]));
+                       fRec8[0] = fSlow9 + (fRec8[1] - std::floor(fSlow9 + fRec8[1]));
+                       output0[i0] = FAUSTFLOAT(0.05f * (0.44444445f * ftbl0tonedspSIG0[int(65536.0f * fRec1[0])] * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst0 * fRec3[0]) + 1.0f)) + ftbl0tonedspSIG0[int(65536.0f * fRec4[0])] * (0.0f - 0.11111111f * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst6 * fRec3[0]) + 1.0f))) + ftbl0tonedspSIG0[int(65536.0f * fRec5[0])] * (0.0f - 0.6666667f * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst7 * fRec3[0]) + 1.0f))) + ftbl0tonedspSIG0[int(65536.0f * fRec6[0])] * (0.0f - 1.2222222f * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst8 * fRec3[0]) + 1.0f))) + ftbl0tonedspSIG0[int(65536.0f * fRec7[0])] * (0.0f - 1.7777778f * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst9 * fRec3[0]) + 1.0f))) + ftbl0tonedspSIG0[int(65536.0f * fRec8[0])] * (0.0f - 2.3333333f * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst10 * fRec3[0]) + 1.0f)))));
+                       fRec1[1] = fRec1[0];
+                       fVec1[1] = fVec1[0];
+                       iRec2[1] = iRec2[0];
+                       fRec3[1] = fRec3[0];
+                       fRec4[1] = fRec4[0];
+                       fRec5[1] = fRec5[0];
+                       fRec6[1] = fRec6[0];
+                       fRec7[1] = fRec7[0];
+                       fRec8[1] = fRec8[0];
+               }
+       }
+
+};
+
+
+#endif
diff --git a/src/volumedsp.h b/src/volumedsp.h
new file mode 100644 (file)
index 0000000..f3df212
--- /dev/null
@@ -0,0 +1,1986 @@
+/* ------------------------------------------------------------
+author: "Matt Horton, adapted from GRAME"
+license: "MIT Style STK-4.2"
+name: "volume"
+version: "1.0"
+Code generated with Faust 2.41.1 (https://faust.grame.fr)
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn volumedsp -es 1 -mcd 16 -single -ftz 0
+------------------------------------------------------------ */
+
+#ifndef  __volumedsp_H__
+#define  __volumedsp_H__
+
+// NOTE: ANY INCLUDE-GUARD HERE MUST BE DERIVED FROM THE CLASS NAME
+//
+// faust2header.cpp - FAUST Architecture File
+// This is a simple variation of matlabplot.cpp in the Faust distribution
+// aimed at creating a simple C++ header file (.h) containing a Faust DSP.
+// See the Makefile for how to use it.
+
+/************************** BEGIN dsp.h ********************************
+ FAUST Architecture File
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ ************************************************************************/
+
+#ifndef __dsp__
+#define __dsp__
+
+#include <string>
+#include <vector>
+
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __export__
+#define __export__
+
+#define FAUSTVERSION "2.41.1"
+
+// Use FAUST_API for code that is part of the external API but is also compiled in faust and libfaust
+// Use LIBFAUST_API for code that is compiled in faust and libfaust
+
+#ifdef _WIN32
+    #pragma warning (disable: 4251)
+    #ifdef FAUST_EXE
+        #define FAUST_API
+        #define LIBFAUST_API
+    #elif FAUST_LIB
+        #define FAUST_API __declspec(dllexport)
+        #define LIBFAUST_API __declspec(dllexport)
+    #else
+        #define FAUST_API
+        #define LIBFAUST_API 
+    #endif
+#else
+    #ifdef FAUST_EXE
+        #define FAUST_API
+        #define LIBFAUST_API
+    #else
+        #define FAUST_API __attribute__((visibility("default")))
+        #define LIBFAUST_API __attribute__((visibility("default")))
+    #endif
+#endif
+
+#endif
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+struct FAUST_API UI;
+struct FAUST_API Meta;
+
+/**
+ * DSP memory manager.
+ */
+
+struct FAUST_API dsp_memory_manager {
+    
+    virtual ~dsp_memory_manager() {}
+    
+    /**
+     * Inform the Memory Manager with the number of expected memory zones.
+     * @param count - the number of expected memory zones
+     */
+    virtual void begin(size_t /*count*/) {}
+    
+    /**
+     * Give the Memory Manager information on a given memory zone.
+     * @param size - the size in bytes of the memory zone
+     * @param reads - the number of Read access to the zone used to compute one frame
+     * @param writes - the number of Write access to the zone used to compute one frame
+     */
+    virtual void info(size_t /*size*/, size_t /*reads*/, size_t /*writes*/) {}
+    
+    /**
+     * Inform the Memory Manager that all memory zones have been described,
+     * to possibly start a 'compute the best allocation strategy' step.
+     */
+    virtual void end() {}
+    
+    /**
+     * Allocate a memory zone.
+     * @param size - the memory zone size in bytes
+     */
+    virtual void* allocate(size_t size) = 0;
+    
+    /**
+     * Destroy a memory zone.
+     * @param ptr - the memory zone pointer to be deallocated
+     */
+    virtual void destroy(void* ptr) = 0;
+    
+};
+
+/**
+* Signal processor definition.
+*/
+
+class FAUST_API dsp {
+
+    public:
+
+        dsp() {}
+        virtual ~dsp() {}
+
+        /* Return instance number of audio inputs */
+        virtual int getNumInputs() = 0;
+    
+        /* Return instance number of audio outputs */
+        virtual int getNumOutputs() = 0;
+    
+        /**
+         * Trigger the ui_interface parameter with instance specific calls
+         * to 'openTabBox', 'addButton', 'addVerticalSlider'... in order to build the UI.
+         *
+         * @param ui_interface - the user interface builder
+         */
+        virtual void buildUserInterface(UI* ui_interface) = 0;
+    
+        /* Return the sample rate currently used by the instance */
+        virtual int getSampleRate() = 0;
+    
+        /**
+         * Global init, calls the following methods:
+         * - static class 'classInit': static tables initialization
+         * - 'instanceInit': constants and instance state initialization
+         *
+         * @param sample_rate - the sampling rate in Hz
+         */
+        virtual void init(int sample_rate) = 0;
+
+        /**
+         * Init instance state
+         *
+         * @param sample_rate - the sampling rate in Hz
+         */
+        virtual void instanceInit(int sample_rate) = 0;
+    
+        /**
+         * Init instance constant state
+         *
+         * @param sample_rate - the sampling rate in Hz
+         */
+        virtual void instanceConstants(int sample_rate) = 0;
+    
+        /* Init default control parameters values */
+        virtual void instanceResetUserInterface() = 0;
+    
+        /* Init instance state (like delay lines...) but keep the control parameter values */
+        virtual void instanceClear() = 0;
+        /**
+         * Return a clone of the instance.
+         *
+         * @return a copy of the instance on success, otherwise a null pointer.
+         */
+        virtual dsp* clone() = 0;
+    
+        /**
+         * Trigger the Meta* parameter with instance specific calls to 'declare' (key, value) metadata.
+         *
+         * @param m - the Meta* meta user
+         */
+        virtual void metadata(Meta* m) = 0;
+    
+        /**
+         * DSP instance computation, to be called with successive in/out audio buffers.
+         *
+         * @param count - the number of frames to compute
+         * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
+         * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
+         *
+         */
+        virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
+    
+        /**
+         * DSP instance computation: alternative method to be used by subclasses.
+         *
+         * @param date_usec - the timestamp in microsec given by audio driver.
+         * @param count - the number of frames to compute
+         * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
+         * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
+         *
+         */
+        virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { compute(count, inputs, outputs); }
+       
+};
+
+/**
+ * Generic DSP decorator.
+ */
+
+class FAUST_API decorator_dsp : public dsp {
+
+    protected:
+
+        dsp* fDSP;
+
+    public:
+
+        decorator_dsp(dsp* dsp = nullptr):fDSP(dsp) {}
+        virtual ~decorator_dsp() { delete fDSP; }
+
+        virtual int getNumInputs() { return fDSP->getNumInputs(); }
+        virtual int getNumOutputs() { return fDSP->getNumOutputs(); }
+        virtual void buildUserInterface(UI* ui_interface) { fDSP->buildUserInterface(ui_interface); }
+        virtual int getSampleRate() { return fDSP->getSampleRate(); }
+        virtual void init(int sample_rate) { fDSP->init(sample_rate); }
+        virtual void instanceInit(int sample_rate) { fDSP->instanceInit(sample_rate); }
+        virtual void instanceConstants(int sample_rate) { fDSP->instanceConstants(sample_rate); }
+        virtual void instanceResetUserInterface() { fDSP->instanceResetUserInterface(); }
+        virtual void instanceClear() { fDSP->instanceClear(); }
+        virtual decorator_dsp* clone() { return new decorator_dsp(fDSP->clone()); }
+        virtual void metadata(Meta* m) { fDSP->metadata(m); }
+        // Beware: subclasses usually have to overload the two 'compute' methods
+        virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(count, inputs, outputs); }
+        virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(date_usec, count, inputs, outputs); }
+    
+};
+
+/**
+ * DSP factory class, used with LLVM and Interpreter backends
+ * to create DSP instances from a compiled DSP program.
+ */
+
+class FAUST_API dsp_factory {
+    
+    protected:
+    
+        // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
+        virtual ~dsp_factory() {}
+    
+    public:
+    
+        virtual std::string getName() = 0;
+        virtual std::string getSHAKey() = 0;
+        virtual std::string getDSPCode() = 0;
+        virtual std::string getCompileOptions() = 0;
+        virtual std::vector<std::string> getLibraryList() = 0;
+        virtual std::vector<std::string> getIncludePathnames() = 0;
+    
+        virtual dsp* createDSPInstance() = 0;
+    
+        virtual void setMemoryManager(dsp_memory_manager* manager) = 0;
+        virtual dsp_memory_manager* getMemoryManager() = 0;
+    
+};
+
+// Denormal handling
+
+#if defined (__SSE__)
+#include <xmmintrin.h>
+#endif
+
+class FAUST_API ScopedNoDenormals {
+    
+    private:
+    
+        intptr_t fpsr;
+        
+        void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+        {
+        #if defined (__arm64__) || defined (__aarch64__)
+           asm volatile("msr fpcr, %0" : : "ri" (fpsr_aux));
+        #elif defined (__SSE__)
+            _mm_setcsr(static_cast<uint32_t>(fpsr_aux));
+        #endif
+        }
+        
+        void getFpStatusRegister() noexcept
+        {
+        #if defined (__arm64__) || defined (__aarch64__)
+            asm volatile("mrs %0, fpcr" : "=r" (fpsr));
+        #elif defined ( __SSE__)
+            fpsr = static_cast<intptr_t>(_mm_getcsr());
+        #endif
+        }
+    
+    public:
+    
+        ScopedNoDenormals() noexcept
+        {
+        #if defined (__arm64__) || defined (__aarch64__)
+            intptr_t mask = (1 << 24 /* FZ */);
+        #else
+            #if defined(__SSE__)
+            #if defined(__SSE2__)
+                intptr_t mask = 0x8040;
+            #else
+                intptr_t mask = 0x8000;
+            #endif
+            #else
+                intptr_t mask = 0x0000;
+            #endif
+        #endif
+            getFpStatusRegister();
+            setFpStatusRegister(fpsr | mask);
+        }
+        
+        ~ScopedNoDenormals() noexcept
+        {
+            setFpStatusRegister(fpsr);
+        }
+
+};
+
+#define AVOIDDENORMALS ScopedNoDenormals();
+
+#endif
+
+/************************** END dsp.h **************************/
+/************************** BEGIN APIUI.h *****************************
+FAUST Architecture File
+Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+---------------------------------------------------------------------
+This program 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 program 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 program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+EXCEPTION : As a special exception, you may create a larger work
+that contains this FAUST architecture section and distribute
+that work under terms of your choice, so long as this FAUST
+architecture section is not modified.
+************************************************************************/
+
+#ifndef API_UI_H
+#define API_UI_H
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <stdio.h>
+#include <map>
+
+/************************** BEGIN meta.h *******************************
+ FAUST Architecture File
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ ************************************************************************/
+
+#ifndef __meta__
+#define __meta__
+
+
+/**
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve (key, value) metadata.
+ */
+struct FAUST_API Meta {
+    virtual ~Meta() {}
+    virtual void declare(const char* key, const char* value) = 0;
+};
+
+#endif
+/**************************  END  meta.h **************************/
+/************************** BEGIN UI.h *****************************
+ FAUST Architecture File
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ ********************************************************************/
+
+#ifndef __UI_H__
+#define __UI_H__
+
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif
+
+/*******************************************************************************
+ * UI : Faust DSP User Interface
+ * User Interface as expected by the buildUserInterface() method of a DSP.
+ * This abstract class contains only the method that the Faust compiler can
+ * generate to describe a DSP user interface.
+ ******************************************************************************/
+
+struct Soundfile;
+
+template <typename REAL>
+struct FAUST_API UIReal {
+    
+    UIReal() {}
+    virtual ~UIReal() {}
+    
+    // -- widget's layouts
+    
+    virtual void openTabBox(const char* label) = 0;
+    virtual void openHorizontalBox(const char* label) = 0;
+    virtual void openVerticalBox(const char* label) = 0;
+    virtual void closeBox() = 0;
+    
+    // -- active widgets
+    
+    virtual void addButton(const char* label, REAL* zone) = 0;
+    virtual void addCheckButton(const char* label, REAL* zone) = 0;
+    virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
+    virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
+    virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
+    
+    // -- passive widgets
+    
+    virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
+    virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
+    
+    // -- soundfiles
+    
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/, Soundfile** /*sf_zone*/) = 0;
+    
+    // -- metadata declarations
+    
+    virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
+    
+    // To be used by LLVM client
+    virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
+};
+
+struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
+    UI() {}
+    virtual ~UI() {}
+};
+
+#endif
+/**************************  END  UI.h **************************/
+/************************** BEGIN PathBuilder.h **************************
+ FAUST Architecture File
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ ************************************************************************/
+
+#ifndef __PathBuilder__
+#define __PathBuilder__
+
+#include <vector>
+#include <set>
+#include <map>
+#include <string>
+#include <algorithm>
+#include <regex>
+
+
+/*******************************************************************************
+ * PathBuilder : Faust User Interface
+ * Helper class to build complete hierarchical path for UI items.
+ ******************************************************************************/
+
+class FAUST_API PathBuilder {
+
+    protected:
+    
+        std::vector<std::string> fControlsLevel;
+        std::vector<std::string> fFullPaths;
+        std::map<std::string, std::string> fFull2Short;  // filled by computeShortNames()
+    
+        /**
+         * @brief check if a character is acceptable for an ID
+         *
+         * @param c
+         * @return true is the character is acceptable for an ID
+         */
+        bool isIDChar(char c) const
+        {
+            return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9'));
+        }
+    
+        /**
+         * @brief remove all "/0x00" parts
+         *
+         * @param src
+         * @return modified string
+         */
+        std::string remove0x00(const std::string& src) const
+        {
+            return std::regex_replace(src, std::regex("/0x00"), "");
+        }
+    
+        /**
+         * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+         *
+         * @param src
+         * @return modified string
+         */
+        std::string str2ID(const std::string& src) const
+        {
+            std::string dst;
+            bool need_underscore = false;
+            for (char c : src) {
+                if (isIDChar(c) || (c == '/')) {
+                    if (need_underscore) {
+                        dst.push_back('_');
+                        need_underscore = false;
+                    }
+                    dst.push_back(c);
+                } else {
+                    need_underscore = true;
+                }
+            }
+            return dst;
+        }
+    
+        /**
+         * @brief Keep only the last n slash-parts
+         *
+         * @param src
+         * @param n : 1 indicates the last slash-part
+         * @return modified string
+         */
+        std::string cut(const std::string& src, int n) const
+        {
+            std::string rdst;
+            for (int i = int(src.length())-1; i >= 0; i--) {
+                char c = src[i];
+                if (c != '/') {
+                    rdst.push_back(c);
+                } else if (n == 1) {
+                    std::string dst;
+                    for (int j = int(rdst.length())-1; j >= 0; j--) {
+                        dst.push_back(rdst[j]);
+                    }
+                    return dst;
+                } else {
+                    n--;
+                    rdst.push_back(c);
+                }
+            }
+            return src;
+        }
+    
+        void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+    
+        /**
+         * @brief Compute the mapping between full path and short names
+         */
+        void computeShortNames()
+        {
+            std::vector<std::string>           uniquePaths;  // all full paths transformed but made unique with a prefix
+            std::map<std::string, std::string> unique2full;  // all full paths transformed but made unique with a prefix
+            char num_buffer[16];
+            int pnum = 0;
+        
+            for (const auto& s : fFullPaths) {
+                sprintf(num_buffer, "%d", pnum++);
+                std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+                uniquePaths.push_back(u);
+                unique2full[u] = s;  // remember the full path associated to a unique path
+            }
+        
+            std::map<std::string, int> uniquePath2level;                // map path to level
+            for (const auto& s : uniquePaths) uniquePath2level[s] = 1;   // we init all levels to 1
+            bool have_collisions = true;
+        
+            while (have_collisions) {
+                // compute collision list
+                std::set<std::string>              collisionSet;
+                std::map<std::string, std::string> short2full;
+                have_collisions = false;
+                for (const auto& it : uniquePath2level) {
+                    std::string u = it.first;
+                    int n = it.second;
+                    std::string shortName = cut(u, n);
+                    auto p = short2full.find(shortName);
+                    if (p == short2full.end()) {
+                        // no collision
+                        short2full[shortName] = u;
+                    } else {
+                        // we have a collision, add the two paths to the collision set
+                        have_collisions = true;
+                        collisionSet.insert(u);
+                        collisionSet.insert(p->second);
+                    }
+                }
+                for (const auto& s : collisionSet) uniquePath2level[s]++;  // increase level of colliding path
+            }
+        
+            for (const auto& it : uniquePath2level) {
+                std::string u = it.first;
+                int n = it.second;
+                std::string shortName = replaceCharList(cut(u, n), {'/'}, '_');
+                fFull2Short[unique2full[u]] = shortName;
+            }
+        }
+    
+        std::string replaceCharList(const std::string& str, const std::vector<char>& ch1, char ch2)
+        {
+            auto beg = ch1.begin();
+            auto end = ch1.end();
+            std::string res = str;
+            for (size_t i = 0; i < str.length(); ++i) {
+                if (std::find(beg, end, str[i]) != end) res[i] = ch2;
+            }
+            return res;
+        }
+     
+    public:
+    
+        PathBuilder() {}
+        virtual ~PathBuilder() {}
+    
+        // Return true for the first level of groups
+        bool pushLabel(const std::string& label) { fControlsLevel.push_back(label); return fControlsLevel.size() == 1;}
+    
+        // Return true for the last level of groups
+        bool popLabel() { fControlsLevel.pop_back(); return fControlsLevel.size() == 0; }
+    
+        std::string buildPath(const std::string& label)
+        {
+            std::string res = "/";
+            for (size_t i = 0; i < fControlsLevel.size(); i++) {
+                res = res + fControlsLevel[i] + "/";
+            }
+            res += label;
+            return replaceCharList(res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
+        }
+    
+};
+
+#endif  // __PathBuilder__
+/**************************  END  PathBuilder.h **************************/
+/************************** BEGIN ValueConverter.h ********************
+ FAUST Architecture File
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+ ---------------------------------------------------------------------
+ This program 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 program 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 program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ EXCEPTION : As a special exception, you may create a larger work
+ that contains this FAUST architecture section and distribute
+ that work under terms of your choice, so long as this FAUST
+ architecture section is not modified.
+ ********************************************************************/
+
+#ifndef __ValueConverter__
+#define __ValueConverter__
+
+/***************************************************************************************
+ ValueConverter.h
+ (GRAME, Copyright 2015-2019)
+ Set of conversion objects used to map user interface values (for example a gui slider
+ delivering values between 0 and 1) to faust values (for example a vslider between
+ 20 and 20000) using a log scale.
+ -- Utilities
+ Range(lo,hi) : clip a value x between lo and hi
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and v2
+ Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1 vm v2
+ -- Value Converters
+ ValueConverter::ui2faust(x)
+ ValueConverter::faust2ui(x)
+ -- ValueConverters used for sliders depending of the scale
+ LinearValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
+ LogValueConverter(umin, umax, fmin, fmax)
+ ExpValueConverter(umin, umax, fmin, fmax)
+ -- ValueConverters used for accelerometers based on 3 points
+ AccUpConverter(amin, amid, amax, fmin, fmid, fmax)        -- curve 0
+ AccDownConverter(amin, amid, amax, fmin, fmid, fmax)      -- curve 1
+ AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 2
+ AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 3
+ -- lists of ZoneControl are used to implement accelerometers metadata for each axes
+ ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
+ -- ZoneReader are used to implement screencolor metadata
+ ZoneReader(zone, valueConverter) : a zone with a data converter
+
+****************************************************************************************/
+
+#include <float.h>
+#include <algorithm>    // std::max
+#include <cmath>
+#include <vector>
+#include <assert.h>
+
+
+//--------------------------------------------------------------------------------------
+// Interpolator(lo,hi,v1,v2)
+// Maps a value x between lo and hi to a value y between v1 and v2
+// y = v1 + (x-lo)/(hi-lo)*(v2-v1)
+// y = v1 + (x-lo) * coef           with coef = (v2-v1)/(hi-lo)
+// y = v1 + x*coef - lo*coef
+// y = v1 - lo*coef + x*coef
+// y = offset + x*coef              with offset = v1 - lo*coef
+//--------------------------------------------------------------------------------------
+class FAUST_API Interpolator {
+    
+    private:
+
+        //--------------------------------------------------------------------------------------
+        // Range(lo,hi) clip a value between lo and hi
+        //--------------------------------------------------------------------------------------
+        struct Range
+        {
+            double fLo;
+            double fHi;
+
+            Range(double x, double y) : fLo(std::min<double>(x,y)), fHi(std::max<double>(x,y)) {}
+            double operator()(double x) { return (x<fLo) ? fLo : (x>fHi) ? fHi : x; }
+        };
+
+
+        Range fRange;
+        double fCoef;
+        double fOffset;
+
+    public:
+
+        Interpolator(double lo, double hi, double v1, double v2) : fRange(lo,hi)
+        {
+            if (hi != lo) {
+                // regular case
+                fCoef = (v2-v1)/(hi-lo);
+                fOffset = v1 - lo*fCoef;
+            } else {
+                // degenerate case, avoids division by zero
+                fCoef = 0;
+                fOffset = (v1+v2)/2;
+            }
+        }
+        double operator()(double v)
+        {
+            double x = fRange(v);
+            return  fOffset + x*fCoef;
+        }
+
+        void getLowHigh(double& amin, double& amax)
+        {
+            amin = fRange.fLo;
+            amax = fRange.fHi;
+        }
+};
+
+//--------------------------------------------------------------------------------------
+// Interpolator3pt(lo,mi,hi,v1,vm,v2)
+// Map values between lo mid hi to values between v1 vm v2
+//--------------------------------------------------------------------------------------
+class FAUST_API Interpolator3pt {
+
+    private:
+
+        Interpolator fSegment1;
+        Interpolator fSegment2;
+        double fMid;
+
+    public:
+
+        Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2) :
+            fSegment1(lo, mi, v1, vm),
+            fSegment2(mi, hi, vm, v2),
+            fMid(mi) {}
+        double operator()(double x) { return  (x < fMid) ? fSegment1(x) : fSegment2(x); }
+
+        void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fSegment1.getLowHigh(amin, amid);
+            fSegment2.getLowHigh(amid, amax);
+        }
+};
+
+//--------------------------------------------------------------------------------------
+// Abstract ValueConverter class. Converts values between UI and Faust representations
+//--------------------------------------------------------------------------------------
+class FAUST_API ValueConverter {
+
+    public:
+
+        virtual ~ValueConverter() {}
+        virtual double ui2faust(double x) { return x; };
+        virtual double faust2ui(double x) { return x; };
+};
+
+//--------------------------------------------------------------------------------------
+// A converter than can be updated
+//--------------------------------------------------------------------------------------
+
+class FAUST_API UpdatableValueConverter : public ValueConverter {
+    
+    protected:
+        
+        bool fActive;
+        
+    public:
+        
+        UpdatableValueConverter():fActive(true)
+        {}
+        virtual ~UpdatableValueConverter()
+        {}
+        
+        virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max) = 0;
+        virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
+        
+        void setActive(bool on_off) { fActive = on_off; }
+        bool getActive() { return fActive; }
+    
+};
+
+//--------------------------------------------------------------------------------------
+// Linear conversion between ui and Faust values
+//--------------------------------------------------------------------------------------
+class FAUST_API LinearValueConverter : public ValueConverter {
+    
+    private:
+        
+        Interpolator fUI2F;
+        Interpolator fF2UI;
+        
+    public:
+        
+        LinearValueConverter(double umin, double umax, double fmin, double fmax) :
+            fUI2F(umin,umax,fmin,fmax), fF2UI(fmin,fmax,umin,umax)
+        {}
+        
+        LinearValueConverter() : fUI2F(0.,0.,0.,0.), fF2UI(0.,0.,0.,0.)
+        {}
+        virtual double ui2faust(double x) { return fUI2F(x); }
+        virtual double faust2ui(double x) { return fF2UI(x); }
+    
+};
+
+//--------------------------------------------------------------------------------------
+// Two segments linear conversion between ui and Faust values
+//--------------------------------------------------------------------------------------
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter {
+    
+    private:
+    
+        Interpolator3pt fUI2F;
+        Interpolator3pt fF2UI;
+        
+    public:
+    
+        LinearValueConverter2(double amin, double amid, double amax, double min, double init, double max) :
+            fUI2F(amin, amid, amax, min, init, max), fF2UI(min, init, max, amin, amid, amax)
+        {}
+        
+        LinearValueConverter2() : fUI2F(0.,0.,0.,0.,0.,0.), fF2UI(0.,0.,0.,0.,0.,0.)
+        {}
+    
+        virtual double ui2faust(double x) { return fUI2F(x); }
+        virtual double faust2ui(double x) { return fF2UI(x); }
+    
+        virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max)
+        {
+            fUI2F = Interpolator3pt(amin, amid, amax, min, init, max);
+            fF2UI = Interpolator3pt(min, init, max, amin, amid, amax);
+        }
+
+        virtual void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fUI2F.getMappingValues(amin, amid, amax);
+        }
+    
+};
+
+//--------------------------------------------------------------------------------------
+// Logarithmic conversion between ui and Faust values
+//--------------------------------------------------------------------------------------
+class FAUST_API LogValueConverter : public LinearValueConverter {
+
+    public:
+
+        LogValueConverter(double umin, double umax, double fmin, double fmax) :
+            LinearValueConverter(umin, umax, std::log(std::max<double>(DBL_MIN, fmin)), std::log(std::max<double>(DBL_MIN, fmax)))
+        {}
+
+        virtual double ui2faust(double x) { return std::exp(LinearValueConverter::ui2faust(x)); }
+        virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::log(std::max<double>(x, DBL_MIN))); }
+
+};
+
+//--------------------------------------------------------------------------------------
+// Exponential conversion between ui and Faust values
+//--------------------------------------------------------------------------------------
+class FAUST_API ExpValueConverter : public LinearValueConverter {
+
+    public:
+
+        ExpValueConverter(double umin, double umax, double fmin, double fmax) :
+            LinearValueConverter(umin, umax, std::min<double>(DBL_MAX, std::exp(fmin)), std::min<double>(DBL_MAX, std::exp(fmax)))
+        {}
+
+        virtual double ui2faust(double x) { return std::log(LinearValueConverter::ui2faust(x)); }
+        virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::min<double>(DBL_MAX, std::exp(x))); }
+
+};
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using an Up curve (curve 0)
+//--------------------------------------------------------------------------------------
+class FAUST_API AccUpConverter : public UpdatableValueConverter {
+
+    private:
+
+        Interpolator3pt fA2F;
+        Interpolator3pt fF2A;
+
+    public:
+
+        AccUpConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
+            fA2F(amin,amid,amax,fmin,fmid,fmax),
+            fF2A(fmin,fmid,fmax,amin,amid,amax)
+        {}
+
+        virtual double ui2faust(double x) { return fA2F(x); }
+        virtual double faust2ui(double x) { return fF2A(x); }
+
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
+        {
+            //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
+            fF2A = Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
+        }
+
+        virtual void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+
+};
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using a Down curve (curve 1)
+//--------------------------------------------------------------------------------------
+class FAUST_API AccDownConverter : public UpdatableValueConverter {
+
+    private:
+
+        Interpolator3pt        fA2F;
+        Interpolator3pt        fF2A;
+
+    public:
+
+        AccDownConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
+            fA2F(amin,amid,amax,fmax,fmid,fmin),
+            fF2A(fmin,fmid,fmax,amax,amid,amin)
+        {}
+
+        virtual double ui2faust(double x) { return fA2F(x); }
+        virtual double faust2ui(double x) { return fF2A(x); }
+
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
+        {
+             //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
+            fF2A = Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
+        }
+
+        virtual void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+};
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using an Up-Down curve (curve 2)
+//--------------------------------------------------------------------------------------
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter {
+
+    private:
+
+        Interpolator3pt        fA2F;
+        Interpolator fF2A;
+
+    public:
+
+        AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax) :
+            fA2F(amin,amid,amax,fmin,fmax,fmin),
+            fF2A(fmin,fmax,amin,amax)                          // Special, pseudo inverse of a non monotonic function
+        {}
+
+        virtual double ui2faust(double x) { return fA2F(x); }
+        virtual double faust2ui(double x) { return fF2A(x); }
+
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax)
+        {
+            //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
+            fF2A = Interpolator(fmin, fmax, amin, amax);
+        }
+
+        virtual void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+};
+
+//--------------------------------------------------------------------------------------
+// Convert accelerometer or gyroscope values to Faust values
+// Using a Down-Up curve (curve 3)
+//--------------------------------------------------------------------------------------
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter {
+
+    private:
+
+        Interpolator3pt        fA2F;
+        Interpolator fF2A;
+
+    public:
+
+        AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax) :
+            fA2F(amin,amid,amax,fmax,fmin,fmax),
+            fF2A(fmin,fmax,amin,amax)                          // Special, pseudo inverse of a non monotonic function
+        {}
+
+        virtual double ui2faust(double x) { return fA2F(x); }
+        virtual double faust2ui(double x) { return fF2A(x); }
+
+        virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax)
+        {
+            //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+            fA2F = Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
+            fF2A = Interpolator(fmin, fmax, amin, amax);
+        }
+
+        virtual void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fA2F.getMappingValues(amin, amid, amax);
+        }
+};
+
+//--------------------------------------------------------------------------------------
+// Base class for ZoneControl
+//--------------------------------------------------------------------------------------
+class FAUST_API ZoneControl {
+
+    protected:
+
+        FAUSTFLOAT*    fZone;
+
+    public:
+
+        ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
+        virtual ~ZoneControl() {}
+
+        virtual void update(double /*v*/) const {}
+
+        virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/, double /*min*/, double /*init*/, double /*max*/) {}
+        virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
+
+        FAUSTFLOAT* getZone() { return fZone; }
+
+        virtual void setActive(bool /*on_off*/) {}
+        virtual bool getActive() { return false; }
+
+        virtual int getCurve() { return -1; }
+
+};
+
+//--------------------------------------------------------------------------------------
+//  Useful to implement accelerometers metadata as a list of ZoneControl for each axes
+//--------------------------------------------------------------------------------------
+class FAUST_API ConverterZoneControl : public ZoneControl {
+
+    protected:
+
+        ValueConverter* fValueConverter;
+
+    public:
+
+        ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* converter) : ZoneControl(zone), fValueConverter(converter) {}
+        virtual ~ConverterZoneControl() { delete fValueConverter; } // Assuming fValueConverter is not kept elsewhere...
+
+        virtual void update(double v) const { *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v)); }
+
+        ValueConverter* getConverter() { return fValueConverter; }
+
+};
+
+//--------------------------------------------------------------------------------------
+// Association of a zone and a four value converter, each one for each possible curve.
+// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
+//--------------------------------------------------------------------------------------
+class FAUST_API CurveZoneControl : public ZoneControl {
+
+    private:
+
+        std::vector<UpdatableValueConverter*> fValueConverters;
+        int fCurve;
+
+    public:
+
+        CurveZoneControl(FAUSTFLOAT* zone, int curve, double amin, double amid, double amax, double min, double init, double max) : ZoneControl(zone), fCurve(0)
+        {
+            assert(curve >= 0 && curve <= 3);
+            fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
+            fValueConverters.push_back(new AccDownConverter(amin, amid, amax, min, init, max));
+            fValueConverters.push_back(new AccUpDownConverter(amin, amid, amax, min, init, max));
+            fValueConverters.push_back(new AccDownUpConverter(amin, amid, amax, min, init, max));
+            fCurve = curve;
+        }
+        virtual ~CurveZoneControl()
+        {
+            for (const auto& it : fValueConverters) { delete it; }
+        }
+        void update(double v) const { if (fValueConverters[fCurve]->getActive()) *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v)); }
+
+        void setMappingValues(int curve, double amin, double amid, double amax, double min, double init, double max)
+        {
+            fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
+            fCurve = curve;
+        }
+
+        void getMappingValues(double& amin, double& amid, double& amax)
+        {
+            fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+        }
+
+        void setActive(bool on_off)
+        {
+            for (const auto& it : fValueConverters) { it->setActive(on_off); }
+        }
+
+        int getCurve() { return fCurve; }
+};
+
+class FAUST_API ZoneReader {
+
+    private:
+
+        FAUSTFLOAT* fZone;
+        Interpolator fInterpolator;
+
+    public:
+
+        ZoneReader(FAUSTFLOAT* zone, double lo, double hi) : fZone(zone), fInterpolator(lo, hi, 0, 255) {}
+
+        virtual ~ZoneReader() {}
+
+        int getValue()
+        {
+            return (fZone != nullptr) ? int(fInterpolator(*fZone)) : 127;
+        }
+
+};
+
+#endif
+/**************************  END  ValueConverter.h **************************/
+
+typedef unsigned int uint;
+
+class APIUI : public PathBuilder, public Meta, public UI
+{
+    public:
+        enum ItemType { kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph };
+        enum Type { kAcc = 0, kGyr = 1, kNoType };
+
+    protected:
+
+        enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+        struct Item {
+            std::string fLabel;
+            std::string fShortname;
+            std::string fPath;
+            ValueConverter* fConversion;
+            FAUSTFLOAT* fZone;
+            FAUSTFLOAT fInit;
+            FAUSTFLOAT fMin;
+            FAUSTFLOAT fMax;
+            FAUSTFLOAT fStep;
+            ItemType fItemType;
+            
+            Item(const std::string& label,
+                 const std::string& short_name,
+                 const std::string& path,
+                 ValueConverter* conversion,
+                 FAUSTFLOAT* zone,
+                 FAUSTFLOAT init,
+                 FAUSTFLOAT min,
+                 FAUSTFLOAT max,
+                 FAUSTFLOAT step,
+                 ItemType item_type)
+            :fLabel(label), fShortname(short_name), fPath(path), fConversion(conversion),
+            fZone(zone), fInit(init), fMin(min), fMax(max), fStep(step), fItemType(item_type)
+            {}
+        };
+        std::vector<Item> fItems;
+
+        std::vector<std::map<std::string, std::string> > fMetaData;
+        std::vector<ZoneControl*> fAcc[3];
+        std::vector<ZoneControl*> fGyr[3];
+
+        // Screen color control
+        // "...[screencolor:red]..." etc.
+        bool fHasScreenControl;      // true if control screen color metadata
+        ZoneReader* fRedReader;
+        ZoneReader* fGreenReader;
+        ZoneReader* fBlueReader;
+
+        // Current values controlled by metadata
+        std::string fCurrentUnit;
+        int fCurrentScale;
+        std::string fCurrentAcc;
+        std::string fCurrentGyr;
+        std::string fCurrentColor;
+        std::string fCurrentTooltip;
+        std::map<std::string, std::string> fCurrentMetadata;
+
+        // Add a generic parameter
+        virtual void addParameter(const char* label,
+                                  FAUSTFLOAT* zone,
+                                  FAUSTFLOAT init,
+                                  FAUSTFLOAT min,
+                                  FAUSTFLOAT max,
+                                  FAUSTFLOAT step,
+                                  ItemType type)
+        {
+            std::string path = buildPath(label);
+            fFullPaths.push_back(path);
+
+            // handle scale metadata
+            ValueConverter* converter = nullptr;
+            switch (fCurrentScale) {
+                case kLin:
+                    converter = new LinearValueConverter(0, 1, min, max);
+                    break;
+                case kLog:
+                    converter = new LogValueConverter(0, 1, min, max);
+                    break;
+                case kExp:
+                    converter = new ExpValueConverter(0, 1, min, max);
+                    break;
+            }
+            fCurrentScale = kLin;
+
+            fItems.push_back(Item(label, "", path, converter, zone, init, min, max, step, type));
+       
+            if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
+                fprintf(stderr, "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n", label);
+            }
+
+            // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
+            if (fCurrentAcc.size() > 0) {
+                std::istringstream iss(fCurrentAcc);
+                int axe, curve;
+                double amin, amid, amax;
+                iss >> axe >> curve >> amin >> amid >> amax;
+
+                if ((0 <= axe) && (axe < 3) &&
+                    (0 <= curve) && (curve < 4) &&
+                    (amin < amax) && (amin <= amid) && (amid <= amax))
+                {
+                    fAcc[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+                } else {
+                    fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
+                }
+                fCurrentAcc = "";
+            }
+
+            // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
+            if (fCurrentGyr.size() > 0) {
+                std::istringstream iss(fCurrentGyr);
+                int axe, curve;
+                double amin, amid, amax;
+                iss >> axe >> curve >> amin >> amid >> amax;
+
+                if ((0 <= axe) && (axe < 3) &&
+                    (0 <= curve) && (curve < 4) &&
+                    (amin < amax) && (amin <= amid) && (amid <= amax))
+                {
+                    fGyr[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+                } else {
+                    fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
+                }
+                fCurrentGyr = "";
+            }
+
+            // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
+            if (fCurrentColor.size() > 0) {
+                if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
+                    fRedReader = new ZoneReader(zone, min, max);
+                    fHasScreenControl = true;
+                } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
+                    fGreenReader = new ZoneReader(zone, min, max);
+                    fHasScreenControl = true;
+                } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
+                    fBlueReader = new ZoneReader(zone, min, max);
+                    fHasScreenControl = true;
+                } else if ((fCurrentColor == "white") && (fRedReader == nullptr) && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
+                    fRedReader = new ZoneReader(zone, min, max);
+                    fGreenReader = new ZoneReader(zone, min, max);
+                    fBlueReader = new ZoneReader(zone, min, max);
+                    fHasScreenControl = true;
+                } else {
+                    fprintf(stderr, "incorrect screencolor metadata : %s \n", fCurrentColor.c_str());
+                }
+            }
+            fCurrentColor = "";
+
+            fMetaData.push_back(fCurrentMetadata);
+            fCurrentMetadata.clear();
+        }
+
+        int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
+        {
+            FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+            for (size_t i = 0; i < table[val].size(); i++) {
+                if (zone == table[val][i]->getZone()) return int(i);
+            }
+            return -1;
+        }
+
+        void setConverter(std::vector<ZoneControl*>* table, int p, int val, int curve, double amin, double amid, double amax)
+        {
+            int id1 = getZoneIndex(table, p, 0);
+            int id2 = getZoneIndex(table, p, 1);
+            int id3 = getZoneIndex(table, p, 2);
+
+            // Deactivates everywhere..
+            if (id1 != -1) table[0][uint(id1)]->setActive(false);
+            if (id2 != -1) table[1][uint(id2)]->setActive(false);
+            if (id3 != -1) table[2][uint(id3)]->setActive(false);
+
+            if (val == -1) { // Means: no more mapping...
+                // So stay all deactivated...
+            } else {
+                int id4 = getZoneIndex(table, p, val);
+                if (id4 != -1) {
+                    // Reactivate the one we edit...
+                  table[val][uint(id4)]->setMappingValues(curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax);
+                  table[val][uint(id4)]->setActive(true);
+                } else {
+                    // Allocate a new CurveZoneControl which is 'active' by default
+                    FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+                    table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax));
+                }
+            }
+        }
+
+        void getConverter(std::vector<ZoneControl*>* table, int p, int& val, int& curve, double& amin, double& amid, double& amax)
+        {
+            int id1 = getZoneIndex(table, p, 0);
+            int id2 = getZoneIndex(table, p, 1);
+            int id3 = getZoneIndex(table, p, 2);
+
+            if (id1 != -1) {
+                val = 0;
+                curve = table[val][uint(id1)]->getCurve();
+                table[val][uint(id1)]->getMappingValues(amin, amid, amax);
+            } else if (id2 != -1) {
+                val = 1;
+                curve = table[val][uint(id2)]->getCurve();
+                table[val][uint(id2)]->getMappingValues(amin, amid, amax);
+            } else if (id3 != -1) {
+                val = 2;
+                curve = table[val][uint(id3)]->getCurve();
+                table[val][uint(id3)]->getMappingValues(amin, amid, amax);
+            } else {
+                val = -1; // No mapping
+                curve = 0;
+                amin = -100.;
+                amid = 0.;
+                amax = 100.;
+            }
+        }
+
+    public:
+
+        APIUI() : fHasScreenControl(false), fRedReader(nullptr), fGreenReader(nullptr), fBlueReader(nullptr), fCurrentScale(kLin)
+        {}
+
+        virtual ~APIUI()
+        {
+            for (const auto& it : fItems) delete it.fConversion;
+            for (int i = 0; i < 3; i++) {
+                for (const auto& it : fAcc[i]) delete it;
+                for (const auto& it : fGyr[i]) delete it;
+            }
+            delete fRedReader;
+            delete fGreenReader;
+            delete fBlueReader;
+        }
+
+        // -- widget's layouts
+
+        virtual void openTabBox(const char* label) { pushLabel(label); }
+        virtual void openHorizontalBox(const char* label) { pushLabel(label); }
+        virtual void openVerticalBox(const char* label) { pushLabel(label); }
+        virtual void closeBox()
+        {
+            if (popLabel()) {
+                // Shortnames can be computed when all fullnames are known
+                computeShortNames();
+                // Fill 'shortname' field for each item
+                for (const auto& it : fFull2Short) {
+                    int index = getParamIndex(it.first.c_str());
+                    fItems[index].fShortname = it.second;
+                }
+            }
+        }
+
+        // -- active widgets
+
+        virtual void addButton(const char* label, FAUSTFLOAT* zone)
+        {
+            addParameter(label, zone, 0, 0, 1, 1, kButton);
+        }
+
+        virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+        {
+            addParameter(label, zone, 0, 0, 1, 1, kCheckButton);
+        }
+
+        virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addParameter(label, zone, init, min, max, step, kVSlider);
+        }
+
+        virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addParameter(label, zone, init, min, max, step, kHSlider);
+        }
+
+        virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+        {
+            addParameter(label, zone, init, min, max, step, kNumEntry);
+        }
+
+        // -- passive widgets
+
+        virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        {
+            addParameter(label, zone, min, min, max, (max-min)/1000.0f, kHBargraph);
+        }
+
+        virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+        {
+            addParameter(label, zone, min, min, max, (max-min)/1000.0f, kVBargraph);
+        }
+
+        // -- soundfiles
+
+        virtual void addSoundfile(const char* /*label*/, const char* /*filename*/, Soundfile** /*sf_zone*/) {}
+
+        // -- metadata declarations
+
+        virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
+        {
+            // Keep metadata
+            fCurrentMetadata[key] = val;
+
+            if (strcmp(key, "scale") == 0) {
+                if (strcmp(val, "log") == 0) {
+                    fCurrentScale = kLog;
+                } else if (strcmp(val, "exp") == 0) {
+                    fCurrentScale = kExp;
+                } else {
+                    fCurrentScale = kLin;
+                }
+            } else if (strcmp(key, "unit") == 0) {
+                fCurrentUnit = val;
+            } else if (strcmp(key, "acc") == 0) {
+                fCurrentAcc = val;
+            } else if (strcmp(key, "gyr") == 0) {
+                fCurrentGyr = val;
+            } else if (strcmp(key, "screencolor") == 0) {
+                fCurrentColor = val; // val = "red", "green", "blue" or "white"
+            } else if (strcmp(key, "tooltip") == 0) {
+                fCurrentTooltip = val;
+            }
+        }
+
+        virtual void declare(const char* /*key*/, const char* /*val*/)
+        {}
+
+        //-------------------------------------------------------------------------------
+        // Simple API part
+        //-------------------------------------------------------------------------------
+        int getParamsCount() { return int(fItems.size()); }
+
+        int getParamIndex(const char* path_aux)
+        {
+            std::string path = std::string(path_aux);
+            auto it = find_if(fItems.begin(), fItems.end(),
+                              [=](const Item& it) { return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path); });
+            return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
+        }
+    
+        const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
+        const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
+        const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+    
+        std::map<const char*, const char*> getMetadata(int p)
+        {
+            std::map<const char*, const char*> res;
+            std::map<std::string, std::string> metadata = fMetaData[uint(p)];
+            for (const auto& it : metadata) {
+                res[it.first.c_str()] = it.second.c_str();
+            }
+            return res;
+        }
+
+        const char* getMetadata(int p, const char* key)
+        {
+            return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end()) ? fMetaData[uint(p)][key].c_str() : "";
+        }
+        FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
+        FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
+        FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
+        FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
+
+        FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
+
+        FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
+        FAUSTFLOAT getParamValue(const char* path)
+        {
+            int index = getParamIndex(path);
+            if (index >= 0) {
+                return getParamValue(index);
+            } else {
+                fprintf(stderr, "getParamValue : '%s' not found\n", (path == nullptr ? "NULL" : path));
+                return FAUSTFLOAT(0);
+            }
+        }
+
+        void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+        void setParamValue(const char* path, FAUSTFLOAT v)
+        {
+            int index = getParamIndex(path);
+            if (index >= 0) {
+                setParamValue(index, v);
+            } else {
+                fprintf(stderr, "setParamValue : '%s' not found\n", (path == nullptr ? "NULL" : path));
+            }
+        }
+
+        double getParamRatio(int p) { return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone); }
+        void setParamRatio(int p, double r) { *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r)); }
+
+        double value2ratio(int p, double r)    { return fItems[uint(p)].fConversion->faust2ui(r); }
+        double ratio2value(int p, double r)    { return fItems[uint(p)].fConversion->ui2faust(r); }
+
+        /**
+         * Return the control type (kAcc, kGyr, or -1) for a given parameter.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the type
+         */
+        Type getParamType(int p)
+        {
+            if (p >= 0) {
+                if (getZoneIndex(fAcc, p, 0) != -1
+                    || getZoneIndex(fAcc, p, 1) != -1
+                    || getZoneIndex(fAcc, p, 2) != -1) {
+                    return kAcc;
+                } else if (getZoneIndex(fGyr, p, 0) != -1
+                           || getZoneIndex(fGyr, p, 1) != -1
+                           || getZoneIndex(fGyr, p, 2) != -1) {
+                    return kGyr;
+                }
+            }
+            return kNoType;
+        }
+
+        /**
+         * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph) for a given parameter.
+         *
+         * @param p - the UI parameter index
+         *
+         * @return the Item type
+         */
+        ItemType getParamItemType(int p)
+        {
+            return fItems[uint(p)].fItemType;
+        }
+
+        /**
+         * Set a new value coming from an accelerometer, propagate it to all relevant FAUSTFLOAT* zones.
+         *
+         * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+         * @param value - the new value
+         *
+         */
+        void propagateAcc(int acc, double value)
+        {
+            for (size_t i = 0; i < fAcc[acc].size(); i++) {
+                fAcc[acc][i]->update(value);
+            }
+        }
+
+        /**
+         * Used to edit accelerometer curves and mapping. Set curve and related mapping for a given UI parameter.
+         *
+         * @param p - the UI parameter index
+         * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer (-1 means "no mapping")
+         * @param curve - between 0 and 3
+         * @param amin - mapping 'min' point
+         * @param amid - mapping 'middle' point
+         * @param amax - mapping 'max' point
+         *
+         */
+        void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
+        {
+            setConverter(fAcc, p, acc, curve, amin, amid, amax);
+        }
+
+        /**
+         * Used to edit gyroscope curves and mapping. Set curve and related mapping for a given UI parameter.
+         *
+         * @param p - the UI parameter index
+         * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no mapping")
+         * @param curve - between 0 and 3
+         * @param amin - mapping 'min' point
+         * @param amid - mapping 'middle' point
+         * @param amax - mapping 'max' point
+         *
+         */
+        void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax)
+        {
+            setConverter(fGyr, p, gyr, curve, amin, amid, amax);
+        }
+
+        /**
+         * Used to edit accelerometer curves and mapping. Get curve and related mapping for a given UI parameter.
+         *
+         * @param p - the UI parameter index
+         * @param acc - the acc value to be retrieved (-1 means "no mapping")
+         * @param curve - the curve value to be retrieved
+         * @param amin - the amin value to be retrieved
+         * @param amid - the amid value to be retrieved
+         * @param amax - the amax value to be retrieved
+         *
+         */
+        void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid, double& amax)
+        {
+            getConverter(fAcc, p, acc, curve, amin, amid, amax);
+        }
+
+        /**
+         * Used to edit gyroscope curves and mapping. Get curve and related mapping for a given UI parameter.
+         *
+         * @param p - the UI parameter index
+         * @param gyr - the gyr value to be retrieved (-1 means "no mapping")
+         * @param curve - the curve value to be retrieved
+         * @param amin - the amin value to be retrieved
+         * @param amid - the amid value to be retrieved
+         * @param amax - the amax value to be retrieved
+         *
+         */
+        void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid, double& amax)
+        {
+            getConverter(fGyr, p, gyr, curve, amin, amid, amax);
+        }
+
+        /**
+         * Set a new value coming from an gyroscope, propagate it to all relevant FAUSTFLOAT* zones.
+         *
+         * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+         * @param value - the new value
+         *
+         */
+        void propagateGyr(int gyr, double value)
+        {
+            for (size_t i = 0; i < fGyr[gyr].size(); i++) {
+                fGyr[gyr][i]->update(value);
+            }
+        }
+
+        /**
+         * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
+         *
+         * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+         * @return the number of zones
+         *
+         */
+        int getAccCount(int acc)
+        {
+            return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0;
+        }
+
+        /**
+         * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
+         *
+         * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+         * @param the number of zones
+         *
+         */
+        int getGyrCount(int gyr)
+        {
+            return (gyr >= 0 && gyr < 3) ? int(fGyr[gyr].size()) : 0;
+        }
+
+        // getScreenColor() : -1 means no screen color control (no screencolor metadata found)
+        // otherwise return 0x00RRGGBB a ready to use color
+        int getScreenColor()
+        {
+            if (fHasScreenControl) {
+                int r = (fRedReader) ? fRedReader->getValue() : 0;
+                int g = (fGreenReader) ? fGreenReader->getValue() : 0;
+                int b = (fBlueReader) ? fBlueReader->getValue() : 0;
+                return (r<<16) | (g<<8) | b;
+            } else {
+                return -1;
+            }
+        }
+
+};
+
+#endif
+/**************************  END  APIUI.h **************************/
+
+// NOTE: "faust -scn name" changes the last line above to
+// #include <faust/name/name.h>
+
+//----------------------------------------------------------------------------
+//  FAUST Generated Code
+//----------------------------------------------------------------------------
+
+
+#ifndef FAUSTFLOAT
+#define FAUSTFLOAT float
+#endif 
+
+#include <algorithm>
+#include <cmath>
+#include <cstdint>
+#include <math.h>
+
+#ifndef FAUSTCLASS 
+#define FAUSTCLASS volumedsp
+#endif
+
+#ifdef __APPLE__ 
+#define exp10f __exp10f
+#define exp10 __exp10
+#endif
+
+#if defined(_WIN32)
+#define RESTRICT __restrict
+#else
+#define RESTRICT __restrict__
+#endif
+
+
+class volumedsp : public dsp {
+       
+ private:
+       
+       FAUSTFLOAT fHslider0;
+       FAUSTFLOAT fCheckbox0;
+       int fSampleRate;
+       float fConst0;
+       float fConst1;
+       float fRec0[2];
+       
+ public:
+       
+       void metadata(Meta* m) { 
+               m->declare("author", "Matt Horton, adapted from GRAME");
+               m->declare("basics.lib/name", "Faust Basic Element Library");
+               m->declare("basics.lib/version", "0.8");
+               m->declare("compile_options", "-a faust2header.cpp -lang cpp -i -inpl -cn volumedsp -es 1 -mcd 16 -single -ftz 0");
+               m->declare("description", "Volume Control Faust Plugin for JackTrip, based on Faust examples");
+               m->declare("filename", "volumedsp.dsp");
+               m->declare("license", "MIT Style STK-4.2");
+               m->declare("maths.lib/author", "GRAME");
+               m->declare("maths.lib/copyright", "GRAME");
+               m->declare("maths.lib/license", "LGPL with exception");
+               m->declare("maths.lib/name", "Faust Math Library");
+               m->declare("maths.lib/version", "2.5");
+               m->declare("name", "volume");
+               m->declare("platform.lib/name", "Generic Platform Library");
+               m->declare("platform.lib/version", "0.2");
+               m->declare("signals.lib/name", "Faust Signal Routing Library");
+               m->declare("signals.lib/version", "0.3");
+               m->declare("version", "1.0");
+       }
+
+       virtual int getNumInputs() {
+               return 1;
+       }
+       virtual int getNumOutputs() {
+               return 1;
+       }
+       
+       static void classInit(int /*sample_rate*/) {
+       }
+       
+       virtual void instanceConstants(int sample_rate) {
+               fSampleRate = sample_rate;
+               fConst0 = 44.0999985f / std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
+               fConst1 = 1.0f - fConst0;
+       }
+       
+       virtual void instanceResetUserInterface() {
+               fHslider0 = FAUSTFLOAT(0.0f);
+               fCheckbox0 = FAUSTFLOAT(0.0f);
+       }
+       
+       virtual void instanceClear() {
+               for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
+                       fRec0[l0] = 0.0f;
+               }
+       }
+       
+       virtual void init(int sample_rate) {
+               classInit(sample_rate);
+               instanceInit(sample_rate);
+       }
+       virtual void instanceInit(int sample_rate) {
+               instanceConstants(sample_rate);
+               instanceResetUserInterface();
+               instanceClear();
+       }
+       
+       virtual volumedsp* clone() {
+               return new volumedsp();
+       }
+       
+       virtual int getSampleRate() {
+               return fSampleRate;
+       }
+       
+       virtual void buildUserInterface(UI* ui_interface) {
+               ui_interface->openVerticalBox("Volume Control");
+               ui_interface->declare(&fHslider0, "0", "");
+               ui_interface->addHorizontalSlider("Volume", &fHslider0, FAUSTFLOAT(0.0f), FAUSTFLOAT(-40.0f), FAUSTFLOAT(0.0f), FAUSTFLOAT(0.100000001f));
+               ui_interface->declare(&fCheckbox0, "1", "");
+               ui_interface->addCheckButton("Mute", &fCheckbox0);
+               ui_interface->closeBox();
+       }
+       
+       virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
+               FAUSTFLOAT* input0 = inputs[0];
+               FAUSTFLOAT* output0 = outputs[0];
+               float fSlow0 = float(fHslider0);
+               int iSlow1 = fSlow0 == -40.0f;
+               int iSlow2 = int(float(fCheckbox0));
+               float fSlow3 = fConst0 * std::pow(10.0f, 0.0500000007f * fSlow0);
+               for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+                       float fTemp0 = float(input0[i0]);
+                       fRec0[0] = fSlow3 + fConst1 * fRec0[1];
+                       float fThen0 = fTemp0 * fRec0[0];
+                       float fThen1 = ((iSlow2) ? 0.0f : fThen0);
+                       output0[i0] = FAUSTFLOAT(((iSlow1) ? 0.0f : fThen1));
+                       fRec0[1] = fRec0[0];
+               }
+       }
+
+};
+
+
+#endif
index 8b26291f90c84cc492b9b59f037ac93f8f1b524f..0ee6905ca45c9c5eb1772afee35c0318abf960f4 100644 (file)
@@ -1,7 +1,8 @@
 /* ------------------------------------------------------------
 name: "zitarevdsp"
-Code generated with Faust 2.28.6 (https://faust.grame.fr)
-Compilation options: -lang cpp -inpl -scal -ftz 0
+Code generated with Faust 2.41.1 (https://faust.grame.fr)
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn zitarevdsp -es 1 -mcd 16
+-single -ftz 0
 ------------------------------------------------------------ */
 
 #ifndef __zitarevdsp_H__
@@ -14,23 +15,23 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 // aimed at creating a simple C++ header file (.h) containing a Faust DSP.
 // See the Makefile for how to use it.
 
-/************************** BEGIN dsp.h **************************/
-/************************************************************************
+/************************** BEGIN dsp.h ********************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -44,29 +45,111 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 #include <string>
 #include <vector>
 
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __export__
+#define __export__
+
+#define FAUSTVERSION "2.41.1"
+
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
+
+#ifdef _WIN32
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API    __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
+#else
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#else
+#define FAUST_API    __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
+#endif
+
+#endif
+
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
 
-struct UI;
-struct Meta;
+struct FAUST_API UI;
+struct FAUST_API Meta;
 
 /**
  * DSP memory manager.
  */
 
-struct dsp_memory_manager {
+struct FAUST_API dsp_memory_manager {
     virtual ~dsp_memory_manager() {}
 
+    /**
+     * Inform the Memory Manager with the number of expected memory zones.
+     * @param count - the number of expected memory zones
+     */
+    virtual void begin(size_t /*count*/) {}
+
+    /**
+     * Give the Memory Manager information on a given memory zone.
+     * @param size - the size in bytes of the memory zone
+     * @param reads - the number of Read access to the zone used to compute one frame
+     * @param writes - the number of Write access to the zone used to compute one frame
+     */
+    virtual void info(size_t /*size*/, size_t /*reads*/, size_t /*writes*/) {}
+
+    /**
+     * Inform the Memory Manager that all memory zones have been described,
+     * to possibly start a 'compute the best allocation strategy' step.
+     */
+    virtual void end() {}
+
+    /**
+     * Allocate a memory zone.
+     * @param size - the memory zone size in bytes
+     */
     virtual void* allocate(size_t size) = 0;
-    virtual void destroy(void* ptr)     = 0;
+
+    /**
+     * Destroy a memory zone.
+     * @param ptr - the memory zone pointer to be deallocated
+     */
+    virtual void destroy(void* ptr) = 0;
 };
 
 /**
  * Signal processor definition.
  */
 
-class dsp
+class FAUST_API dsp
 {
    public:
     dsp() {}
@@ -86,7 +169,7 @@ class dsp
      */
     virtual void buildUserInterface(UI* ui_interface) = 0;
 
-    /* Returns the sample rate currently used by the instance */
+    /* Return the sample rate currently used by the instance */
     virtual int getSampleRate() = 0;
 
     /**
@@ -94,28 +177,28 @@ class dsp
      * - static class 'classInit': static tables initialization
      * - 'instanceInit': constants and instance state initialization
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void init(int sample_rate) = 0;
 
     /**
      * Init instance state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceInit(int sample_rate) = 0;
 
     /**
      * Init instance constant state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceConstants(int sample_rate) = 0;
 
     /* Init default control parameters values */
     virtual void instanceResetUserInterface() = 0;
 
-    /* Init instance state (delay lines...) */
+    /* Init instance state (like delay lines...) but keep the control parameter values */
     virtual void instanceClear() = 0;
 
     /**
@@ -167,7 +250,7 @@ class dsp
  * Generic DSP decorator.
  */
 
-class decorator_dsp : public dsp
+class FAUST_API decorator_dsp : public dsp
 {
    protected:
     dsp* fDSP;
@@ -206,10 +289,11 @@ class decorator_dsp : public dsp
 };
 
 /**
- * DSP factory class.
+ * DSP factory class, used with LLVM and Interpreter backends
+ * to create DSP instances from a compiled DSP program.
  */
 
-class dsp_factory
+class FAUST_API dsp_factory
 {
    protected:
     // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
@@ -229,75 +313,114 @@ class dsp_factory
     virtual dsp_memory_manager* getMemoryManager()             = 0;
 };
 
-/**
- * On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
- * flags to avoid costly denormals.
- */
+// Denormal handling
 
-#ifdef __SSE__
+#if defined(__SSE__)
 #include <xmmintrin.h>
-#ifdef __SSE2__
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
+#endif
+
+class FAUST_API ScopedNoDenormals
+{
+   private:
+    intptr_t fpsr;
+
+    void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("msr fpcr, %0" : : "ri"(fpsr_aux));
+#elif defined(__SSE__)
+        _mm_setcsr(static_cast<uint32_t>(fpsr_aux));
+#endif
+    }
+
+    void getFpStatusRegister() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("mrs %0, fpcr" : "=r"(fpsr));
+#elif defined(__SSE__)
+        fpsr          = static_cast<intptr_t>(_mm_getcsr());
+#endif
+    }
+
+   public:
+    ScopedNoDenormals() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        intptr_t mask = (1 << 24 /* FZ */);
+#else
+#if defined(__SSE__)
+#if defined(__SSE2__)
+        intptr_t mask = 0x8040;
 #else
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
+        intptr_t mask = 0x8000;
 #endif
 #else
-#define AVOIDDENORMALS
+        intptr_t mask = 0x0000;
 #endif
-
 #endif
-/**************************  END  dsp.h **************************/
+        getFpStatusRegister();
+        setFpStatusRegister(fpsr | mask);
+    }
 
-/************************** BEGIN APIUI.h **************************/
-/************************************************************************
- FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
- ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
+    ~ScopedNoDenormals() noexcept { setFpStatusRegister(fpsr); }
+};
 
- This program 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 General Public License for more details.
+#define AVOIDDENORMALS ScopedNoDenormals();
 
- You should have received a copy of the GNU General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+#endif
 
- EXCEPTION : As a special exception, you may create a larger work
- that contains this FAUST architecture section and distribute
- that work under terms of your choice, so long as this FAUST
- architecture section is not modified.
- ************************************************************************/
+/************************** END dsp.h **************************/
+/************************** BEGIN APIUI.h *****************************
+FAUST Architecture File
+Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+---------------------------------------------------------------------
+This program 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 program 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 program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+EXCEPTION : As a special exception, you may create a larger work
+that contains this FAUST architecture section and distribute
+that work under terms of your choice, so long as this FAUST
+architecture section is not modified.
+************************************************************************/
 
 #ifndef API_UI_H
 #define API_UI_H
 
-#include <iostream>
+#include <stdio.h>
+
 #include <map>
 #include <sstream>
 #include <string>
 #include <vector>
 
-/************************** BEGIN meta.h **************************/
-/************************************************************************
+/************************** BEGIN meta.h *******************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -308,36 +431,40 @@ class dsp_factory
 #ifndef __meta__
 #define __meta__
 
-struct Meta {
-    virtual ~Meta(){};
+/**
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
+ (key, value) metadata.
+ */
+struct FAUST_API Meta {
+    virtual ~Meta() {}
     virtual void declare(const char* key, const char* value) = 0;
 };
 
 #endif
 /**************************  END  meta.h **************************/
-/************************** BEGIN UI.h **************************/
-/************************************************************************
+/************************** BEGIN UI.h *****************************
  FAUST Architecture File
- Copyright (C) 2003-2020 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __UI_H__
 #define __UI_H__
@@ -356,7 +483,7 @@ struct Meta {
 struct Soundfile;
 
 template<typename REAL>
-struct UIReal {
+struct FAUST_API UIReal {
     UIReal() {}
     virtual ~UIReal() {}
 
@@ -387,38 +514,41 @@ struct UIReal {
 
     // -- soundfiles
 
-    virtual void addSoundfile(const char* label, const char* filename,
-                              Soundfile** sf_zone) = 0;
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+                              Soundfile** /*sf_zone*/) = 0;
 
     // -- metadata declarations
 
-    virtual void declare(REAL* zone, const char* key, const char* val) {}
+    virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
+
+    // To be used by LLVM client
+    virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
 };
 
-struct UI : public UIReal<FAUSTFLOAT> {
+struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
     UI() {}
     virtual ~UI() {}
 };
 
 #endif
 /**************************  END  UI.h **************************/
-/************************** BEGIN PathBuilder.h **************************/
-/************************************************************************
+/************************** BEGIN PathBuilder.h **************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -426,10 +556,13 @@ struct UI : public UIReal<FAUSTFLOAT> {
  architecture section is not modified.
  ************************************************************************/
 
-#ifndef FAUST_PATHBUILDER_H
-#define FAUST_PATHBUILDER_H
+#ifndef __PathBuilder__
+#define __PathBuilder__
 
 #include <algorithm>
+#include <map>
+#include <regex>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -438,113 +571,266 @@ struct UI : public UIReal<FAUSTFLOAT> {
  * Helper class to build complete hierarchical path for UI items.
  ******************************************************************************/
 
-class PathBuilder
+class FAUST_API PathBuilder
 {
    protected:
     std::vector<std::string> fControlsLevel;
+    std::vector<std::string> fFullPaths;
+    std::map<std::string, std::string> fFull2Short;  // filled by computeShortNames()
+
+    /**
+     * @brief check if a character is acceptable for an ID
+     *
+     * @param c
+     * @return true is the character is acceptable for an ID
+     */
+    bool isIDChar(char c) const
+    {
+        return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+               || ((c >= '0') && (c <= '9'));
+    }
+
+    /**
+     * @brief remove all "/0x00" parts
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string remove0x00(const std::string& src) const
+    {
+        return std::regex_replace(src, std::regex("/0x00"), "");
+    }
+
+    /**
+     * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string str2ID(const std::string& src) const
+    {
+        std::string dst;
+        bool need_underscore = false;
+        for (char c : src) {
+            if (isIDChar(c) || (c == '/')) {
+                if (need_underscore) {
+                    dst.push_back('_');
+                    need_underscore = false;
+                }
+                dst.push_back(c);
+            } else {
+                need_underscore = true;
+            }
+        }
+        return dst;
+    }
+
+    /**
+     * @brief Keep only the last n slash-parts
+     *
+     * @param src
+     * @param n : 1 indicates the last slash-part
+     * @return modified string
+     */
+    std::string cut(const std::string& src, int n) const
+    {
+        std::string rdst;
+        for (int i = int(src.length()) - 1; i >= 0; i--) {
+            char c = src[i];
+            if (c != '/') {
+                rdst.push_back(c);
+            } else if (n == 1) {
+                std::string dst;
+                for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+                    dst.push_back(rdst[j]);
+                }
+                return dst;
+            } else {
+                n--;
+                rdst.push_back(c);
+            }
+        }
+        return src;
+    }
+
+    void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+    /**
+     * @brief Compute the mapping between full path and short names
+     */
+    void computeShortNames()
+    {
+        std::vector<std::string>
+            uniquePaths;  // all full paths transformed but made unique with a prefix
+        std::map<std::string, std::string>
+            unique2full;  // all full paths transformed but made unique with a prefix
+        char num_buffer[16];
+        int pnum = 0;
+
+        for (const auto& s : fFullPaths) {
+            sprintf(num_buffer, "%d", pnum++);
+            std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+            uniquePaths.push_back(u);
+            unique2full[u] = s;  // remember the full path associated to a unique path
+        }
+
+        std::map<std::string, int> uniquePath2level;  // map path to level
+        for (const auto& s : uniquePaths)
+            uniquePath2level[s] = 1;  // we init all levels to 1
+        bool have_collisions = true;
+
+        while (have_collisions) {
+            // compute collision list
+            std::set<std::string> collisionSet;
+            std::map<std::string, std::string> short2full;
+            have_collisions = false;
+            for (const auto& it : uniquePath2level) {
+                std::string u         = it.first;
+                int n                 = it.second;
+                std::string shortName = cut(u, n);
+                auto p                = short2full.find(shortName);
+                if (p == short2full.end()) {
+                    // no collision
+                    short2full[shortName] = u;
+                } else {
+                    // we have a collision, add the two paths to the collision set
+                    have_collisions = true;
+                    collisionSet.insert(u);
+                    collisionSet.insert(p->second);
+                }
+            }
+            for (const auto& s : collisionSet)
+                uniquePath2level[s]++;  // increase level of colliding path
+        }
+
+        for (const auto& it : uniquePath2level) {
+            std::string u               = it.first;
+            int n                       = it.second;
+            std::string shortName       = replaceCharList(cut(u, n), {'/'}, '_');
+            fFull2Short[unique2full[u]] = shortName;
+        }
+    }
+
+    std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+                                char ch2)
+    {
+        auto beg        = ch1.begin();
+        auto end        = ch1.end();
+        std::string res = str;
+        for (size_t i = 0; i < str.length(); ++i) {
+            if (std::find(beg, end, str[i]) != end)
+                res[i] = ch2;
+        }
+        return res;
+    }
 
    public:
     PathBuilder() {}
     virtual ~PathBuilder() {}
 
+    // Return true for the first level of groups
+    bool pushLabel(const std::string& label)
+    {
+        fControlsLevel.push_back(label);
+        return fControlsLevel.size() == 1;
+    }
+
+    // Return true for the last level of groups
+    bool popLabel()
+    {
+        fControlsLevel.pop_back();
+        return fControlsLevel.size() == 0;
+    }
+
     std::string buildPath(const std::string& label)
     {
         std::string res = "/";
         for (size_t i = 0; i < fControlsLevel.size(); i++) {
-            res += fControlsLevel[i];
-            res += "/";
+            res = res + fControlsLevel[i] + "/";
         }
         res += label;
-        std::replace(res.begin(), res.end(), ' ', '_');
-        return res;
+        return replaceCharList(
+            res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
     }
-
-    std::string buildLabel(std::string label)
-    {
-        std::replace(label.begin(), label.end(), ' ', '_');
-        return label;
-    }
-
-    void pushLabel(const std::string& label) { fControlsLevel.push_back(label); }
-    void popLabel() { fControlsLevel.pop_back(); }
 };
 
-#endif  // FAUST_PATHBUILDER_H
+#endif  // __PathBuilder__
 /**************************  END  PathBuilder.h **************************/
-/************************** BEGIN ValueConverter.h **************************/
-/************************************************************************
+/************************** BEGIN ValueConverter.h ********************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __ValueConverter__
 #define __ValueConverter__
 
 /***************************************************************************************
                                                               ValueConverter.h
                           (GRAME, Copyright 2015-2019)
+ ValueConverter.h
+ (GRAME, Copyright 2015-2019)
 
-Set of conversion objects used to map user interface values (for example a gui slider
-delivering values between 0 and 1) to faust values (for example a vslider between
-20 and 20000) using a log scale.
+ Set of conversion objects used to map user interface values (for example a gui slider
+ delivering values between 0 and 1) to faust values (for example a vslider between
+ 20 and 20000) using a log scale.
 
--- Utilities
+ -- Utilities
 
-Range(lo,hi) : clip a value x between lo and hi
-Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
+ Range(lo,hi) : clip a value x between lo and hi
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
 v2 Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1
 vm v2
 
--- Value Converters
+ -- Value Converters
 
-ValueConverter::ui2faust(x)
-ValueConverter::faust2ui(x)
+ ValueConverter::ui2faust(x)
+ ValueConverter::faust2ui(x)
 
--- ValueConverters used for sliders depending of the scale
+ -- ValueConverters used for sliders depending of the scale
 
-LinearValueConverter(umin, umax, fmin, fmax)
-LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
-LogValueConverter(umin, umax, fmin, fmax)
-ExpValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
+ LogValueConverter(umin, umax, fmin, fmax)
+ ExpValueConverter(umin, umax, fmin, fmax)
 
--- ValueConverters used for accelerometers based on 3 points
+ -- ValueConverters used for accelerometers based on 3 points
 
-AccUpConverter(amin, amid, amax, fmin, fmid, fmax)             -- curve 0
-AccDownConverter(amin, amid, amax, fmin, fmid, fmax)   -- curve 1
-AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 2
-AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 3
+ AccUpConverter(amin, amid, amax, fmin, fmid, fmax)        -- curve 0
+ AccDownConverter(amin, amid, amax, fmin, fmid, fmax)      -- curve 1
+ AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 2
+ AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 3
 
--- lists of ZoneControl are used to implement accelerometers metadata for each axes
+ -- lists of ZoneControl are used to implement accelerometers metadata for each axes
 
-ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
+ ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
 
--- ZoneReader are used to implement screencolor metadata
+ -- ZoneReader are used to implement screencolor metadata
 
-ZoneReader(zone, valueConverter) : a zone with a data converter
+ ZoneReader(zone, valueConverter) : a zone with a data converter
 
 ****************************************************************************************/
 
+#include <assert.h>
+#include <float.h>
+
 #include <algorithm>  // std::max
-#include <cassert>
-#include <cfloat>
 #include <cmath>
 #include <vector>
 
@@ -552,12 +838,12 @@ ZoneReader(zone, valueConverter) : a zone with a data converter
 // Interpolator(lo,hi,v1,v2)
 // Maps a value x between lo and hi to a value y between v1 and v2
 // y = v1 + (x-lo)/(hi-lo)*(v2-v1)
-// y = v1 + (x-lo) * coef              with coef = (v2-v1)/(hi-lo)
+// y = v1 + (x-lo) * coef           with coef = (v2-v1)/(hi-lo)
 // y = v1 + x*coef - lo*coef
 // y = v1 - lo*coef + x*coef
-// y = offset + x*coef                         with offset = v1 - lo*coef
+// y = offset + x*coef              with offset = v1 - lo*coef
 //--------------------------------------------------------------------------------------
-class Interpolator
+class FAUST_API Interpolator
 {
    private:
     //--------------------------------------------------------------------------------------
@@ -608,7 +894,7 @@ class Interpolator
 // Interpolator3pt(lo,mi,hi,v1,vm,v2)
 // Map values between lo mid hi to values between v1 vm v2
 //--------------------------------------------------------------------------------------
-class Interpolator3pt
+class FAUST_API Interpolator3pt
 {
    private:
     Interpolator fSegment1;
@@ -632,19 +918,19 @@ class Interpolator3pt
 //--------------------------------------------------------------------------------------
 // Abstract ValueConverter class. Converts values between UI and Faust representations
 //--------------------------------------------------------------------------------------
-class ValueConverter
+class FAUST_API ValueConverter
 {
    public:
     virtual ~ValueConverter() {}
-    virtual double ui2faust(double x) = 0;
-    virtual double faust2ui(double x) = 0;
+    virtual double ui2faust(double x) { return x; };
+    virtual double faust2ui(double x) { return x; };
 };
 
 //--------------------------------------------------------------------------------------
 // A converter than can be updated
 //--------------------------------------------------------------------------------------
 
-class UpdatableValueConverter : public ValueConverter
+class FAUST_API UpdatableValueConverter : public ValueConverter
 {
    protected:
     bool fActive;
@@ -664,7 +950,7 @@ class UpdatableValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter : public ValueConverter
+class FAUST_API LinearValueConverter : public ValueConverter
 {
    private:
     Interpolator fUI2F;
@@ -684,7 +970,7 @@ class LinearValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Two segments linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter2 : public UpdatableValueConverter
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fUI2F;
@@ -720,7 +1006,7 @@ class LinearValueConverter2 : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Logarithmic conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LogValueConverter : public LinearValueConverter
+class FAUST_API LogValueConverter : public LinearValueConverter
 {
    public:
     LogValueConverter(double umin, double umax, double fmin, double fmax)
@@ -742,7 +1028,7 @@ class LogValueConverter : public LinearValueConverter
 //--------------------------------------------------------------------------------------
 // Exponential conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class ExpValueConverter : public LinearValueConverter
+class FAUST_API ExpValueConverter : public LinearValueConverter
 {
    public:
     ExpValueConverter(double umin, double umax, double fmin, double fmax)
@@ -765,7 +1051,7 @@ class ExpValueConverter : public LinearValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up curve (curve 0)
 //--------------------------------------------------------------------------------------
-class AccUpConverter : public UpdatableValueConverter
+class FAUST_API AccUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -801,7 +1087,7 @@ class AccUpConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down curve (curve 1)
 //--------------------------------------------------------------------------------------
-class AccDownConverter : public UpdatableValueConverter
+class FAUST_API AccDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -837,14 +1123,14 @@ class AccDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up-Down curve (curve 2)
 //--------------------------------------------------------------------------------------
-class AccUpDownConverter : public UpdatableValueConverter
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccUpDownConverter(double amin, double amid, double amax, double fmin, double fmid,
+    AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
                        double fmax)
         : fA2F(amin, amid, amax, fmin, fmax, fmin)
         , fF2A(fmin, fmax, amin,
@@ -856,7 +1142,7 @@ class AccUpDownConverter : public UpdatableValueConverter
     virtual double faust2ui(double x) { return fF2A(x); }
 
     virtual void setMappingValues(double amin, double amid, double amax, double fmin,
-                                  double fmid, double fmax)
+                                  double /*fmid*/, double fmax)
     {
         //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f
         //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
@@ -874,14 +1160,14 @@ class AccUpDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down-Up curve (curve 3)
 //--------------------------------------------------------------------------------------
-class AccDownUpConverter : public UpdatableValueConverter
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccDownUpConverter(double amin, double amid, double amax, double fmin, double fmid,
+    AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
                        double fmax)
         : fA2F(amin, amid, amax, fmax, fmin, fmax)
         , fF2A(fmin, fmax, amin,
@@ -893,7 +1179,7 @@ class AccDownUpConverter : public UpdatableValueConverter
     virtual double faust2ui(double x) { return fF2A(x); }
 
     virtual void setMappingValues(double amin, double amid, double amax, double fmin,
-                                  double fmid, double fmax)
+                                  double /*fmid*/, double fmax)
     {
         //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f
         //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
@@ -910,7 +1196,7 @@ class AccDownUpConverter : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Base class for ZoneControl
 //--------------------------------------------------------------------------------------
-class ZoneControl
+class FAUST_API ZoneControl
 {
    protected:
     FAUSTFLOAT* fZone;
@@ -919,17 +1205,17 @@ class ZoneControl
     ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
     virtual ~ZoneControl() {}
 
-    virtual void update(double v) const {}
+    virtual void update(double /*v*/) const {}
 
-    virtual void setMappingValues(int curve, double amin, double amid, double amax,
-                                  double min, double init, double max)
+    virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
+                                  double /*min*/, double /*init*/, double /*max*/)
     {
     }
-    virtual void getMappingValues(double& amin, double& amid, double& amax) {}
+    virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
 
     FAUSTFLOAT* getZone() { return fZone; }
 
-    virtual void setActive(bool on_off) {}
+    virtual void setActive(bool /*on_off*/) {}
     virtual bool getActive() { return false; }
 
     virtual int getCurve() { return -1; }
@@ -938,7 +1224,7 @@ class ZoneControl
 //--------------------------------------------------------------------------------------
 //  Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class ConverterZoneControl : public ZoneControl
+class FAUST_API ConverterZoneControl : public ZoneControl
 {
    protected:
     ValueConverter* fValueConverter;
@@ -953,7 +1239,10 @@ class ConverterZoneControl : public ZoneControl
         delete fValueConverter;
     }  // Assuming fValueConverter is not kept elsewhere...
 
-    virtual void update(double v) const { *fZone = fValueConverter->ui2faust(v); }
+    virtual void update(double v) const
+    {
+        *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v));
+    }
 
     ValueConverter* getConverter() { return fValueConverter; }
 };
@@ -962,7 +1251,7 @@ class ConverterZoneControl : public ZoneControl
 // Association of a zone and a four value converter, each one for each possible curve.
 // Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class CurveZoneControl : public ZoneControl
+class FAUST_API CurveZoneControl : public ZoneControl
 {
    private:
     std::vector<UpdatableValueConverter*> fValueConverters;
@@ -985,15 +1274,14 @@ class CurveZoneControl : public ZoneControl
     }
     virtual ~CurveZoneControl()
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            delete (*it);
+        for (const auto& it : fValueConverters) {
+            delete it;
         }
     }
     void update(double v) const
     {
         if (fValueConverters[fCurve]->getActive())
-            *fZone = fValueConverters[fCurve]->ui2faust(v);
+            *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v));
     }
 
     void setMappingValues(int curve, double amin, double amid, double amax, double min,
@@ -1010,16 +1298,15 @@ class CurveZoneControl : public ZoneControl
 
     void setActive(bool on_off)
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            (*it)->setActive(on_off);
+        for (const auto& it : fValueConverters) {
+            it->setActive(on_off);
         }
     }
 
     int getCurve() { return fCurve; }
 };
 
-class ZoneReader
+class FAUST_API ZoneReader
 {
    private:
     FAUSTFLOAT* fZone;
@@ -1039,6 +1326,8 @@ class ZoneReader
 #endif
 /**************************  END  ValueConverter.h **************************/
 
+typedef unsigned int uint;
+
 class APIUI
     : public PathBuilder
     , public Meta
@@ -1054,22 +1343,42 @@ class APIUI
         kHBargraph,
         kVBargraph
     };
+    enum Type { kAcc = 0, kGyr = 1, kNoType };
 
    protected:
-    enum { kLin = 0, kLog = 1, kExp = 2 };
-
-    int fNumParameters;
-    std::vector<std::string> fPaths;
-    std::vector<std::string> fLabels;
-    std::map<std::string, int> fPathMap;
-    std::map<std::string, int> fLabelMap;
-    std::vector<ValueConverter*> fConversion;
-    std::vector<FAUSTFLOAT*> fZone;
-    std::vector<FAUSTFLOAT> fInit;
-    std::vector<FAUSTFLOAT> fMin;
-    std::vector<FAUSTFLOAT> fMax;
-    std::vector<FAUSTFLOAT> fStep;
-    std::vector<ItemType> fItemType;
+    enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+    struct Item {
+        std::string fLabel;
+        std::string fShortname;
+        std::string fPath;
+        ValueConverter* fConversion;
+        FAUSTFLOAT* fZone;
+        FAUSTFLOAT fInit;
+        FAUSTFLOAT fMin;
+        FAUSTFLOAT fMax;
+        FAUSTFLOAT fStep;
+        ItemType fItemType;
+
+        Item(const std::string& label, const std::string& short_name,
+             const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+             FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+             ItemType item_type)
+            : fLabel(label)
+            , fShortname(short_name)
+            , fPath(path)
+            , fConversion(conversion)
+            , fZone(zone)
+            , fInit(init)
+            , fMin(min)
+            , fMax(max)
+            , fStep(step)
+            , fItemType(item_type)
+        {
+        }
+    };
+    std::vector<Item> fItems;
+
     std::vector<std::map<std::string, std::string> > fMetaData;
     std::vector<ZoneControl*> fAcc[3];
     std::vector<ZoneControl*> fGyr[3];
@@ -1096,33 +1405,31 @@ class APIUI
                               ItemType type)
     {
         std::string path = buildPath(label);
-        fPathMap[path] = fLabelMap[label] = fNumParameters++;
-        fPaths.push_back(path);
-        fLabels.push_back(label);
-        fZone.push_back(zone);
-        fInit.push_back(init);
-        fMin.push_back(min);
-        fMax.push_back(max);
-        fStep.push_back(step);
-        fItemType.push_back(type);
+        fFullPaths.push_back(path);
 
         // handle scale metadata
+        ValueConverter* converter = nullptr;
         switch (fCurrentScale) {
         case kLin:
-            fConversion.push_back(new LinearValueConverter(0, 1, min, max));
+            converter = new LinearValueConverter(0, 1, min, max);
             break;
         case kLog:
-            fConversion.push_back(new LogValueConverter(0, 1, min, max));
+            converter = new LogValueConverter(0, 1, min, max);
             break;
         case kExp:
-            fConversion.push_back(new ExpValueConverter(0, 1, min, max));
+            converter = new ExpValueConverter(0, 1, min, max);
             break;
         }
         fCurrentScale = kLin;
 
+        fItems.push_back(
+            Item(label, "", path, converter, zone, init, min, max, step, type));
+
         if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
-            std::cerr << "warning : 'acc' and 'gyr' metadata used for the same " << label
-                      << " parameter !!\n";
+            fprintf(
+                stderr,
+                "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n",
+                label);
         }
 
         // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
@@ -1137,7 +1444,7 @@ class APIUI
                 fAcc[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect acc metadata : " << fCurrentAcc << std::endl;
+                fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
             }
             fCurrentAcc = "";
         }
@@ -1154,31 +1461,31 @@ class APIUI
                 fGyr[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect gyr metadata : " << fCurrentGyr << std::endl;
+                fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
             }
             fCurrentGyr = "";
         }
 
         // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
         if (fCurrentColor.size() > 0) {
-            if ((fCurrentColor == "red") && (fRedReader == 0)) {
+            if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "green") && (fGreenReader == 0)) {
+            } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "blue") && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "white") && (fRedReader == 0)
-                       && (fGreenReader == 0) && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "white") && (fRedReader == nullptr)
+                       && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
             } else {
-                std::cerr << "incorrect screencolor metadata : " << fCurrentColor
-                          << std::endl;
+                fprintf(stderr, "incorrect screencolor metadata : %s \n",
+                        fCurrentColor.c_str());
             }
         }
         fCurrentColor = "";
@@ -1189,7 +1496,7 @@ class APIUI
 
     int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
     {
-        FAUSTFLOAT* zone = fZone[p];
+        FAUSTFLOAT* zone = fItems[uint(p)].fZone;
         for (size_t i = 0; i < table[val].size(); i++) {
             if (zone == table[val][i]->getZone())
                 return int(i);
@@ -1206,11 +1513,11 @@ class APIUI
 
         // Deactivates everywhere..
         if (id1 != -1)
-            table[0][id1]->setActive(false);
+            table[0][uint(id1)]->setActive(false);
         if (id2 != -1)
-            table[1][id2]->setActive(false);
+            table[1][uint(id2)]->setActive(false);
         if (id3 != -1)
-            table[2][id3]->setActive(false);
+            table[2][uint(id3)]->setActive(false);
 
         if (val == -1) {  // Means: no more mapping...
             // So stay all deactivated...
@@ -1218,14 +1525,16 @@ class APIUI
             int id4 = getZoneIndex(table, p, val);
             if (id4 != -1) {
                 // Reactivate the one we edit...
-                table[val][id4]->setMappingValues(curve, amin, amid, amax, fMin[p],
-                                                  fInit[p], fMax[p]);
-                table[val][id4]->setActive(true);
+                table[val][uint(id4)]->setMappingValues(
+                    curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit,
+                    fItems[uint(p)].fMax);
+                table[val][uint(id4)]->setActive(true);
             } else {
                 // Allocate a new CurveZoneControl which is 'active' by default
-                FAUSTFLOAT* zone = fZone[p];
-                table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax,
-                                                          fMin[p], fInit[p], fMax[p]));
+                FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+                table[val].push_back(new CurveZoneControl(
+                    zone, curve, amin, amid, amax, fItems[uint(p)].fMin,
+                    fItems[uint(p)].fInit, fItems[uint(p)].fMax));
             }
         }
     }
@@ -1239,16 +1548,16 @@ class APIUI
 
         if (id1 != -1) {
             val   = 0;
-            curve = table[val][id1]->getCurve();
-            table[val][id1]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id1)]->getCurve();
+            table[val][uint(id1)]->getMappingValues(amin, amid, amax);
         } else if (id2 != -1) {
             val   = 1;
-            curve = table[val][id2]->getCurve();
-            table[val][id2]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id2)]->getCurve();
+            table[val][uint(id2)]->getMappingValues(amin, amid, amax);
         } else if (id3 != -1) {
             val   = 2;
-            curve = table[val][id3]->getCurve();
-            table[val][id3]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id3)]->getCurve();
+            table[val][uint(id3)]->getMappingValues(amin, amid, amax);
         } else {
             val   = -1;  // No mapping
             curve = 0;
@@ -1259,26 +1568,23 @@ class APIUI
     }
 
    public:
-    enum Type { kAcc = 0, kGyr = 1, kNoType };
-
     APIUI()
-        : fNumParameters(0)
-        , fHasScreenControl(false)
-        , fRedReader(0)
-        , fGreenReader(0)
-        , fBlueReader(0)
+        : fHasScreenControl(false)
+        , fRedReader(nullptr)
+        , fGreenReader(nullptr)
+        , fBlueReader(nullptr)
         , fCurrentScale(kLin)
     {
     }
 
     virtual ~APIUI()
     {
-        for (auto& it : fConversion)
-            delete it;
+        for (const auto& it : fItems)
+            delete it.fConversion;
         for (int i = 0; i < 3; i++) {
-            for (auto& it : fAcc[i])
+            for (const auto& it : fAcc[i])
                 delete it;
-            for (auto& it : fGyr[i])
+            for (const auto& it : fGyr[i])
                 delete it;
         }
         delete fRedReader;
@@ -1291,7 +1597,18 @@ class APIUI
     virtual void openTabBox(const char* label) { pushLabel(label); }
     virtual void openHorizontalBox(const char* label) { pushLabel(label); }
     virtual void openVerticalBox(const char* label) { pushLabel(label); }
-    virtual void closeBox() { popLabel(); }
+    virtual void closeBox()
+    {
+        if (popLabel()) {
+            // Shortnames can be computed when all fullnames are known
+            computeShortNames();
+            // Fill 'shortname' field for each item
+            for (const auto& it : fFull2Short) {
+                int index                = getParamIndex(it.first.c_str());
+                fItems[index].fShortname = it.second;
+            }
+        }
+    }
 
     // -- active widgets
 
@@ -1328,25 +1645,25 @@ class APIUI
     virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone,
                                        FAUSTFLOAT min, FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kHBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kHBargraph);
     }
 
     virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min,
                                      FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kVBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kVBargraph);
     }
 
     // -- soundfiles
 
-    virtual void addSoundfile(const char* label, const char* filename,
-                              Soundfile** sf_zone)
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+                              Soundfile** /*sf_zone*/)
     {
     }
 
     // -- metadata declarations
 
-    virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+    virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
     {
         // Keep metadata
         fCurrentMetadata[key] = val;
@@ -1372,29 +1689,31 @@ class APIUI
         }
     }
 
-    virtual void declare(const char* key, const char* val) {}
+    virtual void declare(const char* /*key*/, const char* /*val*/) {}
 
     //-------------------------------------------------------------------------------
     // Simple API part
     //-------------------------------------------------------------------------------
-    int getParamsCount() { return fNumParameters; }
-    int getParamIndex(const char* path)
+    int getParamsCount() { return int(fItems.size()); }
+
+    int getParamIndex(const char* path_aux)
     {
-        if (fPathMap.find(path) != fPathMap.end()) {
-            return fPathMap[path];
-        } else if (fLabelMap.find(path) != fLabelMap.end()) {
-            return fLabelMap[path];
-        } else {
-            return -1;
-        }
+        std::string path = std::string(path_aux);
+        auto it          = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+            return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+                 });
+        return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
     }
-    const char* getParamAddress(int p) { return fPaths[p].c_str(); }
-    const char* getParamLabel(int p) { return fLabels[p].c_str(); }
+
+    const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
+    const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
+    const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+
     std::map<const char*, const char*> getMetadata(int p)
     {
         std::map<const char*, const char*> res;
-        std::map<std::string, std::string> metadata = fMetaData[p];
-        for (auto it : metadata) {
+        std::map<std::string, std::string> metadata = fMetaData[uint(p)];
+        for (const auto& it : metadata) {
             res[it.first.c_str()] = it.second.c_str();
         }
         return res;
@@ -1402,26 +1721,62 @@ class APIUI
 
     const char* getMetadata(int p, const char* key)
     {
-        return (fMetaData[p].find(key) != fMetaData[p].end()) ? fMetaData[p][key].c_str()
-                                                              : "";
+        return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end())
+                   ? fMetaData[uint(p)][key].c_str()
+                   : "";
     }
-    FAUSTFLOAT getParamMin(int p) { return fMin[p]; }
-    FAUSTFLOAT getParamMax(int p) { return fMax[p]; }
-    FAUSTFLOAT getParamStep(int p) { return fStep[p]; }
-    FAUSTFLOAT getParamInit(int p) { return fInit[p]; }
+    FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
+    FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
+    FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
+    FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
 
-    FAUSTFLOAT* getParamZone(int p) { return fZone[p]; }
-    FAUSTFLOAT getParamValue(int p) { return *fZone[p]; }
-    void setParamValue(int p, FAUSTFLOAT v) { *fZone[p] = v; }
+    FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
+
+    FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
+    FAUSTFLOAT getParamValue(const char* path)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            return getParamValue(index);
+        } else {
+            fprintf(stderr, "getParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+            return FAUSTFLOAT(0);
+        }
+    }
+
+    void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+    void setParamValue(const char* path, FAUSTFLOAT v)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            setParamValue(index, v);
+        } else {
+            fprintf(stderr, "setParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+        }
+    }
 
-    double getParamRatio(int p) { return fConversion[p]->faust2ui(*fZone[p]); }
-    void setParamRatio(int p, double r) { *fZone[p] = fConversion[p]->ui2faust(r); }
+    double getParamRatio(int p)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone);
+    }
+    void setParamRatio(int p, double r)
+    {
+        *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r));
+    }
 
-    double value2ratio(int p, double r) { return fConversion[p]->faust2ui(r); }
-    double ratio2value(int p, double r) { return fConversion[p]->ui2faust(r); }
+    double value2ratio(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(r);
+    }
+    double ratio2value(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->ui2faust(r);
+    }
 
     /**
-     * Return the control type (kAcc, kGyr, or -1) for a given parameter
+     * Return the control type (kAcc, kGyr, or -1) for a given parameter.
      *
      * @param p - the UI parameter index
      *
@@ -1443,13 +1798,13 @@ class APIUI
 
     /**
      * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry,
-     * kHBargraph, kVBargraph) for a given parameter
+     * kHBargraph, kVBargraph) for a given parameter.
      *
      * @param p - the UI parameter index
      *
      * @return the Item type
      */
-    ItemType getParamItemType(int p) { return fItemType[p]; }
+    ItemType getParamItemType(int p) { return fItems[uint(p)].fItemType; }
 
     /**
      * Set a new value coming from an accelerometer, propagate it to all relevant
@@ -1489,7 +1844,7 @@ class APIUI
      * given UI parameter.
      *
      * @param p - the UI parameter index
-     * @param acc - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+     * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
      * mapping")
      * @param curve - between 0 and 3
      * @param amin - mapping 'min' point
@@ -1554,7 +1909,7 @@ class APIUI
     }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer
+     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
      *
      * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
      * @return the number of zones
@@ -1563,7 +1918,7 @@ class APIUI
     int getAccCount(int acc) { return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0; }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope
+     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
      *
      * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
      * @param the number of zones
@@ -1600,13 +1955,11 @@ class APIUI
 #define FAUSTFLOAT float
 #endif
 
+#include <math.h>
+
 #include <algorithm>
 #include <cmath>
-
-static float zitarevdsp_faustpower2_f(float value)
-{
-    return (value * value);
-}
+#include <cstdint>
 
 #ifndef FAUSTCLASS
 #define FAUSTCLASS zitarevdsp
@@ -1617,109 +1970,105 @@ static float zitarevdsp_faustpower2_f(float value)
 #define exp10  __exp10
 #endif
 
+#if defined(_WIN32)
+#define RESTRICT __restrict
+#else
+#define RESTRICT __restrict__
+#endif
+
+static float zitarevdsp_faustpower2_f(float value)
+{
+    return value * value;
+}
+
 class zitarevdsp : public dsp
 {
    private:
-    int IOTA;
+    int IOTA0;
     float fVec0[16384];
     float fVec1[16384];
+    int fSampleRate;
+    float fConst1;
     FAUSTFLOAT fVslider0;
+    float fConst2;
     float fRec0[2];
     FAUSTFLOAT fVslider1;
     float fRec1[2];
-    int fSampleRate;
-    float fConst0;
-    float fConst1;
+    float fConst3;
     FAUSTFLOAT fVslider2;
     FAUSTFLOAT fVslider3;
     FAUSTFLOAT fVslider4;
     FAUSTFLOAT fVslider5;
-    float fConst2;
-    float fConst3;
+    float fConst5;
     FAUSTFLOAT fVslider6;
     FAUSTFLOAT fVslider7;
     FAUSTFLOAT fVslider8;
-    float fConst4;
+    float fConst6;
     FAUSTFLOAT fVslider9;
     float fRec15[2];
     float fRec14[2];
     float fVec2[32768];
-    float fConst5;
-    int iConst6;
-    float fConst7;
+    int iConst8;
+    float fConst9;
     FAUSTFLOAT fVslider10;
     float fVec3[2048];
-    int iConst8;
+    int iConst10;
     float fRec12[2];
-    float fConst9;
-    float fConst10;
+    float fConst12;
     float fRec19[2];
     float fRec18[2];
     float fVec4[32768];
-    float fConst11;
-    int iConst12;
+    int iConst14;
     float fVec5[4096];
-    int iConst13;
+    int iConst15;
     float fRec16[2];
-    float fConst14;
-    float fConst15;
+    float fConst17;
     float fRec23[2];
     float fRec22[2];
     float fVec6[16384];
-    float fConst16;
-    int iConst17;
+    int iConst19;
     float fVec7[4096];
-    int iConst18;
+    int iConst20;
     float fRec20[2];
-    float fConst19;
-    float fConst20;
+    float fConst22;
     float fRec27[2];
     float fRec26[2];
     float fVec8[32768];
-    float fConst21;
-    int iConst22;
+    int iConst24;
     float fVec9[4096];
-    int iConst23;
+    int iConst25;
     float fRec24[2];
-    float fConst24;
-    float fConst25;
+    float fConst27;
     float fRec31[2];
     float fRec30[2];
     float fVec10[16384];
-    float fConst26;
-    int iConst27;
+    int iConst29;
     float fVec11[2048];
-    int iConst28;
+    int iConst30;
     float fRec28[2];
-    float fConst29;
-    float fConst30;
+    float fConst32;
     float fRec35[2];
     float fRec34[2];
     float fVec12[16384];
-    float fConst31;
-    int iConst32;
+    int iConst34;
     float fVec13[4096];
-    int iConst33;
+    int iConst35;
     float fRec32[2];
-    float fConst34;
-    float fConst35;
+    float fConst37;
     float fRec39[2];
     float fRec38[2];
     float fVec14[16384];
-    float fConst36;
-    int iConst37;
+    int iConst39;
     float fVec15[4096];
-    int iConst38;
+    int iConst40;
     float fRec36[2];
-    float fConst39;
-    float fConst40;
+    float fConst42;
     float fRec43[2];
     float fRec42[2];
     float fVec16[16384];
-    float fConst41;
-    int iConst42;
+    int iConst44;
     float fVec17[2048];
-    int iConst43;
+    int iConst45;
     float fRec40[2];
     float fRec4[3];
     float fRec5[3];
@@ -1738,7 +2087,10 @@ class zitarevdsp : public dsp
     void metadata(Meta* m)
     {
         m->declare("basics.lib/name", "Faust Basic Element Library");
-        m->declare("basics.lib/version", "0.1");
+        m->declare("basics.lib/version", "0.8");
+        m->declare("compile_options",
+                   "-a faust2header.cpp -lang cpp -i -inpl -cn zitarevdsp -es 1 -mcd 16 "
+                   "-single -ftz 0");
         m->declare("delays.lib/name", "Faust Delay Library");
         m->declare("delays.lib/version", "0.1");
         m->declare("filename", "zitarevdsp.dsp");
@@ -1785,127 +2137,87 @@ class zitarevdsp : public dsp
             "filters.lib/tf2:copyright",
             "Copyright (C) 2003-2019 by Julius O. Smith III <jos@ccrma.stanford.edu>");
         m->declare("filters.lib/tf2:license", "MIT-style STK-4.3 license");
+        m->declare("filters.lib/version", "0.3");
         m->declare("maths.lib/author", "GRAME");
         m->declare("maths.lib/copyright", "GRAME");
         m->declare("maths.lib/license", "LGPL with exception");
         m->declare("maths.lib/name", "Faust Math Library");
-        m->declare("maths.lib/version", "2.3");
+        m->declare("maths.lib/version", "2.5");
         m->declare("name", "zitarevdsp");
         m->declare("platform.lib/name", "Generic Platform Library");
-        m->declare("platform.lib/version", "0.1");
+        m->declare("platform.lib/version", "0.2");
         m->declare("reverbs.lib/name", "Faust Reverb Library");
-        m->declare("reverbs.lib/version", "0.0");
+        m->declare("reverbs.lib/version", "0.2");
+        m->declare("routes.lib/hadamard:author", "Remy Muller, revised by Romain Michon");
         m->declare("routes.lib/name", "Faust Signal Routing Library");
         m->declare("routes.lib/version", "0.2");
         m->declare("signals.lib/name", "Faust Signal Routing Library");
-        m->declare("signals.lib/version", "0.0");
+        m->declare("signals.lib/version", "0.3");
     }
 
     virtual int getNumInputs() { return 2; }
     virtual int getNumOutputs() { return 2; }
-    virtual int getInputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        case 1: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
-    virtual int getOutputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        case 1: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
 
     static void classInit(int /*sample_rate*/) {}
 
     virtual void instanceConstants(int sample_rate)
     {
         fSampleRate = sample_rate;
-        fConst0 = std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
-        fConst1 = (6.28318548f / fConst0);
-        fConst2 = std::floor(((0.219990999f * fConst0) + 0.5f));
-        fConst3 = ((0.0f - (6.90775537f * fConst2)) / fConst0);
-        fConst4 = (3.14159274f / fConst0);
-        fConst5 = std::floor(((0.0191229992f * fConst0) + 0.5f));
-        iConst6 =
-            int(std::min<float>(16384.0f, std::max<float>(0.0f, (fConst2 - fConst5))));
-        fConst7 = (0.00100000005f * fConst0);
-        iConst8 = int(std::min<float>(1024.0f, std::max<float>(0.0f, (fConst5 + -1.0f))));
-        fConst9 = std::floor(((0.256891012f * fConst0) + 0.5f));
-        fConst10 = ((0.0f - (6.90775537f * fConst9)) / fConst0);
-        fConst11 = std::floor(((0.0273330007f * fConst0) + 0.5f));
-        iConst12 =
-            int(std::min<float>(16384.0f, std::max<float>(0.0f, (fConst9 - fConst11))));
-        iConst13 =
-            int(std::min<float>(2048.0f, std::max<float>(0.0f, (fConst11 + -1.0f))));
-        fConst14 = std::floor(((0.192303002f * fConst0) + 0.5f));
-        fConst15 = ((0.0f - (6.90775537f * fConst14)) / fConst0);
-        fConst16 = std::floor(((0.0292910002f * fConst0) + 0.5f));
-        iConst17 =
-            int(std::min<float>(8192.0f, std::max<float>(0.0f, (fConst14 - fConst16))));
-        iConst18 =
-            int(std::min<float>(2048.0f, std::max<float>(0.0f, (fConst16 + -1.0f))));
-        fConst19 = std::floor(((0.210389003f * fConst0) + 0.5f));
-        fConst20 = ((0.0f - (6.90775537f * fConst19)) / fConst0);
-        fConst21 = std::floor(((0.0244210009f * fConst0) + 0.5f));
-        iConst22 =
-            int(std::min<float>(16384.0f, std::max<float>(0.0f, (fConst19 - fConst21))));
-        iConst23 =
-            int(std::min<float>(2048.0f, std::max<float>(0.0f, (fConst21 + -1.0f))));
-        fConst24 = std::floor(((0.125f * fConst0) + 0.5f));
-        fConst25 = ((0.0f - (6.90775537f * fConst24)) / fConst0);
-        fConst26 = std::floor(((0.0134579996f * fConst0) + 0.5f));
-        iConst27 =
-            int(std::min<float>(8192.0f, std::max<float>(0.0f, (fConst24 - fConst26))));
-        iConst28 =
-            int(std::min<float>(1024.0f, std::max<float>(0.0f, (fConst26 + -1.0f))));
-        fConst29 = std::floor(((0.127837002f * fConst0) + 0.5f));
-        fConst30 = ((0.0f - (6.90775537f * fConst29)) / fConst0);
-        fConst31 = std::floor(((0.0316039994f * fConst0) + 0.5f));
-        iConst32 =
-            int(std::min<float>(8192.0f, std::max<float>(0.0f, (fConst29 - fConst31))));
-        iConst33 =
-            int(std::min<float>(2048.0f, std::max<float>(0.0f, (fConst31 + -1.0f))));
-        fConst34 = std::floor(((0.174713001f * fConst0) + 0.5f));
-        fConst35 = ((0.0f - (6.90775537f * fConst34)) / fConst0);
-        fConst36 = std::floor(((0.0229039993f * fConst0) + 0.5f));
-        iConst37 =
-            int(std::min<float>(8192.0f, std::max<float>(0.0f, (fConst34 - fConst36))));
-        iConst38 =
-            int(std::min<float>(2048.0f, std::max<float>(0.0f, (fConst36 + -1.0f))));
-        fConst39 = std::floor(((0.153128996f * fConst0) + 0.5f));
-        fConst40 = ((0.0f - (6.90775537f * fConst39)) / fConst0);
-        fConst41 = std::floor(((0.0203460008f * fConst0) + 0.5f));
-        iConst42 =
-            int(std::min<float>(8192.0f, std::max<float>(0.0f, (fConst39 - fConst41))));
-        iConst43 =
-            int(std::min<float>(1024.0f, std::max<float>(0.0f, (fConst41 + -1.0f))));
+        float fConst0 =
+            std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
+        fConst1       = 44.0999985f / fConst0;
+        fConst2       = 1.0f - fConst1;
+        fConst3       = 6.28318548f / fConst0;
+        float fConst4 = std::floor(0.219990999f * fConst0 + 0.5f);
+        fConst5       = (0.0f - 6.90775537f * fConst4) / fConst0;
+        fConst6       = 3.14159274f / fConst0;
+        float fConst7 = std::floor(0.0191229992f * fConst0 + 0.5f);
+        iConst8 =
+            int(std::min<float>(16384.0f, std::max<float>(0.0f, fConst4 - fConst7)));
+        fConst9  = 0.00100000005f * fConst0;
+        iConst10 = int(std::min<float>(1024.0f, std::max<float>(0.0f, fConst7 + -1.0f)));
+        float fConst11 = std::floor(0.256891012f * fConst0 + 0.5f);
+        fConst12       = (0.0f - 6.90775537f * fConst11) / fConst0;
+        float fConst13 = std::floor(0.0273330007f * fConst0 + 0.5f);
+        iConst14 =
+            int(std::min<float>(16384.0f, std::max<float>(0.0f, fConst11 - fConst13)));
+        iConst15 = int(std::min<float>(2048.0f, std::max<float>(0.0f, fConst13 + -1.0f)));
+        float fConst16 = std::floor(0.192303002f * fConst0 + 0.5f);
+        fConst17       = (0.0f - 6.90775537f * fConst16) / fConst0;
+        float fConst18 = std::floor(0.0292910002f * fConst0 + 0.5f);
+        iConst19 =
+            int(std::min<float>(8192.0f, std::max<float>(0.0f, fConst16 - fConst18)));
+        iConst20 = int(std::min<float>(2048.0f, std::max<float>(0.0f, fConst18 + -1.0f)));
+        float fConst21 = std::floor(0.210389003f * fConst0 + 0.5f);
+        fConst22       = (0.0f - 6.90775537f * fConst21) / fConst0;
+        float fConst23 = std::floor(0.0244210009f * fConst0 + 0.5f);
+        iConst24 =
+            int(std::min<float>(16384.0f, std::max<float>(0.0f, fConst21 - fConst23)));
+        iConst25 = int(std::min<float>(2048.0f, std::max<float>(0.0f, fConst23 + -1.0f)));
+        float fConst26 = std::floor(0.125f * fConst0 + 0.5f);
+        fConst27       = (0.0f - 6.90775537f * fConst26) / fConst0;
+        float fConst28 = std::floor(0.0134579996f * fConst0 + 0.5f);
+        iConst29 =
+            int(std::min<float>(8192.0f, std::max<float>(0.0f, fConst26 - fConst28)));
+        iConst30 = int(std::min<float>(1024.0f, std::max<float>(0.0f, fConst28 + -1.0f)));
+        float fConst31 = std::floor(0.127837002f * fConst0 + 0.5f);
+        fConst32       = (0.0f - 6.90775537f * fConst31) / fConst0;
+        float fConst33 = std::floor(0.0316039994f * fConst0 + 0.5f);
+        iConst34 =
+            int(std::min<float>(8192.0f, std::max<float>(0.0f, fConst31 - fConst33)));
+        iConst35 = int(std::min<float>(2048.0f, std::max<float>(0.0f, fConst33 + -1.0f)));
+        float fConst36 = std::floor(0.174713001f * fConst0 + 0.5f);
+        fConst37       = (0.0f - 6.90775537f * fConst36) / fConst0;
+        float fConst38 = std::floor(0.0229039993f * fConst0 + 0.5f);
+        iConst39 =
+            int(std::min<float>(8192.0f, std::max<float>(0.0f, fConst36 - fConst38)));
+        iConst40 = int(std::min<float>(2048.0f, std::max<float>(0.0f, fConst38 + -1.0f)));
+        float fConst41 = std::floor(0.153128996f * fConst0 + 0.5f);
+        fConst42       = (0.0f - 6.90775537f * fConst41) / fConst0;
+        float fConst43 = std::floor(0.0203460008f * fConst0 + 0.5f);
+        iConst44 =
+            int(std::min<float>(8192.0f, std::max<float>(0.0f, fConst41 - fConst43)));
+        iConst45 = int(std::min<float>(1024.0f, std::max<float>(0.0f, fConst43 + -1.0f)));
     }
 
     virtual void instanceResetUserInterface()
@@ -1925,173 +2237,173 @@ class zitarevdsp : public dsp
 
     virtual void instanceClear()
     {
-        IOTA = 0;
-        for (int l0 = 0; (l0 < 16384); l0 = (l0 + 1)) {
+        IOTA0 = 0;
+        for (int l0 = 0; l0 < 16384; l0 = l0 + 1) {
             fVec0[l0] = 0.0f;
         }
-        for (int l1 = 0; (l1 < 16384); l1 = (l1 + 1)) {
+        for (int l1 = 0; l1 < 16384; l1 = l1 + 1) {
             fVec1[l1] = 0.0f;
         }
-        for (int l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
+        for (int l2 = 0; l2 < 2; l2 = l2 + 1) {
             fRec0[l2] = 0.0f;
         }
-        for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) {
+        for (int l3 = 0; l3 < 2; l3 = l3 + 1) {
             fRec1[l3] = 0.0f;
         }
-        for (int l4 = 0; (l4 < 2); l4 = (l4 + 1)) {
+        for (int l4 = 0; l4 < 2; l4 = l4 + 1) {
             fRec15[l4] = 0.0f;
         }
-        for (int l5 = 0; (l5 < 2); l5 = (l5 + 1)) {
+        for (int l5 = 0; l5 < 2; l5 = l5 + 1) {
             fRec14[l5] = 0.0f;
         }
-        for (int l6 = 0; (l6 < 32768); l6 = (l6 + 1)) {
+        for (int l6 = 0; l6 < 32768; l6 = l6 + 1) {
             fVec2[l6] = 0.0f;
         }
-        for (int l7 = 0; (l7 < 2048); l7 = (l7 + 1)) {
+        for (int l7 = 0; l7 < 2048; l7 = l7 + 1) {
             fVec3[l7] = 0.0f;
         }
-        for (int l8 = 0; (l8 < 2); l8 = (l8 + 1)) {
+        for (int l8 = 0; l8 < 2; l8 = l8 + 1) {
             fRec12[l8] = 0.0f;
         }
-        for (int l9 = 0; (l9 < 2); l9 = (l9 + 1)) {
+        for (int l9 = 0; l9 < 2; l9 = l9 + 1) {
             fRec19[l9] = 0.0f;
         }
-        for (int l10 = 0; (l10 < 2); l10 = (l10 + 1)) {
+        for (int l10 = 0; l10 < 2; l10 = l10 + 1) {
             fRec18[l10] = 0.0f;
         }
-        for (int l11 = 0; (l11 < 32768); l11 = (l11 + 1)) {
+        for (int l11 = 0; l11 < 32768; l11 = l11 + 1) {
             fVec4[l11] = 0.0f;
         }
-        for (int l12 = 0; (l12 < 4096); l12 = (l12 + 1)) {
+        for (int l12 = 0; l12 < 4096; l12 = l12 + 1) {
             fVec5[l12] = 0.0f;
         }
-        for (int l13 = 0; (l13 < 2); l13 = (l13 + 1)) {
+        for (int l13 = 0; l13 < 2; l13 = l13 + 1) {
             fRec16[l13] = 0.0f;
         }
-        for (int l14 = 0; (l14 < 2); l14 = (l14 + 1)) {
+        for (int l14 = 0; l14 < 2; l14 = l14 + 1) {
             fRec23[l14] = 0.0f;
         }
-        for (int l15 = 0; (l15 < 2); l15 = (l15 + 1)) {
+        for (int l15 = 0; l15 < 2; l15 = l15 + 1) {
             fRec22[l15] = 0.0f;
         }
-        for (int l16 = 0; (l16 < 16384); l16 = (l16 + 1)) {
+        for (int l16 = 0; l16 < 16384; l16 = l16 + 1) {
             fVec6[l16] = 0.0f;
         }
-        for (int l17 = 0; (l17 < 4096); l17 = (l17 + 1)) {
+        for (int l17 = 0; l17 < 4096; l17 = l17 + 1) {
             fVec7[l17] = 0.0f;
         }
-        for (int l18 = 0; (l18 < 2); l18 = (l18 + 1)) {
+        for (int l18 = 0; l18 < 2; l18 = l18 + 1) {
             fRec20[l18] = 0.0f;
         }
-        for (int l19 = 0; (l19 < 2); l19 = (l19 + 1)) {
+        for (int l19 = 0; l19 < 2; l19 = l19 + 1) {
             fRec27[l19] = 0.0f;
         }
-        for (int l20 = 0; (l20 < 2); l20 = (l20 + 1)) {
+        for (int l20 = 0; l20 < 2; l20 = l20 + 1) {
             fRec26[l20] = 0.0f;
         }
-        for (int l21 = 0; (l21 < 32768); l21 = (l21 + 1)) {
+        for (int l21 = 0; l21 < 32768; l21 = l21 + 1) {
             fVec8[l21] = 0.0f;
         }
-        for (int l22 = 0; (l22 < 4096); l22 = (l22 + 1)) {
+        for (int l22 = 0; l22 < 4096; l22 = l22 + 1) {
             fVec9[l22] = 0.0f;
         }
-        for (int l23 = 0; (l23 < 2); l23 = (l23 + 1)) {
+        for (int l23 = 0; l23 < 2; l23 = l23 + 1) {
             fRec24[l23] = 0.0f;
         }
-        for (int l24 = 0; (l24 < 2); l24 = (l24 + 1)) {
+        for (int l24 = 0; l24 < 2; l24 = l24 + 1) {
             fRec31[l24] = 0.0f;
         }
-        for (int l25 = 0; (l25 < 2); l25 = (l25 + 1)) {
+        for (int l25 = 0; l25 < 2; l25 = l25 + 1) {
             fRec30[l25] = 0.0f;
         }
-        for (int l26 = 0; (l26 < 16384); l26 = (l26 + 1)) {
+        for (int l26 = 0; l26 < 16384; l26 = l26 + 1) {
             fVec10[l26] = 0.0f;
         }
-        for (int l27 = 0; (l27 < 2048); l27 = (l27 + 1)) {
+        for (int l27 = 0; l27 < 2048; l27 = l27 + 1) {
             fVec11[l27] = 0.0f;
         }
-        for (int l28 = 0; (l28 < 2); l28 = (l28 + 1)) {
+        for (int l28 = 0; l28 < 2; l28 = l28 + 1) {
             fRec28[l28] = 0.0f;
         }
-        for (int l29 = 0; (l29 < 2); l29 = (l29 + 1)) {
+        for (int l29 = 0; l29 < 2; l29 = l29 + 1) {
             fRec35[l29] = 0.0f;
         }
-        for (int l30 = 0; (l30 < 2); l30 = (l30 + 1)) {
+        for (int l30 = 0; l30 < 2; l30 = l30 + 1) {
             fRec34[l30] = 0.0f;
         }
-        for (int l31 = 0; (l31 < 16384); l31 = (l31 + 1)) {
+        for (int l31 = 0; l31 < 16384; l31 = l31 + 1) {
             fVec12[l31] = 0.0f;
         }
-        for (int l32 = 0; (l32 < 4096); l32 = (l32 + 1)) {
+        for (int l32 = 0; l32 < 4096; l32 = l32 + 1) {
             fVec13[l32] = 0.0f;
         }
-        for (int l33 = 0; (l33 < 2); l33 = (l33 + 1)) {
+        for (int l33 = 0; l33 < 2; l33 = l33 + 1) {
             fRec32[l33] = 0.0f;
         }
-        for (int l34 = 0; (l34 < 2); l34 = (l34 + 1)) {
+        for (int l34 = 0; l34 < 2; l34 = l34 + 1) {
             fRec39[l34] = 0.0f;
         }
-        for (int l35 = 0; (l35 < 2); l35 = (l35 + 1)) {
+        for (int l35 = 0; l35 < 2; l35 = l35 + 1) {
             fRec38[l35] = 0.0f;
         }
-        for (int l36 = 0; (l36 < 16384); l36 = (l36 + 1)) {
+        for (int l36 = 0; l36 < 16384; l36 = l36 + 1) {
             fVec14[l36] = 0.0f;
         }
-        for (int l37 = 0; (l37 < 4096); l37 = (l37 + 1)) {
+        for (int l37 = 0; l37 < 4096; l37 = l37 + 1) {
             fVec15[l37] = 0.0f;
         }
-        for (int l38 = 0; (l38 < 2); l38 = (l38 + 1)) {
+        for (int l38 = 0; l38 < 2; l38 = l38 + 1) {
             fRec36[l38] = 0.0f;
         }
-        for (int l39 = 0; (l39 < 2); l39 = (l39 + 1)) {
+        for (int l39 = 0; l39 < 2; l39 = l39 + 1) {
             fRec43[l39] = 0.0f;
         }
-        for (int l40 = 0; (l40 < 2); l40 = (l40 + 1)) {
+        for (int l40 = 0; l40 < 2; l40 = l40 + 1) {
             fRec42[l40] = 0.0f;
         }
-        for (int l41 = 0; (l41 < 16384); l41 = (l41 + 1)) {
+        for (int l41 = 0; l41 < 16384; l41 = l41 + 1) {
             fVec16[l41] = 0.0f;
         }
-        for (int l42 = 0; (l42 < 2048); l42 = (l42 + 1)) {
+        for (int l42 = 0; l42 < 2048; l42 = l42 + 1) {
             fVec17[l42] = 0.0f;
         }
-        for (int l43 = 0; (l43 < 2); l43 = (l43 + 1)) {
+        for (int l43 = 0; l43 < 2; l43 = l43 + 1) {
             fRec40[l43] = 0.0f;
         }
-        for (int l44 = 0; (l44 < 3); l44 = (l44 + 1)) {
+        for (int l44 = 0; l44 < 3; l44 = l44 + 1) {
             fRec4[l44] = 0.0f;
         }
-        for (int l45 = 0; (l45 < 3); l45 = (l45 + 1)) {
+        for (int l45 = 0; l45 < 3; l45 = l45 + 1) {
             fRec5[l45] = 0.0f;
         }
-        for (int l46 = 0; (l46 < 3); l46 = (l46 + 1)) {
+        for (int l46 = 0; l46 < 3; l46 = l46 + 1) {
             fRec6[l46] = 0.0f;
         }
-        for (int l47 = 0; (l47 < 3); l47 = (l47 + 1)) {
+        for (int l47 = 0; l47 < 3; l47 = l47 + 1) {
             fRec7[l47] = 0.0f;
         }
-        for (int l48 = 0; (l48 < 3); l48 = (l48 + 1)) {
+        for (int l48 = 0; l48 < 3; l48 = l48 + 1) {
             fRec8[l48] = 0.0f;
         }
-        for (int l49 = 0; (l49 < 3); l49 = (l49 + 1)) {
+        for (int l49 = 0; l49 < 3; l49 = l49 + 1) {
             fRec9[l49] = 0.0f;
         }
-        for (int l50 = 0; (l50 < 3); l50 = (l50 + 1)) {
+        for (int l50 = 0; l50 < 3; l50 = l50 + 1) {
             fRec10[l50] = 0.0f;
         }
-        for (int l51 = 0; (l51 < 3); l51 = (l51 + 1)) {
+        for (int l51 = 0; l51 < 3; l51 = l51 + 1) {
             fRec11[l51] = 0.0f;
         }
-        for (int l52 = 0; (l52 < 3); l52 = (l52 + 1)) {
+        for (int l52 = 0; l52 < 3; l52 = l52 + 1) {
             fRec3[l52] = 0.0f;
         }
-        for (int l53 = 0; (l53 < 3); l53 = (l53 + 1)) {
+        for (int l53 = 0; l53 < 3; l53 = l53 + 1) {
             fRec2[l53] = 0.0f;
         }
-        for (int l54 = 0; (l54 < 3); l54 = (l54 + 1)) {
+        for (int l54 = 0; l54 < 3; l54 = l54 + 1) {
             fRec45[l54] = 0.0f;
         }
-        for (int l55 = 0; (l55 < 3); l55 = (l55 + 1)) {
+        for (int l55 = 0; l55 < 3; l55 = l55 + 1) {
             fRec44[l55] = 0.0f;
         }
     }
@@ -2127,8 +2439,9 @@ class zitarevdsp : public dsp
         ui_interface->declare(&fVslider10, "tooltip",
                               "Delay in ms   before reverberation begins");
         ui_interface->declare(&fVslider10, "unit", "ms");
-        ui_interface->addVerticalSlider("In Delay", &fVslider10, 60.0f, 20.0f, 100.0f,
-                                        1.0f);
+        ui_interface->addVerticalSlider("In Delay", &fVslider10, FAUSTFLOAT(60.0f),
+                                        FAUSTFLOAT(20.0f), FAUSTFLOAT(100.0f),
+                                        FAUSTFLOAT(1.0f));
         ui_interface->closeBox();
         ui_interface->declare(0, "2", "");
         ui_interface->openHorizontalBox("Decay Times in Bands (see tooltips)");
@@ -2139,7 +2452,9 @@ class zitarevdsp : public dsp
             &fVslider9, "tooltip",
             "Crossover frequency (Hz) separating low and middle frequencies");
         ui_interface->declare(&fVslider9, "unit", "Hz");
-        ui_interface->addVerticalSlider("LF X", &fVslider9, 200.0f, 50.0f, 1000.0f, 1.0f);
+        ui_interface->addVerticalSlider("LF X", &fVslider9, FAUSTFLOAT(200.0f),
+                                        FAUSTFLOAT(50.0f), FAUSTFLOAT(1000.0f),
+                                        FAUSTFLOAT(1.0f));
         ui_interface->declare(&fVslider8, "2", "");
         ui_interface->declare(&fVslider8, "scale", "log");
         ui_interface->declare(&fVslider8, "style", "knob");
@@ -2147,16 +2462,18 @@ class zitarevdsp : public dsp
             &fVslider8, "tooltip",
             "T60 = time (in seconds) to decay 60dB in low-frequency band");
         ui_interface->declare(&fVslider8, "unit", "s");
-        ui_interface->addVerticalSlider("Low RT60", &fVslider8, 3.0f, 1.0f, 8.0f,
-                                        0.100000001f);
+        ui_interface->addVerticalSlider("Low RT60", &fVslider8, FAUSTFLOAT(3.0f),
+                                        FAUSTFLOAT(1.0f), FAUSTFLOAT(8.0f),
+                                        FAUSTFLOAT(0.100000001f));
         ui_interface->declare(&fVslider6, "3", "");
         ui_interface->declare(&fVslider6, "scale", "log");
         ui_interface->declare(&fVslider6, "style", "knob");
         ui_interface->declare(&fVslider6, "tooltip",
                               "T60 = time (in seconds) to decay 60dB in middle band");
         ui_interface->declare(&fVslider6, "unit", "s");
-        ui_interface->addVerticalSlider("Mid RT60", &fVslider6, 2.0f, 1.0f, 8.0f,
-                                        0.100000001f);
+        ui_interface->addVerticalSlider("Mid RT60", &fVslider6, FAUSTFLOAT(2.0f),
+                                        FAUSTFLOAT(1.0f), FAUSTFLOAT(8.0f),
+                                        FAUSTFLOAT(0.100000001f));
         ui_interface->declare(&fVslider7, "4", "");
         ui_interface->declare(&fVslider7, "scale", "log");
         ui_interface->declare(&fVslider7, "style", "knob");
@@ -2164,8 +2481,9 @@ class zitarevdsp : public dsp
                               "Frequency (Hz) at which the high-frequency T60 is half "
                               "the middle-band's T60");
         ui_interface->declare(&fVslider7, "unit", "Hz");
-        ui_interface->addVerticalSlider("HF Damping", &fVslider7, 6000.0f, 1500.0f,
-                                        23520.0f, 1.0f);
+        ui_interface->addVerticalSlider("HF Damping", &fVslider7, FAUSTFLOAT(6000.0f),
+                                        FAUSTFLOAT(1500.0f), FAUSTFLOAT(23520.0f),
+                                        FAUSTFLOAT(1.0f));
         ui_interface->closeBox();
         ui_interface->declare(0, "3", "");
         ui_interface->openHorizontalBox("RM Peaking Equalizer 1");
@@ -2176,16 +2494,18 @@ class zitarevdsp : public dsp
             &fVslider4, "tooltip",
             "Center-frequency of second-order Regalia-Mitra peaking equalizer section 1");
         ui_interface->declare(&fVslider4, "unit", "Hz");
-        ui_interface->addVerticalSlider("Eq1 Freq", &fVslider4, 315.0f, 40.0f, 2500.0f,
-                                        1.0f);
+        ui_interface->addVerticalSlider("Eq1 Freq", &fVslider4, FAUSTFLOAT(315.0f),
+                                        FAUSTFLOAT(40.0f), FAUSTFLOAT(2500.0f),
+                                        FAUSTFLOAT(1.0f));
         ui_interface->declare(&fVslider5, "2", "");
         ui_interface->declare(&fVslider5, "style", "knob");
         ui_interface->declare(&fVslider5, "tooltip",
                               "Peak level   in dB of second-order Regalia-Mitra peaking "
                               "equalizer section 1");
         ui_interface->declare(&fVslider5, "unit", "dB");
-        ui_interface->addVerticalSlider("Eq1 Level", &fVslider5, 0.0f, -15.0f, 15.0f,
-                                        0.100000001f);
+        ui_interface->addVerticalSlider("Eq1 Level", &fVslider5, FAUSTFLOAT(0.0f),
+                                        FAUSTFLOAT(-15.0f), FAUSTFLOAT(15.0f),
+                                        FAUSTFLOAT(0.100000001f));
         ui_interface->closeBox();
         ui_interface->declare(0, "4", "");
         ui_interface->openHorizontalBox("RM Peaking Equalizer 2");
@@ -2196,30 +2516,34 @@ class zitarevdsp : public dsp
             &fVslider2, "tooltip",
             "Center-frequency of second-order Regalia-Mitra peaking equalizer section 2");
         ui_interface->declare(&fVslider2, "unit", "Hz");
-        ui_interface->addVerticalSlider("Eq2 Freq", &fVslider2, 1500.0f, 160.0f, 10000.0f,
-                                        1.0f);
+        ui_interface->addVerticalSlider("Eq2 Freq", &fVslider2, FAUSTFLOAT(1500.0f),
+                                        FAUSTFLOAT(160.0f), FAUSTFLOAT(10000.0f),
+                                        FAUSTFLOAT(1.0f));
         ui_interface->declare(&fVslider3, "2", "");
         ui_interface->declare(&fVslider3, "style", "knob");
         ui_interface->declare(&fVslider3, "tooltip",
                               "Peak level   in dB of second-order Regalia-Mitra peaking "
                               "equalizer section 2");
         ui_interface->declare(&fVslider3, "unit", "dB");
-        ui_interface->addVerticalSlider("Eq2 Level", &fVslider3, 0.0f, -15.0f, 15.0f,
-                                        0.100000001f);
+        ui_interface->addVerticalSlider("Eq2 Level", &fVslider3, FAUSTFLOAT(0.0f),
+                                        FAUSTFLOAT(-15.0f), FAUSTFLOAT(15.0f),
+                                        FAUSTFLOAT(0.100000001f));
         ui_interface->closeBox();
         ui_interface->declare(0, "5", "");
         ui_interface->openHorizontalBox("Output");
         ui_interface->declare(&fVslider1, "1", "");
         ui_interface->declare(&fVslider1, "style", "knob");
         ui_interface->declare(&fVslider1, "tooltip", "Dry/Wet Mix: 0 = dry, 1 = wet");
-        ui_interface->addVerticalSlider("Wet", &fVslider1, 0.0f, 0.0f, 1.0f,
-                                        0.00999999978f);
+        ui_interface->addVerticalSlider("Wet", &fVslider1, FAUSTFLOAT(0.0f),
+                                        FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+                                        FAUSTFLOAT(0.00999999978f));
         ui_interface->declare(&fVslider0, "2", "");
         ui_interface->declare(&fVslider0, "style", "knob");
         ui_interface->declare(&fVslider0, "tooltip", "Output scale   factor");
         ui_interface->declare(&fVslider0, "unit", "dB");
-        ui_interface->addVerticalSlider("Level", &fVslider0, -3.0f, -70.0f, 20.0f,
-                                        0.100000001f);
+        ui_interface->addVerticalSlider("Level", &fVslider0, FAUSTFLOAT(-3.0f),
+                                        FAUSTFLOAT(-70.0f), FAUSTFLOAT(20.0f),
+                                        FAUSTFLOAT(0.100000001f));
         ui_interface->closeBox();
         ui_interface->closeBox();
     }
@@ -2230,312 +2554,247 @@ class zitarevdsp : public dsp
         FAUSTFLOAT* input1  = inputs[1];
         FAUSTFLOAT* output0 = outputs[0];
         FAUSTFLOAT* output1 = outputs[1];
-        float fSlow0 =
-            (0.00100000005f * std::pow(10.0f, (0.0500000007f * float(fVslider0))));
-        float fSlow1  = (0.00100000005f * float(fVslider1));
-        float fSlow2  = float(fVslider2);
-        float fSlow3  = std::pow(10.0f, (0.0500000007f * float(fVslider3)));
-        float fSlow4  = (fConst1 * (fSlow2 / std::sqrt(std::max<float>(0.0f, fSlow3))));
-        float fSlow5  = ((1.0f - fSlow4) / (fSlow4 + 1.0f));
-        float fSlow6  = float(fVslider4);
-        float fSlow7  = std::pow(10.0f, (0.0500000007f * float(fVslider5)));
-        float fSlow8  = (fConst1 * (fSlow6 / std::sqrt(std::max<float>(0.0f, fSlow7))));
-        float fSlow9  = ((1.0f - fSlow8) / (fSlow8 + 1.0f));
-        float fSlow10 = float(fVslider6);
-        float fSlow11 = std::exp((fConst3 / fSlow10));
-        float fSlow12 = zitarevdsp_faustpower2_f(fSlow11);
-        float fSlow13 = std::cos((fConst1 * float(fVslider7)));
-        float fSlow14 = (1.0f - (fSlow12 * fSlow13));
-        float fSlow15 = (1.0f - fSlow12);
-        float fSlow16 = (fSlow14 / fSlow15);
-        float fSlow17 = std::sqrt(std::max<float>(
-            0.0f, ((zitarevdsp_faustpower2_f(fSlow14) / zitarevdsp_faustpower2_f(fSlow15))
-                   + -1.0f)));
-        float fSlow18 = (fSlow16 - fSlow17);
-        float fSlow19 = (fSlow11 * (fSlow17 + (1.0f - fSlow16)));
-        float fSlow20 = float(fVslider8);
-        float fSlow21 = ((std::exp((fConst3 / fSlow20)) / fSlow11) + -1.0f);
-        float fSlow22 = (1.0f / std::tan((fConst4 * float(fVslider9))));
-        float fSlow23 = (1.0f / (fSlow22 + 1.0f));
-        float fSlow24 = (1.0f - fSlow22);
-        int iSlow25   = int(std::min<float>(
-            8192.0f, std::max<float>(0.0f, (fConst7 * float(fVslider10)))));
-        float fSlow26 = std::exp((fConst10 / fSlow10));
+        float fSlow0        = fConst1 * std::pow(10.0f, 0.0500000007f * float(fVslider0));
+        float fSlow1        = fConst1 * float(fVslider1);
+        float fSlow2        = float(fVslider2);
+        float fSlow3        = std::pow(10.0f, 0.0500000007f * float(fVslider3));
+        float fSlow4        = fConst3 * fSlow2 / std::sqrt(std::max<float>(0.0f, fSlow3));
+        float fSlow5        = (1.0f - fSlow4) / (fSlow4 + 1.0f);
+        float fSlow6        = float(fVslider4);
+        float fSlow7        = std::pow(10.0f, 0.0500000007f * float(fVslider5));
+        float fSlow8        = fConst3 * fSlow6 / std::sqrt(std::max<float>(0.0f, fSlow7));
+        float fSlow9        = (1.0f - fSlow8) / (fSlow8 + 1.0f);
+        float fSlow10       = float(fVslider6);
+        float fSlow11       = std::exp(fConst5 / fSlow10);
+        float fSlow12       = zitarevdsp_faustpower2_f(fSlow11);
+        float fSlow13       = std::cos(fConst3 * float(fVslider7));
+        float fSlow14       = 1.0f - fSlow12 * fSlow13;
+        float fSlow15       = 1.0f - fSlow12;
+        float fSlow16       = std::sqrt(std::max<float>(
+            0.0f, zitarevdsp_faustpower2_f(fSlow14) / zitarevdsp_faustpower2_f(fSlow15)
+                      + -1.0f));
+        float fSlow17       = fSlow14 / fSlow15;
+        float fSlow18       = fSlow11 * (fSlow16 + 1.0f - fSlow17);
+        float fSlow19       = float(fVslider8);
+        float fSlow20       = std::exp(fConst5 / fSlow19) / fSlow11 + -1.0f;
+        float fSlow21       = 1.0f / std::tan(fConst6 * float(fVslider9));
+        float fSlow22       = 1.0f / (fSlow21 + 1.0f);
+        float fSlow23       = 1.0f - fSlow21;
+        float fSlow24       = fSlow17 - fSlow16;
+        int iSlow25         = int(
+            std::min<float>(8192.0f, std::max<float>(0.0f, fConst9 * float(fVslider10))));
+        float fSlow26 = std::exp(fConst12 / fSlow10);
         float fSlow27 = zitarevdsp_faustpower2_f(fSlow26);
-        float fSlow28 = (1.0f - (fSlow27 * fSlow13));
-        float fSlow29 = (1.0f - fSlow27);
-        float fSlow30 = (fSlow28 / fSlow29);
-        float fSlow31 = std::sqrt(std::max<float>(
-            0.0f, ((zitarevdsp_faustpower2_f(fSlow28) / zitarevdsp_faustpower2_f(fSlow29))
-                   + -1.0f)));
-        float fSlow32 = (fSlow30 - fSlow31);
-        float fSlow33 = (fSlow26 * (fSlow31 + (1.0f - fSlow30)));
-        float fSlow34 = ((std::exp((fConst10 / fSlow20)) / fSlow26) + -1.0f);
-        float fSlow35 = std::exp((fConst15 / fSlow10));
+        float fSlow28 = 1.0f - fSlow27 * fSlow13;
+        float fSlow29 = 1.0f - fSlow27;
+        float fSlow30 = std::sqrt(std::max<float>(
+            0.0f, zitarevdsp_faustpower2_f(fSlow28) / zitarevdsp_faustpower2_f(fSlow29)
+                      + -1.0f));
+        float fSlow31 = fSlow28 / fSlow29;
+        float fSlow32 = fSlow26 * (fSlow30 + 1.0f - fSlow31);
+        float fSlow33 = std::exp(fConst12 / fSlow19) / fSlow26 + -1.0f;
+        float fSlow34 = fSlow31 - fSlow30;
+        float fSlow35 = std::exp(fConst17 / fSlow10);
         float fSlow36 = zitarevdsp_faustpower2_f(fSlow35);
-        float fSlow37 = (1.0f - (fSlow36 * fSlow13));
-        float fSlow38 = (1.0f - fSlow36);
-        float fSlow39 = (fSlow37 / fSlow38);
-        float fSlow40 = std::sqrt(std::max<float>(
-            0.0f, ((zitarevdsp_faustpower2_f(fSlow37) / zitarevdsp_faustpower2_f(fSlow38))
-                   + -1.0f)));
-        float fSlow41 = (fSlow39 - fSlow40);
-        float fSlow42 = (fSlow35 * (fSlow40 + (1.0f - fSlow39)));
-        float fSlow43 = ((std::exp((fConst15 / fSlow20)) / fSlow35) + -1.0f);
-        float fSlow44 = std::exp((fConst20 / fSlow10));
+        float fSlow37 = 1.0f - fSlow36 * fSlow13;
+        float fSlow38 = 1.0f - fSlow36;
+        float fSlow39 = std::sqrt(std::max<float>(
+            0.0f, zitarevdsp_faustpower2_f(fSlow37) / zitarevdsp_faustpower2_f(fSlow38)
+                      + -1.0f));
+        float fSlow40 = fSlow37 / fSlow38;
+        float fSlow41 = fSlow35 * (fSlow39 + 1.0f - fSlow40);
+        float fSlow42 = std::exp(fConst17 / fSlow19) / fSlow35 + -1.0f;
+        float fSlow43 = fSlow40 - fSlow39;
+        float fSlow44 = std::exp(fConst22 / fSlow10);
         float fSlow45 = zitarevdsp_faustpower2_f(fSlow44);
-        float fSlow46 = (1.0f - (fSlow45 * fSlow13));
-        float fSlow47 = (1.0f - fSlow45);
-        float fSlow48 = (fSlow46 / fSlow47);
-        float fSlow49 = std::sqrt(std::max<float>(
-            0.0f, ((zitarevdsp_faustpower2_f(fSlow46) / zitarevdsp_faustpower2_f(fSlow47))
-                   + -1.0f)));
-        float fSlow50 = (fSlow48 - fSlow49);
-        float fSlow51 = (fSlow44 * (fSlow49 + (1.0f - fSlow48)));
-        float fSlow52 = ((std::exp((fConst20 / fSlow20)) / fSlow44) + -1.0f);
-        float fSlow53 = std::exp((fConst25 / fSlow10));
+        float fSlow46 = 1.0f - fSlow45 * fSlow13;
+        float fSlow47 = 1.0f - fSlow45;
+        float fSlow48 = std::sqrt(std::max<float>(
+            0.0f, zitarevdsp_faustpower2_f(fSlow46) / zitarevdsp_faustpower2_f(fSlow47)
+                      + -1.0f));
+        float fSlow49 = fSlow46 / fSlow47;
+        float fSlow50 = fSlow44 * (fSlow48 + 1.0f - fSlow49);
+        float fSlow51 = std::exp(fConst22 / fSlow19) / fSlow44 + -1.0f;
+        float fSlow52 = fSlow49 - fSlow48;
+        float fSlow53 = std::exp(fConst27 / fSlow10);
         float fSlow54 = zitarevdsp_faustpower2_f(fSlow53);
-        float fSlow55 = (1.0f - (fSlow54 * fSlow13));
-        float fSlow56 = (1.0f - fSlow54);
-        float fSlow57 = (fSlow55 / fSlow56);
-        float fSlow58 = std::sqrt(std::max<float>(
-            0.0f, ((zitarevdsp_faustpower2_f(fSlow55) / zitarevdsp_faustpower2_f(fSlow56))
-                   + -1.0f)));
-        float fSlow59 = (fSlow57 - fSlow58);
-        float fSlow60 = (fSlow53 * (fSlow58 + (1.0f - fSlow57)));
-        float fSlow61 = ((std::exp((fConst25 / fSlow20)) / fSlow53) + -1.0f);
-        float fSlow62 = std::exp((fConst30 / fSlow10));
+        float fSlow55 = 1.0f - fSlow54 * fSlow13;
+        float fSlow56 = 1.0f - fSlow54;
+        float fSlow57 = std::sqrt(std::max<float>(
+            0.0f, zitarevdsp_faustpower2_f(fSlow55) / zitarevdsp_faustpower2_f(fSlow56)
+                      + -1.0f));
+        float fSlow58 = fSlow55 / fSlow56;
+        float fSlow59 = fSlow53 * (fSlow57 + 1.0f - fSlow58);
+        float fSlow60 = std::exp(fConst27 / fSlow19) / fSlow53 + -1.0f;
+        float fSlow61 = fSlow58 - fSlow57;
+        float fSlow62 = std::exp(fConst32 / fSlow10);
         float fSlow63 = zitarevdsp_faustpower2_f(fSlow62);
-        float fSlow64 = (1.0f - (fSlow63 * fSlow13));
-        float fSlow65 = (1.0f - fSlow63);
-        float fSlow66 = (fSlow64 / fSlow65);
-        float fSlow67 = std::sqrt(std::max<float>(
-            0.0f, ((zitarevdsp_faustpower2_f(fSlow64) / zitarevdsp_faustpower2_f(fSlow65))
-                   + -1.0f)));
-        float fSlow68 = (fSlow66 - fSlow67);
-        float fSlow69 = (fSlow62 * (fSlow67 + (1.0f - fSlow66)));
-        float fSlow70 = ((std::exp((fConst30 / fSlow20)) / fSlow62) + -1.0f);
-        float fSlow71 = std::exp((fConst35 / fSlow10));
+        float fSlow64 = 1.0f - fSlow63 * fSlow13;
+        float fSlow65 = 1.0f - fSlow63;
+        float fSlow66 = std::sqrt(std::max<float>(
+            0.0f, zitarevdsp_faustpower2_f(fSlow64) / zitarevdsp_faustpower2_f(fSlow65)
+                      + -1.0f));
+        float fSlow67 = fSlow64 / fSlow65;
+        float fSlow68 = fSlow62 * (fSlow66 + 1.0f - fSlow67);
+        float fSlow69 = std::exp(fConst32 / fSlow19) / fSlow62 + -1.0f;
+        float fSlow70 = fSlow67 - fSlow66;
+        float fSlow71 = std::exp(fConst37 / fSlow10);
         float fSlow72 = zitarevdsp_faustpower2_f(fSlow71);
-        float fSlow73 = (1.0f - (fSlow72 * fSlow13));
-        float fSlow74 = (1.0f - fSlow72);
-        float fSlow75 = (fSlow73 / fSlow74);
-        float fSlow76 = std::sqrt(std::max<float>(
-            0.0f, ((zitarevdsp_faustpower2_f(fSlow73) / zitarevdsp_faustpower2_f(fSlow74))
-                   + -1.0f)));
-        float fSlow77 = (fSlow75 - fSlow76);
-        float fSlow78 = (fSlow71 * (fSlow76 + (1.0f - fSlow75)));
-        float fSlow79 = ((std::exp((fConst35 / fSlow20)) / fSlow71) + -1.0f);
-        float fSlow80 = std::exp((fConst40 / fSlow10));
+        float fSlow73 = 1.0f - fSlow72 * fSlow13;
+        float fSlow74 = 1.0f - fSlow72;
+        float fSlow75 = std::sqrt(std::max<float>(
+            0.0f, zitarevdsp_faustpower2_f(fSlow73) / zitarevdsp_faustpower2_f(fSlow74)
+                      + -1.0f));
+        float fSlow76 = fSlow73 / fSlow74;
+        float fSlow77 = fSlow71 * (fSlow75 + 1.0f - fSlow76);
+        float fSlow78 = std::exp(fConst37 / fSlow19) / fSlow71 + -1.0f;
+        float fSlow79 = fSlow76 - fSlow75;
+        float fSlow80 = std::exp(fConst42 / fSlow10);
         float fSlow81 = zitarevdsp_faustpower2_f(fSlow80);
-        float fSlow82 = (1.0f - (fSlow81 * fSlow13));
-        float fSlow83 = (1.0f - fSlow81);
-        float fSlow84 = (fSlow82 / fSlow83);
-        float fSlow85 = std::sqrt(std::max<float>(
-            0.0f, ((zitarevdsp_faustpower2_f(fSlow82) / zitarevdsp_faustpower2_f(fSlow83))
-                   + -1.0f)));
-        float fSlow86 = (fSlow84 - fSlow85);
-        float fSlow87 = (fSlow80 * (fSlow85 + (1.0f - fSlow84)));
-        float fSlow88 = ((std::exp((fConst40 / fSlow20)) / fSlow80) + -1.0f);
-        float fSlow89 = (0.0f - (std::cos((fConst1 * fSlow6)) * (fSlow9 + 1.0f)));
-        float fSlow90 = (0.0f - (std::cos((fConst1 * fSlow2)) * (fSlow5 + 1.0f)));
-        for (int i = 0; (i < count); i = (i + 1)) {
-            float fTemp0          = float(input0[i]);
-            fVec0[(IOTA & 16383)] = fTemp0;
-            float fTemp1          = float(input1[i]);
-            fVec1[(IOTA & 16383)] = fTemp1;
-            fRec0[0]              = (fSlow0 + (0.999000013f * fRec0[1]));
-            fRec1[0]              = (fSlow1 + (0.999000013f * fRec1[1]));
-            fRec15[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec15[1]) - (fRec11[1] + fRec11[2]))));
-            fRec14[0] =
-                ((fSlow18 * fRec14[1]) + (fSlow19 * (fRec11[1] + (fSlow21 * fRec15[0]))));
-            fVec2[(IOTA & 32767)] = ((0.353553385f * fRec14[0]) + 9.99999968e-21f);
-            float fTemp2          = (0.300000012f * fVec1[((IOTA - iSlow25) & 16383)]);
+        float fSlow82 = 1.0f - fSlow81 * fSlow13;
+        float fSlow83 = 1.0f - fSlow81;
+        float fSlow84 = std::sqrt(std::max<float>(
+            0.0f, zitarevdsp_faustpower2_f(fSlow82) / zitarevdsp_faustpower2_f(fSlow83)
+                      + -1.0f));
+        float fSlow85 = fSlow82 / fSlow83;
+        float fSlow86 = fSlow80 * (fSlow84 + 1.0f - fSlow85);
+        float fSlow87 = std::exp(fConst42 / fSlow19) / fSlow80 + -1.0f;
+        float fSlow88 = fSlow85 - fSlow84;
+        float fSlow89 = 0.0f - std::cos(fConst3 * fSlow6) * (fSlow9 + 1.0f);
+        float fSlow90 = 0.0f - std::cos(fConst3 * fSlow2) * (fSlow5 + 1.0f);
+        for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+            float fTemp0         = float(input0[i0]);
+            fVec0[IOTA0 & 16383] = fTemp0;
+            float fTemp1         = float(input1[i0]);
+            fVec1[IOTA0 & 16383] = fTemp1;
+            fRec0[0]             = fSlow0 + fConst2 * fRec0[1];
+            fRec1[0]             = fSlow1 + fConst2 * fRec1[1];
+            fRec15[0] = 0.0f - fSlow22 * (fSlow23 * fRec15[1] - (fRec11[1] + fRec11[2]));
+            fRec14[0] = fSlow18 * (fRec11[1] + fSlow20 * fRec15[0]) + fSlow24 * fRec14[1];
+            fVec2[IOTA0 & 32767] = 0.353553385f * fRec14[0] + 9.99999968e-21f;
+            float fTemp2         = 0.300000012f * fVec1[(IOTA0 - iSlow25) & 16383];
             float fTemp3 =
-                (((0.600000024f * fRec12[1]) + fVec2[((IOTA - iConst6) & 32767)])
-                 - fTemp2);
-            fVec3[(IOTA & 2047)] = fTemp3;
-            fRec12[0]            = fVec3[((IOTA - iConst8) & 2047)];
-            float fRec13         = (0.0f - (0.600000024f * fTemp3));
-            fRec19[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec19[1]) - (fRec7[1] + fRec7[2]))));
-            fRec18[0] =
-                ((fSlow32 * fRec18[1]) + (fSlow33 * (fRec7[1] + (fSlow34 * fRec19[0]))));
-            fVec4[(IOTA & 32767)] = ((0.353553385f * fRec18[0]) + 9.99999968e-21f);
+                (0.600000024f * fRec12[1] + fVec2[(IOTA0 - iConst8) & 32767]) - fTemp2;
+            fVec3[IOTA0 & 2047] = fTemp3;
+            fRec12[0]           = fVec3[(IOTA0 - iConst10) & 2047];
+            float fRec13        = 0.0f - 0.600000024f * fTemp3;
+            fRec19[0] = 0.0f - fSlow22 * (fSlow23 * fRec19[1] - (fRec7[1] + fRec7[2]));
+            fRec18[0] = fSlow32 * (fRec7[1] + fSlow33 * fRec19[0]) + fSlow34 * fRec18[1];
+            fVec4[IOTA0 & 32767] = 0.353553385f * fRec18[0] + 9.99999968e-21f;
             float fTemp4 =
-                (((0.600000024f * fRec16[1]) + fVec4[((IOTA - iConst12) & 32767)])
-                 - fTemp2);
-            fVec5[(IOTA & 4095)] = fTemp4;
-            fRec16[0]            = fVec5[((IOTA - iConst13) & 4095)];
-            float fRec17         = (0.0f - (0.600000024f * fTemp4));
-            fRec23[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec23[1]) - (fRec9[1] + fRec9[2]))));
-            fRec22[0] =
-                ((fSlow41 * fRec22[1]) + (fSlow42 * (fRec9[1] + (fSlow43 * fRec23[0]))));
-            fVec6[(IOTA & 16383)] = ((0.353553385f * fRec22[0]) + 9.99999968e-21f);
-            float fTemp5          = (fVec6[((IOTA - iConst17) & 16383)]
-                            + (fTemp2 + (0.600000024f * fRec20[1])));
-            fVec7[(IOTA & 4095)]  = fTemp5;
-            fRec20[0]             = fVec7[((IOTA - iConst18) & 4095)];
-            float fRec21          = (0.0f - (0.600000024f * fTemp5));
-            fRec27[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec27[1]) - (fRec5[1] + fRec5[2]))));
-            fRec26[0] =
-                ((fSlow50 * fRec26[1]) + (fSlow51 * (fRec5[1] + (fSlow52 * fRec27[0]))));
-            fVec8[(IOTA & 32767)] = ((0.353553385f * fRec26[0]) + 9.99999968e-21f);
+                (0.600000024f * fRec16[1] + fVec4[(IOTA0 - iConst14) & 32767]) - fTemp2;
+            fVec5[IOTA0 & 4095] = fTemp4;
+            fRec16[0]           = fVec5[(IOTA0 - iConst15) & 4095];
+            float fRec17        = 0.0f - 0.600000024f * fTemp4;
+            fRec23[0] = 0.0f - fSlow22 * (fSlow23 * fRec23[1] - (fRec9[1] + fRec9[2]));
+            fRec22[0] = fSlow41 * (fRec9[1] + fSlow42 * fRec23[0]) + fSlow43 * fRec22[1];
+            fVec6[IOTA0 & 16383] = 0.353553385f * fRec22[0] + 9.99999968e-21f;
+            float fTemp5 =
+                fVec6[(IOTA0 - iConst19) & 16383] + fTemp2 + 0.600000024f * fRec20[1];
+            fVec7[IOTA0 & 4095] = fTemp5;
+            fRec20[0]           = fVec7[(IOTA0 - iConst20) & 4095];
+            float fRec21        = 0.0f - 0.600000024f * fTemp5;
+            fRec27[0] = 0.0f - fSlow22 * (fSlow23 * fRec27[1] - (fRec5[1] + fRec5[2]));
+            fRec26[0] = fSlow50 * (fRec5[1] + fSlow51 * fRec27[0]) + fSlow52 * fRec26[1];
+            fVec8[IOTA0 & 32767] = 0.353553385f * fRec26[0] + 9.99999968e-21f;
             float fTemp6 =
-                (fTemp2
-                 + ((0.600000024f * fRec24[1]) + fVec8[((IOTA - iConst22) & 32767)]));
-            fVec9[(IOTA & 4095)] = fTemp6;
-            fRec24[0]            = fVec9[((IOTA - iConst23) & 4095)];
-            float fRec25         = (0.0f - (0.600000024f * fTemp6));
-            fRec31[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec31[1]) - (fRec10[1] + fRec10[2]))));
-            fRec30[0] =
-                ((fSlow59 * fRec30[1]) + (fSlow60 * (fRec10[1] + (fSlow61 * fRec31[0]))));
-            fVec10[(IOTA & 16383)] = ((0.353553385f * fRec30[0]) + 9.99999968e-21f);
-            float fTemp7           = (0.300000012f * fVec0[((IOTA - iSlow25) & 16383)]);
-            float fTemp8           = (fVec10[((IOTA - iConst27) & 16383)]
-                            - (fTemp7 + (0.600000024f * fRec28[1])));
-            fVec11[(IOTA & 2047)]  = fTemp8;
-            fRec28[0]              = fVec11[((IOTA - iConst28) & 2047)];
-            float fRec29           = (0.600000024f * fTemp8);
-            fRec35[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec35[1]) - (fRec6[1] + fRec6[2]))));
-            fRec34[0] =
-                ((fSlow68 * fRec34[1]) + (fSlow69 * (fRec6[1] + (fSlow70 * fRec35[0]))));
-            fVec12[(IOTA & 16383)] = ((0.353553385f * fRec34[0]) + 9.99999968e-21f);
-            float fTemp9           = (fVec12[((IOTA - iConst32) & 16383)]
-                            - (fTemp7 + (0.600000024f * fRec32[1])));
-            fVec13[(IOTA & 4095)]  = fTemp9;
-            fRec32[0]              = fVec13[((IOTA - iConst33) & 4095)];
-            float fRec33           = (0.600000024f * fTemp9);
-            fRec39[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec39[1]) - (fRec8[1] + fRec8[2]))));
-            fRec38[0] =
-                ((fSlow77 * fRec38[1]) + (fSlow78 * (fRec8[1] + (fSlow79 * fRec39[0]))));
-            fVec14[(IOTA & 16383)] = ((0.353553385f * fRec38[0]) + 9.99999968e-21f);
-            float fTemp10          = ((fTemp7 + fVec14[((IOTA - iConst37) & 16383)])
-                             - (0.600000024f * fRec36[1]));
-            fVec15[(IOTA & 4095)]  = fTemp10;
-            fRec36[0]              = fVec15[((IOTA - iConst38) & 4095)];
-            float fRec37           = (0.600000024f * fTemp10);
-            fRec43[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec43[1]) - (fRec4[1] + fRec4[2]))));
-            fRec42[0] =
-                ((fSlow86 * fRec42[1]) + (fSlow87 * (fRec4[1] + (fSlow88 * fRec43[0]))));
-            fVec16[(IOTA & 16383)] = ((0.353553385f * fRec42[0]) + 9.99999968e-21f);
-            float fTemp11          = ((fVec16[((IOTA - iConst42) & 16383)] + fTemp7)
-                             - (0.600000024f * fRec40[1]));
-            fVec17[(IOTA & 2047)]  = fTemp11;
-            fRec40[0]              = fVec17[((IOTA - iConst43) & 2047)];
-            float fRec41           = (0.600000024f * fTemp11);
-            float fTemp12          = (fRec41 + fRec37);
-            float fTemp13          = (fRec29 + (fRec33 + fTemp12));
-            fRec4[0] =
-                (fRec12[1]
-                 + (fRec16[1]
-                    + (fRec20[1]
-                       + (fRec24[1]
-                          + (fRec28[1]
-                             + (fRec32[1]
-                                + (fRec36[1]
-                                   + (fRec40[1]
-                                      + (fRec13
-                                         + (fRec17
-                                            + (fRec21 + (fRec25 + fTemp13))))))))))));
-            fRec5[0] =
-                ((fRec28[1] + (fRec32[1] + (fRec36[1] + (fRec40[1] + fTemp13))))
-                 - (fRec12[1]
-                    + (fRec16[1]
-                       + (fRec20[1]
-                          + (fRec24[1] + (fRec13 + (fRec17 + (fRec25 + fRec21))))))));
-            float fTemp14 = (fRec33 + fRec29);
-            fRec6[0] =
-                ((fRec20[1]
-                  + (fRec24[1]
-                     + (fRec36[1] + (fRec40[1] + (fRec21 + (fRec25 + fTemp12))))))
-                 - (fRec12[1]
-                    + (fRec16[1]
-                       + (fRec28[1] + (fRec32[1] + (fRec13 + (fRec17 + fTemp14)))))));
-            fRec7[0] =
-                ((fRec12[1]
-                  + (fRec16[1]
-                     + (fRec36[1] + (fRec40[1] + (fRec13 + (fRec17 + fTemp12))))))
-                 - (fRec20[1]
-                    + (fRec24[1]
-                       + (fRec28[1] + (fRec32[1] + (fRec21 + (fRec25 + fTemp14)))))));
-            float fTemp15 = (fRec41 + fRec33);
-            float fTemp16 = (fRec37 + fRec29);
-            fRec8[0] =
-                ((fRec16[1]
-                  + (fRec24[1]
-                     + (fRec32[1] + (fRec40[1] + (fRec17 + (fRec25 + fTemp15))))))
-                 - (fRec12[1]
-                    + (fRec20[1]
-                       + (fRec28[1] + (fRec36[1] + (fRec13 + (fRec21 + fTemp16)))))));
-            fRec9[0] =
-                ((fRec12[1]
-                  + (fRec20[1]
-                     + (fRec32[1] + (fRec40[1] + (fRec13 + (fRec21 + fTemp15))))))
-                 - (fRec16[1]
-                    + (fRec24[1]
-                       + (fRec28[1] + (fRec36[1] + (fRec17 + (fRec25 + fTemp16)))))));
-            float fTemp17 = (fRec41 + fRec29);
-            float fTemp18 = (fRec37 + fRec33);
-            fRec10[0] =
-                ((fRec12[1]
-                  + (fRec24[1]
-                     + (fRec28[1] + (fRec40[1] + (fRec13 + (fRec25 + fTemp17))))))
-                 - (fRec16[1]
-                    + (fRec20[1]
-                       + (fRec32[1] + (fRec36[1] + (fRec17 + (fRec21 + fTemp18)))))));
-            fRec11[0] =
-                ((fRec16[1]
-                  + (fRec20[1]
-                     + (fRec28[1] + (fRec40[1] + (fRec17 + (fRec21 + fTemp17))))))
-                 - (fRec12[1]
-                    + (fRec24[1]
-                       + (fRec32[1] + (fRec36[1] + (fRec13 + (fRec25 + fTemp18)))))));
-            float fTemp19 = (0.370000005f * (fRec5[0] + fRec6[0]));
-            float fTemp20 = (fSlow89 * fRec3[1]);
-            fRec3[0]      = (fTemp19 - (fTemp20 + (fSlow9 * fRec3[2])));
-            float fTemp21 = (fSlow9 * fRec3[0]);
-            float fTemp22 =
-                (0.5f
-                 * ((fTemp21 + (fRec3[2] + (fTemp19 + fTemp20)))
-                    + (fSlow7 * ((fTemp21 + (fTemp20 + fRec3[2])) - fTemp19))));
-            float fTemp23 = (fSlow90 * fRec2[1]);
-            fRec2[0]      = (fTemp22 - (fTemp23 + (fSlow5 * fRec2[2])));
-            float fTemp24 = (fSlow5 * fRec2[0]);
-            float fTemp25 = (1.0f - fRec1[0]);
-            output0[i]    = FAUSTFLOAT(
-                   (fRec0[0]
-                 * ((0.5f
-                     * (fRec1[0]
-                        * ((fTemp24 + (fRec2[2] + (fTemp22 + fTemp23)))
-                           + (fSlow3 * ((fTemp24 + (fTemp23 + fRec2[2])) - fTemp22)))))
-                    + (fTemp0 * fTemp25))));
-            float fTemp26 = (0.370000005f * (fRec5[0] - fRec6[0]));
-            float fTemp27 = (fSlow89 * fRec45[1]);
-            fRec45[0]     = (fTemp26 - (fTemp27 + (fSlow9 * fRec45[2])));
-            float fTemp28 = (fSlow9 * fRec45[0]);
-            float fTemp29 =
-                (0.5f
-                 * ((fTemp28 + (fRec45[2] + (fTemp26 + fTemp27)))
-                    + (fSlow7 * ((fTemp28 + (fTemp27 + fRec45[2])) - fTemp26))));
-            float fTemp30 = (fSlow90 * fRec44[1]);
-            fRec44[0]     = (fTemp29 - (fTemp30 + (fSlow5 * fRec44[2])));
-            float fTemp31 = (fSlow5 * fRec44[0]);
-            output1[i]    = FAUSTFLOAT(
-                   (fRec0[0]
-                 * ((0.5f
-                     * (fRec1[0]
-                        * ((fTemp31 + (fRec44[2] + (fTemp29 + fTemp30)))
-                           + (fSlow3 * ((fTemp31 + (fTemp30 + fRec44[2])) - fTemp29)))))
-                    + (fTemp1 * fTemp25))));
-            IOTA      = (IOTA + 1);
+                fTemp2 + 0.600000024f * fRec24[1] + fVec8[(IOTA0 - iConst24) & 32767];
+            fVec9[IOTA0 & 4095] = fTemp6;
+            fRec24[0]           = fVec9[(IOTA0 - iConst25) & 4095];
+            float fRec25        = 0.0f - 0.600000024f * fTemp6;
+            fRec31[0] = 0.0f - fSlow22 * (fSlow23 * fRec31[1] - (fRec10[1] + fRec10[2]));
+            fRec30[0] = fSlow59 * (fRec10[1] + fSlow60 * fRec31[0]) + fSlow61 * fRec30[1];
+            fVec10[IOTA0 & 16383] = 0.353553385f * fRec30[0] + 9.99999968e-21f;
+            float fTemp7          = 0.300000012f * fVec0[(IOTA0 - iSlow25) & 16383];
+            float fTemp8 =
+                fVec10[(IOTA0 - iConst29) & 16383] - (fTemp7 + 0.600000024f * fRec28[1]);
+            fVec11[IOTA0 & 2047] = fTemp8;
+            fRec28[0]            = fVec11[(IOTA0 - iConst30) & 2047];
+            float fRec29         = 0.600000024f * fTemp8;
+            fRec35[0] = 0.0f - fSlow22 * (fSlow23 * fRec35[1] - (fRec6[1] + fRec6[2]));
+            fRec34[0] = fSlow68 * (fRec6[1] + fSlow69 * fRec35[0]) + fSlow70 * fRec34[1];
+            fVec12[IOTA0 & 16383] = 0.353553385f * fRec34[0] + 9.99999968e-21f;
+            float fTemp9 =
+                fVec12[(IOTA0 - iConst34) & 16383] - (fTemp7 + 0.600000024f * fRec32[1]);
+            fVec13[IOTA0 & 4095] = fTemp9;
+            fRec32[0]            = fVec13[(IOTA0 - iConst35) & 4095];
+            float fRec33         = 0.600000024f * fTemp9;
+            fRec39[0] = 0.0f - fSlow22 * (fSlow23 * fRec39[1] - (fRec8[1] + fRec8[2]));
+            fRec38[0] = fSlow77 * (fRec8[1] + fSlow78 * fRec39[0]) + fSlow79 * fRec38[1];
+            fVec14[IOTA0 & 16383] = 0.353553385f * fRec38[0] + 9.99999968e-21f;
+            float fTemp10 =
+                (fTemp7 + fVec14[(IOTA0 - iConst39) & 16383]) - 0.600000024f * fRec36[1];
+            fVec15[IOTA0 & 4095] = fTemp10;
+            fRec36[0]            = fVec15[(IOTA0 - iConst40) & 4095];
+            float fRec37         = 0.600000024f * fTemp10;
+            fRec43[0] = 0.0f - fSlow22 * (fSlow23 * fRec43[1] - (fRec4[1] + fRec4[2]));
+            fRec42[0] = fSlow86 * (fRec4[1] + fSlow87 * fRec43[0]) + fSlow88 * fRec42[1];
+            fVec16[IOTA0 & 16383] = 0.353553385f * fRec42[0] + 9.99999968e-21f;
+            float fTemp11 =
+                (fVec16[(IOTA0 - iConst44) & 16383] + fTemp7) - 0.600000024f * fRec40[1];
+            fVec17[IOTA0 & 2047] = fTemp11;
+            fRec40[0]            = fVec17[(IOTA0 - iConst45) & 2047];
+            float fRec41         = 0.600000024f * fTemp11;
+            float fTemp12        = fRec40[1] + fRec36[1];
+            float fTemp13 =
+                fRec29 + fRec33 + fRec37 + fRec41 + fRec28[1] + fTemp12 + fRec32[1];
+            fRec4[0] = fRec12[1] + fRec16[1] + fRec20[1] + fRec24[1] + fRec13 + fRec17
+                       + fRec21 + fRec25 + fTemp13;
+            fRec5[0] = fTemp13
+                       - (fRec12[1] + fRec16[1] + fRec20[1] + fRec24[1] + fRec13 + fRec17
+                          + fRec25 + fRec21);
+            float fTemp14 = fRec37 + fRec41 + fTemp12;
+            float fTemp15 = fRec29 + fRec33 + fRec32[1] + fRec28[1];
+            fRec6[0]      = (fRec20[1] + fRec24[1] + fRec21 + fRec25 + fTemp14)
+                       - (fRec12[1] + fRec16[1] + fRec13 + fRec17 + fTemp15);
+            fRec7[0] = (fRec12[1] + fRec16[1] + fRec13 + fRec17 + fTemp14)
+                       - (fRec20[1] + fRec24[1] + fRec21 + fRec25 + fTemp15);
+            float fTemp16 = fRec33 + fRec41 + fRec40[1] + fRec32[1];
+            float fTemp17 = fRec29 + fRec37 + fRec36[1] + fRec28[1];
+            fRec8[0]      = (fRec16[1] + fRec24[1] + fRec17 + fRec25 + fTemp16)
+                       - (fRec12[1] + fRec20[1] + fRec13 + fRec21 + fTemp17);
+            fRec9[0] = (fRec12[1] + fRec20[1] + fRec13 + fRec21 + fTemp16)
+                       - (fRec16[1] + fRec24[1] + fRec17 + fRec25 + fTemp17);
+            float fTemp18 = fRec29 + fRec41 + fRec40[1] + fRec28[1];
+            float fTemp19 = fRec33 + fRec37 + fRec36[1] + fRec32[1];
+            fRec10[0]     = (fRec12[1] + fRec24[1] + fRec13 + fRec25 + fTemp18)
+                        - (fRec16[1] + fRec20[1] + fRec17 + fRec21 + fTemp19);
+            fRec11[0] = (fRec16[1] + fRec20[1] + fRec17 + fRec21 + fTemp18)
+                        - (fRec12[1] + fRec24[1] + fRec13 + fRec25 + fTemp19);
+            float fTemp20 = 0.370000005f * (fRec5[0] + fRec6[0]);
+            float fTemp21 = fSlow89 * fRec3[1];
+            fRec3[0]      = fTemp20 - (fTemp21 + fSlow9 * fRec3[2]);
+            float fTemp22 = fSlow9 * fRec3[0];
+            float fTemp23 = 0.5f
+                            * (fTemp22 + fRec3[2] + fTemp20 + fTemp21
+                               + fSlow7 * ((fTemp22 + fTemp21 + fRec3[2]) - fTemp20));
+            float fTemp24 = fSlow90 * fRec2[1];
+            fRec2[0]      = fTemp23 - (fTemp24 + fSlow5 * fRec2[2]);
+            float fTemp25 = fSlow5 * fRec2[0];
+            float fTemp26 = 1.0f - fRec1[0];
+            output0[i0]   = FAUSTFLOAT(
+                  fRec0[0]
+                  * (0.5f * fRec1[0]
+                       * (fTemp25 + fRec2[2] + fTemp23 + fTemp24
+                          + fSlow3 * ((fTemp25 + fTemp24 + fRec2[2]) - fTemp23))
+                   + fTemp0 * fTemp26));
+            float fTemp27 = 0.370000005f * (fRec5[0] - fRec6[0]);
+            float fTemp28 = fSlow89 * fRec45[1];
+            fRec45[0]     = fTemp27 - (fTemp28 + fSlow9 * fRec45[2]);
+            float fTemp29 = fSlow9 * fRec45[0];
+            float fTemp30 = 0.5f
+                            * (fTemp29 + fRec45[2] + fTemp27 + fTemp28
+                               + fSlow7 * ((fTemp29 + fTemp28 + fRec45[2]) - fTemp27));
+            float fTemp31 = fSlow90 * fRec44[1];
+            fRec44[0]     = fTemp30 - (fTemp31 + fSlow5 * fRec44[2]);
+            float fTemp32 = fSlow5 * fRec44[0];
+            output1[i0]   = FAUSTFLOAT(
+                  fRec0[0]
+                  * (0.5f * fRec1[0]
+                       * (fTemp32 + fRec44[2] + fTemp30 + fTemp31
+                          + fSlow3 * ((fTemp32 + fTemp31 + fRec44[2]) - fTemp30))
+                   + fTemp1 * fTemp26));
+            IOTA0     = IOTA0 + 1;
             fRec0[1]  = fRec0[0];
             fRec1[1]  = fRec1[0];
             fRec15[1] = fRec15[0];
index 0053a95526e0faac6ac659c23ed671e577beb74a..4f0475b11215cc351832dd156547d352b57f06a5 100644 (file)
@@ -1,7 +1,8 @@
 /* ------------------------------------------------------------
 name: "zitarevmonodsp"
-Code generated with Faust 2.28.6 (https://faust.grame.fr)
-Compilation options: -lang cpp -inpl -scal -ftz 0
+Code generated with Faust 2.41.1 (https://faust.grame.fr)
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn zitarevmonodsp -es 1 -mcd
+16 -single -ftz 0
 ------------------------------------------------------------ */
 
 #ifndef __zitarevmonodsp_H__
@@ -14,23 +15,23 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 // aimed at creating a simple C++ header file (.h) containing a Faust DSP.
 // See the Makefile for how to use it.
 
-/************************** BEGIN dsp.h **************************/
-/************************************************************************
+/************************** BEGIN dsp.h ********************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -44,29 +45,111 @@ Compilation options: -lang cpp -inpl -scal -ftz 0
 #include <string>
 #include <vector>
 
+/************************************************************************
+ ************************************************************************
+    FAUST compiler
+    Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ************************************************************************
+ ************************************************************************/
+
+#ifndef __export__
+#define __export__
+
+#define FAUSTVERSION "2.41.1"
+
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
+
+#ifdef _WIN32
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API    __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
+#else
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#else
+#define FAUST_API    __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
+#endif
+
+#endif
+
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
 
-struct UI;
-struct Meta;
+struct FAUST_API UI;
+struct FAUST_API Meta;
 
 /**
  * DSP memory manager.
  */
 
-struct dsp_memory_manager {
+struct FAUST_API dsp_memory_manager {
     virtual ~dsp_memory_manager() {}
 
+    /**
+     * Inform the Memory Manager with the number of expected memory zones.
+     * @param count - the number of expected memory zones
+     */
+    virtual void begin(size_t /*count*/) {}
+
+    /**
+     * Give the Memory Manager information on a given memory zone.
+     * @param size - the size in bytes of the memory zone
+     * @param reads - the number of Read access to the zone used to compute one frame
+     * @param writes - the number of Write access to the zone used to compute one frame
+     */
+    virtual void info(size_t /*size*/, size_t /*reads*/, size_t /*writes*/) {}
+
+    /**
+     * Inform the Memory Manager that all memory zones have been described,
+     * to possibly start a 'compute the best allocation strategy' step.
+     */
+    virtual void end() {}
+
+    /**
+     * Allocate a memory zone.
+     * @param size - the memory zone size in bytes
+     */
     virtual void* allocate(size_t size) = 0;
-    virtual void destroy(void* ptr)     = 0;
+
+    /**
+     * Destroy a memory zone.
+     * @param ptr - the memory zone pointer to be deallocated
+     */
+    virtual void destroy(void* ptr) = 0;
 };
 
 /**
  * Signal processor definition.
  */
 
-class dsp
+class FAUST_API dsp
 {
    public:
     dsp() {}
@@ -86,7 +169,7 @@ class dsp
      */
     virtual void buildUserInterface(UI* ui_interface) = 0;
 
-    /* Returns the sample rate currently used by the instance */
+    /* Return the sample rate currently used by the instance */
     virtual int getSampleRate() = 0;
 
     /**
@@ -94,28 +177,28 @@ class dsp
      * - static class 'classInit': static tables initialization
      * - 'instanceInit': constants and instance state initialization
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void init(int sample_rate) = 0;
 
     /**
      * Init instance state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceInit(int sample_rate) = 0;
 
     /**
      * Init instance constant state
      *
-     * @param sample_rate - the sampling rate in Hertz
+     * @param sample_rate - the sampling rate in Hz
      */
     virtual void instanceConstants(int sample_rate) = 0;
 
     /* Init default control parameters values */
     virtual void instanceResetUserInterface() = 0;
 
-    /* Init instance state (delay lines...) */
+    /* Init instance state (like delay lines...) but keep the control parameter values */
     virtual void instanceClear() = 0;
 
     /**
@@ -167,7 +250,7 @@ class dsp
  * Generic DSP decorator.
  */
 
-class decorator_dsp : public dsp
+class FAUST_API decorator_dsp : public dsp
 {
    protected:
     dsp* fDSP;
@@ -206,10 +289,11 @@ class decorator_dsp : public dsp
 };
 
 /**
- * DSP factory class.
+ * DSP factory class, used with LLVM and Interpreter backends
+ * to create DSP instances from a compiled DSP program.
  */
 
-class dsp_factory
+class FAUST_API dsp_factory
 {
    protected:
     // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
@@ -229,75 +313,114 @@ class dsp_factory
     virtual dsp_memory_manager* getMemoryManager()             = 0;
 };
 
-/**
- * On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
- * flags to avoid costly denormals.
- */
+// Denormal handling
 
-#ifdef __SSE__
+#if defined(__SSE__)
 #include <xmmintrin.h>
-#ifdef __SSE2__
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
+#endif
+
+class FAUST_API ScopedNoDenormals
+{
+   private:
+    intptr_t fpsr;
+
+    void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("msr fpcr, %0" : : "ri"(fpsr_aux));
+#elif defined(__SSE__)
+        _mm_setcsr(static_cast<uint32_t>(fpsr_aux));
+#endif
+    }
+
+    void getFpStatusRegister() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        asm volatile("mrs %0, fpcr" : "=r"(fpsr));
+#elif defined(__SSE__)
+        fpsr          = static_cast<intptr_t>(_mm_getcsr());
+#endif
+    }
+
+   public:
+    ScopedNoDenormals() noexcept
+    {
+#if defined(__arm64__) || defined(__aarch64__)
+        intptr_t mask = (1 << 24 /* FZ */);
 #else
-#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
+#if defined(__SSE__)
+#if defined(__SSE2__)
+        intptr_t mask = 0x8040;
+#else
+        intptr_t mask = 0x8000;
 #endif
 #else
-#define AVOIDDENORMALS
+        intptr_t mask = 0x0000;
 #endif
-
 #endif
-/**************************  END  dsp.h **************************/
+        getFpStatusRegister();
+        setFpStatusRegister(fpsr | mask);
+    }
 
-/************************** BEGIN APIUI.h **************************/
-/************************************************************************
- FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
- ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
- the License, or (at your option) any later version.
+    ~ScopedNoDenormals() noexcept { setFpStatusRegister(fpsr); }
+};
 
- This program 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 General Public License for more details.
+#define AVOIDDENORMALS ScopedNoDenormals();
 
- You should have received a copy of the GNU General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+#endif
 
- EXCEPTION : As a special exception, you may create a larger work
- that contains this FAUST architecture section and distribute
- that work under terms of your choice, so long as this FAUST
- architecture section is not modified.
- ************************************************************************/
+/************************** END dsp.h **************************/
+/************************** BEGIN APIUI.h *****************************
+FAUST Architecture File
+Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
+---------------------------------------------------------------------
+This program 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 program 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 program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+EXCEPTION : As a special exception, you may create a larger work
+that contains this FAUST architecture section and distribute
+that work under terms of your choice, so long as this FAUST
+architecture section is not modified.
+************************************************************************/
 
 #ifndef API_UI_H
 #define API_UI_H
 
-#include <iostream>
+#include <stdio.h>
+
 #include <map>
 #include <sstream>
 #include <string>
 #include <vector>
 
-/************************** BEGIN meta.h **************************/
-/************************************************************************
+/************************** BEGIN meta.h *******************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -308,36 +431,40 @@ class dsp_factory
 #ifndef __meta__
 #define __meta__
 
-struct Meta {
-    virtual ~Meta(){};
+/**
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
+ (key, value) metadata.
+ */
+struct FAUST_API Meta {
+    virtual ~Meta() {}
     virtual void declare(const char* key, const char* value) = 0;
 };
 
 #endif
 /**************************  END  meta.h **************************/
-/************************** BEGIN UI.h **************************/
-/************************************************************************
+/************************** BEGIN UI.h *****************************
  FAUST Architecture File
- Copyright (C) 2003-2020 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __UI_H__
 #define __UI_H__
@@ -356,7 +483,7 @@ struct Meta {
 struct Soundfile;
 
 template<typename REAL>
-struct UIReal {
+struct FAUST_API UIReal {
     UIReal() {}
     virtual ~UIReal() {}
 
@@ -387,38 +514,41 @@ struct UIReal {
 
     // -- soundfiles
 
-    virtual void addSoundfile(const char* label, const char* filename,
-                              Soundfile** sf_zone) = 0;
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+                              Soundfile** /*sf_zone*/) = 0;
 
     // -- metadata declarations
 
-    virtual void declare(REAL* zone, const char* key, const char* val) {}
+    virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
+
+    // To be used by LLVM client
+    virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
 };
 
-struct UI : public UIReal<FAUSTFLOAT> {
+struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
     UI() {}
     virtual ~UI() {}
 };
 
 #endif
 /**************************  END  UI.h **************************/
-/************************** BEGIN PathBuilder.h **************************/
-/************************************************************************
+/************************** BEGIN PathBuilder.h **************************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
@@ -426,10 +556,13 @@ struct UI : public UIReal<FAUSTFLOAT> {
  architecture section is not modified.
  ************************************************************************/
 
-#ifndef FAUST_PATHBUILDER_H
-#define FAUST_PATHBUILDER_H
+#ifndef __PathBuilder__
+#define __PathBuilder__
 
 #include <algorithm>
+#include <map>
+#include <regex>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -438,113 +571,266 @@ struct UI : public UIReal<FAUSTFLOAT> {
  * Helper class to build complete hierarchical path for UI items.
  ******************************************************************************/
 
-class PathBuilder
+class FAUST_API PathBuilder
 {
    protected:
     std::vector<std::string> fControlsLevel;
+    std::vector<std::string> fFullPaths;
+    std::map<std::string, std::string> fFull2Short;  // filled by computeShortNames()
+
+    /**
+     * @brief check if a character is acceptable for an ID
+     *
+     * @param c
+     * @return true is the character is acceptable for an ID
+     */
+    bool isIDChar(char c) const
+    {
+        return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+               || ((c >= '0') && (c <= '9'));
+    }
+
+    /**
+     * @brief remove all "/0x00" parts
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string remove0x00(const std::string& src) const
+    {
+        return std::regex_replace(src, std::regex("/0x00"), "");
+    }
+
+    /**
+     * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+     *
+     * @param src
+     * @return modified string
+     */
+    std::string str2ID(const std::string& src) const
+    {
+        std::string dst;
+        bool need_underscore = false;
+        for (char c : src) {
+            if (isIDChar(c) || (c == '/')) {
+                if (need_underscore) {
+                    dst.push_back('_');
+                    need_underscore = false;
+                }
+                dst.push_back(c);
+            } else {
+                need_underscore = true;
+            }
+        }
+        return dst;
+    }
+
+    /**
+     * @brief Keep only the last n slash-parts
+     *
+     * @param src
+     * @param n : 1 indicates the last slash-part
+     * @return modified string
+     */
+    std::string cut(const std::string& src, int n) const
+    {
+        std::string rdst;
+        for (int i = int(src.length()) - 1; i >= 0; i--) {
+            char c = src[i];
+            if (c != '/') {
+                rdst.push_back(c);
+            } else if (n == 1) {
+                std::string dst;
+                for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+                    dst.push_back(rdst[j]);
+                }
+                return dst;
+            } else {
+                n--;
+                rdst.push_back(c);
+            }
+        }
+        return src;
+    }
+
+    void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+    /**
+     * @brief Compute the mapping between full path and short names
+     */
+    void computeShortNames()
+    {
+        std::vector<std::string>
+            uniquePaths;  // all full paths transformed but made unique with a prefix
+        std::map<std::string, std::string>
+            unique2full;  // all full paths transformed but made unique with a prefix
+        char num_buffer[16];
+        int pnum = 0;
+
+        for (const auto& s : fFullPaths) {
+            sprintf(num_buffer, "%d", pnum++);
+            std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+            uniquePaths.push_back(u);
+            unique2full[u] = s;  // remember the full path associated to a unique path
+        }
+
+        std::map<std::string, int> uniquePath2level;  // map path to level
+        for (const auto& s : uniquePaths)
+            uniquePath2level[s] = 1;  // we init all levels to 1
+        bool have_collisions = true;
+
+        while (have_collisions) {
+            // compute collision list
+            std::set<std::string> collisionSet;
+            std::map<std::string, std::string> short2full;
+            have_collisions = false;
+            for (const auto& it : uniquePath2level) {
+                std::string u         = it.first;
+                int n                 = it.second;
+                std::string shortName = cut(u, n);
+                auto p                = short2full.find(shortName);
+                if (p == short2full.end()) {
+                    // no collision
+                    short2full[shortName] = u;
+                } else {
+                    // we have a collision, add the two paths to the collision set
+                    have_collisions = true;
+                    collisionSet.insert(u);
+                    collisionSet.insert(p->second);
+                }
+            }
+            for (const auto& s : collisionSet)
+                uniquePath2level[s]++;  // increase level of colliding path
+        }
+
+        for (const auto& it : uniquePath2level) {
+            std::string u               = it.first;
+            int n                       = it.second;
+            std::string shortName       = replaceCharList(cut(u, n), {'/'}, '_');
+            fFull2Short[unique2full[u]] = shortName;
+        }
+    }
+
+    std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+                                char ch2)
+    {
+        auto beg        = ch1.begin();
+        auto end        = ch1.end();
+        std::string res = str;
+        for (size_t i = 0; i < str.length(); ++i) {
+            if (std::find(beg, end, str[i]) != end)
+                res[i] = ch2;
+        }
+        return res;
+    }
 
    public:
     PathBuilder() {}
     virtual ~PathBuilder() {}
 
+    // Return true for the first level of groups
+    bool pushLabel(const std::string& label)
+    {
+        fControlsLevel.push_back(label);
+        return fControlsLevel.size() == 1;
+    }
+
+    // Return true for the last level of groups
+    bool popLabel()
+    {
+        fControlsLevel.pop_back();
+        return fControlsLevel.size() == 0;
+    }
+
     std::string buildPath(const std::string& label)
     {
         std::string res = "/";
         for (size_t i = 0; i < fControlsLevel.size(); i++) {
-            res += fControlsLevel[i];
-            res += "/";
+            res = res + fControlsLevel[i] + "/";
         }
         res += label;
-        std::replace(res.begin(), res.end(), ' ', '_');
-        return res;
+        return replaceCharList(
+            res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
     }
-
-    std::string buildLabel(std::string label)
-    {
-        std::replace(label.begin(), label.end(), ' ', '_');
-        return label;
-    }
-
-    void pushLabel(const std::string& label) { fControlsLevel.push_back(label); }
-    void popLabel() { fControlsLevel.pop_back(); }
 };
 
-#endif  // FAUST_PATHBUILDER_H
+#endif  // __PathBuilder__
 /**************************  END  PathBuilder.h **************************/
-/************************** BEGIN ValueConverter.h **************************/
-/************************************************************************
+/************************** BEGIN ValueConverter.h ********************
  FAUST Architecture File
- Copyright (C) 2003-2017 GRAME, Centre National de Creation Musicale
+ Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale
  ---------------------------------------------------------------------
- This Architecture section is free software; you can redistribute it
- and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3 of
the License, or (at your option) any later version.
+ This program 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 program 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 General Public License for more details.
+ 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 General Public License
- along with this program; If not, see <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
  EXCEPTION : As a special exception, you may create a larger work
  that contains this FAUST architecture section and distribute
  that work under terms of your choice, so long as this FAUST
  architecture section is not modified.
- ************************************************************************/
+ ********************************************************************/
 
 #ifndef __ValueConverter__
 #define __ValueConverter__
 
 /***************************************************************************************
                                                               ValueConverter.h
                           (GRAME, Copyright 2015-2019)
+ ValueConverter.h
+ (GRAME, Copyright 2015-2019)
 
-Set of conversion objects used to map user interface values (for example a gui slider
-delivering values between 0 and 1) to faust values (for example a vslider between
-20 and 20000) using a log scale.
+ Set of conversion objects used to map user interface values (for example a gui slider
+ delivering values between 0 and 1) to faust values (for example a vslider between
+ 20 and 20000) using a log scale.
 
--- Utilities
+ -- Utilities
 
-Range(lo,hi) : clip a value x between lo and hi
-Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
+ Range(lo,hi) : clip a value x between lo and hi
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
 v2 Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1
 vm v2
 
--- Value Converters
+ -- Value Converters
 
-ValueConverter::ui2faust(x)
-ValueConverter::faust2ui(x)
+ ValueConverter::ui2faust(x)
+ ValueConverter::faust2ui(x)
 
--- ValueConverters used for sliders depending of the scale
+ -- ValueConverters used for sliders depending of the scale
 
-LinearValueConverter(umin, umax, fmin, fmax)
-LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
-LogValueConverter(umin, umax, fmin, fmax)
-ExpValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter(umin, umax, fmin, fmax)
+ LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
+ LogValueConverter(umin, umax, fmin, fmax)
+ ExpValueConverter(umin, umax, fmin, fmax)
 
--- ValueConverters used for accelerometers based on 3 points
+ -- ValueConverters used for accelerometers based on 3 points
 
-AccUpConverter(amin, amid, amax, fmin, fmid, fmax)             -- curve 0
-AccDownConverter(amin, amid, amax, fmin, fmid, fmax)   -- curve 1
-AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 2
-AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 3
+ AccUpConverter(amin, amid, amax, fmin, fmid, fmax)        -- curve 0
+ AccDownConverter(amin, amid, amax, fmin, fmid, fmax)      -- curve 1
+ AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 2
+ AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax)    -- curve 3
 
--- lists of ZoneControl are used to implement accelerometers metadata for each axes
+ -- lists of ZoneControl are used to implement accelerometers metadata for each axes
 
-ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
+ ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
 
--- ZoneReader are used to implement screencolor metadata
+ -- ZoneReader are used to implement screencolor metadata
 
-ZoneReader(zone, valueConverter) : a zone with a data converter
+ ZoneReader(zone, valueConverter) : a zone with a data converter
 
 ****************************************************************************************/
 
+#include <assert.h>
+#include <float.h>
+
 #include <algorithm>  // std::max
-#include <cassert>
-#include <cfloat>
 #include <cmath>
 #include <vector>
 
@@ -552,12 +838,12 @@ ZoneReader(zone, valueConverter) : a zone with a data converter
 // Interpolator(lo,hi,v1,v2)
 // Maps a value x between lo and hi to a value y between v1 and v2
 // y = v1 + (x-lo)/(hi-lo)*(v2-v1)
-// y = v1 + (x-lo) * coef              with coef = (v2-v1)/(hi-lo)
+// y = v1 + (x-lo) * coef           with coef = (v2-v1)/(hi-lo)
 // y = v1 + x*coef - lo*coef
 // y = v1 - lo*coef + x*coef
-// y = offset + x*coef                         with offset = v1 - lo*coef
+// y = offset + x*coef              with offset = v1 - lo*coef
 //--------------------------------------------------------------------------------------
-class Interpolator
+class FAUST_API Interpolator
 {
    private:
     //--------------------------------------------------------------------------------------
@@ -608,7 +894,7 @@ class Interpolator
 // Interpolator3pt(lo,mi,hi,v1,vm,v2)
 // Map values between lo mid hi to values between v1 vm v2
 //--------------------------------------------------------------------------------------
-class Interpolator3pt
+class FAUST_API Interpolator3pt
 {
    private:
     Interpolator fSegment1;
@@ -632,19 +918,19 @@ class Interpolator3pt
 //--------------------------------------------------------------------------------------
 // Abstract ValueConverter class. Converts values between UI and Faust representations
 //--------------------------------------------------------------------------------------
-class ValueConverter
+class FAUST_API ValueConverter
 {
    public:
     virtual ~ValueConverter() {}
-    virtual double ui2faust(double x) = 0;
-    virtual double faust2ui(double x) = 0;
+    virtual double ui2faust(double x) { return x; };
+    virtual double faust2ui(double x) { return x; };
 };
 
 //--------------------------------------------------------------------------------------
 // A converter than can be updated
 //--------------------------------------------------------------------------------------
 
-class UpdatableValueConverter : public ValueConverter
+class FAUST_API UpdatableValueConverter : public ValueConverter
 {
    protected:
     bool fActive;
@@ -664,7 +950,7 @@ class UpdatableValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter : public ValueConverter
+class FAUST_API LinearValueConverter : public ValueConverter
 {
    private:
     Interpolator fUI2F;
@@ -684,7 +970,7 @@ class LinearValueConverter : public ValueConverter
 //--------------------------------------------------------------------------------------
 // Two segments linear conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LinearValueConverter2 : public UpdatableValueConverter
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fUI2F;
@@ -720,7 +1006,7 @@ class LinearValueConverter2 : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Logarithmic conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class LogValueConverter : public LinearValueConverter
+class FAUST_API LogValueConverter : public LinearValueConverter
 {
    public:
     LogValueConverter(double umin, double umax, double fmin, double fmax)
@@ -742,7 +1028,7 @@ class LogValueConverter : public LinearValueConverter
 //--------------------------------------------------------------------------------------
 // Exponential conversion between ui and Faust values
 //--------------------------------------------------------------------------------------
-class ExpValueConverter : public LinearValueConverter
+class FAUST_API ExpValueConverter : public LinearValueConverter
 {
    public:
     ExpValueConverter(double umin, double umax, double fmin, double fmax)
@@ -765,7 +1051,7 @@ class ExpValueConverter : public LinearValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up curve (curve 0)
 //--------------------------------------------------------------------------------------
-class AccUpConverter : public UpdatableValueConverter
+class FAUST_API AccUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -801,7 +1087,7 @@ class AccUpConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down curve (curve 1)
 //--------------------------------------------------------------------------------------
-class AccDownConverter : public UpdatableValueConverter
+class FAUST_API AccDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
@@ -837,14 +1123,14 @@ class AccDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using an Up-Down curve (curve 2)
 //--------------------------------------------------------------------------------------
-class AccUpDownConverter : public UpdatableValueConverter
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccUpDownConverter(double amin, double amid, double amax, double fmin, double fmid,
+    AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
                        double fmax)
         : fA2F(amin, amid, amax, fmin, fmax, fmin)
         , fF2A(fmin, fmax, amin,
@@ -856,7 +1142,7 @@ class AccUpDownConverter : public UpdatableValueConverter
     virtual double faust2ui(double x) { return fF2A(x); }
 
     virtual void setMappingValues(double amin, double amid, double amax, double fmin,
-                                  double fmid, double fmax)
+                                  double /*fmid*/, double fmax)
     {
         //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f
         //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
@@ -874,14 +1160,14 @@ class AccUpDownConverter : public UpdatableValueConverter
 // Convert accelerometer or gyroscope values to Faust values
 // Using a Down-Up curve (curve 3)
 //--------------------------------------------------------------------------------------
-class AccDownUpConverter : public UpdatableValueConverter
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
 {
    private:
     Interpolator3pt fA2F;
     Interpolator fF2A;
 
    public:
-    AccDownUpConverter(double amin, double amid, double amax, double fmin, double fmid,
+    AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
                        double fmax)
         : fA2F(amin, amid, amax, fmax, fmin, fmax)
         , fF2A(fmin, fmax, amin,
@@ -893,7 +1179,7 @@ class AccDownUpConverter : public UpdatableValueConverter
     virtual double faust2ui(double x) { return fF2A(x); }
 
     virtual void setMappingValues(double amin, double amid, double amax, double fmin,
-                                  double fmid, double fmax)
+                                  double /*fmid*/, double fmax)
     {
         //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f
         //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
@@ -910,7 +1196,7 @@ class AccDownUpConverter : public UpdatableValueConverter
 //--------------------------------------------------------------------------------------
 // Base class for ZoneControl
 //--------------------------------------------------------------------------------------
-class ZoneControl
+class FAUST_API ZoneControl
 {
    protected:
     FAUSTFLOAT* fZone;
@@ -919,17 +1205,17 @@ class ZoneControl
     ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
     virtual ~ZoneControl() {}
 
-    virtual void update(double v) const {}
+    virtual void update(double /*v*/) const {}
 
-    virtual void setMappingValues(int curve, double amin, double amid, double amax,
-                                  double min, double init, double max)
+    virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
+                                  double /*min*/, double /*init*/, double /*max*/)
     {
     }
-    virtual void getMappingValues(double& amin, double& amid, double& amax) {}
+    virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
 
     FAUSTFLOAT* getZone() { return fZone; }
 
-    virtual void setActive(bool on_off) {}
+    virtual void setActive(bool /*on_off*/) {}
     virtual bool getActive() { return false; }
 
     virtual int getCurve() { return -1; }
@@ -938,7 +1224,7 @@ class ZoneControl
 //--------------------------------------------------------------------------------------
 //  Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class ConverterZoneControl : public ZoneControl
+class FAUST_API ConverterZoneControl : public ZoneControl
 {
    protected:
     ValueConverter* fValueConverter;
@@ -953,7 +1239,10 @@ class ConverterZoneControl : public ZoneControl
         delete fValueConverter;
     }  // Assuming fValueConverter is not kept elsewhere...
 
-    virtual void update(double v) const { *fZone = fValueConverter->ui2faust(v); }
+    virtual void update(double v) const
+    {
+        *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v));
+    }
 
     ValueConverter* getConverter() { return fValueConverter; }
 };
@@ -962,7 +1251,7 @@ class ConverterZoneControl : public ZoneControl
 // Association of a zone and a four value converter, each one for each possible curve.
 // Useful to implement accelerometers metadata as a list of ZoneControl for each axes
 //--------------------------------------------------------------------------------------
-class CurveZoneControl : public ZoneControl
+class FAUST_API CurveZoneControl : public ZoneControl
 {
    private:
     std::vector<UpdatableValueConverter*> fValueConverters;
@@ -985,15 +1274,14 @@ class CurveZoneControl : public ZoneControl
     }
     virtual ~CurveZoneControl()
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            delete (*it);
+        for (const auto& it : fValueConverters) {
+            delete it;
         }
     }
     void update(double v) const
     {
         if (fValueConverters[fCurve]->getActive())
-            *fZone = fValueConverters[fCurve]->ui2faust(v);
+            *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v));
     }
 
     void setMappingValues(int curve, double amin, double amid, double amax, double min,
@@ -1010,16 +1298,15 @@ class CurveZoneControl : public ZoneControl
 
     void setActive(bool on_off)
     {
-        std::vector<UpdatableValueConverter*>::iterator it;
-        for (it = fValueConverters.begin(); it != fValueConverters.end(); it++) {
-            (*it)->setActive(on_off);
+        for (const auto& it : fValueConverters) {
+            it->setActive(on_off);
         }
     }
 
     int getCurve() { return fCurve; }
 };
 
-class ZoneReader
+class FAUST_API ZoneReader
 {
    private:
     FAUSTFLOAT* fZone;
@@ -1039,6 +1326,8 @@ class ZoneReader
 #endif
 /**************************  END  ValueConverter.h **************************/
 
+typedef unsigned int uint;
+
 class APIUI
     : public PathBuilder
     , public Meta
@@ -1054,22 +1343,42 @@ class APIUI
         kHBargraph,
         kVBargraph
     };
+    enum Type { kAcc = 0, kGyr = 1, kNoType };
 
    protected:
-    enum { kLin = 0, kLog = 1, kExp = 2 };
-
-    int fNumParameters;
-    std::vector<std::string> fPaths;
-    std::vector<std::string> fLabels;
-    std::map<std::string, int> fPathMap;
-    std::map<std::string, int> fLabelMap;
-    std::vector<ValueConverter*> fConversion;
-    std::vector<FAUSTFLOAT*> fZone;
-    std::vector<FAUSTFLOAT> fInit;
-    std::vector<FAUSTFLOAT> fMin;
-    std::vector<FAUSTFLOAT> fMax;
-    std::vector<FAUSTFLOAT> fStep;
-    std::vector<ItemType> fItemType;
+    enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+    struct Item {
+        std::string fLabel;
+        std::string fShortname;
+        std::string fPath;
+        ValueConverter* fConversion;
+        FAUSTFLOAT* fZone;
+        FAUSTFLOAT fInit;
+        FAUSTFLOAT fMin;
+        FAUSTFLOAT fMax;
+        FAUSTFLOAT fStep;
+        ItemType fItemType;
+
+        Item(const std::string& label, const std::string& short_name,
+             const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+             FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+             ItemType item_type)
+            : fLabel(label)
+            , fShortname(short_name)
+            , fPath(path)
+            , fConversion(conversion)
+            , fZone(zone)
+            , fInit(init)
+            , fMin(min)
+            , fMax(max)
+            , fStep(step)
+            , fItemType(item_type)
+        {
+        }
+    };
+    std::vector<Item> fItems;
+
     std::vector<std::map<std::string, std::string> > fMetaData;
     std::vector<ZoneControl*> fAcc[3];
     std::vector<ZoneControl*> fGyr[3];
@@ -1096,33 +1405,31 @@ class APIUI
                               ItemType type)
     {
         std::string path = buildPath(label);
-        fPathMap[path] = fLabelMap[label] = fNumParameters++;
-        fPaths.push_back(path);
-        fLabels.push_back(label);
-        fZone.push_back(zone);
-        fInit.push_back(init);
-        fMin.push_back(min);
-        fMax.push_back(max);
-        fStep.push_back(step);
-        fItemType.push_back(type);
+        fFullPaths.push_back(path);
 
         // handle scale metadata
+        ValueConverter* converter = nullptr;
         switch (fCurrentScale) {
         case kLin:
-            fConversion.push_back(new LinearValueConverter(0, 1, min, max));
+            converter = new LinearValueConverter(0, 1, min, max);
             break;
         case kLog:
-            fConversion.push_back(new LogValueConverter(0, 1, min, max));
+            converter = new LogValueConverter(0, 1, min, max);
             break;
         case kExp:
-            fConversion.push_back(new ExpValueConverter(0, 1, min, max));
+            converter = new ExpValueConverter(0, 1, min, max);
             break;
         }
         fCurrentScale = kLin;
 
+        fItems.push_back(
+            Item(label, "", path, converter, zone, init, min, max, step, type));
+
         if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
-            std::cerr << "warning : 'acc' and 'gyr' metadata used for the same " << label
-                      << " parameter !!\n";
+            fprintf(
+                stderr,
+                "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n",
+                label);
         }
 
         // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
@@ -1137,7 +1444,7 @@ class APIUI
                 fAcc[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect acc metadata : " << fCurrentAcc << std::endl;
+                fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
             }
             fCurrentAcc = "";
         }
@@ -1154,31 +1461,31 @@ class APIUI
                 fGyr[axe].push_back(
                     new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
             } else {
-                std::cerr << "incorrect gyr metadata : " << fCurrentGyr << std::endl;
+                fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
             }
             fCurrentGyr = "";
         }
 
         // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
         if (fCurrentColor.size() > 0) {
-            if ((fCurrentColor == "red") && (fRedReader == 0)) {
+            if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "green") && (fGreenReader == 0)) {
+            } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "blue") && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
-            } else if ((fCurrentColor == "white") && (fRedReader == 0)
-                       && (fGreenReader == 0) && (fBlueReader == 0)) {
+            } else if ((fCurrentColor == "white") && (fRedReader == nullptr)
+                       && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
                 fRedReader        = new ZoneReader(zone, min, max);
                 fGreenReader      = new ZoneReader(zone, min, max);
                 fBlueReader       = new ZoneReader(zone, min, max);
                 fHasScreenControl = true;
             } else {
-                std::cerr << "incorrect screencolor metadata : " << fCurrentColor
-                          << std::endl;
+                fprintf(stderr, "incorrect screencolor metadata : %s \n",
+                        fCurrentColor.c_str());
             }
         }
         fCurrentColor = "";
@@ -1189,7 +1496,7 @@ class APIUI
 
     int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
     {
-        FAUSTFLOAT* zone = fZone[p];
+        FAUSTFLOAT* zone = fItems[uint(p)].fZone;
         for (size_t i = 0; i < table[val].size(); i++) {
             if (zone == table[val][i]->getZone())
                 return int(i);
@@ -1206,11 +1513,11 @@ class APIUI
 
         // Deactivates everywhere..
         if (id1 != -1)
-            table[0][id1]->setActive(false);
+            table[0][uint(id1)]->setActive(false);
         if (id2 != -1)
-            table[1][id2]->setActive(false);
+            table[1][uint(id2)]->setActive(false);
         if (id3 != -1)
-            table[2][id3]->setActive(false);
+            table[2][uint(id3)]->setActive(false);
 
         if (val == -1) {  // Means: no more mapping...
             // So stay all deactivated...
@@ -1218,14 +1525,16 @@ class APIUI
             int id4 = getZoneIndex(table, p, val);
             if (id4 != -1) {
                 // Reactivate the one we edit...
-                table[val][id4]->setMappingValues(curve, amin, amid, amax, fMin[p],
-                                                  fInit[p], fMax[p]);
-                table[val][id4]->setActive(true);
+                table[val][uint(id4)]->setMappingValues(
+                    curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit,
+                    fItems[uint(p)].fMax);
+                table[val][uint(id4)]->setActive(true);
             } else {
                 // Allocate a new CurveZoneControl which is 'active' by default
-                FAUSTFLOAT* zone = fZone[p];
-                table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax,
-                                                          fMin[p], fInit[p], fMax[p]));
+                FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+                table[val].push_back(new CurveZoneControl(
+                    zone, curve, amin, amid, amax, fItems[uint(p)].fMin,
+                    fItems[uint(p)].fInit, fItems[uint(p)].fMax));
             }
         }
     }
@@ -1239,16 +1548,16 @@ class APIUI
 
         if (id1 != -1) {
             val   = 0;
-            curve = table[val][id1]->getCurve();
-            table[val][id1]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id1)]->getCurve();
+            table[val][uint(id1)]->getMappingValues(amin, amid, amax);
         } else if (id2 != -1) {
             val   = 1;
-            curve = table[val][id2]->getCurve();
-            table[val][id2]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id2)]->getCurve();
+            table[val][uint(id2)]->getMappingValues(amin, amid, amax);
         } else if (id3 != -1) {
             val   = 2;
-            curve = table[val][id3]->getCurve();
-            table[val][id3]->getMappingValues(amin, amid, amax);
+            curve = table[val][uint(id3)]->getCurve();
+            table[val][uint(id3)]->getMappingValues(amin, amid, amax);
         } else {
             val   = -1;  // No mapping
             curve = 0;
@@ -1259,26 +1568,23 @@ class APIUI
     }
 
    public:
-    enum Type { kAcc = 0, kGyr = 1, kNoType };
-
     APIUI()
-        : fNumParameters(0)
-        , fHasScreenControl(false)
-        , fRedReader(0)
-        , fGreenReader(0)
-        , fBlueReader(0)
+        : fHasScreenControl(false)
+        , fRedReader(nullptr)
+        , fGreenReader(nullptr)
+        , fBlueReader(nullptr)
         , fCurrentScale(kLin)
     {
     }
 
     virtual ~APIUI()
     {
-        for (auto& it : fConversion)
-            delete it;
+        for (const auto& it : fItems)
+            delete it.fConversion;
         for (int i = 0; i < 3; i++) {
-            for (auto& it : fAcc[i])
+            for (const auto& it : fAcc[i])
                 delete it;
-            for (auto& it : fGyr[i])
+            for (const auto& it : fGyr[i])
                 delete it;
         }
         delete fRedReader;
@@ -1291,7 +1597,18 @@ class APIUI
     virtual void openTabBox(const char* label) { pushLabel(label); }
     virtual void openHorizontalBox(const char* label) { pushLabel(label); }
     virtual void openVerticalBox(const char* label) { pushLabel(label); }
-    virtual void closeBox() { popLabel(); }
+    virtual void closeBox()
+    {
+        if (popLabel()) {
+            // Shortnames can be computed when all fullnames are known
+            computeShortNames();
+            // Fill 'shortname' field for each item
+            for (const auto& it : fFull2Short) {
+                int index                = getParamIndex(it.first.c_str());
+                fItems[index].fShortname = it.second;
+            }
+        }
+    }
 
     // -- active widgets
 
@@ -1328,25 +1645,25 @@ class APIUI
     virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone,
                                        FAUSTFLOAT min, FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kHBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kHBargraph);
     }
 
     virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min,
                                      FAUSTFLOAT max)
     {
-        addParameter(label, zone, min, min, max, (max - min) / 1000.0, kVBargraph);
+        addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kVBargraph);
     }
 
     // -- soundfiles
 
-    virtual void addSoundfile(const char* label, const char* filename,
-                              Soundfile** sf_zone)
+    virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+                              Soundfile** /*sf_zone*/)
     {
     }
 
     // -- metadata declarations
 
-    virtual void declare(FAUSTFLOAT* zone, const char* key, const char* val)
+    virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
     {
         // Keep metadata
         fCurrentMetadata[key] = val;
@@ -1372,29 +1689,31 @@ class APIUI
         }
     }
 
-    virtual void declare(const char* key, const char* val) {}
+    virtual void declare(const char* /*key*/, const char* /*val*/) {}
 
     //-------------------------------------------------------------------------------
     // Simple API part
     //-------------------------------------------------------------------------------
-    int getParamsCount() { return fNumParameters; }
-    int getParamIndex(const char* path)
+    int getParamsCount() { return int(fItems.size()); }
+
+    int getParamIndex(const char* path_aux)
     {
-        if (fPathMap.find(path) != fPathMap.end()) {
-            return fPathMap[path];
-        } else if (fLabelMap.find(path) != fLabelMap.end()) {
-            return fLabelMap[path];
-        } else {
-            return -1;
-        }
+        std::string path = std::string(path_aux);
+        auto it          = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+            return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+                 });
+        return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
     }
-    const char* getParamAddress(int p) { return fPaths[p].c_str(); }
-    const char* getParamLabel(int p) { return fLabels[p].c_str(); }
+
+    const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
+    const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
+    const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+
     std::map<const char*, const char*> getMetadata(int p)
     {
         std::map<const char*, const char*> res;
-        std::map<std::string, std::string> metadata = fMetaData[p];
-        for (auto it : metadata) {
+        std::map<std::string, std::string> metadata = fMetaData[uint(p)];
+        for (const auto& it : metadata) {
             res[it.first.c_str()] = it.second.c_str();
         }
         return res;
@@ -1402,26 +1721,62 @@ class APIUI
 
     const char* getMetadata(int p, const char* key)
     {
-        return (fMetaData[p].find(key) != fMetaData[p].end()) ? fMetaData[p][key].c_str()
-                                                              : "";
+        return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end())
+                   ? fMetaData[uint(p)][key].c_str()
+                   : "";
+    }
+    FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
+    FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
+    FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
+    FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
+
+    FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
+
+    FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
+    FAUSTFLOAT getParamValue(const char* path)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            return getParamValue(index);
+        } else {
+            fprintf(stderr, "getParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+            return FAUSTFLOAT(0);
+        }
     }
-    FAUSTFLOAT getParamMin(int p) { return fMin[p]; }
-    FAUSTFLOAT getParamMax(int p) { return fMax[p]; }
-    FAUSTFLOAT getParamStep(int p) { return fStep[p]; }
-    FAUSTFLOAT getParamInit(int p) { return fInit[p]; }
 
-    FAUSTFLOAT* getParamZone(int p) { return fZone[p]; }
-    FAUSTFLOAT getParamValue(int p) { return *fZone[p]; }
-    void setParamValue(int p, FAUSTFLOAT v) { *fZone[p] = v; }
+    void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+    void setParamValue(const char* path, FAUSTFLOAT v)
+    {
+        int index = getParamIndex(path);
+        if (index >= 0) {
+            setParamValue(index, v);
+        } else {
+            fprintf(stderr, "setParamValue : '%s' not found\n",
+                    (path == nullptr ? "NULL" : path));
+        }
+    }
 
-    double getParamRatio(int p) { return fConversion[p]->faust2ui(*fZone[p]); }
-    void setParamRatio(int p, double r) { *fZone[p] = fConversion[p]->ui2faust(r); }
+    double getParamRatio(int p)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone);
+    }
+    void setParamRatio(int p, double r)
+    {
+        *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r));
+    }
 
-    double value2ratio(int p, double r) { return fConversion[p]->faust2ui(r); }
-    double ratio2value(int p, double r) { return fConversion[p]->ui2faust(r); }
+    double value2ratio(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->faust2ui(r);
+    }
+    double ratio2value(int p, double r)
+    {
+        return fItems[uint(p)].fConversion->ui2faust(r);
+    }
 
     /**
-     * Return the control type (kAcc, kGyr, or -1) for a given parameter
+     * Return the control type (kAcc, kGyr, or -1) for a given parameter.
      *
      * @param p - the UI parameter index
      *
@@ -1443,13 +1798,13 @@ class APIUI
 
     /**
      * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry,
-     * kHBargraph, kVBargraph) for a given parameter
+     * kHBargraph, kVBargraph) for a given parameter.
      *
      * @param p - the UI parameter index
      *
      * @return the Item type
      */
-    ItemType getParamItemType(int p) { return fItemType[p]; }
+    ItemType getParamItemType(int p) { return fItems[uint(p)].fItemType; }
 
     /**
      * Set a new value coming from an accelerometer, propagate it to all relevant
@@ -1489,7 +1844,7 @@ class APIUI
      * given UI parameter.
      *
      * @param p - the UI parameter index
-     * @param acc - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+     * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
      * mapping")
      * @param curve - between 0 and 3
      * @param amin - mapping 'min' point
@@ -1554,7 +1909,7 @@ class APIUI
     }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer
+     * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
      *
      * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
      * @return the number of zones
@@ -1563,7 +1918,7 @@ class APIUI
     int getAccCount(int acc) { return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0; }
 
     /**
-     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope
+     * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
      *
      * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
      * @param the number of zones
@@ -1600,13 +1955,11 @@ class APIUI
 #define FAUSTFLOAT float
 #endif
 
+#include <math.h>
+
 #include <algorithm>
 #include <cmath>
-
-static float zitarevmonodsp_faustpower2_f(float value)
-{
-    return (value * value);
-}
+#include <cstdint>
 
 #ifndef FAUSTCLASS
 #define FAUSTCLASS zitarevmonodsp
@@ -1617,108 +1970,104 @@ static float zitarevmonodsp_faustpower2_f(float value)
 #define exp10  __exp10
 #endif
 
+#if defined(_WIN32)
+#define RESTRICT __restrict
+#else
+#define RESTRICT __restrict__
+#endif
+
+static float zitarevmonodsp_faustpower2_f(float value)
+{
+    return value * value;
+}
+
 class zitarevmonodsp : public dsp
 {
    private:
-    int IOTA;
+    int IOTA0;
     float fVec0[16384];
+    int fSampleRate;
+    float fConst1;
     FAUSTFLOAT fVslider0;
+    float fConst2;
     float fRec0[2];
     FAUSTFLOAT fVslider1;
     float fRec1[2];
-    int fSampleRate;
-    float fConst0;
-    float fConst1;
+    float fConst3;
     FAUSTFLOAT fVslider2;
     FAUSTFLOAT fVslider3;
     FAUSTFLOAT fVslider4;
     FAUSTFLOAT fVslider5;
-    float fConst2;
-    float fConst3;
+    float fConst5;
     FAUSTFLOAT fVslider6;
     FAUSTFLOAT fVslider7;
     FAUSTFLOAT fVslider8;
-    float fConst4;
+    float fConst6;
     FAUSTFLOAT fVslider9;
     float fRec15[2];
     float fRec14[2];
     float fVec1[32768];
-    float fConst5;
-    int iConst6;
-    float fConst7;
+    int iConst8;
+    float fConst9;
     FAUSTFLOAT fVslider10;
     float fVec2[2048];
-    int iConst8;
+    int iConst10;
     float fRec12[2];
-    float fConst9;
-    float fConst10;
+    float fConst12;
     float fRec19[2];
     float fRec18[2];
     float fVec3[32768];
-    float fConst11;
-    int iConst12;
+    int iConst14;
     float fVec4[4096];
-    int iConst13;
+    int iConst15;
     float fRec16[2];
-    float fConst14;
-    float fConst15;
+    float fConst17;
     float fRec23[2];
     float fRec22[2];
     float fVec5[16384];
-    float fConst16;
-    int iConst17;
+    int iConst19;
     float fVec6[4096];
-    int iConst18;
+    int iConst20;
     float fRec20[2];
-    float fConst19;
-    float fConst20;
+    float fConst22;
     float fRec27[2];
     float fRec26[2];
     float fVec7[32768];
-    float fConst21;
-    int iConst22;
+    int iConst24;
     float fVec8[4096];
-    int iConst23;
+    int iConst25;
     float fRec24[2];
-    float fConst24;
-    float fConst25;
+    float fConst27;
     float fRec31[2];
     float fRec30[2];
     float fVec9[16384];
-    float fConst26;
-    int iConst27;
+    int iConst29;
     float fVec10[2048];
-    int iConst28;
+    int iConst30;
     float fRec28[2];
-    float fConst29;
-    float fConst30;
+    float fConst32;
     float fRec35[2];
     float fRec34[2];
     float fVec11[16384];
-    float fConst31;
-    int iConst32;
+    int iConst34;
     float fVec12[4096];
-    int iConst33;
+    int iConst35;
     float fRec32[2];
-    float fConst34;
-    float fConst35;
+    float fConst37;
     float fRec39[2];
     float fRec38[2];
     float fVec13[16384];
-    float fConst36;
-    int iConst37;
+    int iConst39;
     float fVec14[4096];
-    int iConst38;
+    int iConst40;
     float fRec36[2];
-    float fConst39;
-    float fConst40;
+    float fConst42;
     float fRec43[2];
     float fRec42[2];
     float fVec15[16384];
-    float fConst41;
-    int iConst42;
+    int iConst44;
     float fVec16[2048];
-    int iConst43;
+    int iConst45;
     float fRec40[2];
     float fRec4[3];
     float fRec5[3];
@@ -1737,7 +2086,10 @@ class zitarevmonodsp : public dsp
     void metadata(Meta* m)
     {
         m->declare("basics.lib/name", "Faust Basic Element Library");
-        m->declare("basics.lib/version", "0.1");
+        m->declare("basics.lib/version", "0.8");
+        m->declare("compile_options",
+                   "-a faust2header.cpp -lang cpp -i -inpl -cn zitarevmonodsp -es 1 -mcd "
+                   "16 -single -ftz 0");
         m->declare("delays.lib/name", "Faust Delay Library");
         m->declare("delays.lib/version", "0.1");
         m->declare("filename", "zitarevmonodsp.dsp");
@@ -1784,119 +2136,87 @@ class zitarevmonodsp : public dsp
             "filters.lib/tf2:copyright",
             "Copyright (C) 2003-2019 by Julius O. Smith III <jos@ccrma.stanford.edu>");
         m->declare("filters.lib/tf2:license", "MIT-style STK-4.3 license");
+        m->declare("filters.lib/version", "0.3");
         m->declare("maths.lib/author", "GRAME");
         m->declare("maths.lib/copyright", "GRAME");
         m->declare("maths.lib/license", "LGPL with exception");
         m->declare("maths.lib/name", "Faust Math Library");
-        m->declare("maths.lib/version", "2.3");
+        m->declare("maths.lib/version", "2.5");
         m->declare("name", "zitarevmonodsp");
         m->declare("platform.lib/name", "Generic Platform Library");
-        m->declare("platform.lib/version", "0.1");
+        m->declare("platform.lib/version", "0.2");
         m->declare("reverbs.lib/name", "Faust Reverb Library");
-        m->declare("reverbs.lib/version", "0.0");
+        m->declare("reverbs.lib/version", "0.2");
+        m->declare("routes.lib/hadamard:author", "Remy Muller, revised by Romain Michon");
         m->declare("routes.lib/name", "Faust Signal Routing Library");
         m->declare("routes.lib/version", "0.2");
         m->declare("signals.lib/name", "Faust Signal Routing Library");
-        m->declare("signals.lib/version", "0.0");
+        m->declare("signals.lib/version", "0.3");
     }
 
     virtual int getNumInputs() { return 1; }
     virtual int getNumOutputs() { return 1; }
-    virtual int getInputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
-    virtual int getOutputRate(int channel)
-    {
-        int rate;
-        switch ((channel)) {
-        case 0: {
-            rate = 1;
-            break;
-        }
-        default: {
-            rate = -1;
-            break;
-        }
-        }
-        return rate;
-    }
 
     static void classInit(int /*sample_rate*/) {}
 
     virtual void instanceConstants(int sample_rate)
     {
         fSampleRate = sample_rate;
-        fConst0 = std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
-        fConst1 = (6.28318548f / fConst0);
-        fConst2 = std::floor(((0.219990999f * fConst0) + 0.5f));
-        fConst3 = ((0.0f - (6.90775537f * fConst2)) / fConst0);
-        fConst4 = (3.14159274f / fConst0);
-        fConst5 = std::floor(((0.0191229992f * fConst0) + 0.5f));
-        iConst6 =
-            int(std::min<float>(16384.0f, std::max<float>(0.0f, (fConst2 - fConst5))));
-        fConst7 = (0.00100000005f * fConst0);
-        iConst8 = int(std::min<float>(1024.0f, std::max<float>(0.0f, (fConst5 + -1.0f))));
-        fConst9 = std::floor(((0.256891012f * fConst0) + 0.5f));
-        fConst10 = ((0.0f - (6.90775537f * fConst9)) / fConst0);
-        fConst11 = std::floor(((0.0273330007f * fConst0) + 0.5f));
-        iConst12 =
-            int(std::min<float>(16384.0f, std::max<float>(0.0f, (fConst9 - fConst11))));
-        iConst13 =
-            int(std::min<float>(2048.0f, std::max<float>(0.0f, (fConst11 + -1.0f))));
-        fConst14 = std::floor(((0.192303002f * fConst0) + 0.5f));
-        fConst15 = ((0.0f - (6.90775537f * fConst14)) / fConst0);
-        fConst16 = std::floor(((0.0292910002f * fConst0) + 0.5f));
-        iConst17 =
-            int(std::min<float>(8192.0f, std::max<float>(0.0f, (fConst14 - fConst16))));
-        iConst18 =
-            int(std::min<float>(2048.0f, std::max<float>(0.0f, (fConst16 + -1.0f))));
-        fConst19 = std::floor(((0.210389003f * fConst0) + 0.5f));
-        fConst20 = ((0.0f - (6.90775537f * fConst19)) / fConst0);
-        fConst21 = std::floor(((0.0244210009f * fConst0) + 0.5f));
-        iConst22 =
-            int(std::min<float>(16384.0f, std::max<float>(0.0f, (fConst19 - fConst21))));
-        iConst23 =
-            int(std::min<float>(2048.0f, std::max<float>(0.0f, (fConst21 + -1.0f))));
-        fConst24 = std::floor(((0.125f * fConst0) + 0.5f));
-        fConst25 = ((0.0f - (6.90775537f * fConst24)) / fConst0);
-        fConst26 = std::floor(((0.0134579996f * fConst0) + 0.5f));
-        iConst27 =
-            int(std::min<float>(8192.0f, std::max<float>(0.0f, (fConst24 - fConst26))));
-        iConst28 =
-            int(std::min<float>(1024.0f, std::max<float>(0.0f, (fConst26 + -1.0f))));
-        fConst29 = std::floor(((0.127837002f * fConst0) + 0.5f));
-        fConst30 = ((0.0f - (6.90775537f * fConst29)) / fConst0);
-        fConst31 = std::floor(((0.0316039994f * fConst0) + 0.5f));
-        iConst32 =
-            int(std::min<float>(8192.0f, std::max<float>(0.0f, (fConst29 - fConst31))));
-        iConst33 =
-            int(std::min<float>(2048.0f, std::max<float>(0.0f, (fConst31 + -1.0f))));
-        fConst34 = std::floor(((0.174713001f * fConst0) + 0.5f));
-        fConst35 = ((0.0f - (6.90775537f * fConst34)) / fConst0);
-        fConst36 = std::floor(((0.0229039993f * fConst0) + 0.5f));
-        iConst37 =
-            int(std::min<float>(8192.0f, std::max<float>(0.0f, (fConst34 - fConst36))));
-        iConst38 =
-            int(std::min<float>(2048.0f, std::max<float>(0.0f, (fConst36 + -1.0f))));
-        fConst39 = std::floor(((0.153128996f * fConst0) + 0.5f));
-        fConst40 = ((0.0f - (6.90775537f * fConst39)) / fConst0);
-        fConst41 = std::floor(((0.0203460008f * fConst0) + 0.5f));
-        iConst42 =
-            int(std::min<float>(8192.0f, std::max<float>(0.0f, (fConst39 - fConst41))));
-        iConst43 =
-            int(std::min<float>(1024.0f, std::max<float>(0.0f, (fConst41 + -1.0f))));
+        float fConst0 =
+            std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
+        fConst1       = 44.0999985f / fConst0;
+        fConst2       = 1.0f - fConst1;
+        fConst3       = 6.28318548f / fConst0;
+        float fConst4 = std::floor(0.219990999f * fConst0 + 0.5f);
+        fConst5       = (0.0f - 6.90775537f * fConst4) / fConst0;
+        fConst6       = 3.14159274f / fConst0;
+        float fConst7 = std::floor(0.0191229992f * fConst0 + 0.5f);
+        iConst8 =
+            int(std::min<float>(16384.0f, std::max<float>(0.0f, fConst4 - fConst7)));
+        fConst9  = 0.00100000005f * fConst0;
+        iConst10 = int(std::min<float>(1024.0f, std::max<float>(0.0f, fConst7 + -1.0f)));
+        float fConst11 = std::floor(0.256891012f * fConst0 + 0.5f);
+        fConst12       = (0.0f - 6.90775537f * fConst11) / fConst0;
+        float fConst13 = std::floor(0.0273330007f * fConst0 + 0.5f);
+        iConst14 =
+            int(std::min<float>(16384.0f, std::max<float>(0.0f, fConst11 - fConst13)));
+        iConst15 = int(std::min<float>(2048.0f, std::max<float>(0.0f, fConst13 + -1.0f)));
+        float fConst16 = std::floor(0.192303002f * fConst0 + 0.5f);
+        fConst17       = (0.0f - 6.90775537f * fConst16) / fConst0;
+        float fConst18 = std::floor(0.0292910002f * fConst0 + 0.5f);
+        iConst19 =
+            int(std::min<float>(8192.0f, std::max<float>(0.0f, fConst16 - fConst18)));
+        iConst20 = int(std::min<float>(2048.0f, std::max<float>(0.0f, fConst18 + -1.0f)));
+        float fConst21 = std::floor(0.210389003f * fConst0 + 0.5f);
+        fConst22       = (0.0f - 6.90775537f * fConst21) / fConst0;
+        float fConst23 = std::floor(0.0244210009f * fConst0 + 0.5f);
+        iConst24 =
+            int(std::min<float>(16384.0f, std::max<float>(0.0f, fConst21 - fConst23)));
+        iConst25 = int(std::min<float>(2048.0f, std::max<float>(0.0f, fConst23 + -1.0f)));
+        float fConst26 = std::floor(0.125f * fConst0 + 0.5f);
+        fConst27       = (0.0f - 6.90775537f * fConst26) / fConst0;
+        float fConst28 = std::floor(0.0134579996f * fConst0 + 0.5f);
+        iConst29 =
+            int(std::min<float>(8192.0f, std::max<float>(0.0f, fConst26 - fConst28)));
+        iConst30 = int(std::min<float>(1024.0f, std::max<float>(0.0f, fConst28 + -1.0f)));
+        float fConst31 = std::floor(0.127837002f * fConst0 + 0.5f);
+        fConst32       = (0.0f - 6.90775537f * fConst31) / fConst0;
+        float fConst33 = std::floor(0.0316039994f * fConst0 + 0.5f);
+        iConst34 =
+            int(std::min<float>(8192.0f, std::max<float>(0.0f, fConst31 - fConst33)));
+        iConst35 = int(std::min<float>(2048.0f, std::max<float>(0.0f, fConst33 + -1.0f)));
+        float fConst36 = std::floor(0.174713001f * fConst0 + 0.5f);
+        fConst37       = (0.0f - 6.90775537f * fConst36) / fConst0;
+        float fConst38 = std::floor(0.0229039993f * fConst0 + 0.5f);
+        iConst39 =
+            int(std::min<float>(8192.0f, std::max<float>(0.0f, fConst36 - fConst38)));
+        iConst40 = int(std::min<float>(2048.0f, std::max<float>(0.0f, fConst38 + -1.0f)));
+        float fConst41 = std::floor(0.153128996f * fConst0 + 0.5f);
+        fConst42       = (0.0f - 6.90775537f * fConst41) / fConst0;
+        float fConst43 = std::floor(0.0203460008f * fConst0 + 0.5f);
+        iConst44 =
+            int(std::min<float>(8192.0f, std::max<float>(0.0f, fConst41 - fConst43)));
+        iConst45 = int(std::min<float>(1024.0f, std::max<float>(0.0f, fConst43 + -1.0f)));
     }
 
     virtual void instanceResetUserInterface()
@@ -1916,170 +2236,170 @@ class zitarevmonodsp : public dsp
 
     virtual void instanceClear()
     {
-        IOTA = 0;
-        for (int l0 = 0; (l0 < 16384); l0 = (l0 + 1)) {
+        IOTA0 = 0;
+        for (int l0 = 0; l0 < 16384; l0 = l0 + 1) {
             fVec0[l0] = 0.0f;
         }
-        for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) {
+        for (int l1 = 0; l1 < 2; l1 = l1 + 1) {
             fRec0[l1] = 0.0f;
         }
-        for (int l2 = 0; (l2 < 2); l2 = (l2 + 1)) {
+        for (int l2 = 0; l2 < 2; l2 = l2 + 1) {
             fRec1[l2] = 0.0f;
         }
-        for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) {
+        for (int l3 = 0; l3 < 2; l3 = l3 + 1) {
             fRec15[l3] = 0.0f;
         }
-        for (int l4 = 0; (l4 < 2); l4 = (l4 + 1)) {
+        for (int l4 = 0; l4 < 2; l4 = l4 + 1) {
             fRec14[l4] = 0.0f;
         }
-        for (int l5 = 0; (l5 < 32768); l5 = (l5 + 1)) {
+        for (int l5 = 0; l5 < 32768; l5 = l5 + 1) {
             fVec1[l5] = 0.0f;
         }
-        for (int l6 = 0; (l6 < 2048); l6 = (l6 + 1)) {
+        for (int l6 = 0; l6 < 2048; l6 = l6 + 1) {
             fVec2[l6] = 0.0f;
         }
-        for (int l7 = 0; (l7 < 2); l7 = (l7 + 1)) {
+        for (int l7 = 0; l7 < 2; l7 = l7 + 1) {
             fRec12[l7] = 0.0f;
         }
-        for (int l8 = 0; (l8 < 2); l8 = (l8 + 1)) {
+        for (int l8 = 0; l8 < 2; l8 = l8 + 1) {
             fRec19[l8] = 0.0f;
         }
-        for (int l9 = 0; (l9 < 2); l9 = (l9 + 1)) {
+        for (int l9 = 0; l9 < 2; l9 = l9 + 1) {
             fRec18[l9] = 0.0f;
         }
-        for (int l10 = 0; (l10 < 32768); l10 = (l10 + 1)) {
+        for (int l10 = 0; l10 < 32768; l10 = l10 + 1) {
             fVec3[l10] = 0.0f;
         }
-        for (int l11 = 0; (l11 < 4096); l11 = (l11 + 1)) {
+        for (int l11 = 0; l11 < 4096; l11 = l11 + 1) {
             fVec4[l11] = 0.0f;
         }
-        for (int l12 = 0; (l12 < 2); l12 = (l12 + 1)) {
+        for (int l12 = 0; l12 < 2; l12 = l12 + 1) {
             fRec16[l12] = 0.0f;
         }
-        for (int l13 = 0; (l13 < 2); l13 = (l13 + 1)) {
+        for (int l13 = 0; l13 < 2; l13 = l13 + 1) {
             fRec23[l13] = 0.0f;
         }
-        for (int l14 = 0; (l14 < 2); l14 = (l14 + 1)) {
+        for (int l14 = 0; l14 < 2; l14 = l14 + 1) {
             fRec22[l14] = 0.0f;
         }
-        for (int l15 = 0; (l15 < 16384); l15 = (l15 + 1)) {
+        for (int l15 = 0; l15 < 16384; l15 = l15 + 1) {
             fVec5[l15] = 0.0f;
         }
-        for (int l16 = 0; (l16 < 4096); l16 = (l16 + 1)) {
+        for (int l16 = 0; l16 < 4096; l16 = l16 + 1) {
             fVec6[l16] = 0.0f;
         }
-        for (int l17 = 0; (l17 < 2); l17 = (l17 + 1)) {
+        for (int l17 = 0; l17 < 2; l17 = l17 + 1) {
             fRec20[l17] = 0.0f;
         }
-        for (int l18 = 0; (l18 < 2); l18 = (l18 + 1)) {
+        for (int l18 = 0; l18 < 2; l18 = l18 + 1) {
             fRec27[l18] = 0.0f;
         }
-        for (int l19 = 0; (l19 < 2); l19 = (l19 + 1)) {
+        for (int l19 = 0; l19 < 2; l19 = l19 + 1) {
             fRec26[l19] = 0.0f;
         }
-        for (int l20 = 0; (l20 < 32768); l20 = (l20 + 1)) {
+        for (int l20 = 0; l20 < 32768; l20 = l20 + 1) {
             fVec7[l20] = 0.0f;
         }
-        for (int l21 = 0; (l21 < 4096); l21 = (l21 + 1)) {
+        for (int l21 = 0; l21 < 4096; l21 = l21 + 1) {
             fVec8[l21] = 0.0f;
         }
-        for (int l22 = 0; (l22 < 2); l22 = (l22 + 1)) {
+        for (int l22 = 0; l22 < 2; l22 = l22 + 1) {
             fRec24[l22] = 0.0f;
         }
-        for (int l23 = 0; (l23 < 2); l23 = (l23 + 1)) {
+        for (int l23 = 0; l23 < 2; l23 = l23 + 1) {
             fRec31[l23] = 0.0f;
         }
-        for (int l24 = 0; (l24 < 2); l24 = (l24 + 1)) {
+        for (int l24 = 0; l24 < 2; l24 = l24 + 1) {
             fRec30[l24] = 0.0f;
         }
-        for (int l25 = 0; (l25 < 16384); l25 = (l25 + 1)) {
+        for (int l25 = 0; l25 < 16384; l25 = l25 + 1) {
             fVec9[l25] = 0.0f;
         }
-        for (int l26 = 0; (l26 < 2048); l26 = (l26 + 1)) {
+        for (int l26 = 0; l26 < 2048; l26 = l26 + 1) {
             fVec10[l26] = 0.0f;
         }
-        for (int l27 = 0; (l27 < 2); l27 = (l27 + 1)) {
+        for (int l27 = 0; l27 < 2; l27 = l27 + 1) {
             fRec28[l27] = 0.0f;
         }
-        for (int l28 = 0; (l28 < 2); l28 = (l28 + 1)) {
+        for (int l28 = 0; l28 < 2; l28 = l28 + 1) {
             fRec35[l28] = 0.0f;
         }
-        for (int l29 = 0; (l29 < 2); l29 = (l29 + 1)) {
+        for (int l29 = 0; l29 < 2; l29 = l29 + 1) {
             fRec34[l29] = 0.0f;
         }
-        for (int l30 = 0; (l30 < 16384); l30 = (l30 + 1)) {
+        for (int l30 = 0; l30 < 16384; l30 = l30 + 1) {
             fVec11[l30] = 0.0f;
         }
-        for (int l31 = 0; (l31 < 4096); l31 = (l31 + 1)) {
+        for (int l31 = 0; l31 < 4096; l31 = l31 + 1) {
             fVec12[l31] = 0.0f;
         }
-        for (int l32 = 0; (l32 < 2); l32 = (l32 + 1)) {
+        for (int l32 = 0; l32 < 2; l32 = l32 + 1) {
             fRec32[l32] = 0.0f;
         }
-        for (int l33 = 0; (l33 < 2); l33 = (l33 + 1)) {
+        for (int l33 = 0; l33 < 2; l33 = l33 + 1) {
             fRec39[l33] = 0.0f;
         }
-        for (int l34 = 0; (l34 < 2); l34 = (l34 + 1)) {
+        for (int l34 = 0; l34 < 2; l34 = l34 + 1) {
             fRec38[l34] = 0.0f;
         }
-        for (int l35 = 0; (l35 < 16384); l35 = (l35 + 1)) {
+        for (int l35 = 0; l35 < 16384; l35 = l35 + 1) {
             fVec13[l35] = 0.0f;
         }
-        for (int l36 = 0; (l36 < 4096); l36 = (l36 + 1)) {
+        for (int l36 = 0; l36 < 4096; l36 = l36 + 1) {
             fVec14[l36] = 0.0f;
         }
-        for (int l37 = 0; (l37 < 2); l37 = (l37 + 1)) {
+        for (int l37 = 0; l37 < 2; l37 = l37 + 1) {
             fRec36[l37] = 0.0f;
         }
-        for (int l38 = 0; (l38 < 2); l38 = (l38 + 1)) {
+        for (int l38 = 0; l38 < 2; l38 = l38 + 1) {
             fRec43[l38] = 0.0f;
         }
-        for (int l39 = 0; (l39 < 2); l39 = (l39 + 1)) {
+        for (int l39 = 0; l39 < 2; l39 = l39 + 1) {
             fRec42[l39] = 0.0f;
         }
-        for (int l40 = 0; (l40 < 16384); l40 = (l40 + 1)) {
+        for (int l40 = 0; l40 < 16384; l40 = l40 + 1) {
             fVec15[l40] = 0.0f;
         }
-        for (int l41 = 0; (l41 < 2048); l41 = (l41 + 1)) {
+        for (int l41 = 0; l41 < 2048; l41 = l41 + 1) {
             fVec16[l41] = 0.0f;
         }
-        for (int l42 = 0; (l42 < 2); l42 = (l42 + 1)) {
+        for (int l42 = 0; l42 < 2; l42 = l42 + 1) {
             fRec40[l42] = 0.0f;
         }
-        for (int l43 = 0; (l43 < 3); l43 = (l43 + 1)) {
+        for (int l43 = 0; l43 < 3; l43 = l43 + 1) {
             fRec4[l43] = 0.0f;
         }
-        for (int l44 = 0; (l44 < 3); l44 = (l44 + 1)) {
+        for (int l44 = 0; l44 < 3; l44 = l44 + 1) {
             fRec5[l44] = 0.0f;
         }
-        for (int l45 = 0; (l45 < 3); l45 = (l45 + 1)) {
+        for (int l45 = 0; l45 < 3; l45 = l45 + 1) {
             fRec6[l45] = 0.0f;
         }
-        for (int l46 = 0; (l46 < 3); l46 = (l46 + 1)) {
+        for (int l46 = 0; l46 < 3; l46 = l46 + 1) {
             fRec7[l46] = 0.0f;
         }
-        for (int l47 = 0; (l47 < 3); l47 = (l47 + 1)) {
+        for (int l47 = 0; l47 < 3; l47 = l47 + 1) {
             fRec8[l47] = 0.0f;
         }
-        for (int l48 = 0; (l48 < 3); l48 = (l48 + 1)) {
+        for (int l48 = 0; l48 < 3; l48 = l48 + 1) {
             fRec9[l48] = 0.0f;
         }
-        for (int l49 = 0; (l49 < 3); l49 = (l49 + 1)) {
+        for (int l49 = 0; l49 < 3; l49 = l49 + 1) {
             fRec10[l49] = 0.0f;
         }
-        for (int l50 = 0; (l50 < 3); l50 = (l50 + 1)) {
+        for (int l50 = 0; l50 < 3; l50 = l50 + 1) {
             fRec11[l50] = 0.0f;
         }
-        for (int l51 = 0; (l51 < 3); l51 = (l51 + 1)) {
+        for (int l51 = 0; l51 < 3; l51 = l51 + 1) {
             fRec3[l51] = 0.0f;
         }
-        for (int l52 = 0; (l52 < 3); l52 = (l52 + 1)) {
+        for (int l52 = 0; l52 < 3; l52 = l52 + 1) {
             fRec2[l52] = 0.0f;
         }
-        for (int l53 = 0; (l53 < 3); l53 = (l53 + 1)) {
+        for (int l53 = 0; l53 < 3; l53 = l53 + 1) {
             fRec45[l53] = 0.0f;
         }
-        for (int l54 = 0; (l54 < 3); l54 = (l54 + 1)) {
+        for (int l54 = 0; l54 < 3; l54 = l54 + 1) {
             fRec44[l54] = 0.0f;
         }
     }
@@ -2115,8 +2435,9 @@ class zitarevmonodsp : public dsp
         ui_interface->declare(&fVslider10, "tooltip",
                               "Delay in ms   before reverberation begins");
         ui_interface->declare(&fVslider10, "unit", "ms");
-        ui_interface->addVerticalSlider("In Delay", &fVslider10, 60.0f, 20.0f, 100.0f,
-                                        1.0f);
+        ui_interface->addVerticalSlider("In Delay", &fVslider10, FAUSTFLOAT(60.0f),
+                                        FAUSTFLOAT(20.0f), FAUSTFLOAT(100.0f),
+                                        FAUSTFLOAT(1.0f));
         ui_interface->closeBox();
         ui_interface->declare(0, "2", "");
         ui_interface->openHorizontalBox("Decay Times in Bands (see tooltips)");
@@ -2127,7 +2448,9 @@ class zitarevmonodsp : public dsp
             &fVslider9, "tooltip",
             "Crossover frequency (Hz) separating low and middle frequencies");
         ui_interface->declare(&fVslider9, "unit", "Hz");
-        ui_interface->addVerticalSlider("LF X", &fVslider9, 200.0f, 50.0f, 1000.0f, 1.0f);
+        ui_interface->addVerticalSlider("LF X", &fVslider9, FAUSTFLOAT(200.0f),
+                                        FAUSTFLOAT(50.0f), FAUSTFLOAT(1000.0f),
+                                        FAUSTFLOAT(1.0f));
         ui_interface->declare(&fVslider8, "2", "");
         ui_interface->declare(&fVslider8, "scale", "log");
         ui_interface->declare(&fVslider8, "style", "knob");
@@ -2135,16 +2458,18 @@ class zitarevmonodsp : public dsp
             &fVslider8, "tooltip",
             "T60 = time (in seconds) to decay 60dB in low-frequency band");
         ui_interface->declare(&fVslider8, "unit", "s");
-        ui_interface->addVerticalSlider("Low RT60", &fVslider8, 3.0f, 1.0f, 8.0f,
-                                        0.100000001f);
+        ui_interface->addVerticalSlider("Low RT60", &fVslider8, FAUSTFLOAT(3.0f),
+                                        FAUSTFLOAT(1.0f), FAUSTFLOAT(8.0f),
+                                        FAUSTFLOAT(0.100000001f));
         ui_interface->declare(&fVslider6, "3", "");
         ui_interface->declare(&fVslider6, "scale", "log");
         ui_interface->declare(&fVslider6, "style", "knob");
         ui_interface->declare(&fVslider6, "tooltip",
                               "T60 = time (in seconds) to decay 60dB in middle band");
         ui_interface->declare(&fVslider6, "unit", "s");
-        ui_interface->addVerticalSlider("Mid RT60", &fVslider6, 2.0f, 1.0f, 8.0f,
-                                        0.100000001f);
+        ui_interface->addVerticalSlider("Mid RT60", &fVslider6, FAUSTFLOAT(2.0f),
+                                        FAUSTFLOAT(1.0f), FAUSTFLOAT(8.0f),
+                                        FAUSTFLOAT(0.100000001f));
         ui_interface->declare(&fVslider7, "4", "");
         ui_interface->declare(&fVslider7, "scale", "log");
         ui_interface->declare(&fVslider7, "style", "knob");
@@ -2152,8 +2477,9 @@ class zitarevmonodsp : public dsp
                               "Frequency (Hz) at which the high-frequency T60 is half "
                               "the middle-band's T60");
         ui_interface->declare(&fVslider7, "unit", "Hz");
-        ui_interface->addVerticalSlider("HF Damping", &fVslider7, 6000.0f, 1500.0f,
-                                        23520.0f, 1.0f);
+        ui_interface->addVerticalSlider("HF Damping", &fVslider7, FAUSTFLOAT(6000.0f),
+                                        FAUSTFLOAT(1500.0f), FAUSTFLOAT(23520.0f),
+                                        FAUSTFLOAT(1.0f));
         ui_interface->closeBox();
         ui_interface->declare(0, "3", "");
         ui_interface->openHorizontalBox("RM Peaking Equalizer 1");
@@ -2164,16 +2490,18 @@ class zitarevmonodsp : public dsp
             &fVslider4, "tooltip",
             "Center-frequency of second-order Regalia-Mitra peaking equalizer section 1");
         ui_interface->declare(&fVslider4, "unit", "Hz");
-        ui_interface->addVerticalSlider("Eq1 Freq", &fVslider4, 315.0f, 40.0f, 2500.0f,
-                                        1.0f);
+        ui_interface->addVerticalSlider("Eq1 Freq", &fVslider4, FAUSTFLOAT(315.0f),
+                                        FAUSTFLOAT(40.0f), FAUSTFLOAT(2500.0f),
+                                        FAUSTFLOAT(1.0f));
         ui_interface->declare(&fVslider5, "2", "");
         ui_interface->declare(&fVslider5, "style", "knob");
         ui_interface->declare(&fVslider5, "tooltip",
                               "Peak level   in dB of second-order Regalia-Mitra peaking "
                               "equalizer section 1");
         ui_interface->declare(&fVslider5, "unit", "dB");
-        ui_interface->addVerticalSlider("Eq1 Level", &fVslider5, 0.0f, -15.0f, 15.0f,
-                                        0.100000001f);
+        ui_interface->addVerticalSlider("Eq1 Level", &fVslider5, FAUSTFLOAT(0.0f),
+                                        FAUSTFLOAT(-15.0f), FAUSTFLOAT(15.0f),
+                                        FAUSTFLOAT(0.100000001f));
         ui_interface->closeBox();
         ui_interface->declare(0, "4", "");
         ui_interface->openHorizontalBox("RM Peaking Equalizer 2");
@@ -2184,30 +2512,34 @@ class zitarevmonodsp : public dsp
             &fVslider2, "tooltip",
             "Center-frequency of second-order Regalia-Mitra peaking equalizer section 2");
         ui_interface->declare(&fVslider2, "unit", "Hz");
-        ui_interface->addVerticalSlider("Eq2 Freq", &fVslider2, 1500.0f, 160.0f, 10000.0f,
-                                        1.0f);
+        ui_interface->addVerticalSlider("Eq2 Freq", &fVslider2, FAUSTFLOAT(1500.0f),
+                                        FAUSTFLOAT(160.0f), FAUSTFLOAT(10000.0f),
+                                        FAUSTFLOAT(1.0f));
         ui_interface->declare(&fVslider3, "2", "");
         ui_interface->declare(&fVslider3, "style", "knob");
         ui_interface->declare(&fVslider3, "tooltip",
                               "Peak level   in dB of second-order Regalia-Mitra peaking "
                               "equalizer section 2");
         ui_interface->declare(&fVslider3, "unit", "dB");
-        ui_interface->addVerticalSlider("Eq2 Level", &fVslider3, 0.0f, -15.0f, 15.0f,
-                                        0.100000001f);
+        ui_interface->addVerticalSlider("Eq2 Level", &fVslider3, FAUSTFLOAT(0.0f),
+                                        FAUSTFLOAT(-15.0f), FAUSTFLOAT(15.0f),
+                                        FAUSTFLOAT(0.100000001f));
         ui_interface->closeBox();
         ui_interface->declare(0, "5", "");
         ui_interface->openHorizontalBox("Output");
         ui_interface->declare(&fVslider1, "1", "");
         ui_interface->declare(&fVslider1, "style", "knob");
         ui_interface->declare(&fVslider1, "tooltip", "Dry/Wet Mix: 0 = dry, 1 = wet");
-        ui_interface->addVerticalSlider("Wet", &fVslider1, 0.0f, 0.0f, 1.0f,
-                                        0.00999999978f);
+        ui_interface->addVerticalSlider("Wet", &fVslider1, FAUSTFLOAT(0.0f),
+                                        FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+                                        FAUSTFLOAT(0.00999999978f));
         ui_interface->declare(&fVslider0, "2", "");
         ui_interface->declare(&fVslider0, "style", "knob");
         ui_interface->declare(&fVslider0, "tooltip", "Output scale   factor");
         ui_interface->declare(&fVslider0, "unit", "dB");
-        ui_interface->addVerticalSlider("Level", &fVslider0, -3.0f, -70.0f, 20.0f,
-                                        0.100000001f);
+        ui_interface->addVerticalSlider("Level", &fVslider0, FAUSTFLOAT(-3.0f),
+                                        FAUSTFLOAT(-70.0f), FAUSTFLOAT(20.0f),
+                                        FAUSTFLOAT(0.100000001f));
         ui_interface->closeBox();
         ui_interface->closeBox();
     }
@@ -2216,365 +2548,310 @@ class zitarevmonodsp : public dsp
     {
         FAUSTFLOAT* input0  = inputs[0];
         FAUSTFLOAT* output0 = outputs[0];
-        float fSlow0 =
-            (0.00100000005f * std::pow(10.0f, (0.0500000007f * float(fVslider0))));
-        float fSlow1  = (0.00100000005f * float(fVslider1));
-        float fSlow2  = float(fVslider2);
-        float fSlow3  = std::pow(10.0f, (0.0500000007f * float(fVslider3)));
-        float fSlow4  = (fConst1 * (fSlow2 / std::sqrt(std::max<float>(0.0f, fSlow3))));
-        float fSlow5  = ((1.0f - fSlow4) / (fSlow4 + 1.0f));
-        float fSlow6  = float(fVslider4);
-        float fSlow7  = std::pow(10.0f, (0.0500000007f * float(fVslider5)));
-        float fSlow8  = (fConst1 * (fSlow6 / std::sqrt(std::max<float>(0.0f, fSlow7))));
-        float fSlow9  = ((1.0f - fSlow8) / (fSlow8 + 1.0f));
-        float fSlow10 = float(fVslider6);
-        float fSlow11 = std::exp((fConst3 / fSlow10));
-        float fSlow12 = zitarevmonodsp_faustpower2_f(fSlow11);
-        float fSlow13 = std::cos((fConst1 * float(fVslider7)));
-        float fSlow14 = (1.0f - (fSlow12 * fSlow13));
-        float fSlow15 = (1.0f - fSlow12);
-        float fSlow16 = (fSlow14 / fSlow15);
-        float fSlow17 =
-            std::sqrt(std::max<float>(0.0f, ((zitarevmonodsp_faustpower2_f(fSlow14)
-                                              / zitarevmonodsp_faustpower2_f(fSlow15))
-                                             + -1.0f)));
-        float fSlow18 = (fSlow16 - fSlow17);
-        float fSlow19 = (fSlow11 * (fSlow17 + (1.0f - fSlow16)));
-        float fSlow20 = float(fVslider8);
-        float fSlow21 = ((std::exp((fConst3 / fSlow20)) / fSlow11) + -1.0f);
-        float fSlow22 = (1.0f / std::tan((fConst4 * float(fVslider9))));
-        float fSlow23 = (1.0f / (fSlow22 + 1.0f));
-        float fSlow24 = (1.0f - fSlow22);
-        int iSlow25   = int(std::min<float>(
-            8192.0f, std::max<float>(0.0f, (fConst7 * float(fVslider10)))));
-        float fSlow26 = std::exp((fConst10 / fSlow10));
+        float fSlow0        = fConst1 * std::pow(10.0f, 0.0500000007f * float(fVslider0));
+        float fSlow1        = fConst1 * float(fVslider1);
+        float fSlow2        = float(fVslider2);
+        float fSlow3        = std::pow(10.0f, 0.0500000007f * float(fVslider3));
+        float fSlow4        = fConst3 * fSlow2 / std::sqrt(std::max<float>(0.0f, fSlow3));
+        float fSlow5        = (1.0f - fSlow4) / (fSlow4 + 1.0f);
+        float fSlow6        = float(fVslider4);
+        float fSlow7        = std::pow(10.0f, 0.0500000007f * float(fVslider5));
+        float fSlow8        = fConst3 * fSlow6 / std::sqrt(std::max<float>(0.0f, fSlow7));
+        float fSlow9        = (1.0f - fSlow8) / (fSlow8 + 1.0f);
+        float fSlow10       = float(fVslider6);
+        float fSlow11       = std::exp(fConst5 / fSlow10);
+        float fSlow12       = zitarevmonodsp_faustpower2_f(fSlow11);
+        float fSlow13       = std::cos(fConst3 * float(fVslider7));
+        float fSlow14       = 1.0f - fSlow12 * fSlow13;
+        float fSlow15       = 1.0f - fSlow12;
+        float fSlow16       = std::sqrt(std::max<float>(
+            0.0f,
+            zitarevmonodsp_faustpower2_f(fSlow14) / zitarevmonodsp_faustpower2_f(fSlow15)
+                + -1.0f));
+        float fSlow17       = fSlow14 / fSlow15;
+        float fSlow18       = fSlow11 * (fSlow16 + 1.0f - fSlow17);
+        float fSlow19       = float(fVslider8);
+        float fSlow20       = std::exp(fConst5 / fSlow19) / fSlow11 + -1.0f;
+        float fSlow21       = 1.0f / std::tan(fConst6 * float(fVslider9));
+        float fSlow22       = 1.0f / (fSlow21 + 1.0f);
+        float fSlow23       = 1.0f - fSlow21;
+        float fSlow24       = fSlow17 - fSlow16;
+        int iSlow25         = int(
+            std::min<float>(8192.0f, std::max<float>(0.0f, fConst9 * float(fVslider10))));
+        float fSlow26 = std::exp(fConst12 / fSlow10);
         float fSlow27 = zitarevmonodsp_faustpower2_f(fSlow26);
-        float fSlow28 = (1.0f - (fSlow27 * fSlow13));
-        float fSlow29 = (1.0f - fSlow27);
-        float fSlow30 = (fSlow28 / fSlow29);
-        float fSlow31 =
-            std::sqrt(std::max<float>(0.0f, ((zitarevmonodsp_faustpower2_f(fSlow28)
-                                              / zitarevmonodsp_faustpower2_f(fSlow29))
-                                             + -1.0f)));
-        float fSlow32 = (fSlow30 - fSlow31);
-        float fSlow33 = (fSlow26 * (fSlow31 + (1.0f - fSlow30)));
-        float fSlow34 = ((std::exp((fConst10 / fSlow20)) / fSlow26) + -1.0f);
-        float fSlow35 = std::exp((fConst15 / fSlow10));
+        float fSlow28 = 1.0f - fSlow27 * fSlow13;
+        float fSlow29 = 1.0f - fSlow27;
+        float fSlow30 = std::sqrt(std::max<float>(
+            0.0f,
+            zitarevmonodsp_faustpower2_f(fSlow28) / zitarevmonodsp_faustpower2_f(fSlow29)
+                + -1.0f));
+        float fSlow31 = fSlow28 / fSlow29;
+        float fSlow32 = fSlow26 * (fSlow30 + 1.0f - fSlow31);
+        float fSlow33 = std::exp(fConst12 / fSlow19) / fSlow26 + -1.0f;
+        float fSlow34 = fSlow31 - fSlow30;
+        float fSlow35 = std::exp(fConst17 / fSlow10);
         float fSlow36 = zitarevmonodsp_faustpower2_f(fSlow35);
-        float fSlow37 = (1.0f - (fSlow36 * fSlow13));
-        float fSlow38 = (1.0f - fSlow36);
-        float fSlow39 = (fSlow37 / fSlow38);
-        float fSlow40 =
-            std::sqrt(std::max<float>(0.0f, ((zitarevmonodsp_faustpower2_f(fSlow37)
-                                              / zitarevmonodsp_faustpower2_f(fSlow38))
-                                             + -1.0f)));
-        float fSlow41 = (fSlow39 - fSlow40);
-        float fSlow42 = (fSlow35 * (fSlow40 + (1.0f - fSlow39)));
-        float fSlow43 = ((std::exp((fConst15 / fSlow20)) / fSlow35) + -1.0f);
-        float fSlow44 = std::exp((fConst20 / fSlow10));
+        float fSlow37 = 1.0f - fSlow36 * fSlow13;
+        float fSlow38 = 1.0f - fSlow36;
+        float fSlow39 = std::sqrt(std::max<float>(
+            0.0f,
+            zitarevmonodsp_faustpower2_f(fSlow37) / zitarevmonodsp_faustpower2_f(fSlow38)
+                + -1.0f));
+        float fSlow40 = fSlow37 / fSlow38;
+        float fSlow41 = fSlow35 * (fSlow39 + 1.0f - fSlow40);
+        float fSlow42 = std::exp(fConst17 / fSlow19) / fSlow35 + -1.0f;
+        float fSlow43 = fSlow40 - fSlow39;
+        float fSlow44 = std::exp(fConst22 / fSlow10);
         float fSlow45 = zitarevmonodsp_faustpower2_f(fSlow44);
-        float fSlow46 = (1.0f - (fSlow45 * fSlow13));
-        float fSlow47 = (1.0f - fSlow45);
-        float fSlow48 = (fSlow46 / fSlow47);
-        float fSlow49 =
-            std::sqrt(std::max<float>(0.0f, ((zitarevmonodsp_faustpower2_f(fSlow46)
-                                              / zitarevmonodsp_faustpower2_f(fSlow47))
-                                             + -1.0f)));
-        float fSlow50 = (fSlow48 - fSlow49);
-        float fSlow51 = (fSlow44 * (fSlow49 + (1.0f - fSlow48)));
-        float fSlow52 = ((std::exp((fConst20 / fSlow20)) / fSlow44) + -1.0f);
-        float fSlow53 = std::exp((fConst25 / fSlow10));
+        float fSlow46 = 1.0f - fSlow45 * fSlow13;
+        float fSlow47 = 1.0f - fSlow45;
+        float fSlow48 = std::sqrt(std::max<float>(
+            0.0f,
+            zitarevmonodsp_faustpower2_f(fSlow46) / zitarevmonodsp_faustpower2_f(fSlow47)
+                + -1.0f));
+        float fSlow49 = fSlow46 / fSlow47;
+        float fSlow50 = fSlow44 * (fSlow48 + 1.0f - fSlow49);
+        float fSlow51 = std::exp(fConst22 / fSlow19) / fSlow44 + -1.0f;
+        float fSlow52 = fSlow49 - fSlow48;
+        float fSlow53 = std::exp(fConst27 / fSlow10);
         float fSlow54 = zitarevmonodsp_faustpower2_f(fSlow53);
-        float fSlow55 = (1.0f - (fSlow54 * fSlow13));
-        float fSlow56 = (1.0f - fSlow54);
-        float fSlow57 = (fSlow55 / fSlow56);
-        float fSlow58 =
-            std::sqrt(std::max<float>(0.0f, ((zitarevmonodsp_faustpower2_f(fSlow55)
-                                              / zitarevmonodsp_faustpower2_f(fSlow56))
-                                             + -1.0f)));
-        float fSlow59 = (fSlow57 - fSlow58);
-        float fSlow60 = (fSlow53 * (fSlow58 + (1.0f - fSlow57)));
-        float fSlow61 = ((std::exp((fConst25 / fSlow20)) / fSlow53) + -1.0f);
-        float fSlow62 = std::exp((fConst30 / fSlow10));
+        float fSlow55 = 1.0f - fSlow54 * fSlow13;
+        float fSlow56 = 1.0f - fSlow54;
+        float fSlow57 = std::sqrt(std::max<float>(
+            0.0f,
+            zitarevmonodsp_faustpower2_f(fSlow55) / zitarevmonodsp_faustpower2_f(fSlow56)
+                + -1.0f));
+        float fSlow58 = fSlow55 / fSlow56;
+        float fSlow59 = fSlow53 * (fSlow57 + 1.0f - fSlow58);
+        float fSlow60 = std::exp(fConst27 / fSlow19) / fSlow53 + -1.0f;
+        float fSlow61 = fSlow58 - fSlow57;
+        float fSlow62 = std::exp(fConst32 / fSlow10);
         float fSlow63 = zitarevmonodsp_faustpower2_f(fSlow62);
-        float fSlow64 = (1.0f - (fSlow63 * fSlow13));
-        float fSlow65 = (1.0f - fSlow63);
-        float fSlow66 = (fSlow64 / fSlow65);
-        float fSlow67 =
-            std::sqrt(std::max<float>(0.0f, ((zitarevmonodsp_faustpower2_f(fSlow64)
-                                              / zitarevmonodsp_faustpower2_f(fSlow65))
-                                             + -1.0f)));
-        float fSlow68 = (fSlow66 - fSlow67);
-        float fSlow69 = (fSlow62 * (fSlow67 + (1.0f - fSlow66)));
-        float fSlow70 = ((std::exp((fConst30 / fSlow20)) / fSlow62) + -1.0f);
-        float fSlow71 = std::exp((fConst35 / fSlow10));
+        float fSlow64 = 1.0f - fSlow63 * fSlow13;
+        float fSlow65 = 1.0f - fSlow63;
+        float fSlow66 = std::sqrt(std::max<float>(
+            0.0f,
+            zitarevmonodsp_faustpower2_f(fSlow64) / zitarevmonodsp_faustpower2_f(fSlow65)
+                + -1.0f));
+        float fSlow67 = fSlow64 / fSlow65;
+        float fSlow68 = fSlow62 * (fSlow66 + 1.0f - fSlow67);
+        float fSlow69 = std::exp(fConst32 / fSlow19) / fSlow62 + -1.0f;
+        float fSlow70 = fSlow67 - fSlow66;
+        float fSlow71 = std::exp(fConst37 / fSlow10);
         float fSlow72 = zitarevmonodsp_faustpower2_f(fSlow71);
-        float fSlow73 = (1.0f - (fSlow72 * fSlow13));
-        float fSlow74 = (1.0f - fSlow72);
-        float fSlow75 = (fSlow73 / fSlow74);
-        float fSlow76 =
-            std::sqrt(std::max<float>(0.0f, ((zitarevmonodsp_faustpower2_f(fSlow73)
-                                              / zitarevmonodsp_faustpower2_f(fSlow74))
-                                             + -1.0f)));
-        float fSlow77 = (fSlow75 - fSlow76);
-        float fSlow78 = (fSlow71 * (fSlow76 + (1.0f - fSlow75)));
-        float fSlow79 = ((std::exp((fConst35 / fSlow20)) / fSlow71) + -1.0f);
-        float fSlow80 = std::exp((fConst40 / fSlow10));
+        float fSlow73 = 1.0f - fSlow72 * fSlow13;
+        float fSlow74 = 1.0f - fSlow72;
+        float fSlow75 = std::sqrt(std::max<float>(
+            0.0f,
+            zitarevmonodsp_faustpower2_f(fSlow73) / zitarevmonodsp_faustpower2_f(fSlow74)
+                + -1.0f));
+        float fSlow76 = fSlow73 / fSlow74;
+        float fSlow77 = fSlow71 * (fSlow75 + 1.0f - fSlow76);
+        float fSlow78 = std::exp(fConst37 / fSlow19) / fSlow71 + -1.0f;
+        float fSlow79 = fSlow76 - fSlow75;
+        float fSlow80 = std::exp(fConst42 / fSlow10);
         float fSlow81 = zitarevmonodsp_faustpower2_f(fSlow80);
-        float fSlow82 = (1.0f - (fSlow81 * fSlow13));
-        float fSlow83 = (1.0f - fSlow81);
-        float fSlow84 = (fSlow82 / fSlow83);
-        float fSlow85 =
-            std::sqrt(std::max<float>(0.0f, ((zitarevmonodsp_faustpower2_f(fSlow82)
-                                              / zitarevmonodsp_faustpower2_f(fSlow83))
-                                             + -1.0f)));
-        float fSlow86 = (fSlow84 - fSlow85);
-        float fSlow87 = (fSlow80 * (fSlow85 + (1.0f - fSlow84)));
-        float fSlow88 = ((std::exp((fConst40 / fSlow20)) / fSlow80) + -1.0f);
-        float fSlow89 = (0.0f - (std::cos((fConst1 * fSlow6)) * (fSlow9 + 1.0f)));
-        float fSlow90 = (0.0f - (std::cos((fConst1 * fSlow2)) * (fSlow5 + 1.0f)));
-        for (int i = 0; (i < count); i = (i + 1)) {
-            float fTemp0          = float(input0[i]);
-            fVec0[(IOTA & 16383)] = fTemp0;
-            fRec0[0]              = (fSlow0 + (0.999000013f * fRec0[1]));
-            fRec1[0]              = (fSlow1 + (0.999000013f * fRec1[1]));
-            fRec15[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec15[1]) - (fRec11[1] + fRec11[2]))));
-            fRec14[0] =
-                ((fSlow18 * fRec14[1]) + (fSlow19 * (fRec11[1] + (fSlow21 * fRec15[0]))));
-            fVec1[(IOTA & 32767)] = ((0.353553385f * fRec14[0]) + 9.99999968e-21f);
-            float fTemp1          = (0.300000012f * fVec0[((IOTA - iSlow25) & 16383)]);
+        float fSlow82 = 1.0f - fSlow81 * fSlow13;
+        float fSlow83 = 1.0f - fSlow81;
+        float fSlow84 = std::sqrt(std::max<float>(
+            0.0f,
+            zitarevmonodsp_faustpower2_f(fSlow82) / zitarevmonodsp_faustpower2_f(fSlow83)
+                + -1.0f));
+        float fSlow85 = fSlow82 / fSlow83;
+        float fSlow86 = fSlow80 * (fSlow84 + 1.0f - fSlow85);
+        float fSlow87 = std::exp(fConst42 / fSlow19) / fSlow80 + -1.0f;
+        float fSlow88 = fSlow85 - fSlow84;
+        float fSlow89 = 0.0f - std::cos(fConst3 * fSlow6) * (fSlow9 + 1.0f);
+        float fSlow90 = 0.0f - std::cos(fConst3 * fSlow2) * (fSlow5 + 1.0f);
+        for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+            float fTemp0         = float(input0[i0]);
+            fVec0[IOTA0 & 16383] = fTemp0;
+            fRec0[0]             = fSlow0 + fConst2 * fRec0[1];
+            fRec1[0]             = fSlow1 + fConst2 * fRec1[1];
+            fRec15[0] = 0.0f - fSlow22 * (fSlow23 * fRec15[1] - (fRec11[1] + fRec11[2]));
+            fRec14[0] = fSlow18 * (fRec11[1] + fSlow20 * fRec15[0]) + fSlow24 * fRec14[1];
+            fVec1[IOTA0 & 32767] = 0.353553385f * fRec14[0] + 9.99999968e-21f;
+            float fTemp1         = 0.300000012f * fVec0[(IOTA0 - iSlow25) & 16383];
             float fTemp2 =
-                (((0.600000024f * fRec12[1]) + fVec1[((IOTA - iConst6) & 32767)])
-                 - fTemp1);
-            fVec2[(IOTA & 2047)] = fTemp2;
-            fRec12[0]            = fVec2[((IOTA - iConst8) & 2047)];
-            float fRec13         = (0.0f - (0.600000024f * fTemp2));
-            fRec19[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec19[1]) - (fRec7[1] + fRec7[2]))));
-            fRec18[0] =
-                ((fSlow32 * fRec18[1]) + (fSlow33 * (fRec7[1] + (fSlow34 * fRec19[0]))));
-            fVec3[(IOTA & 32767)] = ((0.353553385f * fRec18[0]) + 9.99999968e-21f);
+                (0.600000024f * fRec12[1] + fVec1[(IOTA0 - iConst8) & 32767]) - fTemp1;
+            fVec2[IOTA0 & 2047] = fTemp2;
+            fRec12[0]           = fVec2[(IOTA0 - iConst10) & 2047];
+            float fRec13        = 0.0f - 0.600000024f * fTemp2;
+            fRec19[0] = 0.0f - fSlow22 * (fSlow23 * fRec19[1] - (fRec7[1] + fRec7[2]));
+            fRec18[0] = fSlow32 * (fRec7[1] + fSlow33 * fRec19[0]) + fSlow34 * fRec18[1];
+            fVec3[IOTA0 & 32767] = 0.353553385f * fRec18[0] + 9.99999968e-21f;
             float fTemp3 =
-                (((0.600000024f * fRec16[1]) + fVec3[((IOTA - iConst12) & 32767)])
-                 - fTemp1);
-            fVec4[(IOTA & 4095)] = fTemp3;
-            fRec16[0]            = fVec4[((IOTA - iConst13) & 4095)];
-            float fRec17         = (0.0f - (0.600000024f * fTemp3));
-            fRec23[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec23[1]) - (fRec9[1] + fRec9[2]))));
-            fRec22[0] =
-                ((fSlow41 * fRec22[1]) + (fSlow42 * (fRec9[1] + (fSlow43 * fRec23[0]))));
-            fVec5[(IOTA & 16383)] = ((0.353553385f * fRec22[0]) + 9.99999968e-21f);
-            float fTemp4          = (fVec5[((IOTA - iConst17) & 16383)]
-                            + (fTemp1 + (0.600000024f * fRec20[1])));
-            fVec6[(IOTA & 4095)]  = fTemp4;
-            fRec20[0]             = fVec6[((IOTA - iConst18) & 4095)];
-            float fRec21          = (0.0f - (0.600000024f * fTemp4));
-            fRec27[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec27[1]) - (fRec5[1] + fRec5[2]))));
-            fRec26[0] =
-                ((fSlow50 * fRec26[1]) + (fSlow51 * (fRec5[1] + (fSlow52 * fRec27[0]))));
-            fVec7[(IOTA & 32767)] = ((0.353553385f * fRec26[0]) + 9.99999968e-21f);
-            float fTemp5          = (fVec7[((IOTA - iConst22) & 32767)]
-                            + (fTemp1 + (0.600000024f * fRec24[1])));
-            fVec8[(IOTA & 4095)]  = fTemp5;
-            fRec24[0]             = fVec8[((IOTA - iConst23) & 4095)];
-            float fRec25          = (0.0f - (0.600000024f * fTemp5));
-            fRec31[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec31[1]) - (fRec10[1] + fRec10[2]))));
-            fRec30[0] =
-                ((fSlow59 * fRec30[1]) + (fSlow60 * (fRec10[1] + (fSlow61 * fRec31[0]))));
-            fVec9[(IOTA & 16383)] = ((0.353553385f * fRec30[0]) + 9.99999968e-21f);
-            float fTemp6          = (fVec9[((IOTA - iConst27) & 16383)]
-                            - (fTemp1 + (0.600000024f * fRec28[1])));
-            fVec10[(IOTA & 2047)] = fTemp6;
-            fRec28[0]             = fVec10[((IOTA - iConst28) & 2047)];
-            float fRec29          = (0.600000024f * fTemp6);
-            fRec35[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec35[1]) - (fRec6[1] + fRec6[2]))));
-            fRec34[0] =
-                ((fSlow68 * fRec34[1]) + (fSlow69 * (fRec6[1] + (fSlow70 * fRec35[0]))));
-            fVec11[(IOTA & 16383)] = ((0.353553385f * fRec34[0]) + 9.99999968e-21f);
-            float fTemp7           = (fVec11[((IOTA - iConst32) & 16383)]
-                            - (fTemp1 + (0.600000024f * fRec32[1])));
-            fVec12[(IOTA & 4095)]  = fTemp7;
-            fRec32[0]              = fVec12[((IOTA - iConst33) & 4095)];
-            float fRec33           = (0.600000024f * fTemp7);
-            fRec39[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec39[1]) - (fRec8[1] + fRec8[2]))));
-            fRec38[0] =
-                ((fSlow77 * fRec38[1]) + (fSlow78 * (fRec8[1] + (fSlow79 * fRec39[0]))));
-            fVec13[(IOTA & 16383)] = ((0.353553385f * fRec38[0]) + 9.99999968e-21f);
-            float fTemp8           = ((fTemp1 + fVec13[((IOTA - iConst37) & 16383)])
-                            - (0.600000024f * fRec36[1]));
-            fVec14[(IOTA & 4095)]  = fTemp8;
-            fRec36[0]              = fVec14[((IOTA - iConst38) & 4095)];
-            float fRec37           = (0.600000024f * fTemp8);
-            fRec43[0] =
-                (0.0f - (fSlow23 * ((fSlow24 * fRec43[1]) - (fRec4[1] + fRec4[2]))));
-            fRec42[0] =
-                ((fSlow86 * fRec42[1]) + (fSlow87 * (fRec4[1] + (fSlow88 * fRec43[0]))));
-            fVec15[(IOTA & 16383)] = ((0.353553385f * fRec42[0]) + 9.99999968e-21f);
-            float fTemp9           = ((fVec15[((IOTA - iConst42) & 16383)] + fTemp1)
-                            - (0.600000024f * fRec40[1]));
-            fVec16[(IOTA & 2047)]  = fTemp9;
-            fRec40[0]              = fVec16[((IOTA - iConst43) & 2047)];
-            float fRec41           = (0.600000024f * fTemp9);
-            float fTemp10          = (fRec41 + fRec37);
-            float fTemp11          = (fRec29 + (fRec33 + fTemp10));
-            fRec4[0] =
-                (fRec12[1]
-                 + (fRec16[1]
-                    + (fRec20[1]
-                       + (fRec24[1]
-                          + (fRec28[1]
-                             + (fRec32[1]
-                                + (fRec36[1]
-                                   + (fRec40[1]
-                                      + (fRec13
-                                         + (fRec17
-                                            + (fRec21 + (fRec25 + fTemp11))))))))))));
-            fRec5[0] =
-                ((fRec28[1] + (fRec32[1] + (fRec36[1] + (fRec40[1] + fTemp11))))
-                 - (fRec12[1]
-                    + (fRec16[1]
-                       + (fRec20[1]
-                          + (fRec24[1] + (fRec13 + (fRec17 + (fRec25 + fRec21))))))));
-            float fTemp12 = (fRec33 + fRec29);
-            fRec6[0] =
-                ((fRec20[1]
-                  + (fRec24[1]
-                     + (fRec36[1] + (fRec40[1] + (fRec21 + (fRec25 + fTemp10))))))
-                 - (fRec12[1]
-                    + (fRec16[1]
-                       + (fRec28[1] + (fRec32[1] + (fRec13 + (fRec17 + fTemp12)))))));
-            fRec7[0] =
-                ((fRec12[1]
-                  + (fRec16[1]
-                     + (fRec36[1] + (fRec40[1] + (fRec13 + (fRec17 + fTemp10))))))
-                 - (fRec20[1]
-                    + (fRec24[1]
-                       + (fRec28[1] + (fRec32[1] + (fRec21 + (fRec25 + fTemp12)))))));
-            float fTemp13 = (fRec41 + fRec33);
-            float fTemp14 = (fRec37 + fRec29);
-            fRec8[0] =
-                ((fRec16[1]
-                  + (fRec24[1]
-                     + (fRec32[1] + (fRec40[1] + (fRec17 + (fRec25 + fTemp13))))))
-                 - (fRec12[1]
-                    + (fRec20[1]
-                       + (fRec28[1] + (fRec36[1] + (fRec13 + (fRec21 + fTemp14)))))));
-            fRec9[0] =
-                ((fRec12[1]
-                  + (fRec20[1]
-                     + (fRec32[1] + (fRec40[1] + (fRec13 + (fRec21 + fTemp13))))))
-                 - (fRec16[1]
-                    + (fRec24[1]
-                       + (fRec28[1] + (fRec36[1] + (fRec17 + (fRec25 + fTemp14)))))));
-            float fTemp15 = (fRec41 + fRec29);
-            float fTemp16 = (fRec37 + fRec33);
-            fRec10[0] =
-                ((fRec12[1]
-                  + (fRec24[1]
-                     + (fRec28[1] + (fRec40[1] + (fRec13 + (fRec25 + fTemp15))))))
-                 - (fRec16[1]
-                    + (fRec20[1]
-                       + (fRec32[1] + (fRec36[1] + (fRec17 + (fRec21 + fTemp16)))))));
-            fRec11[0] =
-                ((fRec16[1]
-                  + (fRec20[1]
-                     + (fRec28[1] + (fRec40[1] + (fRec17 + (fRec21 + fTemp15))))))
-                 - (fRec12[1]
-                    + (fRec24[1]
-                       + (fRec32[1] + (fRec36[1] + (fRec13 + (fRec25 + fTemp16)))))));
-            float fTemp17 = (0.370000005f * (fRec5[0] + fRec6[0]));
-            float fTemp18 = (fSlow89 * fRec3[1]);
-            fRec3[0]      = (fTemp17 - (fTemp18 + (fSlow9 * fRec3[2])));
-            float fTemp19 = (fSlow9 * fRec3[0]);
-            float fTemp20 =
-                (0.5f
-                 * ((fTemp19 + (fRec3[2] + (fTemp17 + fTemp18)))
-                    + (fSlow7 * ((fTemp19 + (fTemp18 + fRec3[2])) - fTemp17))));
-            float fTemp21 = (fSlow90 * fRec2[1]);
-            fRec2[0]      = (fTemp20 - (fTemp21 + (fSlow5 * fRec2[2])));
-            float fTemp22 = (fSlow5 * fRec2[0]);
-            float fTemp23 = (fTemp0 * (1.0f - fRec1[0]));
-            float fTemp24 = (0.370000005f * (fRec5[0] - fRec6[0]));
-            float fTemp25 = (fSlow89 * fRec45[1]);
-            fRec45[0]     = (fTemp24 - (fTemp25 + (fSlow9 * fRec45[2])));
-            float fTemp26 = (fSlow9 * fRec45[0]);
-            float fTemp27 =
-                (0.5f
-                 * ((fTemp26 + (fRec45[2] + (fTemp24 + fTemp25)))
-                    + (fSlow7 * ((fTemp26 + (fTemp25 + fRec45[2])) - fTemp24))));
-            float fTemp28 = (fSlow90 * fRec44[1]);
-            fRec44[0]     = (fTemp27 - (fTemp28 + (fSlow5 * fRec44[2])));
-            float fTemp29 = (fSlow5 * fRec44[0]);
-            output0[i]    = FAUSTFLOAT((
-                fRec0[0]
-                * (((0.5f
-                     * (fRec1[0]
-                        * ((fTemp22 + (fRec2[2] + (fTemp20 + fTemp21)))
-                           + (fSlow3 * ((fTemp22 + (fTemp21 + fRec2[2])) - fTemp20)))))
-                    + fTemp23)
-                   + (fTemp23
-                      + (0.5f
-                         * (fRec1[0]
-                            * ((fTemp29 + (fRec44[2] + (fTemp27 + fTemp28)))
-                               + (fSlow3
-                                  * ((fTemp29 + (fTemp28 + fRec44[2])) - fTemp27)))))))));
-            IOTA          = (IOTA + 1);
-            fRec0[1]      = fRec0[0];
-            fRec1[1]      = fRec1[0];
-            fRec15[1]     = fRec15[0];
-            fRec14[1]     = fRec14[0];
-            fRec12[1]     = fRec12[0];
-            fRec19[1]     = fRec19[0];
-            fRec18[1]     = fRec18[0];
-            fRec16[1]     = fRec16[0];
-            fRec23[1]     = fRec23[0];
-            fRec22[1]     = fRec22[0];
-            fRec20[1]     = fRec20[0];
-            fRec27[1]     = fRec27[0];
-            fRec26[1]     = fRec26[0];
-            fRec24[1]     = fRec24[0];
-            fRec31[1]     = fRec31[0];
-            fRec30[1]     = fRec30[0];
-            fRec28[1]     = fRec28[0];
-            fRec35[1]     = fRec35[0];
-            fRec34[1]     = fRec34[0];
-            fRec32[1]     = fRec32[0];
-            fRec39[1]     = fRec39[0];
-            fRec38[1]     = fRec38[0];
-            fRec36[1]     = fRec36[0];
-            fRec43[1]     = fRec43[0];
-            fRec42[1]     = fRec42[0];
-            fRec40[1]     = fRec40[0];
-            fRec4[2]      = fRec4[1];
-            fRec4[1]      = fRec4[0];
-            fRec5[2]      = fRec5[1];
-            fRec5[1]      = fRec5[0];
-            fRec6[2]      = fRec6[1];
-            fRec6[1]      = fRec6[0];
-            fRec7[2]      = fRec7[1];
-            fRec7[1]      = fRec7[0];
-            fRec8[2]      = fRec8[1];
-            fRec8[1]      = fRec8[0];
-            fRec9[2]      = fRec9[1];
-            fRec9[1]      = fRec9[0];
-            fRec10[2]     = fRec10[1];
-            fRec10[1]     = fRec10[0];
-            fRec11[2]     = fRec11[1];
-            fRec11[1]     = fRec11[0];
-            fRec3[2]      = fRec3[1];
-            fRec3[1]      = fRec3[0];
-            fRec2[2]      = fRec2[1];
-            fRec2[1]      = fRec2[0];
-            fRec45[2]     = fRec45[1];
-            fRec45[1]     = fRec45[0];
-            fRec44[2]     = fRec44[1];
-            fRec44[1]     = fRec44[0];
+                (0.600000024f * fRec16[1] + fVec3[(IOTA0 - iConst14) & 32767]) - fTemp1;
+            fVec4[IOTA0 & 4095] = fTemp3;
+            fRec16[0]           = fVec4[(IOTA0 - iConst15) & 4095];
+            float fRec17        = 0.0f - 0.600000024f * fTemp3;
+            fRec23[0] = 0.0f - fSlow22 * (fSlow23 * fRec23[1] - (fRec9[1] + fRec9[2]));
+            fRec22[0] = fSlow41 * (fRec9[1] + fSlow42 * fRec23[0]) + fSlow43 * fRec22[1];
+            fVec5[IOTA0 & 16383] = 0.353553385f * fRec22[0] + 9.99999968e-21f;
+            float fTemp4 =
+                fVec5[(IOTA0 - iConst19) & 16383] + fTemp1 + 0.600000024f * fRec20[1];
+            fVec6[IOTA0 & 4095] = fTemp4;
+            fRec20[0]           = fVec6[(IOTA0 - iConst20) & 4095];
+            float fRec21        = 0.0f - 0.600000024f * fTemp4;
+            fRec27[0] = 0.0f - fSlow22 * (fSlow23 * fRec27[1] - (fRec5[1] + fRec5[2]));
+            fRec26[0] = fSlow50 * (fRec5[1] + fSlow51 * fRec27[0]) + fSlow52 * fRec26[1];
+            fVec7[IOTA0 & 32767] = 0.353553385f * fRec26[0] + 9.99999968e-21f;
+            float fTemp5 =
+                fVec7[(IOTA0 - iConst24) & 32767] + fTemp1 + 0.600000024f * fRec24[1];
+            fVec8[IOTA0 & 4095] = fTemp5;
+            fRec24[0]           = fVec8[(IOTA0 - iConst25) & 4095];
+            float fRec25        = 0.0f - 0.600000024f * fTemp5;
+            fRec31[0] = 0.0f - fSlow22 * (fSlow23 * fRec31[1] - (fRec10[1] + fRec10[2]));
+            fRec30[0] = fSlow59 * (fRec10[1] + fSlow60 * fRec31[0]) + fSlow61 * fRec30[1];
+            fVec9[IOTA0 & 16383] = 0.353553385f * fRec30[0] + 9.99999968e-21f;
+            float fTemp6 =
+                fVec9[(IOTA0 - iConst29) & 16383] - (fTemp1 + 0.600000024f * fRec28[1]);
+            fVec10[IOTA0 & 2047] = fTemp6;
+            fRec28[0]            = fVec10[(IOTA0 - iConst30) & 2047];
+            float fRec29         = 0.600000024f * fTemp6;
+            fRec35[0] = 0.0f - fSlow22 * (fSlow23 * fRec35[1] - (fRec6[1] + fRec6[2]));
+            fRec34[0] = fSlow68 * (fRec6[1] + fSlow69 * fRec35[0]) + fSlow70 * fRec34[1];
+            fVec11[IOTA0 & 16383] = 0.353553385f * fRec34[0] + 9.99999968e-21f;
+            float fTemp7 =
+                fVec11[(IOTA0 - iConst34) & 16383] - (fTemp1 + 0.600000024f * fRec32[1]);
+            fVec12[IOTA0 & 4095] = fTemp7;
+            fRec32[0]            = fVec12[(IOTA0 - iConst35) & 4095];
+            float fRec33         = 0.600000024f * fTemp7;
+            fRec39[0] = 0.0f - fSlow22 * (fSlow23 * fRec39[1] - (fRec8[1] + fRec8[2]));
+            fRec38[0] = fSlow77 * (fRec8[1] + fSlow78 * fRec39[0]) + fSlow79 * fRec38[1];
+            fVec13[IOTA0 & 16383] = 0.353553385f * fRec38[0] + 9.99999968e-21f;
+            float fTemp8 =
+                (fTemp1 + fVec13[(IOTA0 - iConst39) & 16383]) - 0.600000024f * fRec36[1];
+            fVec14[IOTA0 & 4095] = fTemp8;
+            fRec36[0]            = fVec14[(IOTA0 - iConst40) & 4095];
+            float fRec37         = 0.600000024f * fTemp8;
+            fRec43[0] = 0.0f - fSlow22 * (fSlow23 * fRec43[1] - (fRec4[1] + fRec4[2]));
+            fRec42[0] = fSlow86 * (fRec4[1] + fSlow87 * fRec43[0]) + fSlow88 * fRec42[1];
+            fVec15[IOTA0 & 16383] = 0.353553385f * fRec42[0] + 9.99999968e-21f;
+            float fTemp9 =
+                (fVec15[(IOTA0 - iConst44) & 16383] + fTemp1) - 0.600000024f * fRec40[1];
+            fVec16[IOTA0 & 2047] = fTemp9;
+            fRec40[0]            = fVec16[(IOTA0 - iConst45) & 2047];
+            float fRec41         = 0.600000024f * fTemp9;
+            float fTemp10        = fRec41 + fRec37;
+            float fTemp11        = fRec29 + fRec33 + fTemp10;
+            fRec4[0] = fRec12[1] + fRec16[1] + fRec20[1] + fRec24[1] + fRec28[1]
+                       + fRec32[1] + fRec36[1] + fRec40[1] + fRec13 + fRec17 + fRec21
+                       + fRec25 + fTemp11;
+            fRec5[0] = (fRec28[1] + fRec32[1] + fRec36[1] + fRec40[1] + fTemp11)
+                       - (fRec12[1] + fRec16[1] + fRec20[1] + fRec24[1] + fRec13 + fRec17
+                          + fRec25 + fRec21);
+            float fTemp12 = fRec33 + fRec29;
+            fRec6[0] = (fRec20[1] + fRec24[1] + fRec36[1] + fRec40[1] + fRec21 + fRec25
+                        + fTemp10)
+                       - (fRec12[1] + fRec16[1] + fRec28[1] + fRec32[1] + fRec13 + fRec17
+                          + fTemp12);
+            fRec7[0] = (fRec12[1] + fRec16[1] + fRec36[1] + fRec40[1] + fRec13 + fRec17
+                        + fTemp10)
+                       - (fRec20[1] + fRec24[1] + fRec28[1] + fRec32[1] + fRec21 + fRec25
+                          + fTemp12);
+            float fTemp13 = fRec41 + fRec33;
+            float fTemp14 = fRec37 + fRec29;
+            fRec8[0] = (fRec16[1] + fRec24[1] + fRec32[1] + fRec40[1] + fRec17 + fRec25
+                        + fTemp13)
+                       - (fRec12[1] + fRec20[1] + fRec28[1] + fRec36[1] + fRec13 + fRec21
+                          + fTemp14);
+            fRec9[0] = (fRec12[1] + fRec20[1] + fRec32[1] + fRec40[1] + fRec13 + fRec21
+                        + fTemp13)
+                       - (fRec16[1] + fRec24[1] + fRec28[1] + fRec36[1] + fRec17 + fRec25
+                          + fTemp14);
+            float fTemp15 = fRec41 + fRec29;
+            float fTemp16 = fRec37 + fRec33;
+            fRec10[0] = (fRec12[1] + fRec24[1] + fRec28[1] + fRec40[1] + fRec13 + fRec25
+                         + fTemp15)
+                        - (fRec16[1] + fRec20[1] + fRec32[1] + fRec36[1] + fRec17 + fRec21
+                           + fTemp16);
+            fRec11[0] = (fRec16[1] + fRec20[1] + fRec28[1] + fRec40[1] + fRec17 + fRec21
+                         + fTemp15)
+                        - (fRec12[1] + fRec24[1] + fRec32[1] + fRec36[1] + fRec13 + fRec25
+                           + fTemp16);
+            float fTemp17 = 0.370000005f * (fRec5[0] + fRec6[0]);
+            float fTemp18 = fSlow89 * fRec3[1];
+            fRec3[0]      = fTemp17 - (fTemp18 + fSlow9 * fRec3[2]);
+            float fTemp19 = fSlow9 * fRec3[0];
+            float fTemp20 = 0.5f
+                            * (fTemp19 + fRec3[2] + fTemp17 + fTemp18
+                               + fSlow7 * ((fTemp19 + fTemp18 + fRec3[2]) - fTemp17));
+            float fTemp21 = fSlow90 * fRec2[1];
+            fRec2[0]      = fTemp20 - (fTemp21 + fSlow5 * fRec2[2]);
+            float fTemp22 = fSlow5 * fRec2[0];
+            float fTemp23 = fTemp0 * (1.0f - fRec1[0]);
+            float fTemp24 = 0.370000005f * (fRec5[0] - fRec6[0]);
+            float fTemp25 = fSlow89 * fRec45[1];
+            fRec45[0]     = fTemp24 - (fTemp25 + fSlow9 * fRec45[2]);
+            float fTemp26 = fSlow9 * fRec45[0];
+            float fTemp27 = 0.5f
+                            * (fTemp26 + fRec45[2] + fTemp24 + fTemp25
+                               + fSlow7 * ((fTemp26 + fTemp25 + fRec45[2]) - fTemp24));
+            float fTemp28 = fSlow90 * fRec44[1];
+            fRec44[0]     = fTemp27 - (fTemp28 + fSlow5 * fRec44[2]);
+            float fTemp29 = fSlow5 * fRec44[0];
+            output0[i0]   = FAUSTFLOAT(
+                  fRec0[0]
+                  * (0.5f * fRec1[0]
+                       * (fTemp22 + fRec2[2] + fTemp20 + fTemp21
+                          + fSlow3 * ((fTemp22 + fTemp21 + fRec2[2]) - fTemp20))
+                   + fTemp23 + fTemp23
+                   + 0.5f * fRec1[0]
+                         * (fTemp29 + fRec44[2] + fTemp27 + fTemp28
+                            + fSlow3 * ((fTemp29 + fTemp28 + fRec44[2]) - fTemp27))));
+            IOTA0     = IOTA0 + 1;
+            fRec0[1]  = fRec0[0];
+            fRec1[1]  = fRec1[0];
+            fRec15[1] = fRec15[0];
+            fRec14[1] = fRec14[0];
+            fRec12[1] = fRec12[0];
+            fRec19[1] = fRec19[0];
+            fRec18[1] = fRec18[0];
+            fRec16[1] = fRec16[0];
+            fRec23[1] = fRec23[0];
+            fRec22[1] = fRec22[0];
+            fRec20[1] = fRec20[0];
+            fRec27[1] = fRec27[0];
+            fRec26[1] = fRec26[0];
+            fRec24[1] = fRec24[0];
+            fRec31[1] = fRec31[0];
+            fRec30[1] = fRec30[0];
+            fRec28[1] = fRec28[0];
+            fRec35[1] = fRec35[0];
+            fRec34[1] = fRec34[0];
+            fRec32[1] = fRec32[0];
+            fRec39[1] = fRec39[0];
+            fRec38[1] = fRec38[0];
+            fRec36[1] = fRec36[0];
+            fRec43[1] = fRec43[0];
+            fRec42[1] = fRec42[0];
+            fRec40[1] = fRec40[0];
+            fRec4[2]  = fRec4[1];
+            fRec4[1]  = fRec4[0];
+            fRec5[2]  = fRec5[1];
+            fRec5[1]  = fRec5[0];
+            fRec6[2]  = fRec6[1];
+            fRec6[1]  = fRec6[0];
+            fRec7[2]  = fRec7[1];
+            fRec7[1]  = fRec7[0];
+            fRec8[2]  = fRec8[1];
+            fRec8[1]  = fRec8[0];
+            fRec9[2]  = fRec9[1];
+            fRec9[1]  = fRec9[0];
+            fRec10[2] = fRec10[1];
+            fRec10[1] = fRec10[0];
+            fRec11[2] = fRec11[1];
+            fRec11[1] = fRec11[0];
+            fRec3[2]  = fRec3[1];
+            fRec3[1]  = fRec3[0];
+            fRec2[2]  = fRec2[1];
+            fRec2[1]  = fRec2[0];
+            fRec45[2] = fRec45[1];
+            fRec45[1] = fRec45[0];
+            fRec44[2] = fRec44[1];
+            fRec44[1] = fRec44[0];
         }
     }
 };
index 71a53402fe49876bb5e67dfb61255ad7cf4fd3cd..06d5f2e941ce2b1f2d45db368451be4b4115a661 100755 (executable)
@@ -1,15 +1,19 @@
 @echo off\r
 setlocal EnableDelayedExpansion\r
 \r
+set QTVERSION="5"\r
+\r
 if not defined QTBINPATH (\r
-       for /f "delims=" %%a in ('dir /b C:\Qt\5*') do set QTVERSION=%%a\r
-       for /f "delims=" %%a in ('dir /b C:\Qt\!QTVERSION!\min*') do set QTBINPATH=%%a\r
-       set QTBINPATH=C:\Qt\!QTVERSION!\!QTBINPATH!\bin\r
+       for /f "delims=" %%a in ('dir /b C:\Qt\%QTVERSION%.*') do set QTFULLVERSION=%%a\r
+       for /f "delims=" %%a in ('dir /b C:\Qt\!QTFULLVERSION!\mingw*') do set QTBINPATH=%%a\r
+       set QTBINPATH=C:\Qt\!QTFULLVERSION!\!QTBINPATH!\bin\r
 )\r
+echo Using Qt Version %QTFULLVERSION%\r
 if not defined QTLIBPATH (\r
-       for /f "delims=" %%a in ('dir /b C:\Qt\Tools\min*') do set QTLIBPATH=%%a\r
+       for /f "delims=" %%a in ('dir /b C:\Qt\Tools\mingw*') do set QTLIBPATH=%%a\r
        set QTLIBPATH=C:\Qt\Tools\!QTLIBPATH!\bin\r
 )\r
+echo Using mingw libraries from %QTLIBPATH%\r
 if not defined WIXPATH (\r
        for /f "delims=" %%a in ('dir /b "C:\Program Files (x86)\Wix Toolset*"') do set WIXPATH=%%a\r
        set WIXPATH=C:\Program Files ^(x86^)\!WIXPATH!\bin\r
@@ -36,16 +40,24 @@ for %%f in (..\LICENSE.md ..\LICENSES\MIT.txt ..\LICENSES\GPL-3.0.txt ..\LICENSE
 )\r
 echo }>>%LICENSEPATH%\r
 \r
-copy dialog.bmp deploy\\r
+if "%~1"=="/q" (\r
+    copy dialog_alt.bmp deploy\dialog.bmp\r
+) else (\r
+    copy dialog.bmp deploy\\r
+)\r
 if exist ..\builddir\release\jacktrip.exe (set JACKTRIP=..\builddir\release\jacktrip.exe) else (set JACKTRIP=..\builddir\jacktrip.exe)\r
 copy %JACKTRIP% deploy\\r
 cd deploy\r
 set "WIXDEFINES="\r
-for /f "tokens=*" %%a in ('%QTLIBPATH%\objdump -p jacktrip.exe ^| findstr Qt5Core.dll') do set DYNAMIC_QT=%%a\r
+for /f "tokens=*" %%a in ('%QTLIBPATH%\objdump -p jacktrip.exe ^| findstr Qt%QTVERSION%Core.dll') do set DYNAMIC_QT=%%a\r
 if defined DYNAMIC_QT (\r
        echo Including Qt Files\r
-       for /f "tokens=*" %%a in ('%QTLIBPATH%\objdump -p jacktrip.exe ^| findstr Qt5Qml.dll') do set VS=%%a\r
+       for /f "tokens=*" %%a in ('%QTLIBPATH%\objdump -p jacktrip.exe ^| findstr Qt%QTVERSION%Qml.dll') do set VS=%%a\r
        if defined VS (\r
+               if %QTVERSION%=="6" (\r
+                       echo The installer is not designed to handle dynamic Virtual Studio builds using Qt6 yet.\r
+                       exit /b 1\r
+               )\r
                %QTBINPATH%\windeployqt --qmldir ..\..\src\gui jacktrip.exe\r
                set WIXDEFINES=%WIXDEFINES% -dvs\r
        ) else (\r
@@ -64,6 +76,7 @@ if defined RTAUDIO (
        copy %RTAUDIOLIB% .\\r
        set WIXDEFINES=%WIXDEFINES% -drtaudio\r
 )\r
+set WIXDEFINES=%WIXDEFINES% -dqt%QTVERSION%\r
 \r
 copy ..\jacktrip.wxs .\\r
 copy ..\files.wxs .\\r
@@ -76,6 +89,6 @@ rem Get our version number
 for /f "tokens=*" %%a in ('.\jacktrip -v ^| findstr VERSION') do for %%b in (%%~a) do set VERSION=%%b\r
 for /f "tokens=1 delims=-" %%a in ("%VERSION%") do set VERSION=%%a\r
 echo Version=%VERSION%\r
-candle.exe -ext WixUIExtension -ext WixUtilExtension -dVersion=%VERSION%%WIXDEFINES% jacktrip.wxs files.wxs\r
+candle.exe -arch x64 -ext WixUIExtension -ext WixUtilExtension -dVersion=%VERSION%%WIXDEFINES% jacktrip.wxs files.wxs\r
 light.exe -ext WixUIExtension -ext WixUtilExtension -o JackTrip.msi jacktrip.wixobj files.wixobj\r
 endlocal\r
diff --git a/win/dialog_alt.bmp b/win/dialog_alt.bmp
new file mode 100644 (file)
index 0000000..5d6e642
Binary files /dev/null and b/win/dialog_alt.bmp differ
index 00e2c1e5a22072f7dfc14ac5230e0e4751f48931..cda214057a62cbee23a231090bfaddb65fe2902d 100644 (file)
             <Component Id="cmpF83098612A5B11C5398DBA3894ED590A" Guid="6A0A67A9-3318-4CFB-BC07-5AF3FF7B7E87">\r
                 <File Id="fil526FA994C1850220CFA7BD7FCD995C32" KeyPath="yes" Source="SourceDir\D3Dcompiler_47.dll" />\r
             </Component>\r
-            <Component Id="cmpB60B52D038613C3F20F84A0E1C83D4D4" Guid="62E3CBE5-9787-4A5C-B6CD-B867781773EE">\r
-                <File Id="fil09D765981E2E493119D2DBD2DA179B9D" KeyPath="yes" Source="SourceDir\libcrypto-1_1-x64.dll" />\r
-            </Component>\r
+<?ifdef qt5?>\r
             <Component Id="cmp5DDCF0CE56D406D1B8B1F93E988AED6B" Guid="4346C308-2912-4CAF-B01B-1FB85781DAD0">\r
                 <File Id="fil0F4CD3729AF07C1C460E292E0F081D0A" KeyPath="yes" Source="SourceDir\libEGL.dll" />\r
             </Component>\r
-            <Component Id="cmpDEFDDDBEBEA7255D07EE4400F2CDA2FF" Guid="904EB309-B381-443D-A064-4C2669E8E66E">\r
-                <File Id="fil2ECEB8B8BE6121A2C5659BA0F64D92FC" KeyPath="yes" Source="SourceDir\libgcc_s_seh-1.dll" />\r
-            </Component>\r
             <Component Id="cmpB0CFEB9FF932521D6A75B6BE6F8D644F" Guid="73A8C873-FBDB-4BC5-BB74-2F82619DC3EC">\r
                 <File Id="fil736048FE57EC840EA5DCE88625C38E8D" KeyPath="yes" Source="SourceDir\libGLESv2.dll" />\r
             </Component>\r
+<?endif?>\r
+            <Component Id="cmpB60B52D038613C3F20F84A0E1C83D4D4" Guid="62E3CBE5-9787-4A5C-B6CD-B867781773EE">\r
+                <File Id="fil09D765981E2E493119D2DBD2DA179B9D" KeyPath="yes" Source="SourceDir\libcrypto-1_1-x64.dll" />\r
+            </Component>\r
+            <Component Id="cmpDEFDDDBEBEA7255D07EE4400F2CDA2FF" Guid="904EB309-B381-443D-A064-4C2669E8E66E">\r
+                <File Id="fil2ECEB8B8BE6121A2C5659BA0F64D92FC" KeyPath="yes" Source="SourceDir\libgcc_s_seh-1.dll" />\r
+            </Component>\r
             <Component Id="cmp809509D62BD9EA848EF243F03D83758F" Guid="FE4AFCE9-7DE1-4A82-A96E-42C8B93E04C7">\r
                 <File Id="filCE00A8B273087E758109FEC2AC699195" KeyPath="yes" Source="SourceDir\libssl-1_1-x64.dll" />\r
             </Component>\r
@@ -54,6 +56,7 @@
             <Component Id="cmpEA16414E09FD1D5068139520966B49EB" Guid="9B14A007-CA41-4C45-BE9E-0B1067DD5311">\r
                 <File Id="filFC8C908E3AD35E8090AFF39C9B0FB744" KeyPath="yes" Source="SourceDir\opengl32sw.dll" />\r
             </Component>\r
+<?ifdef qt5?>\r
             <Component Id="cmp01229088A6F1DEA1BE391E6E7CC3D3EE" Guid="9A610B9C-6322-4045-9C4B-910FFBA38502">\r
                 <File Id="filAD80F4724AAE3D8B0682F5982CC2548D" KeyPath="yes" Source="SourceDir\Qt5Core.dll" />\r
             </Component>\r
                     <File Id="fil94C33B546082B4DF43813FFB7569FBF6" KeyPath="yes" Source="SourceDir\bearer\qgenericbearer.dll" />\r
                 </Component>\r
             </Directory>\r
+<?endif?>\r
+<?ifdef qt6?>\r
+            <Component Id="cmp9147A534CD8EDAB4BA7FDEAEEFE9C511" Guid="{8D05F121-517E-4A1F-86FE-26A735F23F1C}">\r
+                <File Id="fil88DECE330C4A1F60E0198BE9EAD7F35B" KeyPath="yes" Source="SourceDir\Qt6Core.dll" />\r
+            </Component>\r
+            <Component Id="cmp52AB384603E096D6B6A1E1FC66B089D4" Guid="{FA746517-7C88-4473-9162-22E9A8CF6507}">\r
+                <File Id="fil93995D4EFFB081D1CEF92B0D38526E04" KeyPath="yes" Source="SourceDir\Qt6Gui.dll" />\r
+            </Component>\r
+            <Component Id="cmp0E8605D5C55843FCDFE809B5EE8DFDFA" Guid="{499C045E-88C6-43A6-B567-6C3438CA5FFD}">\r
+                <File Id="fil63F02A7FFBCDAAB6EAB6E65E642AC7B0" KeyPath="yes" Source="SourceDir\Qt6Network.dll" />\r
+            </Component>\r
+            <Component Id="cmp5D904885C8104A4049616BBAA95F34A3" Guid="{B47BE8F9-D9B5-4345-A232-F2EE8B6D4931}">\r
+                <File Id="fil30A776C0F63064A6AF65369FF23FDB8C" KeyPath="yes" Source="SourceDir\Qt6Svg.dll" />\r
+            </Component>\r
+            <Component Id="cmpCAE694BB34A9EC66AEA9D10D697F1EAA" Guid="{C1A11A59-3BF3-4562-92C6-304A80B93DAE}">\r
+                <File Id="fil43665A392379256FF1D68CF38B97EA38" KeyPath="yes" Source="SourceDir\Qt6Widgets.dll" />\r
+            </Component>\r
+<?endif qt6?>\r
             <Directory Id="dirB4D909CA5877E8EBEB32B83B2D15F595" Name="iconengines">\r
                 <Component Id="cmp1AAFF160C8E04AD945D74CA884667ABC" Guid="F9CAC368-2789-40F4-ADB8-0EDF377306DF">\r
                     <File Id="filB4B2363760DE489E24EBDBD0BC837FDE" KeyPath="yes" Source="SourceDir\iconengines\qsvgicon.dll" />\r
                     <File Id="fil84E6446D9ECFA487C5A2EC4752E07F04" KeyPath="yes" Source="SourceDir\styles\qwindowsvistastyle.dll" />\r
                 </Component>\r
             </Directory>\r
+<?ifdef qt6?>\r
+            <Directory Id="dir65521F18679A6D14A7BDE5A8612E8C69" Name="tls">\r
+                <Component Id="cmp83139013FA2C9A99CF2772FD54090FAA" Guid="{60DFDBBA-4832-44FD-B14A-C67EBD4D8119}">\r
+                    <File Id="fil737932C7578FEA0392CDEFB7540D7E44" KeyPath="yes" Source="SourceDir\tls\qcertonlybackend.dll" />\r
+                </Component>\r
+                <Component Id="cmp6E4460E3D6226693FEA5DBBF500895C7" Guid="{CBF26A3F-BA32-4017-BAEF-014AA3C51653}">\r
+                    <File Id="fil02E5C4A93CDAD6084E6372A2EE1F7ABA" KeyPath="yes" Source="SourceDir\tls\qopensslbackend.dll" />\r
+                </Component>\r
+                <Component Id="cmp53306F84AD30BD49CF0C1A68007F9531" Guid="{47907844-2DC3-4E99-B1C9-B9C716E59407}">\r
+                    <File Id="filD182E98DFB41D91EC2F2A531F6CAF918" KeyPath="yes" Source="SourceDir\tls\qschannelbackend.dll" />\r
+                </Component>\r
+            </Directory>\r
+<?endif qt6?>\r
             <Directory Id="dirF1C5FA08924D46D2A43D5134DF70C0A8" Name="translations">\r
                 <Component Id="cmpBCDC6995284E75B9A24E4646E6117744" Guid="51A3610B-4AE8-4020-926E-80B77B650E52">\r
                     <File Id="fil694FD3DFB9C088844BF9929014423509" KeyPath="yes" Source="SourceDir\translations\qt_ar.qm" />\r
                 <Component Id="cmpFDB70117D8E46EB188997470A3793B5D" Guid="EA2F54B9-EE49-4426-A2EF-EDDF3CAC83FD">\r
                     <File Id="fil9085627E4E33630ABCDB62A5CC05B794" KeyPath="yes" Source="SourceDir\translations\qt_zh_TW.qm" />\r
                 </Component>\r
-            </Directory>\r
+<?ifdef qt6?>\r
+                <Component Id="cmpF0099CF54A0669D87CC17418C3911422" Guid="{3405A05E-CB26-47D2-9C70-C52167AB8FDC}">\r
+                    <File Id="fil71B9851F396CBCC25B18299EDCBF5FF5" KeyPath="yes" Source="SourceDir\translations\qt_fa.qm" />\r
+                </Component>\r
+                <Component Id="cmpE89BF9966FD9EC39B16BC14B5586E0FA" Guid="{818D0415-1B0D-4C20-A21B-634467D7ABED}">\r
+                    <File Id="filB4B324E9728AE54A2B57A18E91814BC1" KeyPath="yes" Source="SourceDir\translations\qt_hr.qm" />\r
+                </Component>\r
+                <Component Id="cmp7F6AC80CE7E39EEDC9A962EAFADD113B" Guid="{E7491B72-07BC-4811-9AA2-9C90EA586475}">\r
+                    <File Id="filAB0862690AA36917007DE3C425A282CD" KeyPath="yes" Source="SourceDir\translations\qt_nl.qm" />\r
+                </Component>\r
+                <Component Id="cmp9EB4F508A604A4AD35BC558C456111DD" Guid="{035418D9-E833-45B1-B33E-15B8C6EA4E03}">\r
+                    <File Id="filA89B168478D587343A282C54242055A0" KeyPath="yes" Source="SourceDir\translations\qt_nn.qm" />\r
+                </Component>\r
+                <Component Id="cmp09D69EFDCF1B331A37D028C962FE6147" Guid="{BBD6ABD9-DDF9-4AC2-B8C1-FB4CB547B14F}">\r
+                    <File Id="fil3DBA8083389C96E9A47E27507D39EA05" KeyPath="yes" Source="SourceDir\translations\qt_pt_BR.qm" />\r
+                </Component>\r
+                <Component Id="cmpA23046CBC7F8B7E62AF4843CBB72DEC9" Guid="{FE5DC38D-3ABF-406D-8FB7-258119E76380}">\r
+                    <File Id="filCAF43146A9F7B1727B4975BB51D0A045" KeyPath="yes" Source="SourceDir\translations\qt_zh_CN.qm" />\r
+                </Component>\r
 <?endif?>\r
+            </Directory>\r
 <?ifdef vs?>\r
             <Component Id="cmp26187F331810660B2B23AB9501BE69AF" Guid="{B9D40CBB-9764-4DAA-9121-B74B8EADE326}">\r
                 <File Id="fil548462476B423A98BF378EB6B7FED697" KeyPath="yes" Source="SourceDir\Qt5NetworkAuth.dll" />\r
                     <File Id="fil4ED5B7A970D8897099777F501E3BDC88" KeyPath="yes" Source="SourceDir\QtQuick.2\qtquick2plugin.dll" />\r
                 </Component>\r
             </Directory>\r
+<?endif?>\r
 <?endif?>\r
         </DirectoryRef>\r
     </Fragment>\r
 <?endif?>\r
 <?ifdef dynamic?>\r
             <ComponentRef Id="cmpF83098612A5B11C5398DBA3894ED590A" />\r
-            <ComponentRef Id="cmpB60B52D038613C3F20F84A0E1C83D4D4" />\r
+<?ifdef qt5?>\r
             <ComponentRef Id="cmp5DDCF0CE56D406D1B8B1F93E988AED6B" />\r
-            <ComponentRef Id="cmpDEFDDDBEBEA7255D07EE4400F2CDA2FF" />\r
             <ComponentRef Id="cmpB0CFEB9FF932521D6A75B6BE6F8D644F" />\r
+<?endif?>\r
+            <ComponentRef Id="cmpB60B52D038613C3F20F84A0E1C83D4D4" />\r
+            <ComponentRef Id="cmpDEFDDDBEBEA7255D07EE4400F2CDA2FF" />\r
             <ComponentRef Id="cmp809509D62BD9EA848EF243F03D83758F" />\r
             <ComponentRef Id="cmp57DDA83E372188A5B760684B961DE685" />\r
             <ComponentRef Id="cmpF76D0CD1138260DB167395B86D0011CF" />\r
             <ComponentRef Id="cmpEA16414E09FD1D5068139520966B49EB" />\r
+<?ifdef qt5?>\r
             <ComponentRef Id="cmp01229088A6F1DEA1BE391E6E7CC3D3EE" />\r
             <ComponentRef Id="cmp1658AEC83DA2CDD0D93D5BAAABBEAD46" />\r
             <ComponentRef Id="cmp2DE804C107C75B0C71470A93647D09B5" />\r
             <ComponentRef Id="cmp82912105030EA0D2D7550CF8AC5677F6" />\r
             <ComponentRef Id="cmp975651B71289ACA70B3EB154C08A27F0" />\r
             <ComponentRef Id="cmp3CE5AF7CB2F8B2689D2096769883BC56" />\r
+<?endif?>\r
+<?ifdef qt6?>\r
+            <ComponentRef Id="cmp9147A534CD8EDAB4BA7FDEAEEFE9C511" />\r
+            <ComponentRef Id="cmp52AB384603E096D6B6A1E1FC66B089D4" />\r
+            <ComponentRef Id="cmp0E8605D5C55843FCDFE809B5EE8DFDFA" />\r
+            <ComponentRef Id="cmp5D904885C8104A4049616BBAA95F34A3" />\r
+            <ComponentRef Id="cmpCAE694BB34A9EC66AEA9D10D697F1EAA" />\r
+<?endif?>\r
             <ComponentRef Id="cmp1AAFF160C8E04AD945D74CA884667ABC" />\r
             <ComponentRef Id="cmp02252B1C1976959CFEE7FA11B6E36C4C" />\r
             <ComponentRef Id="cmp62CBFF830BF239A4E376FAE29937AFAB" />\r
             <ComponentRef Id="cmpE6323C810986405043F219CECD6B6C10" />\r
             <ComponentRef Id="cmp9132FD413972F732967B8BC075BC2781" />\r
             <ComponentRef Id="cmp52840D209B2AC1DC45A29A6BA5A75FF8" />\r
+<?ifdef qt6?>\r
+            <ComponentRef Id="cmp83139013FA2C9A99CF2772FD54090FAA" />\r
+            <ComponentRef Id="cmp6E4460E3D6226693FEA5DBBF500895C7" />\r
+            <ComponentRef Id="cmp53306F84AD30BD49CF0C1A68007F9531" />\r
+<?endif?>\r
             <ComponentRef Id="cmpBCDC6995284E75B9A24E4646E6117744" />\r
             <ComponentRef Id="cmp3B3D2ADEE08668758CB9FDB1D243AA11" />\r
             <ComponentRef Id="cmpDAE87E8CC29C30A200A5D17D81DF1DE7" />\r
             <ComponentRef Id="cmp8DAF13208A863A841AEE7A46E79FB87C" />\r
             <ComponentRef Id="cmpA214B663A372012F5DCBA6A5CDAE421D" />\r
             <ComponentRef Id="cmpFDB70117D8E46EB188997470A3793B5D" />\r
+<?ifdef qt6?>\r
+            <ComponentRef Id="cmpF0099CF54A0669D87CC17418C3911422" />\r
+            <ComponentRef Id="cmpE89BF9966FD9EC39B16BC14B5586E0FA" />\r
+            <ComponentRef Id="cmp7F6AC80CE7E39EEDC9A962EAFADD113B" />\r
+            <ComponentRef Id="cmp9EB4F508A604A4AD35BC558C456111DD" />\r
+            <ComponentRef Id="cmp09D69EFDCF1B331A37D028C962FE6147" />\r
+            <ComponentRef Id="cmpA23046CBC7F8B7E62AF4843CBB72DEC9" />\r
 <?endif?>\r
 <?ifdef vs?>\r
             <ComponentRef Id="cmp26187F331810660B2B23AB9501BE69AF" />\r
             <ComponentRef Id="cmp80E63D0ACF59FD23F5B051FE5BD003DF" />\r
             <ComponentRef Id="cmp65C97B5A564AB844DB2F02FFA5B163A4" />\r
             <ComponentRef Id="cmp4A028D7062688CA7458F90092B47AAAC" />\r
+<?endif?>\r
 <?endif?>\r
         </ComponentGroup>\r
     </Fragment>\r
diff --git a/win/getCsv.sh b/win/getCsv.sh
new file mode 100755 (executable)
index 0000000..f19f830
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+cat files.wxs | awk '/<Component Id/{ printf "%s ", $2; getline; print $4; }' | sed -E 's/Id="(.*)" Source="SourceDir\\(.*)"/\1,\2/'
index d6901b82f74bfe24728fba3861410c9a0d7f4a06..7617489e555ea7aa9131f9e89223a073b543db37 100644 (file)
@@ -7,14 +7,14 @@
 \r
         <Package Id='*' Keywords='Installer' Description='JackTrip Installer'\r
             Comments='Developed by SoundWIRE Group at CCRMA, Stanford' Manufacturer='JackTrip'\r
-            InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />\r
+            InstallerVersion='200' Languages='1033' Compressed='yes' SummaryCodepage='1252' />\r
         <Media Id='1' Cabinet='JackTrip.cab' EmbedCab='yes' DiskPrompt='Disk 1' />\r
         <Property Id='DiskPrompt' Value='JackTrip Installer File' />\r
         <MajorUpgrade AllowDowngrades="no" DowngradeErrorMessage="A newer version is already installed."\r
             AllowSameVersionUpgrades="no" />\r
 \r
         <Directory Id='TARGETDIR' Name='SourceDir'>\r
-            <Directory Id='ProgramFilesFolder' Name='PFiles'>\r
+            <Directory Id='ProgramFiles64Folder' Name='PFiles'>\r
                 <Directory Id='INSTALLDIR' Name='JackTrip'>\r
                 </Directory>\r
             </Directory>\r
diff --git a/win/jacktrip_alt.ico b/win/jacktrip_alt.ico
new file mode 100644 (file)
index 0000000..1fdf3e0
Binary files /dev/null and b/win/jacktrip_alt.ico differ