diff --git a/.gitignore b/.gitignore
index 185edb9266c96415826b5c90fc37ad3a191b7673..85836339d2da43bc7c7a2e3a71c9cbb6cafdee84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ JuceLibraryCode/jucer/Builds/Linux/build
 Builds/Linux/build/data
 Builds/Linux/build/savedState.xml
 Builds/Linux/build/windowState.xml
+Builds/Linux/build/Data
diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile
index 151287fe10235e5717abf93f8105602401514331..ee7bed61056a5eae174ad1d68e41fd951af4ad51 100644
--- a/Builds/Linux/Makefile
+++ b/Builds/Linux/Makefile
@@ -19,7 +19,7 @@ ifeq ($(CONFIG),Debug)
   OUTDIR := build
   CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I "/usr/include" -I "/usr/include/freetype2"
   CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0
-  CXXFLAGS += $(CFLAGS) -export-dynamic
+  CXXFLAGS += $(CFLAGS) -export-dynamic -pg
   LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../JuceLibraryCode/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound -lftdi -lftgl
   LDDEPS :=
   RESFLAGS :=  -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I "/usr/include" -I "/usr/include/freetype2"
@@ -34,7 +34,7 @@ ifeq ($(CONFIG),Release)
   OUTDIR := build
   CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I "/usr/include" -I "/usr/include/freetype2"
   CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3
-  CXXFLAGS += $(CFLAGS) -export-dynamic
+  CXXFLAGS += $(CFLAGS) -export-dynamic -pg
   LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../JuceLibraryCode/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound -lftdi -lftgl
   LDDEPS :=
   RESFLAGS :=  -D "LINUX=1" -D "NDEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -I "/usr/include" -I "/usr/include/freetype2"
@@ -63,17 +63,30 @@ OBJECTS := \
   $(OBJDIR)/RootFinder_239a995f.o \
   $(OBJDIR)/State_22979684.o \
   $(OBJDIR)/AudioComponent_521bd9c9.o \
+  $(OBJDIR)/Parameter_ae008024.o \
+  $(OBJDIR)/SpikeDisplayNode_9c52e4ad.o \
   $(OBJDIR)/WiFiOutput_fa464ec5.o \
   $(OBJDIR)/LfpDisplayNode_30ef22fd.o \
   $(OBJDIR)/Merger_2f90542e.o \
   $(OBJDIR)/Splitter_6e27a57b.o \
+  $(OBJDIR)/StereotrodePlot_4710b8f1.o \
+  $(OBJDIR)/ElectrodePlot_7a206ec4.o \
+  $(OBJDIR)/BaseUIElement_ec903c4d.o \
+  $(OBJDIR)/GenericAxes_d802ed92.o \
+  $(OBJDIR)/PlotUtils_9ef52686.o \
+  $(OBJDIR)/ProjectionAxes_7c67c3e8.o \
+  $(OBJDIR)/TetrodePlot_b42fd798.o \
+  $(OBJDIR)/WaveAxes_8adc45d2.o \
+  $(OBJDIR)/SpikeObject_24e8c655.o \
+  $(OBJDIR)/SpikeDisplayCanvas_b208ff6e.o \
   $(OBJDIR)/DataWindow_83ce6754.o \
   $(OBJDIR)/LfpDisplayCanvas_4a58e87e.o \
   $(OBJDIR)/OpenGLCanvas_3c775a41.o \
   $(OBJDIR)/SpikeDetector_300d85e7.o \
-  $(OBJDIR)/FileReader_18023b0e.o \
   $(OBJDIR)/AudioNode_94606ff3.o \
   $(OBJDIR)/EventNode_95c842b7.o \
+  $(OBJDIR)/SpikeDisplayEditor_e1812c1.o \
+  $(OBJDIR)/VisualizerEditor_3672b003.o \
   $(OBJDIR)/MergerEditor_d1fcc0df.o \
   $(OBJDIR)/ImageIcon_c89b23a6.o \
   $(OBJDIR)/WiFiOutputEditor_1d3ba5bb.o \
@@ -107,7 +120,6 @@ OBJECTS := \
   $(OBJDIR)/CustomLookAndFeel_53a8fcdb.o \
   $(OBJDIR)/InfoLabel_a2051bf4.o \
   $(OBJDIR)/DataViewport_2cf95d2c.o \
-  $(OBJDIR)/Configuration_6915cd84.o \
   $(OBJDIR)/MessageCenter_748a1cca.o \
   $(OBJDIR)/ControlPanel_a895ede3.o \
   $(OBJDIR)/UIComponent_d667ba37.o \
@@ -234,6 +246,16 @@ $(OBJDIR)/AudioComponent_521bd9c9.o: ../../Source/Audio/AudioComponent.cpp
 	@echo "Compiling AudioComponent.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
+$(OBJDIR)/Parameter_ae008024.o: ../../Source/Processors/Parameter.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling Parameter.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/SpikeDisplayNode_9c52e4ad.o: ../../Source/Processors/SpikeDisplayNode.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling SpikeDisplayNode.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
 $(OBJDIR)/WiFiOutput_fa464ec5.o: ../../Source/Processors/WiFiOutput.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling WiFiOutput.cpp"
@@ -254,6 +276,56 @@ $(OBJDIR)/Splitter_6e27a57b.o: ../../Source/Processors/Utilities/Splitter.cpp
 	@echo "Compiling Splitter.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
+$(OBJDIR)/StereotrodePlot_4710b8f1.o: ../../Source/Processors/Visualization/SpikePlotting/StereotrodePlot.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling StereotrodePlot.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/ElectrodePlot_7a206ec4.o: ../../Source/Processors/Visualization/SpikePlotting/ElectrodePlot.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling ElectrodePlot.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/BaseUIElement_ec903c4d.o: ../../Source/Processors/Visualization/SpikePlotting/BaseUIElement.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling BaseUIElement.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/GenericAxes_d802ed92.o: ../../Source/Processors/Visualization/SpikePlotting/GenericAxes.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling GenericAxes.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/PlotUtils_9ef52686.o: ../../Source/Processors/Visualization/SpikePlotting/PlotUtils.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling PlotUtils.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/ProjectionAxes_7c67c3e8.o: ../../Source/Processors/Visualization/SpikePlotting/ProjectionAxes.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling ProjectionAxes.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/TetrodePlot_b42fd798.o: ../../Source/Processors/Visualization/SpikePlotting/TetrodePlot.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling TetrodePlot.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/WaveAxes_8adc45d2.o: ../../Source/Processors/Visualization/SpikePlotting/WaveAxes.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling WaveAxes.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/SpikeObject_24e8c655.o: ../../Source/Processors/Visualization/SpikeObject.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling SpikeObject.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/SpikeDisplayCanvas_b208ff6e.o: ../../Source/Processors/Visualization/SpikeDisplayCanvas.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling SpikeDisplayCanvas.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
 $(OBJDIR)/DataWindow_83ce6754.o: ../../Source/Processors/Visualization/DataWindow.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling DataWindow.cpp"
@@ -274,11 +346,6 @@ $(OBJDIR)/SpikeDetector_300d85e7.o: ../../Source/Processors/SpikeDetector.cpp
 	@echo "Compiling SpikeDetector.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
-$(OBJDIR)/FileReader_18023b0e.o: ../../Source/Processors/FileReader.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling FileReader.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
 $(OBJDIR)/AudioNode_94606ff3.o: ../../Source/Processors/AudioNode.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling AudioNode.cpp"
@@ -289,6 +356,16 @@ $(OBJDIR)/EventNode_95c842b7.o: ../../Source/Processors/EventNode.cpp
 	@echo "Compiling EventNode.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
+$(OBJDIR)/SpikeDisplayEditor_e1812c1.o: ../../Source/Processors/Editors/SpikeDisplayEditor.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling SpikeDisplayEditor.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
+$(OBJDIR)/VisualizerEditor_3672b003.o: ../../Source/Processors/Editors/VisualizerEditor.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling VisualizerEditor.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
 $(OBJDIR)/MergerEditor_d1fcc0df.o: ../../Source/Processors/Editors/MergerEditor.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling MergerEditor.cpp"
@@ -454,11 +531,6 @@ $(OBJDIR)/DataViewport_2cf95d2c.o: ../../Source/UI/DataViewport.cpp
 	@echo "Compiling DataViewport.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
-$(OBJDIR)/Configuration_6915cd84.o: ../../Source/UI/Configuration.cpp
-	-@mkdir -p $(OBJDIR)
-	@echo "Compiling Configuration.cpp"
-	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
-
 $(OBJDIR)/MessageCenter_748a1cca.o: ../../Source/UI/MessageCenter.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling MessageCenter.cpp"
diff --git a/Builds/Linux/build/data_stream_16ch b/Builds/Linux/build/data_stream_16ch
new file mode 100644
index 0000000000000000000000000000000000000000..de0196c18569705d7b26fdfa2d22b14ef5f92436
Binary files /dev/null and b/Builds/Linux/build/data_stream_16ch differ
diff --git a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
index e6dfea255137553f617920d46d8f9d8ae4730225..e402638d5a9032e0194b606679806d7674a52d68 100644
--- a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
+++ b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
@@ -37,17 +37,30 @@
 		8E138283FC265B58D252AAC3 = { isa = PBXBuildFile; fileRef = F4A53064BA75472765338C1D; };
 		EE1DC0B09AE0727BC7A5A99C = { isa = PBXBuildFile; fileRef = 0D20C3399D0492771F7A808A; };
 		4ACF816CB5CDB285D8005AB8 = { isa = PBXBuildFile; fileRef = F74662D3D82975EDB5AD42E0; };
+		717D108DC8B2379D556C4B2F = { isa = PBXBuildFile; fileRef = 751C52F2BEA7F1328ED13333; };
+		1F67A9ACD509FB4DC5A633DF = { isa = PBXBuildFile; fileRef = 4AEDD076CCA918481C6F9CF2; };
 		B992DDBFF8928A985EEE1557 = { isa = PBXBuildFile; fileRef = 268005410FB62BCB9099A762; };
 		F1268EC5E783EC8ECEBCA5D3 = { isa = PBXBuildFile; fileRef = 5935F823A2EE45AC36A0201F; };
 		4A00153E1E69A74BC6B7D8A6 = { isa = PBXBuildFile; fileRef = 3973173C7FA07073B4F86B29; };
 		5F13B8FFB1584BFF6C05AD39 = { isa = PBXBuildFile; fileRef = 9A47B52E5E1CD17DC9C72B53; };
+		B11D72764B1B17BF2B8C6E67 = { isa = PBXBuildFile; fileRef = C92B3F413B0F24752ADE6730; };
+		938FC2F779C2CF4B8C7ECFFE = { isa = PBXBuildFile; fileRef = 3BB44F767E701E3642435FA0; };
+		55A240CCFCD604CA8DF8FC8C = { isa = PBXBuildFile; fileRef = 41591F74A761BAC908FA8AD8; };
+		8025F04ED261C7F7D2DC0F06 = { isa = PBXBuildFile; fileRef = 24C6D768C87E1C42C644C4BD; };
+		49F046C8BE137BF77338DD7B = { isa = PBXBuildFile; fileRef = B195AD6CEB9B6E3625C8D087; };
+		566E42D2B7105CFB4DB45170 = { isa = PBXBuildFile; fileRef = 2FA2FA826CBAD9C639A61E4A; };
+		0DDC562EC2B04A26AE6CBB2B = { isa = PBXBuildFile; fileRef = FBB9A423728922E96F55074F; };
+		BCD7C4797178C8EF65CDC2D7 = { isa = PBXBuildFile; fileRef = 9F208A66C09E80D14F087CB1; };
+		9145D84C7D665BCAFE698432 = { isa = PBXBuildFile; fileRef = E7247F5EE9588903C924994F; };
+		7659F31912D12C91E9554909 = { isa = PBXBuildFile; fileRef = 7A9A31FC1AE8FB238FAE995E; };
 		9D687F73F2FD2462C5D5588C = { isa = PBXBuildFile; fileRef = ED179D5A10DD051DDB3ECB8B; };
 		B13883377C9316B9603336B4 = { isa = PBXBuildFile; fileRef = 2E96DA81EE37A0ECE471A928; };
 		073B178E7EF1759BA0AACCCE = { isa = PBXBuildFile; fileRef = 0C5335B0E57C9DC92FC57E5F; };
 		4BE0DDA01B73223EF0BD934A = { isa = PBXBuildFile; fileRef = 3DD0741FCFBC7563EC722D9B; };
-		6656467170D2822949BD2F7F = { isa = PBXBuildFile; fileRef = 5AC4DD48CCB1AB4936A2DE4A; };
 		08B501E0D7764C6B613AF529 = { isa = PBXBuildFile; fileRef = B7750B27E4F3748ECCCCF69D; };
 		9CBA3837CC8CAA03A03F2D9C = { isa = PBXBuildFile; fileRef = FA57CE4F63FF1592D6B3F9B5; };
+		DD22A06702F4CF995893DD5C = { isa = PBXBuildFile; fileRef = F0B09605D4108F0F94EF3B57; };
+		F4CEF74DDCD7EFA0891249B5 = { isa = PBXBuildFile; fileRef = 9A3976537C96B39716B5312D; };
 		93A3E6284F2DAED3F491332B = { isa = PBXBuildFile; fileRef = AD73EA6B24378294003DC2D0; };
 		CB77C89226102EF30F85E3EC = { isa = PBXBuildFile; fileRef = 544DA1EF90EBBDB6FF2DE0A5; };
 		A126280FF39A61DEFD3ABFE5 = { isa = PBXBuildFile; fileRef = 2B11714BCE362D4EA7E377F5; };
@@ -81,7 +94,6 @@
 		13457B3248E7646270A4FF88 = { isa = PBXBuildFile; fileRef = A32D8455B95FD230EBFD7891; };
 		D060C0893EDAE6CBC86A5FE2 = { isa = PBXBuildFile; fileRef = AA00883DC021E36B7EFDAC43; };
 		E36C0018635A85E09D4EDE01 = { isa = PBXBuildFile; fileRef = B977C2809B309C8038CB5D95; };
-		4BE24CDF92926150BFC83ED2 = { isa = PBXBuildFile; fileRef = 2F53BB2693AA5F1C2F27AF7C; };
 		C170A763D33146C74ED4CE4B = { isa = PBXBuildFile; fileRef = EEDA71600D817BF9444FE3E7; };
 		116BB2F62451986C75586F9D = { isa = PBXBuildFile; fileRef = 5AB4A3A63B9FDEAB09EEC9C8; };
 		1F301384375DA0F3652C01DA = { isa = PBXBuildFile; fileRef = 2A78F719BAFBDCD63AE9A88A; };
@@ -119,6 +131,31 @@
 		C2A7939DF5ED600BBB2F30C4 = { isa = PBXFileReference; lastKnownFileType = file; name = "silkscreen-serialized"; path = "../../Resources/Fonts/silkscreen-serialized"; sourceTree = SOURCE_ROOT; };
 		F8CAE2412B173788F325BD8B = { isa = PBXFileReference; lastKnownFileType = file.ttf; name = silkscreen.ttf; path = ../../Resources/Fonts/silkscreen.ttf; sourceTree = SOURCE_ROOT; };
 		363B59958615D35C5C948300 = { isa = PBXFileReference; lastKnownFileType = file.otf; name = "unibody-8.otf"; path = "../../Resources/Fonts/unibody-8.otf"; sourceTree = SOURCE_ROOT; };
+		4DB02C352236D9D030E01205 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons-01.png"; path = "../../Resources/Images/Icons/RadioButtons-01.png"; sourceTree = SOURCE_ROOT; };
+		EEAB043F90902D8F9D1102C2 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons-02.png"; path = "../../Resources/Images/Icons/RadioButtons-02.png"; sourceTree = SOURCE_ROOT; };
+		8086EC3AFDEA802E0B43F19E = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons-03.png"; path = "../../Resources/Images/Icons/RadioButtons-03.png"; sourceTree = SOURCE_ROOT; };
+		2171C4356B44D4CD6865E06B = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons-04.png"; path = "../../Resources/Images/Icons/RadioButtons-04.png"; sourceTree = SOURCE_ROOT; };
+		C25CAC3FC9AE387CD597DF37 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons-05.png"; path = "../../Resources/Images/Icons/RadioButtons-05.png"; sourceTree = SOURCE_ROOT; };
+		59CAEFDE36164ABB19B3CA76 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_neutral-01.png"; path = "../../Resources/Images/Icons/RadioButtons_neutral-01.png"; sourceTree = SOURCE_ROOT; };
+		E0587F61AD4A92C2661E5073 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_neutral-02.png"; path = "../../Resources/Images/Icons/RadioButtons_neutral-02.png"; sourceTree = SOURCE_ROOT; };
+		87F60F05136FEBD8A36AE670 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_neutral-03.png"; path = "../../Resources/Images/Icons/RadioButtons_neutral-03.png"; sourceTree = SOURCE_ROOT; };
+		1E849F999A8333FFF0B57C6D = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_neutral-04.png"; path = "../../Resources/Images/Icons/RadioButtons_neutral-04.png"; sourceTree = SOURCE_ROOT; };
+		A5231F3D01B88C063D10026A = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_neutral-05.png"; path = "../../Resources/Images/Icons/RadioButtons_neutral-05.png"; sourceTree = SOURCE_ROOT; };
+		40A802FCEDFDE7B2FFEBDEA8 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected-01.png"; path = "../../Resources/Images/Icons/RadioButtons_selected-01.png"; sourceTree = SOURCE_ROOT; };
+		8A3AE5CF9D452810BA48A3EF = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected-02.png"; path = "../../Resources/Images/Icons/RadioButtons_selected-02.png"; sourceTree = SOURCE_ROOT; };
+		B3CDC8825DAD5A7D75956726 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected-03.png"; path = "../../Resources/Images/Icons/RadioButtons_selected-03.png"; sourceTree = SOURCE_ROOT; };
+		ED50AB550D058BEB30F12C7D = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected-04.png"; path = "../../Resources/Images/Icons/RadioButtons_selected-04.png"; sourceTree = SOURCE_ROOT; };
+		17E38F29BD6CBC490B5EF1B4 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected-05.png"; path = "../../Resources/Images/Icons/RadioButtons_selected-05.png"; sourceTree = SOURCE_ROOT; };
+		D95C78F42494CD5995FBC15E = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected_over-01.png"; path = "../../Resources/Images/Icons/RadioButtons_selected_over-01.png"; sourceTree = SOURCE_ROOT; };
+		20B50BC2221C593AC67D80F8 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected_over-02.png"; path = "../../Resources/Images/Icons/RadioButtons_selected_over-02.png"; sourceTree = SOURCE_ROOT; };
+		771E8D912F94E52AF7E05F91 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected_over-03.png"; path = "../../Resources/Images/Icons/RadioButtons_selected_over-03.png"; sourceTree = SOURCE_ROOT; };
+		CE771F502D1D710B28632E3A = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected_over-04.png"; path = "../../Resources/Images/Icons/RadioButtons_selected_over-04.png"; sourceTree = SOURCE_ROOT; };
+		05D0A12F2A850EEC48D5EDD4 = { isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected_over-05.png"; path = "../../Resources/Images/Icons/RadioButtons_selected_over-05.png"; sourceTree = SOURCE_ROOT; };
+		8F8F55DD042F61BB213AFC0B = { isa = PBXFileReference; lastKnownFileType = image.png; name = noise_wave.png; path = ../../Resources/Images/Icons/noise_wave.png; sourceTree = SOURCE_ROOT; };
+		7C09194091360867C4CAB0E8 = { isa = PBXFileReference; lastKnownFileType = image.png; name = saw_wave.png; path = ../../Resources/Images/Icons/saw_wave.png; sourceTree = SOURCE_ROOT; };
+		126B0DE9B8D4E42DA7D57AAB = { isa = PBXFileReference; lastKnownFileType = image.png; name = sine_wave.png; path = ../../Resources/Images/Icons/sine_wave.png; sourceTree = SOURCE_ROOT; };
+		BDFFB5B0A8E8A022C25D7FDB = { isa = PBXFileReference; lastKnownFileType = image.png; name = square_wave.png; path = ../../Resources/Images/Icons/square_wave.png; sourceTree = SOURCE_ROOT; };
+		3D20C932FB058CC20989B129 = { isa = PBXFileReference; lastKnownFileType = image.png; name = triangle_wave.png; path = ../../Resources/Images/Icons/triangle_wave.png; sourceTree = SOURCE_ROOT; };
 		8E041C8C49F1A5B710CC812C = { isa = PBXFileReference; lastKnownFileType = image.png; name = wifi.png; path = ../../Resources/Images/Icons/wifi.png; sourceTree = SOURCE_ROOT; };
 		2A1D9144C59B92B32483924B = { isa = PBXFileReference; lastKnownFileType = image.png; name = SourceDrop.png; path = ../../Resources/Images/Icons/SourceDrop.png; sourceTree = SOURCE_ROOT; };
 		D99F56FB46F631F67AF23F2C = { isa = PBXFileReference; lastKnownFileType = image.png; name = DefaultDataSource.png; path = ../../Resources/Images/Icons/DefaultDataSource.png; sourceTree = SOURCE_ROOT; };
@@ -180,6 +217,10 @@
 		E27B5891A52FDAB2B00901A0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Utilities.h; path = ../../Source/Dsp/Utilities.h; sourceTree = SOURCE_ROOT; };
 		F74662D3D82975EDB5AD42E0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioComponent.cpp; path = ../../Source/Audio/AudioComponent.cpp; sourceTree = SOURCE_ROOT; };
 		FA55B9FDE138CCB1F16BA905 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioComponent.h; path = ../../Source/Audio/AudioComponent.h; sourceTree = SOURCE_ROOT; };
+		751C52F2BEA7F1328ED13333 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Parameter.cpp; path = ../../Source/Processors/Parameter.cpp; sourceTree = SOURCE_ROOT; };
+		7B825983F25D8984E02F6FFB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Parameter.h; path = ../../Source/Processors/Parameter.h; sourceTree = SOURCE_ROOT; };
+		4AEDD076CCA918481C6F9CF2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeDisplayNode.cpp; path = ../../Source/Processors/SpikeDisplayNode.cpp; sourceTree = SOURCE_ROOT; };
+		671CC5EA3DF4F21E9A7E392B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeDisplayNode.h; path = ../../Source/Processors/SpikeDisplayNode.h; sourceTree = SOURCE_ROOT; };
 		268005410FB62BCB9099A762 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = WiFiOutput.cpp; path = ../../Source/Processors/WiFiOutput.cpp; sourceTree = SOURCE_ROOT; };
 		32959675287F77DD9B7FA96B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WiFiOutput.h; path = ../../Source/Processors/WiFiOutput.h; sourceTree = SOURCE_ROOT; };
 		5935F823A2EE45AC36A0201F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LfpDisplayNode.cpp; path = ../../Source/Processors/LfpDisplayNode.cpp; sourceTree = SOURCE_ROOT; };
@@ -188,6 +229,28 @@
 		7977CAB4A151C41F4140FE1A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Merger.h; path = ../../Source/Processors/Utilities/Merger.h; sourceTree = SOURCE_ROOT; };
 		9A47B52E5E1CD17DC9C72B53 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Splitter.cpp; path = ../../Source/Processors/Utilities/Splitter.cpp; sourceTree = SOURCE_ROOT; };
 		B92E8189F69E0B926C73B654 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Splitter.h; path = ../../Source/Processors/Utilities/Splitter.h; sourceTree = SOURCE_ROOT; };
+		C92B3F413B0F24752ADE6730 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = StereotrodePlot.cpp; path = ../../Source/Processors/Visualization/SpikePlotting/StereotrodePlot.cpp; sourceTree = SOURCE_ROOT; };
+		FDD549F527C378CF36BDB8C7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StereotrodePlot.h; path = ../../Source/Processors/Visualization/SpikePlotting/StereotrodePlot.h; sourceTree = SOURCE_ROOT; };
+		3BB44F767E701E3642435FA0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ElectrodePlot.cpp; path = ../../Source/Processors/Visualization/SpikePlotting/ElectrodePlot.cpp; sourceTree = SOURCE_ROOT; };
+		1AAF672654B16469EFB41AC2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ElectrodePlot.h; path = ../../Source/Processors/Visualization/SpikePlotting/ElectrodePlot.h; sourceTree = SOURCE_ROOT; };
+		41591F74A761BAC908FA8AD8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = BaseUIElement.cpp; path = ../../Source/Processors/Visualization/SpikePlotting/BaseUIElement.cpp; sourceTree = SOURCE_ROOT; };
+		9C8EA29582DBFF6E5A14B8A3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BaseUIElement.h; path = ../../Source/Processors/Visualization/SpikePlotting/BaseUIElement.h; sourceTree = SOURCE_ROOT; };
+		24C6D768C87E1C42C644C4BD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = GenericAxes.cpp; path = ../../Source/Processors/Visualization/SpikePlotting/GenericAxes.cpp; sourceTree = SOURCE_ROOT; };
+		BCBB865ED53E8AFD278D1A53 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GenericAxes.h; path = ../../Source/Processors/Visualization/SpikePlotting/GenericAxes.h; sourceTree = SOURCE_ROOT; };
+		B195AD6CEB9B6E3625C8D087 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PlotUtils.cpp; path = ../../Source/Processors/Visualization/SpikePlotting/PlotUtils.cpp; sourceTree = SOURCE_ROOT; };
+		521FECC75E9DDB0D34B22AF8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PlotUtils.h; path = ../../Source/Processors/Visualization/SpikePlotting/PlotUtils.h; sourceTree = SOURCE_ROOT; };
+		2FA2FA826CBAD9C639A61E4A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ProjectionAxes.cpp; path = ../../Source/Processors/Visualization/SpikePlotting/ProjectionAxes.cpp; sourceTree = SOURCE_ROOT; };
+		B1CF7BFC5F1892735D4FA1EE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProjectionAxes.h; path = ../../Source/Processors/Visualization/SpikePlotting/ProjectionAxes.h; sourceTree = SOURCE_ROOT; };
+		50E7B88E8140BB293B27ED67 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SimpleKeyEvent.h; path = ../../Source/Processors/Visualization/SpikePlotting/SimpleKeyEvent.h; sourceTree = SOURCE_ROOT; };
+		FBB9A423728922E96F55074F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = TetrodePlot.cpp; path = ../../Source/Processors/Visualization/SpikePlotting/TetrodePlot.cpp; sourceTree = SOURCE_ROOT; };
+		6CFF95D08DB1000B1EDD1240 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TetrodePlot.h; path = ../../Source/Processors/Visualization/SpikePlotting/TetrodePlot.h; sourceTree = SOURCE_ROOT; };
+		9F208A66C09E80D14F087CB1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = WaveAxes.cpp; path = ../../Source/Processors/Visualization/SpikePlotting/WaveAxes.cpp; sourceTree = SOURCE_ROOT; };
+		A3F978AE6999903C47650173 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WaveAxes.h; path = ../../Source/Processors/Visualization/SpikePlotting/WaveAxes.h; sourceTree = SOURCE_ROOT; };
+		E7247F5EE9588903C924994F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeObject.cpp; path = ../../Source/Processors/Visualization/SpikeObject.cpp; sourceTree = SOURCE_ROOT; };
+		B0A6A0635113C4B4CD424BEC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeObject.h; path = ../../Source/Processors/Visualization/SpikeObject.h; sourceTree = SOURCE_ROOT; };
+		7A9A31FC1AE8FB238FAE995E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeDisplayCanvas.cpp; path = ../../Source/Processors/Visualization/SpikeDisplayCanvas.cpp; sourceTree = SOURCE_ROOT; };
+		9E884AEDB6035FFC74886EE8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeDisplayCanvas.h; path = ../../Source/Processors/Visualization/SpikeDisplayCanvas.h; sourceTree = SOURCE_ROOT; };
+		9ACFB6A181D09434268CE006 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Visualizer.h; path = ../../Source/Processors/Visualization/Visualizer.h; sourceTree = SOURCE_ROOT; };
 		ED179D5A10DD051DDB3ECB8B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DataWindow.cpp; path = ../../Source/Processors/Visualization/DataWindow.cpp; sourceTree = SOURCE_ROOT; };
 		63C18F4066C75D3C312877D8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DataWindow.h; path = ../../Source/Processors/Visualization/DataWindow.h; sourceTree = SOURCE_ROOT; };
 		2E96DA81EE37A0ECE471A928 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LfpDisplayCanvas.cpp; path = ../../Source/Processors/Visualization/LfpDisplayCanvas.cpp; sourceTree = SOURCE_ROOT; };
@@ -196,12 +259,14 @@
 		7738F51AE0EC63D76EE0F761 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OpenGLCanvas.h; path = ../../Source/Processors/Visualization/OpenGLCanvas.h; sourceTree = SOURCE_ROOT; };
 		3DD0741FCFBC7563EC722D9B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeDetector.cpp; path = ../../Source/Processors/SpikeDetector.cpp; sourceTree = SOURCE_ROOT; };
 		6E4B37AA4BFEB5A37E3AC250 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeDetector.h; path = ../../Source/Processors/SpikeDetector.h; sourceTree = SOURCE_ROOT; };
-		5AC4DD48CCB1AB4936A2DE4A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = FileReader.cpp; path = ../../Source/Processors/FileReader.cpp; sourceTree = SOURCE_ROOT; };
-		44E93A2D64EB5ADA54CB2CFB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FileReader.h; path = ../../Source/Processors/FileReader.h; sourceTree = SOURCE_ROOT; };
 		B7750B27E4F3748ECCCCF69D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioNode.cpp; path = ../../Source/Processors/AudioNode.cpp; sourceTree = SOURCE_ROOT; };
 		12866D44BE115E8837468F48 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioNode.h; path = ../../Source/Processors/AudioNode.h; sourceTree = SOURCE_ROOT; };
 		FA57CE4F63FF1592D6B3F9B5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = EventNode.cpp; path = ../../Source/Processors/EventNode.cpp; sourceTree = SOURCE_ROOT; };
 		32163C956C8A6F5C1DD7FE7F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = EventNode.h; path = ../../Source/Processors/EventNode.h; sourceTree = SOURCE_ROOT; };
+		F0B09605D4108F0F94EF3B57 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeDisplayEditor.cpp; path = ../../Source/Processors/Editors/SpikeDisplayEditor.cpp; sourceTree = SOURCE_ROOT; };
+		2A46D8E3EC7207D969A2B202 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SpikeDisplayEditor.h; path = ../../Source/Processors/Editors/SpikeDisplayEditor.h; sourceTree = SOURCE_ROOT; };
+		9A3976537C96B39716B5312D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = VisualizerEditor.cpp; path = ../../Source/Processors/Editors/VisualizerEditor.cpp; sourceTree = SOURCE_ROOT; };
+		C546D55EDE65ADDD95C6A6F5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VisualizerEditor.h; path = ../../Source/Processors/Editors/VisualizerEditor.h; sourceTree = SOURCE_ROOT; };
 		AD73EA6B24378294003DC2D0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MergerEditor.cpp; path = ../../Source/Processors/Editors/MergerEditor.cpp; sourceTree = SOURCE_ROOT; };
 		B7FD86B9DA02771D3519FAA0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MergerEditor.h; path = ../../Source/Processors/Editors/MergerEditor.h; sourceTree = SOURCE_ROOT; };
 		544DA1EF90EBBDB6FF2DE0A5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ImageIcon.cpp; path = ../../Source/Processors/Editors/ImageIcon.cpp; sourceTree = SOURCE_ROOT; };
@@ -268,8 +333,6 @@
 		1561F28CD560AB8F2E177628 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InfoLabel.h; path = ../../Source/UI/InfoLabel.h; sourceTree = SOURCE_ROOT; };
 		B977C2809B309C8038CB5D95 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DataViewport.cpp; path = ../../Source/UI/DataViewport.cpp; sourceTree = SOURCE_ROOT; };
 		877F9F9DA7A1B51D3EDCBC07 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DataViewport.h; path = ../../Source/UI/DataViewport.h; sourceTree = SOURCE_ROOT; };
-		2F53BB2693AA5F1C2F27AF7C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Configuration.cpp; path = ../../Source/UI/Configuration.cpp; sourceTree = SOURCE_ROOT; };
-		DE21954E89A302C554C403B3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Configuration.h; path = ../../Source/UI/Configuration.h; sourceTree = SOURCE_ROOT; };
 		EEDA71600D817BF9444FE3E7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MessageCenter.cpp; path = ../../Source/UI/MessageCenter.cpp; sourceTree = SOURCE_ROOT; };
 		4EE6CA70F229EDE04E7E320B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MessageCenter.h; path = ../../Source/UI/MessageCenter.h; sourceTree = SOURCE_ROOT; };
 		5AB4A3A63B9FDEAB09EEC9C8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ControlPanel.cpp; path = ../../Source/UI/ControlPanel.cpp; sourceTree = SOURCE_ROOT; };
@@ -303,6 +366,31 @@
 				F8CAE2412B173788F325BD8B,
 				363B59958615D35C5C948300 ); name = Fonts; sourceTree = "<group>"; };
 		891C5A157F059822288EDC9F = { isa = PBXGroup; children = (
+				4DB02C352236D9D030E01205,
+				EEAB043F90902D8F9D1102C2,
+				8086EC3AFDEA802E0B43F19E,
+				2171C4356B44D4CD6865E06B,
+				C25CAC3FC9AE387CD597DF37,
+				59CAEFDE36164ABB19B3CA76,
+				E0587F61AD4A92C2661E5073,
+				87F60F05136FEBD8A36AE670,
+				1E849F999A8333FFF0B57C6D,
+				A5231F3D01B88C063D10026A,
+				40A802FCEDFDE7B2FFEBDEA8,
+				8A3AE5CF9D452810BA48A3EF,
+				B3CDC8825DAD5A7D75956726,
+				ED50AB550D058BEB30F12C7D,
+				17E38F29BD6CBC490B5EF1B4,
+				D95C78F42494CD5995FBC15E,
+				20B50BC2221C593AC67D80F8,
+				771E8D912F94E52AF7E05F91,
+				CE771F502D1D710B28632E3A,
+				05D0A12F2A850EEC48D5EDD4,
+				8F8F55DD042F61BB213AFC0B,
+				7C09194091360867C4CAB0E8,
+				126B0DE9B8D4E42DA7D57AAB,
+				BDFFB5B0A8E8A022C25D7FDB,
+				3D20C932FB058CC20989B129,
 				8E041C8C49F1A5B710CC812C,
 				2A1D9144C59B92B32483924B,
 				D99F56FB46F631F67AF23F2C,
@@ -378,7 +466,31 @@
 				7977CAB4A151C41F4140FE1A,
 				9A47B52E5E1CD17DC9C72B53,
 				B92E8189F69E0B926C73B654 ); name = Utilities; sourceTree = "<group>"; };
+		1255E9B28ADAA1A1CADC4A6E = { isa = PBXGroup; children = (
+				C92B3F413B0F24752ADE6730,
+				FDD549F527C378CF36BDB8C7,
+				3BB44F767E701E3642435FA0,
+				1AAF672654B16469EFB41AC2,
+				41591F74A761BAC908FA8AD8,
+				9C8EA29582DBFF6E5A14B8A3,
+				24C6D768C87E1C42C644C4BD,
+				BCBB865ED53E8AFD278D1A53,
+				B195AD6CEB9B6E3625C8D087,
+				521FECC75E9DDB0D34B22AF8,
+				2FA2FA826CBAD9C639A61E4A,
+				B1CF7BFC5F1892735D4FA1EE,
+				50E7B88E8140BB293B27ED67,
+				FBB9A423728922E96F55074F,
+				6CFF95D08DB1000B1EDD1240,
+				9F208A66C09E80D14F087CB1,
+				A3F978AE6999903C47650173 ); name = SpikePlotting; sourceTree = "<group>"; };
 		15543D7982B26B70879960F4 = { isa = PBXGroup; children = (
+				1255E9B28ADAA1A1CADC4A6E,
+				E7247F5EE9588903C924994F,
+				B0A6A0635113C4B4CD424BEC,
+				7A9A31FC1AE8FB238FAE995E,
+				9E884AEDB6035FFC74886EE8,
+				9ACFB6A181D09434268CE006,
 				ED179D5A10DD051DDB3ECB8B,
 				63C18F4066C75D3C312877D8,
 				2E96DA81EE37A0ECE471A928,
@@ -386,6 +498,10 @@
 				0C5335B0E57C9DC92FC57E5F,
 				7738F51AE0EC63D76EE0F761 ); name = Visualization; sourceTree = "<group>"; };
 		953CC35B9116404D6AA8D1C7 = { isa = PBXGroup; children = (
+				F0B09605D4108F0F94EF3B57,
+				2A46D8E3EC7207D969A2B202,
+				9A3976537C96B39716B5312D,
+				C546D55EDE65ADDD95C6A6F5,
 				AD73EA6B24378294003DC2D0,
 				B7FD86B9DA02771D3519FAA0,
 				544DA1EF90EBBDB6FF2DE0A5,
@@ -426,6 +542,10 @@
 				72123888A7DD78159AA032AF,
 				2164BFCDF57A5AA752CAA3A2 ); name = DataThreads; sourceTree = "<group>"; };
 		33A88A7C3FF426F051834D6A = { isa = PBXGroup; children = (
+				751C52F2BEA7F1328ED13333,
+				7B825983F25D8984E02F6FFB,
+				4AEDD076CCA918481C6F9CF2,
+				671CC5EA3DF4F21E9A7E392B,
 				268005410FB62BCB9099A762,
 				32959675287F77DD9B7FA96B,
 				5935F823A2EE45AC36A0201F,
@@ -434,8 +554,6 @@
 				15543D7982B26B70879960F4,
 				3DD0741FCFBC7563EC722D9B,
 				6E4B37AA4BFEB5A37E3AC250,
-				5AC4DD48CCB1AB4936A2DE4A,
-				44E93A2D64EB5ADA54CB2CFB,
 				B7750B27E4F3748ECCCCF69D,
 				12866D44BE115E8837468F48,
 				FA57CE4F63FF1592D6B3F9B5,
@@ -471,8 +589,6 @@
 				1561F28CD560AB8F2E177628,
 				B977C2809B309C8038CB5D95,
 				877F9F9DA7A1B51D3EDCBC07,
-				2F53BB2693AA5F1C2F27AF7C,
-				DE21954E89A302C554C403B3,
 				EEDA71600D817BF9444FE3E7,
 				4EE6CA70F229EDE04E7E320B,
 				5AB4A3A63B9FDEAB09EEC9C8,
@@ -539,6 +655,7 @@
 				GCC_PREPROCESSOR_DEFINITIONS = (
 				"_DEBUG=1",
 				"DEBUG=1",
+				"JUCE_ObjCExtraSuffix=fea2mT",
 				"JUCER_XCODE_MAC_F6D2F4CF=1"); }; name = Debug; };
 		5D7484BAF16E272FF0E9EEAE = { isa = XCBuildConfiguration; buildSettings = {
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
@@ -554,6 +671,7 @@
 				GCC_PREPROCESSOR_DEFINITIONS = (
 				"_NDEBUG=1",
 				"NDEBUG=1",
+				"JUCE_ObjCExtraSuffix=fea2mT",
 				"JUCER_XCODE_MAC_F6D2F4CF=1"); }; name = Release; };
 		4E274274B609972E0988736B = { isa = XCBuildConfiguration; buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
@@ -613,17 +731,30 @@
 				8E138283FC265B58D252AAC3,
 				EE1DC0B09AE0727BC7A5A99C,
 				4ACF816CB5CDB285D8005AB8,
+				717D108DC8B2379D556C4B2F,
+				1F67A9ACD509FB4DC5A633DF,
 				B992DDBFF8928A985EEE1557,
 				F1268EC5E783EC8ECEBCA5D3,
 				4A00153E1E69A74BC6B7D8A6,
 				5F13B8FFB1584BFF6C05AD39,
+				B11D72764B1B17BF2B8C6E67,
+				938FC2F779C2CF4B8C7ECFFE,
+				55A240CCFCD604CA8DF8FC8C,
+				8025F04ED261C7F7D2DC0F06,
+				49F046C8BE137BF77338DD7B,
+				566E42D2B7105CFB4DB45170,
+				0DDC562EC2B04A26AE6CBB2B,
+				BCD7C4797178C8EF65CDC2D7,
+				9145D84C7D665BCAFE698432,
+				7659F31912D12C91E9554909,
 				9D687F73F2FD2462C5D5588C,
 				B13883377C9316B9603336B4,
 				073B178E7EF1759BA0AACCCE,
 				4BE0DDA01B73223EF0BD934A,
-				6656467170D2822949BD2F7F,
 				08B501E0D7764C6B613AF529,
 				9CBA3837CC8CAA03A03F2D9C,
+				DD22A06702F4CF995893DD5C,
+				F4CEF74DDCD7EFA0891249B5,
 				93A3E6284F2DAED3F491332B,
 				CB77C89226102EF30F85E3EC,
 				A126280FF39A61DEFD3ABFE5,
@@ -657,7 +788,6 @@
 				13457B3248E7646270A4FF88,
 				D060C0893EDAE6CBC86A5FE2,
 				E36C0018635A85E09D4EDE01,
-				4BE24CDF92926150BFC83ED2,
 				C170A763D33146C74ED4CE4B,
 				116BB2F62451986C75586F9D,
 				1F301384375DA0F3652C01DA,
diff --git a/JuceLibraryCode/BinaryData.cpp b/JuceLibraryCode/BinaryData.cpp
index ab8f390247024fdd51802cc565d95c86cac9ee03..6eaabf40614aa2688907e6aa1286a24d10474141 100644
--- a/JuceLibraryCode/BinaryData.cpp
+++ b/JuceLibraryCode/BinaryData.cpp
@@ -30,6 +30,31 @@ const char* BinaryData::getNamedResource (const char* resourceNameUTF8, int& num
         case 0x1eb42b13:  numBytes = BinaryData::ostrich_ttfSize; return BinaryData::ostrich_ttf;
         case 0xafad3345:  numBytes = BinaryData::silkscreenserializedSize; return BinaryData::silkscreenserialized;
         case 0xac0c53a8:  numBytes = BinaryData::silkscreen_ttfSize; return BinaryData::silkscreen_ttf;
+        case 0x9dbdc191:  numBytes = BinaryData::RadioButtons01_pngSize; return BinaryData::RadioButtons01_png;
+        case 0x9dcbd912:  numBytes = BinaryData::RadioButtons02_pngSize; return BinaryData::RadioButtons02_png;
+        case 0x9dd9f093:  numBytes = BinaryData::RadioButtons03_pngSize; return BinaryData::RadioButtons03_png;
+        case 0x9de80814:  numBytes = BinaryData::RadioButtons04_pngSize; return BinaryData::RadioButtons04_png;
+        case 0x9df61f95:  numBytes = BinaryData::RadioButtons05_pngSize; return BinaryData::RadioButtons05_png;
+        case 0xa1a5fa19:  numBytes = BinaryData::RadioButtons_neutral01_pngSize; return BinaryData::RadioButtons_neutral01_png;
+        case 0xa1b4119a:  numBytes = BinaryData::RadioButtons_neutral02_pngSize; return BinaryData::RadioButtons_neutral02_png;
+        case 0xa1c2291b:  numBytes = BinaryData::RadioButtons_neutral03_pngSize; return BinaryData::RadioButtons_neutral03_png;
+        case 0xa1d0409c:  numBytes = BinaryData::RadioButtons_neutral04_pngSize; return BinaryData::RadioButtons_neutral04_png;
+        case 0xa1de581d:  numBytes = BinaryData::RadioButtons_neutral05_pngSize; return BinaryData::RadioButtons_neutral05_png;
+        case 0x91e6977f:  numBytes = BinaryData::RadioButtons_selected01_pngSize; return BinaryData::RadioButtons_selected01_png;
+        case 0x91f4af00:  numBytes = BinaryData::RadioButtons_selected02_pngSize; return BinaryData::RadioButtons_selected02_png;
+        case 0x9202c681:  numBytes = BinaryData::RadioButtons_selected03_pngSize; return BinaryData::RadioButtons_selected03_png;
+        case 0x9210de02:  numBytes = BinaryData::RadioButtons_selected04_pngSize; return BinaryData::RadioButtons_selected04_png;
+        case 0x921ef583:  numBytes = BinaryData::RadioButtons_selected05_pngSize; return BinaryData::RadioButtons_selected05_png;
+        case 0x0634464a:  numBytes = BinaryData::RadioButtons_selected_over01_pngSize; return BinaryData::RadioButtons_selected_over01_png;
+        case 0x06425dcb:  numBytes = BinaryData::RadioButtons_selected_over02_pngSize; return BinaryData::RadioButtons_selected_over02_png;
+        case 0x0650754c:  numBytes = BinaryData::RadioButtons_selected_over03_pngSize; return BinaryData::RadioButtons_selected_over03_png;
+        case 0x065e8ccd:  numBytes = BinaryData::RadioButtons_selected_over04_pngSize; return BinaryData::RadioButtons_selected_over04_png;
+        case 0x066ca44e:  numBytes = BinaryData::RadioButtons_selected_over05_pngSize; return BinaryData::RadioButtons_selected_over05_png;
+        case 0x0d14b768:  numBytes = BinaryData::noise_wave_pngSize; return BinaryData::noise_wave_png;
+        case 0x96fe1b79:  numBytes = BinaryData::saw_wave_pngSize; return BinaryData::saw_wave_png;
+        case 0xd15cb155:  numBytes = BinaryData::sine_wave_pngSize; return BinaryData::sine_wave_png;
+        case 0xd4df18c5:  numBytes = BinaryData::square_wave_pngSize; return BinaryData::square_wave_png;
+        case 0x5f96403a:  numBytes = BinaryData::triangle_wave_pngSize; return BinaryData::triangle_wave_png;
         case 0xb01cfdff:  numBytes = BinaryData::wifi_pngSize; return BinaryData::wifi_png;
         case 0x593e4e34:  numBytes = BinaryData::SourceDrop_pngSize; return BinaryData::SourceDrop_png;
         case 0x6189efd0:  numBytes = BinaryData::DefaultDataSource_pngSize; return BinaryData::DefaultDataSource_png;
@@ -5840,6 +5865,1122 @@ static const unsigned char temp_46c3ac32[] =
 
 const char* BinaryData::silkscreen_ttf = (const char*) temp_46c3ac32;
 
+//================== RadioButtons-01.png ==================
+static const unsigned char temp_819db025[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,19,8,6,0,0,0,241,148,15,247,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,191,73,68,65,84,120,218,196,150,219,78,19,81,20,134,255,61,199,118,128,136,209,132,150,27,98,226,133,70,99,104,69,206,82,18,9,166,49,122,161,9,23,92,250,4,190,129,190,130,207,161,55,106,76,19,37,86,40,162,40,109,154,84,4,
+34,98,5,76,228,2,16,122,156,233,28,92,211,169,74,109,109,13,69,88,201,206,236,116,239,174,245,173,127,173,189,103,24,200,60,30,207,29,122,4,104,180,226,144,141,81,240,123,62,255,197,187,221,221,189,80,20,229,80,131,71,34,83,16,36,73,12,140,94,13,226,
+40,140,231,121,2,16,37,72,146,84,95,42,246,123,110,89,7,4,32,16,128,61,17,69,177,230,70,142,3,100,201,66,65,203,17,9,7,11,46,24,198,1,0,112,255,0,96,103,238,146,13,180,52,73,232,31,188,133,141,141,175,136,206,69,96,152,10,13,214,16,0,199,115,14,128,93,
+139,90,193,155,20,25,125,253,65,168,185,37,120,218,78,163,171,235,50,98,177,25,240,86,99,16,28,171,1,192,24,9,45,25,112,187,5,244,246,5,241,125,251,3,22,23,150,209,222,190,137,142,83,61,240,251,251,17,143,191,166,255,54,215,129,176,27,134,253,37,65,6,
+238,231,100,239,224,56,70,153,91,112,187,248,82,240,5,36,18,73,236,102,100,44,175,236,32,185,242,22,109,30,15,58,59,251,32,112,25,8,66,117,31,50,249,216,218,92,135,88,101,221,30,54,151,160,21,52,164,82,169,138,236,185,22,29,129,192,24,54,190,197,16,141,
+126,68,54,207,195,52,89,177,44,246,254,108,46,131,51,103,135,112,238,124,55,102,103,195,208,237,158,48,88,73,90,144,114,164,158,44,99,124,252,54,66,161,135,180,159,175,56,61,154,170,17,128,86,160,12,183,43,106,159,207,89,152,142,60,192,218,250,14,114,
+57,142,130,151,175,239,238,238,144,131,28,206,95,24,133,207,55,128,201,201,16,52,221,85,220,167,184,45,52,43,77,24,24,188,137,181,213,69,108,109,145,143,60,115,170,177,199,242,249,188,211,3,170,166,149,3,216,116,244,211,251,249,205,34,181,89,229,220,
+219,235,115,177,85,20,244,16,124,254,32,134,2,65,132,95,60,129,36,139,56,222,122,12,35,163,99,88,95,91,196,84,100,18,233,52,163,62,169,244,97,24,186,3,160,105,234,190,186,216,134,120,55,151,36,71,79,209,117,233,26,174,140,92,199,202,167,104,49,243,213,
+47,11,8,135,39,144,74,163,106,112,7,192,40,1,168,218,190,143,146,74,236,111,102,151,201,217,99,244,244,222,128,215,219,129,228,231,121,60,159,120,70,101,50,203,74,247,167,233,122,9,64,85,213,134,46,20,91,192,87,51,75,228,231,17,78,156,108,163,204,167,
+139,193,13,163,246,157,221,112,9,202,148,32,17,195,47,19,116,2,18,208,41,176,105,214,127,97,252,42,65,58,157,174,251,62,248,31,166,235,142,2,247,227,241,216,176,215,219,78,23,198,225,66,100,179,25,231,142,164,143,146,97,122,12,31,197,55,193,15,1,6,0,
+156,20,41,102,255,70,71,224,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons01_png = (const char*) temp_819db025;
+
+//================== RadioButtons-02.png ==================
+static const unsigned char temp_81abc7a6[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,197,73,68,65,84,120,218,196,150,107,79,19,65,20,134,223,153,157,221,110,11,36,152,20,104,52,154,144,160,40,69,32,164,40,136,52,38,24,141,31,252,79,254,31,191,154,104,248,224,133,86,80,145,134,91,32,70,32,202,69,46,134,91,
+111,123,233,94,60,179,106,44,180,24,109,19,152,228,100,119,178,115,206,115,230,61,115,38,203,98,177,216,43,156,211,16,137,129,219,247,70,70,146,103,14,78,165,198,33,20,69,129,22,10,157,57,92,114,133,34,8,174,105,167,46,98,140,228,81,200,132,15,159,230,
+142,195,224,186,128,239,215,9,23,18,206,21,168,170,90,117,1,231,64,88,247,160,48,7,109,177,203,1,112,107,107,29,158,175,194,178,24,61,235,128,19,87,112,133,87,133,203,29,71,116,23,225,176,138,129,91,143,41,75,27,114,239,93,241,4,222,77,142,145,18,30,
+44,155,215,172,128,228,10,206,120,160,255,73,176,166,122,208,67,14,129,31,193,182,246,144,89,152,38,37,124,196,227,253,24,28,122,128,247,147,47,104,29,67,201,169,45,1,201,229,50,128,132,151,155,170,50,52,70,28,116,223,76,194,117,242,152,155,159,197,81,
+86,197,225,145,134,197,197,25,42,184,129,158,190,36,84,97,144,85,250,7,49,4,71,72,99,193,83,81,120,197,119,201,229,96,8,94,126,27,231,140,156,128,150,214,43,104,104,108,194,234,234,34,10,69,218,29,45,245,124,142,108,78,96,109,109,1,145,136,142,142,171,
+125,36,191,9,41,92,121,12,57,215,84,3,26,149,70,85,157,32,102,249,119,105,146,43,108,203,70,46,151,251,35,57,153,29,114,113,189,179,3,43,203,25,124,94,222,14,164,45,47,137,97,100,41,65,29,209,214,46,124,219,92,193,238,247,44,29,64,30,116,67,112,86,194,
+46,218,90,162,184,214,57,136,185,217,183,216,216,60,162,196,217,49,217,37,87,152,166,137,195,131,131,227,53,39,214,243,23,175,3,7,217,86,240,43,187,96,218,153,193,221,225,102,196,187,135,177,251,242,41,242,121,15,14,173,13,105,62,26,116,142,139,151,146,
+20,247,43,37,255,5,134,201,42,98,72,46,119,93,135,78,173,125,204,76,211,70,161,80,130,81,164,185,101,87,253,190,179,99,33,147,73,195,243,12,36,18,163,84,219,28,129,45,232,90,30,157,55,134,232,176,114,140,167,222,144,170,165,170,49,36,87,184,180,53,219,
+182,254,251,180,146,63,237,202,70,83,83,10,61,189,163,24,186,243,16,235,107,75,104,111,239,69,52,218,138,137,137,49,74,208,248,121,33,85,241,151,92,225,144,86,82,255,90,134,76,224,195,212,10,221,122,62,250,251,7,17,107,187,79,109,87,64,58,253,12,243,
+11,27,40,149,78,239,65,201,21,129,236,150,85,243,77,37,93,83,233,37,76,125,252,132,11,205,13,216,219,207,83,89,124,42,135,255,215,254,175,75,246,147,9,20,10,192,254,126,241,159,47,156,95,178,215,183,243,90,135,228,138,98,177,128,157,237,237,51,135,75,
+46,163,63,153,39,231,245,39,243,67,128,1,0,60,21,103,165,70,150,193,96,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons02_png = (const char*) temp_81abc7a6;
+
+//================== RadioButtons-03.png ==================
+static const unsigned char temp_81b9df27[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,77,73,68,65,84,120,218,196,150,219,110,211,64,16,134,255,61,196,109,66,165,86,106,47,242,32,173,8,23,69,240,16,136,103,225,142,151,42,92,34,40,32,113,1,151,160,34,78,82,213,67,148,66,147,56,118,236,181,119,205,76,156,162,
+172,157,22,25,161,116,164,141,226,221,153,249,230,228,149,69,183,219,125,129,91,18,189,187,119,247,193,254,254,253,149,131,15,15,95,65,43,165,16,172,173,173,28,206,92,173,52,193,131,160,118,40,37,32,4,45,126,16,75,172,11,192,209,42,230,171,49,92,51,92,
+42,180,90,45,191,23,138,157,199,232,116,52,148,20,75,141,25,24,197,6,66,118,144,229,162,113,0,204,213,82,201,26,188,189,110,177,183,251,16,119,54,118,254,234,228,205,235,103,8,35,221,24,206,92,45,133,156,213,255,74,184,212,65,80,204,202,62,141,142,48,
+24,28,35,207,53,10,47,106,135,173,205,54,182,182,239,145,46,217,39,170,57,156,184,90,16,109,17,206,205,84,76,38,137,99,129,147,83,32,49,133,215,120,10,154,180,4,193,121,54,216,94,18,252,154,193,192,242,161,97,174,230,125,254,179,184,41,68,57,109,12,160,
+26,144,99,89,141,123,190,174,244,69,13,160,100,129,233,52,36,219,2,235,237,205,122,112,244,168,77,106,16,134,161,183,159,25,11,147,230,148,185,193,104,60,129,49,178,50,144,236,24,176,214,34,138,38,100,223,170,57,231,185,233,245,122,24,94,254,196,199,
+79,95,104,40,125,31,204,213,73,146,144,194,165,119,16,82,23,222,127,120,139,148,2,184,184,72,224,92,229,102,210,212,146,72,206,224,163,209,24,195,33,245,220,249,89,185,13,71,231,41,178,44,198,120,60,36,95,126,112,204,213,214,230,72,141,169,86,4,95,191,
+253,250,211,182,234,44,113,48,57,129,89,172,205,8,96,61,56,119,33,207,139,89,201,29,41,27,242,111,140,240,252,48,87,115,244,198,164,141,38,181,112,130,156,151,240,73,120,138,120,82,94,56,139,193,43,250,177,185,33,8,195,51,74,208,79,129,185,154,157,112,
+253,155,136,179,130,202,88,194,31,61,126,114,163,110,191,63,32,93,202,60,245,225,204,45,203,158,54,203,60,163,88,191,255,56,193,206,246,75,186,44,236,245,21,162,183,228,232,243,49,205,71,74,109,170,102,254,143,101,103,57,59,51,56,120,254,14,66,220,208,
+30,190,255,169,31,214,214,111,160,121,217,155,103,254,63,132,185,58,142,35,244,207,207,87,14,103,174,160,47,153,167,183,245,37,243,91,128,1,0,11,149,65,182,96,70,58,8,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons03_png = (const char*) temp_81b9df27;
+
+//================== RadioButtons-04.png ==================
+static const unsigned char temp_81c7f6a8[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,165,73,68,65,84,120,218,196,150,237,79,211,80,24,197,207,109,111,1,157,74,50,144,76,226,198,139,128,2,66,162,66,136,31,48,42,248,217,232,95,228,127,102,2,74,130,38,203,192,12,84,134,1,231,88,145,142,194,218,117,107,215,23,
+159,219,161,216,161,198,200,132,155,52,109,239,189,233,239,60,231,60,109,202,18,137,196,75,156,211,224,83,211,51,15,103,103,31,156,57,120,113,113,1,92,150,101,180,181,183,159,57,92,112,185,204,9,222,214,118,98,145,177,227,235,32,248,15,112,46,224,146,
+12,69,81,34,11,146,36,136,85,48,248,225,38,63,104,135,231,177,150,138,16,92,46,201,210,9,184,194,3,140,143,77,226,90,239,8,242,159,115,216,204,101,225,250,194,129,14,120,126,107,68,8,46,151,152,20,250,31,129,43,62,56,23,213,87,208,215,215,133,100,234,
+41,242,249,28,212,226,22,42,149,42,249,113,225,212,78,8,46,103,20,110,20,30,144,170,70,230,182,109,33,191,253,22,241,174,36,82,201,1,36,147,67,216,223,223,195,198,135,12,12,211,160,70,237,60,18,193,126,131,248,174,142,253,162,167,24,184,152,103,63,119,
+23,77,72,172,113,246,3,9,135,134,2,117,79,67,236,162,134,84,170,7,221,221,253,136,223,127,18,138,200,109,172,192,52,77,106,216,78,184,158,20,113,130,177,128,114,245,96,24,101,196,46,197,225,251,77,2,232,150,59,182,67,27,140,200,124,141,251,176,44,135,
+236,119,161,235,22,172,154,140,125,29,40,170,155,136,197,54,209,155,136,99,96,112,16,247,166,30,133,34,62,190,79,195,52,74,20,85,39,234,110,195,9,17,221,237,177,27,184,114,101,2,203,111,150,81,179,165,8,67,112,121,173,86,195,129,174,71,69,209,190,108,
+118,13,29,29,28,234,87,19,158,123,188,166,149,128,66,225,0,107,235,57,140,12,95,37,17,19,152,158,153,135,166,237,98,117,101,9,229,67,141,98,188,12,145,164,235,90,116,56,36,76,135,105,73,199,41,136,2,137,203,61,122,178,237,56,205,142,224,203,142,243,35,
+182,230,190,18,235,150,5,232,7,69,188,203,22,49,122,179,7,195,195,119,240,120,238,89,40,98,37,243,26,229,178,74,241,121,228,66,0,167,94,167,74,89,228,57,130,75,112,15,142,99,255,83,199,50,187,33,98,73,47,32,179,90,32,155,123,113,107,244,46,230,230,159,
+83,92,187,240,93,35,132,215,5,220,9,154,224,30,184,235,122,161,255,167,29,66,196,171,165,45,164,51,219,152,156,184,142,241,241,41,112,101,8,165,210,14,89,236,208,155,19,245,79,112,27,182,219,118,203,190,92,66,196,194,98,14,233,244,39,18,208,143,106,213,
+167,134,182,195,202,209,74,219,255,52,42,21,134,61,109,61,188,246,253,224,196,7,233,200,246,214,86,254,183,67,112,185,101,85,176,171,170,103,14,23,92,70,127,50,47,206,235,79,230,155,0,3,0,91,7,91,249,23,102,61,167,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons04_png = (const char*) temp_81c7f6a8;
+
+//================== RadioButtons-05.png ==================
+static const unsigned char temp_81d60e29[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,30,0,0,0,19,8,6,0,0,0,135,174,189,124,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,3,59,73,68,65,84,120,218,188,86,91,79,19,81,16,254,118,247,244,94,160,208,2,229,98,137,37,38,154,0,33,154,24,34,193,152,24,227,139,202,139,62,250,95,252,9,254,4,159,140,190,171,49,74,226,237,197,68,154,24,64,5,74,145,164,152,
+110,239,133,182,219,221,109,119,143,179,91,16,106,91,245,197,78,114,218,115,153,51,223,204,55,51,39,43,132,195,225,55,232,173,188,163,241,80,184,117,123,153,47,45,93,237,9,98,189,94,71,124,123,11,43,43,175,222,50,73,146,224,116,185,122,2,108,225,204,
+95,188,132,120,124,251,26,147,24,1,59,157,61,229,218,194,99,146,40,193,225,112,116,84,16,126,253,0,156,211,84,56,25,220,4,76,222,217,176,72,231,18,163,67,46,160,97,52,239,182,216,37,3,76,148,196,142,192,22,30,163,203,165,98,6,67,193,97,202,143,8,65,228,
+112,59,57,25,117,216,249,82,53,177,197,232,177,163,46,167,137,177,240,56,10,133,20,84,157,67,215,91,245,68,242,140,134,8,43,207,191,15,230,144,48,48,224,194,221,123,247,225,247,74,240,249,0,159,23,56,127,97,14,139,139,215,17,232,23,225,113,11,228,52,
+49,70,233,114,187,68,168,106,158,64,53,58,19,108,189,43,139,55,225,243,88,1,180,218,182,188,99,86,216,205,197,105,225,100,140,35,20,28,180,87,151,23,110,224,203,250,123,24,134,134,145,145,113,123,47,20,26,163,98,49,160,84,51,200,229,11,232,247,135,176,
+176,176,140,124,46,5,203,156,32,24,40,230,215,97,152,140,162,19,109,122,79,168,38,103,32,160,101,243,56,71,162,160,193,235,237,131,217,72,219,30,134,134,135,80,215,203,77,183,12,25,147,145,89,123,190,27,127,137,153,185,59,112,187,189,246,122,242,204,
+180,253,175,214,210,72,236,102,161,215,29,246,253,86,8,138,88,215,116,148,203,229,22,96,137,114,57,59,19,37,176,41,202,241,6,28,78,31,81,29,68,78,41,80,212,6,106,213,36,60,190,97,91,119,100,244,44,209,237,178,247,85,101,13,30,111,132,248,10,160,88,76,
+35,95,80,80,83,165,182,250,209,52,21,76,85,85,50,94,108,45,44,17,88,91,255,76,148,113,236,39,119,48,26,142,160,175,143,195,229,98,208,181,44,209,171,192,233,54,142,10,165,223,6,229,166,130,88,44,134,200,84,29,227,19,243,56,40,89,192,7,164,47,180,1,215,
+8,147,25,70,3,154,174,183,85,116,154,24,126,189,242,145,10,3,8,12,78,96,98,114,10,133,92,6,181,154,138,108,54,143,64,176,169,203,156,65,210,47,82,158,127,32,69,119,220,158,28,1,3,197,82,133,116,235,104,52,218,219,141,83,31,50,203,91,93,215,186,246,177,
+36,9,144,229,20,162,148,58,159,127,26,135,135,50,69,82,194,185,83,122,187,137,13,124,90,221,66,165,74,185,99,57,68,163,73,236,36,168,149,106,157,123,221,52,77,176,6,117,184,149,231,110,66,5,73,212,52,221,246,122,253,72,36,178,216,221,171,80,110,99,212,
+94,2,229,116,0,95,191,125,71,161,168,19,229,192,254,190,134,39,79,159,209,156,219,235,78,98,210,235,211,164,90,211,186,2,91,213,184,185,185,71,252,60,70,165,162,64,78,43,212,175,38,158,191,248,64,207,94,179,90,245,58,39,74,121,219,11,213,77,254,74,245,
+73,21,2,171,177,228,209,211,249,239,0,221,228,136,234,63,71,252,63,68,167,98,102,138,82,69,90,150,123,6,154,205,102,168,64,15,30,10,244,5,242,160,199,95,32,123,178,44,63,250,41,192,0,169,115,113,154,200,139,135,81,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons05_png = (const char*) temp_81d60e29;
+
+//================== RadioButtons_neutral-01.png ==================
+static const unsigned char temp_38c869d[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,19,8,6,0,0,0,241,148,15,247,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,103,73,68,65,84,120,218,196,86,221,75,83,97,28,126,206,217,217,161,177,205,64,177,121,154,125,96,132,23,125,144,36,117,219,77,222,108,115,36,74,11,22,140,210,182,187,162,174,130,46,250,83,6,121,83,162,99,69,69,17,164,77,152,
+168,67,48,203,106,141,105,160,172,109,110,147,181,185,243,181,211,123,142,37,68,251,10,199,250,193,15,94,206,251,62,239,243,252,62,248,157,151,82,20,5,28,199,221,49,27,141,55,201,218,140,22,27,67,200,31,234,245,250,251,54,199,32,123,200,194,181,148,252,
+237,155,215,96,218,76,38,183,243,202,16,107,225,172,173,14,30,58,157,14,140,193,96,96,143,30,239,193,255,48,154,166,193,80,20,64,74,208,16,96,61,246,5,166,182,131,232,232,180,52,79,0,64,129,101,217,186,135,11,219,25,220,190,123,15,185,108,22,193,224,
+83,116,90,186,154,34,128,86,51,160,214,162,150,23,182,179,24,113,93,131,192,151,208,222,209,14,167,115,16,153,116,178,46,174,158,83,132,156,254,221,12,213,60,159,77,19,114,23,137,60,131,119,179,97,68,163,49,77,132,221,110,71,58,153,104,134,0,74,91,84,
+242,92,250,59,134,175,238,146,71,150,150,181,111,107,235,223,16,139,197,53,17,54,155,13,201,196,102,85,188,234,95,63,175,214,216,39,115,64,148,68,165,88,44,86,172,209,208,240,8,82,201,36,230,230,23,255,248,190,242,225,35,120,158,71,111,239,73,92,30,24,
+64,96,106,10,156,245,200,95,248,76,42,129,91,94,47,158,191,124,85,241,126,89,146,193,72,162,164,168,141,85,113,80,204,132,176,185,177,81,113,111,97,97,17,165,210,14,206,156,62,5,135,195,129,241,241,71,232,226,186,247,246,243,185,45,140,122,125,72,146,
+0,170,221,207,139,2,24,117,20,11,130,80,241,192,90,60,94,179,139,35,145,37,72,36,138,190,115,103,225,118,95,135,223,239,135,58,77,249,66,30,163,62,31,182,210,105,188,168,18,189,106,101,185,188,43,128,175,34,160,17,155,39,153,144,101,25,253,231,251,224,
+241,120,16,12,4,246,200,3,193,103,53,177,114,153,148,64,33,11,129,212,115,63,22,14,207,105,34,46,94,232,199,141,177,49,66,158,194,227,39,147,117,113,90,6,160,102,96,159,2,84,11,133,102,33,17,17,221,214,195,152,152,152,108,8,83,214,50,160,245,0,223,148,
+209,58,51,61,253,79,231,101,53,3,162,36,255,136,126,90,197,177,158,19,45,255,25,169,101,99,120,129,127,176,188,242,62,176,83,42,193,108,110,237,123,68,18,69,80,191,94,68,151,140,6,131,75,71,211,7,90,157,133,159,2,12,0,238,13,9,71,19,58,158,165,0,0,0,
+0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_neutral01_png = (const char*) temp_38c869d;
+
+//================== RadioButtons_neutral-02.png ==================
+static const unsigned char temp_39a9e1e[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,54,73,68,65,84,120,218,196,150,207,79,19,65,20,199,191,187,157,182,86,131,166,254,72,69,19,13,141,137,49,30,12,218,131,225,102,106,140,129,112,52,210,150,67,19,53,130,240,223,104,188,123,210,196,171,98,148,6,127,20,104,145,
+32,28,48,129,130,201,66,65,91,160,148,110,161,178,219,157,226,204,28,56,176,187,13,182,164,125,201,203,190,153,247,94,62,243,230,205,76,86,186,226,247,43,104,146,144,182,54,255,229,59,119,239,53,28,252,57,246,9,196,225,112,192,229,118,55,28,206,185,68,
+150,101,184,155,0,231,92,1,119,58,157,85,3,179,171,203,8,4,2,32,44,46,153,72,192,119,241,210,209,193,93,46,151,109,208,78,97,19,79,159,13,128,16,34,198,55,218,111,226,237,155,215,56,113,234,116,221,112,89,146,36,177,255,86,186,246,103,5,15,122,66,160,
+70,25,195,177,17,161,220,230,115,91,185,117,219,188,195,40,231,218,194,119,138,42,194,145,8,246,246,42,24,29,159,0,165,84,40,183,101,9,120,24,10,97,99,45,83,47,28,194,56,168,215,175,93,197,49,143,7,179,179,63,97,24,198,254,60,183,231,231,23,216,57,33,
+8,6,131,216,253,91,178,204,231,243,217,223,105,108,171,5,75,63,231,18,106,80,148,74,37,83,79,206,250,124,72,205,165,160,44,165,77,190,185,212,2,60,199,61,184,208,218,10,67,219,5,195,155,123,90,161,8,133,35,152,248,62,137,141,220,166,201,207,185,68,43,
+235,216,202,231,77,206,161,161,143,85,15,204,216,120,18,93,157,247,209,217,221,141,151,47,158,227,204,185,243,251,190,220,122,6,253,3,131,40,168,42,22,23,127,89,230,115,46,91,96,5,186,174,255,183,110,23,139,248,22,31,19,125,123,244,248,9,86,210,75,98,
+158,127,35,189,189,172,175,50,222,189,255,96,155,207,185,132,178,237,209,216,160,22,81,20,5,83,63,166,17,184,213,142,104,52,138,145,216,48,250,250,251,112,178,165,69,236,76,145,45,208,78,56,151,136,202,53,173,230,251,154,72,36,197,45,232,232,184,141,
+158,112,24,14,246,30,124,249,26,199,204,244,76,213,60,81,121,133,87,94,7,156,75,60,62,42,212,235,245,34,111,113,126,44,225,188,114,42,122,174,29,201,123,157,205,102,14,29,75,69,207,217,150,233,53,246,188,30,225,92,98,148,203,88,77,47,55,28,206,185,68,
+85,11,175,152,54,229,79,230,159,0,3,0,178,38,58,166,235,164,14,20,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_neutral02_png = (const char*) temp_39a9e1e;
+
+//================== RadioButtons_neutral-03.png ==================
+static const unsigned char temp_3a8b59f[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,1,165,73,68,65,84,120,218,196,150,109,75,194,80,20,199,207,220,221,172,12,21,122,130,40,76,139,94,7,245,162,122,19,73,244,213,194,143,209,75,251,0,69,169,212,103,136,232,77,132,154,104,69,234,210,72,216,195,189,235,222,13,133,
+218,217,70,19,244,63,198,6,255,115,206,111,231,222,187,187,73,91,185,92,13,166,36,146,205,230,50,199,39,167,19,7,223,150,111,128,200,178,12,106,60,62,113,184,224,146,88,44,6,241,41,192,5,215,129,43,138,226,49,91,141,58,88,166,25,88,192,182,25,100,54,
+183,199,131,171,170,234,49,15,15,246,97,103,119,47,180,200,229,213,117,116,184,36,73,206,248,99,186,171,148,33,189,176,140,122,189,110,27,142,242,121,223,220,48,9,110,32,156,49,6,237,78,7,247,12,125,180,112,198,128,187,55,136,235,156,168,55,244,1,252,
+125,174,247,215,38,36,83,105,152,157,75,160,233,132,90,20,6,131,129,199,76,37,102,64,85,84,208,190,190,241,206,77,29,24,197,115,135,90,89,90,228,35,215,5,27,188,15,40,184,68,55,13,248,212,52,143,105,89,22,24,134,1,134,174,227,239,41,48,176,56,28,203,
+29,53,176,190,10,50,95,88,88,140,224,18,70,153,3,249,171,174,207,92,15,165,18,183,27,44,247,215,235,200,15,44,70,112,9,101,20,244,144,2,104,231,146,187,55,60,62,220,251,198,108,100,214,248,94,96,163,245,5,215,237,220,103,104,131,148,78,206,59,215,179,
+66,33,48,174,82,42,65,235,237,3,239,156,137,206,35,192,219,29,13,170,181,122,104,220,211,115,21,173,47,184,132,58,115,254,127,184,200,185,40,22,35,239,237,212,153,115,190,98,141,8,115,62,174,4,151,136,143,71,179,241,50,113,184,224,146,126,191,119,206,
+207,169,252,201,252,8,48,0,227,76,197,247,89,122,10,69,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_neutral03_png = (const char*) temp_3a8b59f;
+
+//================== RadioButtons_neutral-04.png ==================
+static const unsigned char temp_3b6cd20[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,27,73,68,65,84,120,218,196,150,109,79,211,80,24,134,239,182,167,29,219,50,100,176,110,200,48,203,22,127,5,209,15,4,162,63,68,72,36,209,175,26,241,215,248,7,28,159,36,129,69,92,228,69,167,113,250,9,156,16,141,14,98,125,9,91,
+11,117,93,123,138,61,167,209,4,219,17,18,203,246,36,39,79,211,59,231,190,158,231,188,52,21,174,150,74,159,48,160,32,197,98,169,48,61,123,163,239,224,181,202,10,136,36,73,80,98,177,190,195,25,151,136,162,136,216,0,224,140,203,225,178,44,7,196,159,223,
+53,28,233,109,100,39,38,17,143,39,46,14,174,40,74,64,44,92,153,196,236,205,57,108,174,63,71,253,77,29,227,121,175,136,68,50,90,184,32,8,124,253,3,162,224,162,217,108,34,63,145,199,212,181,235,188,136,247,59,59,72,103,178,145,20,193,184,61,225,112,93,
+252,208,190,162,125,220,129,40,43,127,139,248,184,183,135,202,234,10,134,71,70,49,166,102,255,23,238,63,132,168,124,56,142,131,198,135,93,126,46,36,37,230,173,136,128,249,219,11,126,17,149,85,140,164,199,48,154,81,67,1,191,204,99,232,237,22,114,151,243,
+161,246,132,58,20,166,105,6,196,116,42,9,199,182,79,105,245,183,239,248,249,48,59,22,12,189,133,91,115,243,216,109,52,176,188,252,4,169,75,105,168,185,241,83,30,166,161,35,167,102,66,253,25,151,88,118,23,173,195,195,128,200,38,48,208,145,97,4,180,111,
+154,198,115,60,153,2,245,230,47,220,185,139,198,246,54,150,150,202,72,164,134,161,170,57,95,87,8,100,207,163,165,29,4,60,24,151,184,212,69,183,219,13,136,97,239,254,141,90,237,21,207,39,162,4,193,165,184,247,96,145,23,81,46,63,134,50,148,64,169,88,232,
+233,197,184,132,122,147,172,115,128,206,138,173,173,23,60,219,238,9,100,17,184,191,248,144,23,177,127,224,119,28,230,207,184,126,231,150,21,201,221,221,88,223,224,185,211,165,24,82,36,76,207,204,224,117,237,101,168,63,239,220,101,157,71,4,255,19,213,
+106,149,103,195,180,60,111,59,212,159,113,9,229,123,110,93,200,247,251,217,218,211,158,26,229,123,78,233,185,14,87,212,193,184,132,221,229,253,47,159,251,14,103,92,162,235,237,71,222,24,200,159,204,111,1,6,0,203,214,249,255,62,204,159,178,0,0,0,0,73,
+69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_neutral04_png = (const char*) temp_3b6cd20;
+
+//================== RadioButtons_neutral-05.png ==================
+static const unsigned char temp_3c4e4a1[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,30,0,0,0,19,8,6,0,0,0,135,174,189,124,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,194,73,68,65,84,120,218,188,148,91,75,84,81,20,199,255,51,115,102,6,109,102,116,102,196,75,134,153,121,137,202,212,215,208,34,178,94,130,82,169,135,32,8,66,177,94,162,190,69,31,161,151,192,72,66,10,42,122,52,10,223,203,91,
+50,163,134,118,70,71,207,164,168,103,46,103,198,115,63,237,189,213,129,156,139,16,53,11,54,103,159,181,214,94,191,181,214,190,216,154,155,154,34,40,161,200,154,58,166,107,250,51,219,181,171,189,214,149,222,235,165,129,202,50,222,189,29,219,221,22,197,
+41,206,225,112,192,229,118,151,4,76,57,119,239,221,47,123,53,242,162,139,179,219,237,112,151,8,76,133,178,130,193,160,206,192,78,167,179,148,219,12,155,205,6,6,118,185,92,5,157,150,22,195,104,110,59,155,253,223,218,16,160,235,58,106,235,27,138,6,183,
+52,25,130,32,160,254,100,83,46,152,12,59,165,211,125,206,55,118,211,73,60,126,242,20,194,106,36,171,235,234,236,196,131,193,33,100,210,169,28,255,95,194,26,84,69,102,182,27,55,111,97,232,225,163,188,113,73,201,197,193,110,231,94,39,6,135,135,145,216,
+222,132,156,73,163,189,179,139,233,28,176,152,142,250,9,107,81,68,249,101,244,15,12,160,186,42,128,227,181,53,72,198,227,216,17,197,188,113,105,197,28,225,178,158,31,22,33,186,130,134,134,19,152,155,157,129,97,24,240,250,124,100,17,199,108,84,215,127,
+251,14,155,191,30,29,69,95,127,31,252,126,63,251,191,216,221,195,190,83,223,190,66,76,166,243,198,166,194,25,186,129,76,38,147,99,56,213,216,72,130,116,99,226,203,103,114,248,92,8,4,2,224,249,8,76,146,68,116,53,138,115,231,219,153,95,77,77,53,42,72,82,
+84,191,48,63,79,146,179,161,165,245,12,98,66,12,166,157,43,116,159,45,78,209,84,196,73,75,14,11,77,230,251,220,28,50,170,14,121,71,132,63,24,0,185,244,152,153,153,134,78,32,116,80,169,171,171,99,243,8,255,19,147,211,179,168,244,30,195,169,211,45,48,76,
+3,137,68,42,47,120,151,130,77,195,132,170,170,57,70,170,155,156,156,102,243,170,64,37,122,46,93,38,175,206,27,72,169,20,9,24,207,250,53,183,182,97,113,62,12,73,146,216,154,148,100,49,189,73,118,50,95,92,118,226,45,139,180,154,100,166,20,112,56,16,113,
+191,35,23,58,58,88,187,221,229,190,63,236,203,75,203,16,54,183,216,220,235,171,96,45,23,98,27,133,175,26,5,179,138,21,165,40,184,42,184,119,112,60,30,15,56,206,9,97,157,71,40,20,102,213,123,61,229,72,43,90,54,134,176,190,198,70,209,59,206,192,180,226,
+35,192,60,191,130,247,31,62,34,65,174,200,65,245,227,227,159,254,250,229,218,107,53,219,99,229,72,231,31,139,11,255,236,201,220,7,27,5,15,193,255,16,113,103,11,73,73,42,227,116,77,195,122,116,181,36,80,141,176,66,225,144,106,154,230,115,46,153,76,188,
+36,163,100,21,19,232,68,44,22,27,249,45,192,0,199,255,94,204,221,247,116,245,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_neutral05_png = (const char*) temp_3c4e4a1;
+
+//================== RadioButtons_selected-01.png ==================
+static const unsigned char temp_647cc073[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,19,8,6,0,0,0,241,148,15,247,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,134,73,68,65,84,120,218,196,86,75,104,19,81,20,61,47,153,76,147,104,90,146,214,106,68,65,116,81,116,99,43,72,109,87,21,139,65,171,82,161,152,44,20,233,39,70,10,69,219,69,161,16,138,96,65,186,112,227,82,139,248,87,106,53,169,
+46,20,252,130,138,40,45,88,41,46,130,198,66,193,79,98,205,111,38,49,153,207,115,146,148,34,152,31,166,140,15,238,48,188,251,206,187,231,157,185,239,222,33,148,82,88,173,214,147,235,170,140,221,162,76,77,80,121,48,74,240,83,134,10,118,104,120,231,6,118,
+179,153,81,53,248,217,169,16,152,53,149,198,195,103,246,108,100,183,212,48,106,31,30,68,75,192,24,12,122,182,97,61,139,255,49,52,105,2,32,4,172,158,148,4,24,159,183,160,110,101,2,91,205,137,229,83,64,137,15,70,95,124,177,135,111,70,251,128,19,225,80,
+8,179,30,55,234,87,197,203,39,160,81,84,72,191,104,117,164,160,121,226,205,176,57,156,32,137,5,88,170,45,168,61,56,130,247,33,99,81,92,49,35,26,162,16,80,20,208,48,36,175,221,137,52,193,102,119,2,63,125,168,124,53,8,157,207,147,33,81,179,127,4,51,63,
+140,5,177,197,140,16,146,85,64,163,205,109,183,23,118,96,247,98,112,243,204,104,102,206,56,127,31,236,71,111,134,132,165,237,52,222,5,13,121,241,105,123,238,207,239,203,212,1,81,16,169,204,7,114,126,163,214,142,46,200,129,89,152,223,14,65,254,99,190,
+226,195,24,104,138,71,85,157,3,66,235,48,94,123,7,208,104,141,252,133,191,28,220,133,3,221,125,144,31,180,231,78,2,73,2,35,136,2,13,7,131,57,253,250,199,39,144,252,50,133,112,46,103,240,28,228,104,4,150,109,61,16,219,70,241,232,106,15,182,215,134,150,
+220,55,185,125,232,112,245,34,250,245,19,72,158,253,197,164,17,12,85,142,22,227,114,95,195,152,111,58,157,171,249,211,248,205,21,48,73,9,181,77,46,224,200,24,94,92,232,66,189,37,138,123,116,47,14,29,31,4,247,125,14,140,247,40,98,121,246,16,69,89,33,160,
+244,130,8,167,249,247,187,244,242,6,86,164,73,180,244,2,206,139,152,188,123,13,118,87,63,184,111,159,193,95,239,44,120,128,37,2,49,142,150,117,159,99,207,110,33,153,38,97,235,131,253,88,191,34,187,31,129,243,157,69,113,66,150,0,16,79,208,178,139,74,252,
+201,56,82,41,9,166,77,13,152,187,228,46,9,35,137,52,171,0,207,211,101,41,173,252,195,9,229,57,81,242,122,81,82,20,72,73,50,247,52,160,67,163,73,84,189,25,101,114,32,250,75,112,79,250,5,79,108,173,1,171,85,110,138,73,65,6,89,252,35,106,169,54,232,28,74,
+103,210,171,173,194,111,1,6,0,169,191,241,34,56,210,107,35,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_selected01_png = (const char*) temp_647cc073;
+
+//================== RadioButtons_selected-02.png ==================
+static const unsigned char temp_648ad7f4[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,102,73,68,65,84,120,218,196,150,77,104,19,65,20,199,255,187,153,181,201,134,212,24,42,126,32,86,15,133,10,69,26,40,162,17,84,68,41,10,18,84,90,171,205,69,37,135,74,241,82,240,3,188,120,241,100,241,224,199,69,17,60,104,75,
+43,22,105,197,70,35,226,71,139,7,17,63,138,20,139,208,18,164,24,107,178,105,178,155,110,146,221,117,102,11,10,238,166,132,180,164,11,111,118,118,222,188,249,241,248,207,155,89,210,88,183,121,18,203,244,144,237,155,106,106,187,154,86,85,28,220,253,62,
+9,194,57,56,172,16,249,138,195,25,151,240,180,169,114,85,30,206,184,243,153,59,185,5,39,246,255,172,197,198,109,205,16,4,1,223,71,134,208,178,102,106,105,50,231,104,210,196,89,124,210,128,28,64,176,51,12,66,136,249,221,224,111,194,96,239,109,28,118,143,
+46,14,78,185,60,199,115,112,8,246,246,52,190,1,205,109,97,24,121,5,174,72,135,105,172,207,198,134,103,183,20,141,43,197,24,151,231,56,218,16,171,77,41,110,4,66,151,192,25,26,188,163,23,192,27,138,105,102,159,170,180,179,173,11,159,102,68,219,216,82,204,
+228,206,139,111,53,169,254,20,221,136,78,8,159,239,128,215,229,127,62,218,23,198,123,168,254,4,238,189,23,145,202,241,182,241,108,252,254,180,31,147,25,209,214,111,214,57,180,28,116,57,110,209,100,109,141,23,249,175,143,225,137,13,65,255,207,231,156,
+120,0,73,172,199,234,245,91,17,205,6,112,84,127,100,137,127,171,183,224,224,137,118,168,239,110,64,79,70,173,162,107,26,72,65,157,131,244,75,177,248,92,79,142,155,111,169,200,134,17,95,159,131,18,236,195,174,67,237,232,191,62,130,253,190,177,191,190,
+231,137,6,236,238,60,134,57,105,26,174,111,61,182,107,20,84,145,194,11,58,210,25,174,140,253,154,65,213,240,121,240,193,155,216,17,238,198,155,107,173,104,244,205,226,99,162,26,254,142,43,112,56,120,228,31,158,68,58,103,191,54,227,154,240,84,89,112,250,
+76,140,193,253,234,22,86,238,57,131,186,240,93,68,158,13,98,95,168,21,213,30,15,146,145,171,200,38,100,86,84,197,225,121,51,115,163,236,122,77,191,236,133,170,106,88,119,224,44,142,132,78,195,65,75,97,102,224,50,226,31,162,11,198,49,46,209,10,6,148,172,
+177,168,3,67,121,209,135,31,212,156,94,31,213,57,81,82,12,227,146,130,166,67,150,141,37,57,175,101,249,119,201,115,25,215,212,92,206,26,21,191,88,76,205,213,188,142,47,169,202,223,106,140,75,98,178,113,47,38,107,203,242,39,243,71,128,1,0,163,90,231,150,
+52,232,169,252,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_selected02_png = (const char*) temp_648ad7f4;
+
+//================== RadioButtons_selected-03.png ==================
+static const unsigned char temp_6498ef75[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,1,190,73,68,65,84,120,218,196,150,189,79,194,80,20,197,207,43,79,144,26,163,68,6,29,140,50,24,29,77,208,196,56,56,184,57,27,157,116,112,116,246,223,80,255,5,227,226,234,224,199,164,51,241,35,58,56,104,116,129,176,16,48,10,161,
+69,90,222,135,125,69,166,190,130,96,130,55,13,29,238,61,231,215,155,243,82,74,230,103,82,89,252,83,209,165,233,228,212,222,66,162,239,224,131,251,79,80,18,33,136,154,70,223,225,138,75,13,239,39,22,239,63,92,113,155,155,15,146,64,243,170,48,140,34,27,
+106,159,153,116,177,57,249,209,251,230,196,91,154,14,6,155,35,203,219,88,73,47,118,62,52,103,59,189,193,21,151,24,4,145,1,162,233,18,100,174,207,177,54,250,172,21,223,84,38,48,187,186,165,215,254,10,174,54,247,32,6,13,49,16,12,242,243,69,47,254,137,36,
+84,219,9,238,113,105,51,252,118,7,35,164,193,9,58,105,31,10,113,164,70,28,36,226,66,31,25,184,11,97,23,131,75,155,14,134,163,18,162,90,212,10,221,134,5,193,185,86,219,170,92,114,23,111,239,57,108,136,75,205,195,115,80,230,212,81,46,213,2,189,244,215,
+62,164,107,161,236,86,181,198,182,81,5,243,12,202,165,82,40,60,146,138,129,145,168,118,134,57,166,7,103,2,85,75,147,155,85,104,165,163,53,102,38,247,239,90,109,171,164,119,73,169,157,81,92,31,94,177,186,63,52,46,109,230,120,241,58,16,58,51,62,199,33,
+133,212,250,251,240,134,191,185,236,26,30,27,107,26,174,31,92,181,157,187,187,60,209,250,43,46,229,76,162,246,213,61,220,204,102,80,127,56,237,56,55,116,123,140,90,61,232,175,184,148,113,1,219,238,30,14,187,134,199,163,195,158,223,237,138,235,103,110,
+247,176,249,95,203,207,220,105,8,60,85,250,255,175,166,184,52,111,203,227,188,205,255,229,75,230,91,128,1,0,165,175,191,223,100,163,205,167,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_selected03_png = (const char*) temp_6498ef75;
+
+//================== RadioButtons_selected-04.png ==================
+static const unsigned char temp_64a706f6[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,100,73,68,65,84,120,218,196,150,77,104,211,96,24,199,255,111,154,102,205,92,221,186,85,17,71,173,58,198,188,232,6,14,84,148,162,172,226,7,76,70,65,119,216,209,195,64,60,41,130,99,87,15,122,24,168,7,5,79,83,97,8,165,155,122,
+17,199,16,25,58,61,104,81,118,152,173,171,19,183,22,109,221,154,146,164,31,107,154,248,38,21,81,147,94,180,235,2,239,75,194,147,252,127,255,231,125,222,143,144,174,246,29,159,177,78,23,187,127,187,219,123,177,219,85,115,240,200,155,52,88,98,35,224,234,
+153,154,195,117,46,203,208,174,142,175,61,92,231,150,51,119,16,83,240,125,154,71,68,226,225,223,180,130,102,199,26,101,78,104,210,172,133,184,224,245,163,239,88,0,175,94,76,35,30,158,68,239,150,4,92,188,86,61,184,206,37,12,129,205,78,44,198,133,65,124,
+105,17,173,91,91,113,224,208,21,195,196,242,135,25,28,119,127,132,203,161,85,1,174,103,78,8,24,214,2,78,245,191,39,191,193,39,222,131,196,6,168,9,15,53,113,25,11,177,24,66,83,227,232,105,138,160,173,229,223,77,24,220,114,241,205,237,215,0,168,50,54,198,
+238,163,51,113,19,182,197,231,160,165,66,255,224,37,136,221,67,184,243,105,23,22,210,196,242,123,189,101,86,25,188,75,241,21,245,89,148,86,161,202,73,147,51,167,83,67,177,88,248,45,150,68,131,48,130,61,156,19,66,238,20,150,69,15,78,159,189,128,249,104,
+20,143,158,60,192,137,230,89,116,184,139,127,104,76,138,39,193,185,189,232,146,111,155,83,47,149,192,42,133,60,132,84,214,20,219,157,185,5,194,53,64,144,82,127,69,232,115,252,58,246,210,59,158,27,64,1,251,48,112,126,24,209,185,57,4,31,222,197,209,13,
+97,116,180,228,141,55,21,158,3,111,175,131,176,148,50,233,43,133,122,10,87,84,136,146,69,205,33,253,108,164,98,221,196,151,99,240,98,12,92,238,12,52,254,32,6,135,174,26,38,110,140,143,194,103,11,67,107,215,140,185,99,165,175,115,13,120,70,34,255,53,115,
+51,211,65,52,33,8,53,29,128,218,232,195,185,225,107,134,9,123,34,94,142,87,130,23,141,204,171,179,126,197,103,33,58,137,66,200,38,251,160,110,62,130,195,61,126,188,125,61,99,169,175,115,217,146,162,33,155,211,170,186,123,205,79,77,208,126,2,43,95,122,
+225,201,103,241,213,66,95,231,178,74,73,133,44,107,107,178,127,71,158,62,174,24,211,185,70,205,229,156,86,243,131,197,168,121,161,168,98,54,83,251,83,77,231,146,206,157,219,70,215,235,79,230,135,0,3,0,71,200,242,251,63,187,157,122,0,0,0,0,73,69,78,68,
+174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_selected04_png = (const char*) temp_64a706f6;
+
+//================== RadioButtons_selected-05.png ==================
+static const unsigned char temp_64b51e77[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,30,0,0,0,19,8,6,0,0,0,135,174,189,124,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,242,73,68,65,84,120,218,188,85,93,72,20,81,20,254,102,118,212,93,93,117,253,163,52,127,211,53,243,167,52,130,10,37,235,37,122,232,7,163,16,234,41,138,18,31,244,33,159,130,222,123,14,42,31,132,126,164,63,159,202,34,136,160,
+20,77,68,197,214,108,93,17,117,215,118,213,214,85,217,93,103,118,119,118,254,154,185,146,32,142,74,16,123,224,114,238,61,223,153,243,205,57,247,222,115,169,106,107,145,11,49,148,181,168,248,154,227,133,251,204,241,194,204,130,59,71,211,98,66,26,140,42,
+104,254,244,171,133,23,214,234,24,202,64,33,62,145,142,9,113,102,34,208,209,80,100,186,214,53,93,195,208,42,113,130,137,142,89,169,179,76,192,190,76,139,184,158,177,145,66,76,69,165,163,41,53,89,198,184,253,248,188,96,220,180,238,99,115,209,25,168,217,
+241,27,109,116,39,156,71,231,74,133,46,70,81,148,70,76,193,16,167,63,134,35,197,168,111,125,140,39,139,21,27,182,196,154,6,52,222,108,193,68,36,123,139,191,109,137,70,80,162,9,118,246,194,37,52,54,181,233,198,213,132,33,236,140,126,169,151,227,11,136,
+110,188,213,134,119,175,30,160,216,180,138,170,234,35,196,246,147,170,196,168,255,32,174,103,246,96,196,67,97,52,90,134,51,87,110,96,216,62,78,240,116,191,31,249,146,3,138,94,108,213,196,104,154,54,108,197,250,231,45,160,115,178,97,31,251,14,81,146,64,
+167,228,128,103,226,8,166,217,206,93,190,74,230,31,95,122,80,126,177,9,141,105,235,87,242,68,221,73,162,109,195,131,40,96,59,64,25,244,183,153,129,20,133,204,45,109,1,148,188,115,168,173,59,141,161,47,221,80,226,205,72,74,223,139,57,231,2,74,212,159,
+240,185,167,32,87,30,34,126,209,172,106,164,166,164,64,86,237,238,201,17,240,180,25,37,165,101,240,255,118,66,166,150,116,73,121,62,162,48,34,31,129,223,23,218,2,86,5,30,193,105,75,70,57,215,139,254,149,42,152,50,242,32,208,73,24,179,141,130,18,66,164,
+10,154,236,201,206,37,115,215,236,12,172,67,173,248,106,105,70,97,177,21,201,194,18,252,1,159,46,113,56,108,80,137,69,25,107,172,222,30,179,72,31,184,71,102,166,236,42,212,214,159,194,135,174,231,96,131,65,48,171,211,27,94,37,165,7,48,229,176,3,1,15,
+137,147,64,57,137,61,149,247,110,19,87,173,166,162,128,16,7,216,93,238,177,111,157,168,172,250,24,22,102,28,56,44,207,110,130,87,28,3,216,239,124,129,128,122,106,74,141,147,112,255,248,134,4,87,15,89,235,137,44,171,196,2,201,88,217,145,215,146,33,18,
+109,54,155,145,33,47,195,231,114,65,26,124,131,32,199,67,204,176,34,223,219,187,17,99,141,85,223,28,215,93,240,59,196,83,52,98,73,84,16,10,239,76,140,201,62,204,181,223,6,239,247,66,242,175,66,59,17,161,183,15,55,224,208,63,54,174,245,82,75,50,56,78,
+217,213,153,179,79,252,183,142,41,255,221,99,46,172,196,172,77,123,162,6,120,217,176,137,225,5,25,227,129,216,188,78,188,12,188,159,143,68,213,42,183,51,110,78,121,230,230,164,152,101,44,72,82,207,226,226,226,211,63,2,12,0,110,51,67,131,64,218,62,45,
+0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_selected05_png = (const char*) temp_64b51e77;
+
+//================== RadioButtons_selected_over-01.png ==================
+static const unsigned char temp_4d6e0f0c[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,19,8,6,0,0,0,241,148,15,247,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,239,73,68,65,84,120,218,196,86,93,72,20,81,20,254,238,236,236,56,179,174,43,91,130,187,130,136,97,81,22,244,3,105,8,134,105,168,245,32,229,147,15,10,25,37,173,81,212,67,15,86,15,65,68,244,212,83,62,244,24,65,68,166,32,18,
+132,63,69,17,82,61,20,171,65,81,216,139,144,238,34,106,59,59,251,51,51,247,118,103,86,130,220,137,149,86,182,129,195,12,115,206,61,223,119,190,57,247,204,37,140,49,4,131,193,75,213,91,188,251,240,31,46,145,131,223,80,138,164,129,211,117,85,82,169,34,
+21,20,124,232,211,34,196,128,207,211,125,251,216,54,169,182,76,228,175,88,65,9,188,248,46,66,84,20,89,218,95,185,193,202,201,218,125,147,120,10,46,2,17,132,64,146,73,110,96,129,96,116,177,12,53,94,13,181,197,26,64,89,222,68,136,69,128,227,67,148,115,
+160,187,128,9,52,162,61,212,139,164,22,193,220,248,45,236,144,99,128,153,159,28,68,224,117,89,15,46,55,113,54,137,155,66,48,229,106,68,195,241,94,184,233,44,148,98,63,202,90,175,99,14,62,219,103,199,184,255,205,8,87,85,176,10,20,68,146,109,86,80,17,193,
+36,175,252,80,27,7,79,77,163,120,246,30,228,31,79,161,120,252,240,31,185,134,175,166,207,142,177,98,29,115,228,48,66,72,70,1,193,149,109,132,7,60,215,27,81,119,244,20,196,228,52,188,159,31,128,252,212,33,127,155,224,36,134,33,91,36,14,95,197,151,180,
+15,2,87,193,41,135,192,55,214,235,121,1,130,69,82,204,246,219,115,192,208,13,70,227,145,236,15,36,11,56,216,220,3,33,254,18,222,240,93,208,24,255,214,122,198,37,133,31,130,166,84,208,202,110,148,52,92,65,120,98,0,123,228,229,76,79,176,181,158,224,13,
+54,164,182,162,165,39,4,246,174,19,44,206,223,27,235,250,197,52,33,234,134,206,86,162,209,236,6,225,178,42,239,67,48,22,194,88,81,121,94,125,157,63,114,31,228,128,10,105,251,25,148,54,221,196,219,209,126,236,116,45,129,165,153,221,89,99,228,36,218,186,
+250,144,142,133,161,174,70,96,68,25,152,241,103,14,35,229,129,200,40,16,83,137,99,243,147,15,51,176,252,160,206,219,148,188,122,132,162,52,133,103,119,31,42,58,6,49,51,28,66,53,91,198,148,208,129,246,174,203,160,218,44,92,111,206,99,101,129,128,38,178,
+55,140,97,80,78,128,75,182,170,10,27,152,62,206,46,97,242,49,252,60,145,103,239,57,84,117,14,226,227,244,24,218,91,206,218,224,169,241,11,72,112,112,61,110,129,103,231,249,77,32,166,230,49,81,120,222,216,179,39,40,79,82,148,212,247,163,206,6,159,193,
+210,200,69,104,11,12,70,130,75,111,58,47,213,51,4,0,45,145,231,72,227,242,106,99,67,8,38,77,148,214,236,194,252,232,29,104,81,10,211,2,167,127,95,102,242,166,180,21,136,199,55,103,184,171,35,195,246,76,128,201,96,234,185,135,164,97,114,5,210,38,85,167,
+34,110,212,151,24,155,244,143,219,120,49,86,15,144,64,32,112,130,63,143,52,87,40,40,47,236,113,0,95,227,156,192,218,137,168,105,171,226,238,226,127,38,185,208,39,162,95,2,12,0,137,200,31,90,212,72,119,82,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_selected_over01_png = (const char*) temp_4d6e0f0c;
+
+//================== RadioButtons_selected_over-02.png ==================
+static const unsigned char temp_4d7c268d[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,216,73,68,65,84,120,218,196,149,79,72,84,65,28,199,191,51,239,237,190,221,183,184,166,22,145,84,70,137,97,90,33,107,218,22,129,18,17,29,162,67,66,209,255,78,117,137,14,29,11,138,200,110,17,116,232,84,80,116,8,73,41,188,164,
+93,182,63,104,148,34,149,186,176,22,37,122,200,63,152,171,187,179,239,173,251,254,52,111,246,80,235,110,82,107,232,240,230,49,204,252,230,247,249,205,124,103,126,67,130,91,202,31,96,153,138,188,110,165,255,116,83,213,234,37,7,183,14,142,67,46,81,101,
+212,151,218,11,91,146,223,27,182,248,22,91,66,223,100,200,84,34,80,188,244,207,86,124,136,184,9,136,146,182,177,231,44,94,57,221,92,28,220,225,202,132,255,220,30,146,219,66,226,96,159,132,110,115,51,214,84,55,138,174,177,112,8,65,41,2,59,110,1,70,254,
+91,64,4,156,47,72,246,228,10,141,7,164,82,244,120,26,16,8,158,128,36,105,162,187,116,125,45,62,188,127,132,128,251,53,16,231,203,183,242,11,64,112,9,135,72,46,146,173,49,223,230,94,115,19,170,56,152,90,227,80,223,54,11,173,217,206,43,168,172,59,137,143,
+93,81,212,20,124,2,209,204,188,206,128,195,165,132,240,159,156,89,37,133,96,194,229,71,69,227,5,46,121,20,254,222,102,208,4,3,213,24,252,61,55,32,145,4,202,119,157,195,8,10,33,169,18,168,43,219,135,211,39,121,210,53,215,184,224,166,197,207,172,196,77,
+193,54,28,231,109,47,92,159,31,3,90,2,148,91,58,149,232,12,174,225,167,188,77,225,13,92,4,83,228,180,243,121,62,98,252,192,116,36,131,248,46,21,130,186,179,199,197,61,135,57,7,139,77,100,238,73,138,160,192,231,3,134,159,193,243,229,57,108,211,206,216,
+89,37,220,130,184,186,17,74,113,29,194,174,61,168,213,91,120,128,246,47,253,121,48,253,5,71,80,87,127,20,214,208,29,88,35,33,238,115,158,54,166,9,217,72,234,136,78,38,178,52,119,183,159,17,190,162,86,110,205,148,55,87,161,31,184,143,178,170,38,116,191,
+232,66,117,162,15,150,19,0,159,219,75,106,176,189,225,16,76,109,0,158,72,11,162,51,124,194,60,63,70,82,229,112,195,66,44,78,254,253,196,176,24,188,47,175,131,238,187,133,242,189,215,16,110,59,139,50,250,3,17,182,2,149,199,46,67,150,116,24,157,151,16,
+29,35,176,83,217,211,29,174,128,207,228,3,231,37,54,48,128,194,162,123,240,4,206,99,237,193,187,136,12,190,66,197,182,253,80,20,31,180,190,219,152,253,154,128,161,147,156,183,65,192,83,98,229,249,39,139,88,199,19,172,226,89,175,120,247,41,108,221,113,
+152,175,120,22,147,161,155,152,126,23,130,33,206,65,238,121,14,87,54,121,150,74,104,139,72,214,60,247,176,246,86,140,116,182,65,45,41,130,30,157,134,153,180,97,25,88,240,254,59,92,217,48,45,48,246,31,94,138,152,141,217,169,169,116,251,47,220,57,92,161,
+57,211,236,37,127,82,133,230,201,148,133,254,25,186,228,112,135,43,143,50,251,225,40,51,177,28,229,167,0,3,0,110,188,26,228,110,165,221,163,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_selected_over02_png = (const char*) temp_4d7c268d;
+
+//================== RadioButtons_selected_over-03.png ==================
+static const unsigned char temp_4d8a3e0e[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,101,73,68,65,84,120,218,196,150,61,143,211,64,16,134,223,89,111,226,195,7,220,33,78,66,128,34,16,80,5,209,32,1,66,162,165,161,166,160,65,80,208,242,51,248,13,84,72,92,139,104,168,40,40,174,58,10,26,78,66,87,33,133,143,0,34,
+137,20,146,216,107,39,142,215,203,172,147,226,108,135,128,41,114,43,37,78,188,51,243,236,188,51,187,54,221,108,94,122,142,67,26,178,177,117,252,193,221,203,167,86,14,126,185,223,129,60,233,73,220,56,99,86,14,223,249,36,33,133,67,112,143,136,242,44,21,
+174,197,97,10,215,138,195,114,37,241,87,125,173,64,144,132,221,225,9,248,114,99,105,240,116,28,226,206,86,23,152,86,95,1,101,112,78,90,174,21,82,94,23,56,125,245,33,174,157,187,242,247,166,217,121,4,4,105,101,9,50,46,9,130,83,163,188,220,158,128,235,
+74,252,104,189,65,83,190,227,20,169,84,146,47,73,3,27,23,239,195,177,37,139,25,110,168,34,220,102,78,4,33,243,112,226,255,105,106,16,169,4,102,244,25,52,77,243,229,118,4,166,199,182,178,223,14,203,103,172,127,69,229,45,87,206,138,159,207,138,230,253,
+103,23,32,248,83,12,76,198,64,207,213,176,190,198,89,172,250,94,111,29,231,55,199,216,172,235,133,243,18,58,70,170,186,7,151,196,17,9,113,20,160,142,241,108,46,41,120,114,182,177,244,145,106,13,29,253,4,148,93,96,217,166,215,184,135,142,255,21,183,227,
+87,92,154,194,60,251,202,100,50,198,160,23,230,51,27,18,46,196,79,96,194,16,131,95,62,75,80,88,50,103,26,50,60,225,0,126,191,3,221,71,201,134,92,1,239,172,135,4,46,70,237,30,39,145,135,39,19,143,225,73,10,63,40,52,139,98,231,65,151,147,49,229,102,179,
+129,107,124,91,207,104,97,200,42,4,101,59,193,211,130,21,36,50,240,21,247,80,144,143,97,185,25,124,24,252,169,83,23,223,23,53,147,57,219,241,246,155,135,81,79,115,127,228,109,92,143,213,187,158,102,181,14,88,216,169,202,55,101,6,159,102,153,87,107,85,
+81,199,172,83,121,220,122,252,122,169,237,247,253,22,2,86,50,83,231,0,198,114,165,230,102,10,163,138,7,68,12,28,253,184,11,209,220,230,147,202,192,164,139,183,146,165,209,251,23,240,71,188,59,162,60,220,114,101,194,181,83,170,234,38,5,162,150,66,255,
+233,51,62,35,150,31,110,188,153,144,140,121,129,186,80,115,61,175,185,138,254,243,233,48,250,71,191,5,102,89,205,39,124,122,125,24,138,149,63,82,45,87,182,149,217,110,43,125,40,111,50,191,5,24,0,98,67,27,130,54,13,67,66,0,0,0,0,73,69,78,68,174,66,96,
+130,0,0 };
+
+const char* BinaryData::RadioButtons_selected_over03_png = (const char*) temp_4d8a3e0e;
+
+//================== RadioButtons_selected_over-04.png ==================
+static const unsigned char temp_4d98558f[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,31,0,0,0,19,8,6,0,0,0,104,108,214,66,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,2,211,73,68,65,84,120,218,196,150,205,75,20,97,28,199,191,207,204,179,186,179,187,90,90,184,100,25,26,43,149,122,176,64,74,33,37,148,204,50,12,234,84,135,110,65,151,110,29,252,51,58,132,208,169,46,5,33,228,91,210,139,96,16,
+145,93,180,178,14,97,104,33,42,235,186,235,174,59,179,187,243,246,60,61,179,43,184,57,219,69,86,125,96,102,96,158,121,158,207,247,247,250,12,105,109,8,61,193,62,13,90,115,184,252,206,205,198,224,158,131,7,127,132,65,15,249,40,206,85,243,61,135,79,46,
+80,80,73,38,40,85,164,194,95,144,205,231,46,104,115,184,148,136,91,137,151,184,38,103,55,124,248,109,6,208,17,140,162,156,48,192,22,10,88,241,224,36,11,23,70,83,175,219,100,45,120,9,221,237,125,152,159,155,198,244,247,55,56,31,152,71,128,217,128,133,
+162,184,35,203,37,18,129,236,33,46,119,123,60,50,52,53,140,234,234,74,156,168,239,199,194,175,25,68,126,78,160,197,63,135,114,238,120,130,229,248,124,167,112,199,114,66,32,81,55,220,185,82,106,12,33,227,49,82,122,39,42,42,27,81,119,245,1,214,99,203,248,
+244,121,24,77,100,6,199,21,27,220,218,153,35,28,46,205,5,191,112,162,49,198,33,165,117,148,173,140,160,172,100,2,42,235,22,139,78,162,173,231,30,98,209,37,140,77,141,160,217,243,5,53,66,68,54,39,182,9,88,207,72,248,147,84,208,124,36,37,54,115,231,12,
+133,109,128,105,171,219,101,193,235,51,96,100,84,112,117,25,44,206,178,177,86,194,3,168,13,4,144,172,189,134,12,59,141,182,203,119,17,93,91,196,224,199,65,156,149,166,80,231,55,192,77,228,64,98,188,85,123,112,240,88,8,220,243,72,236,35,94,164,243,232,
+182,13,106,233,25,196,35,41,151,91,78,101,6,64,82,85,72,172,133,133,184,60,213,68,8,157,127,136,163,10,129,114,230,58,86,104,7,46,244,222,199,218,106,31,158,127,120,134,38,243,61,106,60,58,184,33,22,248,189,80,252,10,82,198,50,44,85,134,29,219,218,223,
+210,125,2,110,49,36,85,119,169,137,108,3,9,11,203,185,3,46,48,159,0,54,222,13,225,64,233,48,148,150,62,176,64,59,58,111,244,35,186,122,11,227,66,68,200,152,132,167,2,144,101,9,134,45,33,157,38,48,213,60,184,224,102,225,137,66,112,87,167,249,255,116,226,
+245,144,40,215,97,200,109,189,176,43,46,162,203,17,17,185,141,170,200,18,188,94,9,122,66,130,150,22,2,84,254,47,220,204,90,94,132,22,38,113,196,71,71,33,123,199,96,117,244,192,14,118,161,190,161,21,209,240,55,232,134,4,85,117,170,103,139,227,112,169,
+109,113,164,210,69,236,159,73,142,228,203,87,66,196,56,202,58,175,192,79,85,68,23,8,212,117,6,61,143,227,112,169,37,154,133,166,237,66,243,222,224,248,250,98,12,114,73,174,166,109,131,131,153,121,49,183,55,99,174,165,119,249,84,35,238,30,144,141,185,
+110,50,204,38,164,61,63,82,29,46,93,212,248,211,69,205,222,151,63,153,191,2,12,0,199,181,70,142,38,155,205,86,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_selected_over04_png = (const char*) temp_4d98558f;
+
+//================== RadioButtons_selected_over-05.png ==================
+static const unsigned char temp_4da66d10[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,30,0,0,0,19,8,6,0,0,0,135,174,189,124,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,
+100,121,113,201,101,60,0,0,3,94,73,68,65,84,120,218,188,85,93,104,19,89,20,254,238,204,157,100,38,77,108,173,105,107,250,71,45,117,101,119,117,65,163,86,65,65,80,31,84,16,138,34,203,10,250,164,176,248,226,155,111,203,62,238,211,190,44,136,136,15,46,138,
+15,190,46,116,5,65,42,42,34,40,162,134,86,219,90,163,77,77,39,177,209,73,50,153,76,146,153,241,100,82,139,109,38,138,15,102,224,48,247,156,123,238,249,238,249,206,185,247,178,157,63,13,93,70,19,191,148,110,206,235,102,249,47,222,23,94,117,242,232,207,
+93,77,1,117,108,27,127,223,139,27,102,57,183,139,175,9,112,12,119,59,77,202,151,225,210,200,58,229,248,245,233,205,92,16,25,252,138,240,61,48,40,197,122,115,135,2,244,132,219,42,156,17,176,79,102,222,139,63,237,199,89,148,170,206,89,109,92,113,60,3,187,
+128,228,195,72,156,170,143,151,31,249,8,140,130,113,217,67,2,12,188,93,196,125,61,8,30,20,192,21,210,87,139,136,41,131,24,117,118,212,230,101,246,217,154,69,157,236,82,7,199,195,200,175,248,223,138,46,250,45,143,205,24,171,2,51,136,210,10,241,145,4,4,
+196,67,63,34,122,226,31,140,150,182,66,8,9,144,218,57,194,91,126,195,190,145,211,72,135,250,92,31,81,174,249,138,109,34,38,45,9,133,144,132,249,80,47,54,69,247,99,239,145,51,16,253,245,241,225,146,82,69,231,172,142,10,214,34,160,20,92,231,170,123,14,
+255,142,187,55,207,99,136,127,64,123,120,208,181,37,90,135,241,52,99,226,64,235,13,76,105,2,230,165,109,216,112,224,24,212,76,28,2,37,227,43,230,209,89,124,184,68,253,202,248,220,45,165,184,162,6,180,171,113,179,19,66,75,63,50,233,73,88,150,13,121,77,
+31,108,191,228,78,23,242,211,216,240,203,65,119,60,254,100,14,29,187,79,162,195,23,114,245,174,200,70,247,63,51,249,8,107,231,175,214,128,197,250,86,224,176,74,176,245,212,114,171,44,192,233,57,132,181,221,155,241,122,98,20,82,160,21,242,170,110,100,
+242,42,130,150,5,35,59,1,89,169,177,225,143,108,135,40,6,96,147,93,95,184,75,134,126,180,4,251,241,94,157,129,157,163,184,78,125,7,154,102,209,225,21,179,136,15,233,194,242,25,218,97,127,225,60,18,80,16,121,127,19,111,74,195,212,96,131,112,4,5,201,185,
+9,136,197,12,42,97,171,6,44,71,80,33,208,133,119,9,244,62,62,135,153,129,179,240,175,239,129,98,188,165,184,41,207,206,55,12,145,128,43,54,114,121,143,227,148,205,35,48,251,39,108,106,42,190,41,138,222,129,40,94,63,79,32,151,205,34,100,188,90,114,243,
+201,93,72,171,211,48,212,41,104,170,0,83,153,2,214,3,10,177,152,203,121,31,83,135,88,112,129,181,124,131,115,76,141,39,217,128,165,189,116,213,214,206,40,230,94,62,193,128,57,177,204,77,141,141,161,43,118,5,26,141,59,91,198,161,190,184,13,223,244,45,
+104,21,239,184,182,77,192,101,55,227,198,87,166,80,34,230,179,197,165,150,240,229,146,72,60,155,69,120,245,85,20,202,37,152,129,31,16,142,143,65,211,22,137,138,197,129,216,31,181,210,58,78,131,59,155,128,45,186,89,10,70,99,96,102,18,248,131,59,120,155,
+58,5,35,147,70,49,149,65,117,27,218,181,139,85,66,220,216,142,237,125,61,54,124,44,92,170,233,168,232,250,87,86,17,35,217,133,231,223,20,252,75,159,253,169,198,186,225,52,237,61,78,148,68,168,121,67,225,102,217,198,51,77,104,10,168,73,37,249,111,174,
+88,34,150,47,240,89,221,249,119,86,183,154,150,113,217,178,198,146,201,228,229,143,2,12,0,249,150,92,255,88,186,243,251,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::RadioButtons_selected_over05_png = (const char*) temp_4da66d10;
+
+//================== noise_wave.png ==================
+static const unsigned char temp_9db0b117[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,4,101,0,0,2,30,8,6,0,0,0,18,223,178,102,0,0,0,9,112,72,89,115,0,0,23,18,0,0,23,18,1,103,159,210,82,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,
+97,100,121,113,201,101,60,0,0,76,229,73,68,65,84,120,218,236,221,235,149,21,55,214,48,96,13,203,255,221,95,4,212,68,64,59,2,202,17,24,71,48,77,4,47,142,192,77,4,120,34,160,39,2,112,4,20,17,24,34,112,57,2,67,4,243,181,56,167,135,6,250,114,46,117,145,180,
+159,103,173,90,96,3,125,78,237,146,84,210,46,149,244,143,4,0,0,0,172,229,228,242,56,189,60,186,237,113,155,225,242,248,112,121,188,19,50,0,0,0,128,253,229,36,204,217,229,241,242,242,248,243,242,248,239,1,199,155,203,227,60,109,146,57,0,0,0,0,220,225,
+236,242,120,149,14,75,194,220,117,228,196,206,121,186,123,150,13,0,0,0,64,40,121,86,204,121,58,124,70,204,190,71,158,125,211,9,59,0,0,0,16,217,217,229,241,119,90,38,25,35,57,3,0,0,0,132,151,215,121,249,35,173,147,140,185,126,228,132,208,51,151,3,0,0,
+0,136,32,39,65,254,91,216,145,23,5,62,113,105,0,0,0,128,22,229,164,71,126,101,232,191,133,30,121,214,140,157,154,0,0,0,128,166,228,132,76,9,175,43,237,146,152,57,115,185,0,0,0,128,22,212,146,144,185,126,156,185,108,0,0,0,64,205,106,76,200,92,29,79,92,
+62,0,0,0,160,86,175,82,157,9,25,107,204,0,0,0,0,213,122,145,234,77,200,92,29,127,38,187,50,1,0,0,0,21,233,83,253,9,153,235,219,101,179,162,127,8,1,0,5,56,221,30,221,229,241,40,221,253,212,230,221,229,241,241,242,24,182,191,255,32,124,0,192,66,114,31,
+165,181,25,38,191,93,30,191,184,180,0,16,171,67,115,118,121,188,76,155,119,154,143,121,194,147,23,216,203,83,136,189,23,13,0,204,173,133,215,150,236,200,4,0,65,229,196,201,20,137,152,187,222,141,126,150,188,31,13,0,76,175,75,109,38,100,44,252,11,0,141,
+235,211,230,157,229,37,59,22,231,73,114,6,0,152,206,146,125,25,11,255,2,0,71,203,55,246,151,105,221,167,62,207,92,6,0,224,72,93,106,59,33,99,225,95,0,104,204,89,154,239,53,165,67,58,24,157,75,2,0,28,104,205,135,76,75,31,47,92,110,0,168,215,218,179,99,
+238,154,53,115,230,242,0,0,7,244,109,74,121,208,100,225,95,0,224,86,93,218,236,134,228,233,15,0,208,138,179,20,43,33,99,225,95,0,168,208,105,170,231,41,210,75,151,11,0,216,209,171,20,47,41,99,225,95,0,168,72,77,9,25,137,25,0,96,87,39,41,102,66,198,194,
+191,0,80,137,46,213,251,158,181,196,12,0,112,151,103,41,118,82,198,171,223,0,80,176,252,244,168,244,53,100,238,59,206,93,70,0,224,22,181,247,115,44,252,11,0,13,107,229,29,235,39,46,37,0,240,149,46,73,198,88,248,23,0,10,117,214,88,71,195,66,118,0,192,
+117,94,93,178,240,47,0,20,169,75,245,174,35,115,219,241,202,101,5,0,174,241,234,146,133,127,1,160,72,173,110,13,217,187,180,0,64,218,188,170,35,9,99,225,95,0,40,78,159,218,158,150,11,0,240,34,73,190,88,248,23,0,10,212,250,84,94,157,12,0,224,207,36,241,
+98,225,95,0,40,204,89,138,177,136,29,0,16,151,87,151,44,252,11,0,197,57,73,113,158,26,245,46,55,0,132,229,213,37,11,255,2,64,113,206,3,117,48,94,186,220,0,16,86,107,59,76,90,248,23,0,42,215,5,235,160,252,237,146,3,64,72,79,36,89,172,201,7,0,165,121,25,
+176,115,241,196,101,7,0,125,30,135,133,127,1,96,77,125,208,206,133,87,152,0,32,30,175,46,89,248,23,0,138,242,38,197,125,226,3,0,196,225,213,37,11,255,2,64,81,206,130,119,44,188,194,4,0,113,188,146,84,177,240,239,210,254,33,4,124,165,79,155,41,103,87,
+239,3,62,76,155,5,62,179,119,151,199,199,107,191,31,183,191,2,109,202,109,193,31,215,218,128,136,126,187,60,126,81,20,0,32,68,191,199,44,217,233,60,189,60,46,132,1,238,151,147,47,47,182,3,175,99,166,168,61,75,22,118,130,214,156,39,79,122,254,84,12,0,
+32,132,51,253,30,11,255,194,82,186,109,34,230,207,153,6,48,57,65,99,129,39,168,191,157,176,208,221,230,208,161,0,128,246,121,117,201,194,191,176,200,32,107,201,45,222,94,166,216,175,61,64,205,108,7,233,189,104,0,136,226,68,127,199,194,191,48,119,35,179,
+230,0,235,60,201,144,66,77,122,29,8,175,48,1,64,32,207,244,119,60,224,130,57,27,152,18,94,65,200,223,193,46,38,80,135,168,91,96,123,133,9,0,98,58,102,125,77,135,29,45,225,70,121,102,74,137,239,69,190,76,102,205,64,201,206,116,26,110,60,158,41,26,0,208,
+164,78,63,199,194,191,48,181,92,216,255,44,184,66,254,33,49,3,69,58,41,188,237,88,187,221,2,0,218,227,213,37,227,64,152,60,33,83,195,142,41,50,165,80,158,115,157,133,59,143,78,17,1,128,230,120,117,105,217,227,149,34,135,132,140,196,12,240,173,46,217,
+2,219,43,76,0,16,111,252,164,143,179,206,70,48,32,33,35,49,3,92,99,11,108,175,48,1,64,52,47,244,111,44,252,11,83,232,82,221,79,184,243,26,22,222,45,132,245,244,58,6,59,31,218,42,0,104,135,181,244,60,156,135,163,229,1,66,11,239,65,90,244,9,214,99,11,236,
+221,143,51,197,5,0,154,224,213,37,99,64,152,196,139,228,213,0,224,112,103,58,4,22,167,3,0,227,40,135,190,21,236,175,111,176,82,190,116,89,97,81,166,237,122,133,9,0,34,178,193,129,133,127,193,96,74,98,6,86,117,174,19,224,21,38,0,8,232,137,254,140,133,
+127,193,96,202,214,179,176,166,60,219,195,19,34,137,99,0,136,200,174,147,22,254,5,131,169,228,105,52,232,140,212,219,105,0,0,234,229,193,148,133,127,225,40,231,201,52,54,224,112,118,27,208,54,1,64,84,94,93,178,240,47,28,45,210,194,156,166,177,193,244,
+108,129,237,21,38,0,136,234,149,126,140,133,127,225,24,17,51,187,18,51,160,13,241,10,19,0,112,172,19,125,24,179,146,75,243,64,189,172,206,191,130,54,158,175,146,247,11,97,10,47,132,96,178,118,169,23,6,0,168,138,215,143,235,145,103,37,135,120,48,47,41,
+163,33,169,69,151,54,175,92,72,204,192,225,206,183,117,137,105,252,36,4,0,224,222,205,44,242,184,239,165,241,31,165,233,147,105,108,127,40,6,112,240,141,205,78,3,211,30,127,42,86,0,80,85,95,72,255,197,194,191,197,49,83,166,190,164,76,116,121,10,155,5,
+54,97,127,47,146,39,13,83,235,146,245,174,0,160,22,103,66,80,165,252,166,200,185,48,80,10,59,166,216,249,4,14,97,11,236,249,14,107,244,0,64,29,254,208,111,169,250,232,21,97,74,224,213,131,47,143,103,138,4,236,68,66,215,43,76,0,16,89,167,207,162,207,85,
+42,175,47,213,213,144,120,245,224,75,249,9,245,153,48,192,157,242,148,207,94,24,102,109,155,59,97,0,128,226,251,67,212,223,231,58,111,241,196,36,101,234,97,221,130,155,189,212,200,194,157,188,94,163,163,7,0,209,253,75,8,154,240,127,169,193,135,97,146,
+50,245,120,44,4,183,10,179,135,61,236,233,60,153,197,161,163,7,0,177,157,26,43,52,35,191,57,242,107,107,39,37,41,83,87,99,194,237,149,243,141,24,193,55,245,226,255,132,97,177,246,185,19,6,0,40,146,135,39,109,57,75,141,45,235,33,41,83,143,94,8,238,29,
+128,190,73,214,221,129,43,182,192,94,150,87,152,0,192,61,154,101,52,181,225,139,164,76,29,204,0,217,141,196,12,124,110,51,206,132,97,81,63,9,1,0,20,217,39,234,132,161,57,77,205,126,146,148,169,167,49,97,247,88,73,204,16,157,197,125,151,215,107,119,0,
+192,224,157,69,116,45,141,145,37,101,234,240,72,8,246,114,106,80,74,96,125,242,186,227,90,76,143,6,128,178,156,9,65,179,154,73,184,73,202,212,193,76,153,195,26,224,151,194,64,64,202,253,122,188,194,4,0,229,200,15,75,204,98,109,87,47,4,44,233,191,142,
+131,143,115,197,135,64,158,169,243,171,31,58,127,0,80,134,151,250,37,250,93,53,48,83,166,124,102,201,28,39,239,99,127,38,12,4,112,178,45,239,172,171,23,2,0,40,130,215,138,141,149,171,32,41,163,160,69,144,179,228,103,194,64,227,114,66,198,44,141,245,121,
+133,9,0,214,231,213,37,99,229,106,72,202,148,207,34,191,211,120,145,36,184,104,87,151,54,175,46,81,70,39,16,0,88,151,93,151,98,240,250,18,139,232,133,96,178,10,155,183,202,150,152,161,69,22,247,45,171,173,145,152,1,0,247,98,230,247,184,133,147,144,148,
+41,159,36,194,180,13,244,155,100,42,35,109,233,147,228,109,105,188,194,4,0,235,145,144,161,42,146,50,229,15,182,152,150,196,12,173,49,75,70,103,16,0,248,204,195,17,170,34,41,83,54,179,100,230,139,171,196,12,45,200,235,200,116,194,80,156,19,237,55,0,172,
+118,15,246,112,132,170,72,202,148,205,34,191,243,201,3,166,23,194,64,229,157,14,91,96,151,203,2,131,0,176,188,51,33,160,54,146,50,101,243,164,117,254,70,219,171,31,212,202,22,216,101,243,148,14,0,150,231,161,8,213,145,148,41,155,164,204,252,206,46,143,
+115,97,160,50,93,178,5,118,13,215,72,27,14,0,238,189,204,231,67,11,39,33,41,83,174,94,8,22,147,103,28,156,9,3,21,49,195,171,14,158,214,1,192,114,204,82,141,231,125,11,39,33,41,83,46,89,222,229,7,185,103,194,64,5,250,36,105,91,211,181,2,0,150,225,97,72,
+60,99,11,39,33,41,83,46,139,252,46,47,47,252,43,25,70,233,204,146,169,71,110,79,58,97,0,128,69,238,185,250,241,241,140,45,156,132,164,76,217,13,11,203,202,139,166,190,17,123,10,102,11,236,250,152,74,13,0,243,51,75,38,166,161,133,147,248,135,235,88,172,
+255,10,193,106,242,130,81,255,76,141,44,28,69,51,114,210,240,207,100,199,165,218,188,187,60,126,16,6,0,152,85,238,35,117,194,16,202,112,121,252,216,194,137,152,41,83,166,94,8,86,31,252,190,49,248,165,48,182,192,174,147,87,152,0,192,189,150,233,253,222,
+202,137,72,202,148,169,23,130,34,26,119,137,25,74,145,59,26,182,192,174,151,87,152,0,96,62,94,93,138,233,117,43,39,34,41,83,38,139,252,150,65,98,134,82,88,220,183,110,143,133,0,0,102,115,38,4,225,228,215,195,199,86,78,70,82,166,220,100,0,229,92,139,63,
+92,19,86,212,39,179,231,106,151,103,202,72,238,2,128,123,236,156,222,5,58,215,127,183,116,50,146,50,229,201,141,74,39,12,69,201,215,35,207,152,57,19,10,86,240,66,8,154,233,52,2,0,211,250,73,8,62,185,184,60,126,78,49,54,42,201,231,248,186,165,19,146,148,
+41,143,25,25,101,202,201,178,151,201,107,36,44,235,76,155,160,211,8,0,220,202,67,143,141,188,232,237,152,54,137,153,214,229,89,50,118,201,101,86,231,105,179,29,182,163,220,35,191,206,100,154,36,115,203,101,236,111,245,173,169,3,0,152,54,33,163,127,177,
+233,47,94,247,172,241,115,109,110,28,102,166,76,121,44,242,91,190,60,115,225,207,100,157,15,230,245,44,73,254,181,216,121,4,0,166,97,215,165,141,175,95,229,249,45,109,94,103,106,209,47,201,44,25,22,144,7,251,50,190,245,28,182,41,102,14,157,186,213,228,
+225,245,71,0,152,198,137,126,197,255,142,39,183,196,231,143,198,206,243,141,98,143,198,197,113,215,64,203,140,6,166,244,74,189,10,49,189,24,0,56,204,153,126,197,167,227,207,59,98,212,165,118,94,133,255,59,53,188,25,142,215,151,202,98,65,207,122,111,10,
+111,92,63,38,210,39,175,185,180,234,196,181,5,128,73,88,64,127,227,174,93,136,198,212,206,194,191,79,183,231,3,179,59,79,178,189,181,103,112,13,184,56,214,27,117,201,43,76,0,192,173,188,93,240,249,216,229,161,112,237,11,255,190,80,228,49,24,115,236,123,
+156,43,202,28,168,87,127,66,79,51,6,0,218,79,50,172,209,167,120,153,60,204,130,157,216,254,182,173,133,168,172,51,195,190,172,37,227,169,22,0,112,183,214,22,176,93,106,6,73,109,137,25,9,25,22,215,105,88,154,204,94,27,124,161,13,112,152,134,11,0,250,75,
+83,31,221,1,241,171,37,49,19,42,33,99,161,223,114,24,188,183,121,211,200,153,252,51,161,96,7,214,35,114,173,1,0,247,208,93,188,75,135,45,124,155,23,204,253,165,240,115,123,190,253,158,97,72,202,148,67,82,166,93,47,147,233,119,220,207,46,2,113,116,218,
+124,0,56,200,191,132,224,147,255,28,241,111,127,187,60,126,188,60,62,20,118,78,249,251,228,221,162,206,93,94,214,98,145,223,246,143,63,210,97,211,12,105,159,93,4,44,8,14,0,220,237,84,255,225,168,87,151,110,234,127,150,178,158,225,171,20,120,61,78,51,
+101,202,106,100,104,255,26,231,196,76,47,20,124,69,153,136,199,204,40,0,216,143,89,50,27,135,190,186,244,181,171,153,41,63,78,244,243,14,49,110,191,195,207,169,188,153,59,139,145,148,41,67,151,236,212,19,69,190,206,121,86,212,51,161,224,26,73,217,152,
+215,188,19,6,160,177,62,78,94,239,227,60,109,158,122,231,254,206,109,59,139,190,217,30,249,239,158,105,15,217,145,245,100,54,254,61,241,207,27,46,143,127,166,205,58,46,227,66,231,48,110,63,47,127,238,107,151,148,82,26,24,211,240,226,29,161,167,233,241,
+5,91,97,199,60,36,103,129,218,229,100,74,222,81,110,138,45,138,243,174,149,47,13,188,185,133,87,151,62,31,115,143,31,158,204,216,55,125,165,142,83,170,115,141,75,232,117,102,204,146,224,15,117,33,108,253,7,168,209,217,204,247,174,63,183,253,99,15,175,
+184,242,66,191,225,127,73,141,165,156,108,235,250,203,109,157,60,38,217,122,166,62,223,238,31,66,80,132,60,125,179,23,134,176,242,251,147,121,250,158,169,123,113,253,87,8,194,202,211,118,71,97,0,42,145,7,86,191,166,229,94,55,202,125,164,252,170,198,111,
+41,240,122,19,124,242,183,65,253,39,121,204,112,177,210,103,231,248,159,110,143,171,107,241,232,218,239,223,94,171,183,87,235,222,232,227,236,64,82,70,35,67,57,114,135,227,23,97,8,73,82,70,231,10,160,100,125,218,60,237,238,86,250,252,60,200,123,190,237,
+43,69,114,53,8,190,186,6,95,123,183,141,77,235,131,223,171,215,105,72,233,255,37,9,74,152,156,247,35,29,95,47,124,39,65,23,175,163,171,236,155,134,12,80,106,82,160,164,215,70,222,164,182,23,5,206,231,246,108,123,111,216,247,117,145,191,211,231,197,147,
+91,123,53,254,165,254,194,167,227,165,38,9,230,113,166,129,113,164,111,223,189,180,206,140,164,140,195,130,125,0,107,202,125,145,18,215,60,251,123,219,127,110,41,241,245,108,134,88,255,185,77,168,181,144,196,250,91,95,225,211,97,129,92,152,137,69,171,
+28,183,29,103,170,71,8,231,202,186,186,174,26,0,133,121,82,193,64,248,69,229,49,206,201,146,165,102,128,212,188,126,165,93,106,63,39,35,129,153,188,209,200,56,146,105,138,146,50,14,175,48,1,148,225,76,63,105,86,39,105,189,215,113,242,184,163,182,217,
+216,175,146,126,130,49,1,204,76,35,227,216,101,219,220,78,85,105,150,206,134,195,66,207,128,132,76,140,193,106,126,77,169,132,25,72,47,82,29,175,206,158,232,31,120,117,9,230,102,145,95,199,62,83,22,123,85,166,73,102,203,57,116,182,128,18,212,252,154,
+72,233,137,153,147,2,239,247,53,172,97,120,150,244,15,174,174,21,13,123,32,4,171,39,101,96,159,155,249,185,80,52,167,19,2,46,253,36,4,192,202,125,210,154,95,143,56,75,229,174,207,117,186,29,84,247,5,246,63,254,72,101,175,107,230,222,184,241,90,8,96,62,
+22,249,117,28,186,254,132,221,90,218,225,245,60,175,112,89,192,15,88,123,112,222,202,238,54,165,61,240,60,171,36,110,47,10,45,151,250,253,101,150,107,38,246,157,16,172,74,5,227,16,79,182,55,170,167,151,199,59,225,168,190,35,28,221,47,219,56,68,127,125,
+231,100,27,131,40,79,195,78,183,71,190,246,15,239,168,11,227,229,241,215,182,173,123,183,253,111,96,218,182,167,165,135,61,249,92,126,184,60,62,20,146,144,169,101,246,209,179,109,25,120,90,88,127,151,205,125,79,127,31,102,36,243,235,56,246,201,186,27,
+86,221,250,100,214,215,213,160,64,157,174,127,123,215,251,6,126,103,219,107,254,247,145,237,222,203,237,207,50,99,16,142,215,226,186,102,37,180,165,103,201,218,60,199,250,67,191,160,249,190,1,172,206,34,191,142,169,142,51,213,169,90,79,130,151,221,174,
+241,129,129,133,252,54,101,124,174,215,211,174,18,52,189,166,4,14,178,214,182,204,173,191,238,209,235,87,30,173,211,39,184,177,175,4,76,236,153,70,198,33,49,19,222,121,242,228,71,155,216,230,123,227,103,219,36,211,82,113,123,35,57,3,238,63,95,181,9,107,
+37,19,90,88,159,103,237,246,84,159,224,243,186,123,192,140,94,106,104,28,18,51,225,189,80,94,191,232,200,170,199,245,79,83,238,211,186,83,206,223,36,79,21,97,151,164,105,132,246,116,141,196,66,43,175,220,228,196,210,154,175,136,254,153,244,7,254,187,
+77,78,1,26,109,135,14,8,51,122,163,172,106,23,83,27,175,48,157,20,150,100,60,215,188,192,141,34,189,62,191,244,108,153,243,198,226,247,74,25,245,234,18,180,78,67,227,152,235,201,134,6,92,82,166,214,142,134,233,202,117,190,194,116,90,104,66,237,77,178,
+24,48,124,93,87,91,217,250,186,180,135,85,93,163,241,91,99,67,137,200,179,136,189,186,4,11,234,53,52,14,141,56,193,203,105,164,78,109,203,211,149,207,10,31,228,253,157,218,89,167,7,142,113,146,98,206,70,92,106,182,76,171,15,89,214,152,189,233,213,37,
+203,18,192,34,60,13,118,152,186,79,228,164,204,223,58,99,77,36,86,207,42,42,111,189,230,6,9,25,175,203,206,164,215,167,156,140,87,151,62,31,102,122,194,204,44,242,235,240,26,19,125,224,242,121,215,147,75,211,150,235,120,143,252,44,121,234,8,250,157,102,
+203,164,212,254,171,200,127,43,171,97,214,243,97,37,15,132,96,21,166,82,51,183,156,93,255,85,24,40,212,135,59,254,236,63,194,243,201,147,130,191,219,217,182,227,92,155,23,238,191,4,244,34,73,72,246,105,190,217,50,115,254,236,146,250,148,75,149,161,39,
+170,236,39,191,11,1,204,79,6,216,225,105,59,145,95,99,60,191,39,54,94,97,42,247,21,166,62,153,69,8,181,56,211,150,206,62,91,38,202,253,106,137,123,210,19,229,212,171,75,81,153,41,179,78,135,22,150,98,182,76,185,220,112,111,247,90,8,62,205,232,56,41,176,
+204,190,106,160,222,189,82,255,8,32,15,112,95,10,195,23,253,239,169,251,224,103,41,78,146,247,116,129,115,253,73,49,253,228,34,221,61,163,152,6,73,202,172,211,168,193,82,34,117,24,106,243,48,240,185,15,247,252,185,105,187,159,7,85,37,105,37,153,145,239,
+195,18,214,180,222,215,148,144,249,214,175,133,255,188,232,247,36,175,46,233,3,133,37,41,179,188,71,193,207,127,84,4,22,119,38,4,69,234,132,224,86,67,242,148,40,43,233,169,97,126,221,174,111,40,182,173,157,15,92,201,137,211,55,201,108,176,155,244,19,
+214,251,179,128,247,241,57,239,73,103,202,236,39,185,239,99,182,48,44,32,250,90,9,209,183,101,92,227,248,83,181,211,22,164,250,222,149,182,3,67,57,239,149,231,239,240,183,182,17,170,72,200,232,99,205,191,182,204,73,224,123,248,92,94,41,155,159,14,51,
+220,130,50,83,102,249,155,101,23,248,252,135,109,6,248,199,203,227,157,226,176,152,92,230,188,54,87,230,117,137,106,151,89,48,166,239,110,148,48,157,251,69,106,243,9,102,174,131,207,20,49,26,242,210,253,254,94,125,58,126,182,204,179,192,247,240,190,178,
+159,91,27,125,159,160,36,101,150,21,253,70,249,238,218,128,44,39,102,46,20,137,234,111,162,28,230,68,59,112,175,215,201,43,76,217,218,175,48,229,129,199,89,195,241,253,53,153,50,79,27,114,66,198,154,28,187,215,251,99,238,223,255,103,44,51,121,31,85,59,
+188,89,226,193,171,75,65,73,202,24,24,47,233,253,181,223,231,193,214,211,203,227,23,197,98,17,143,133,160,249,78,77,45,246,73,180,232,156,172,127,223,104,125,33,203,19,3,89,26,144,103,110,156,9,195,94,237,106,127,68,172,35,39,16,30,206,116,61,208,231,
+9,77,82,102,89,209,23,249,189,233,9,249,111,105,51,107,198,19,241,182,7,118,124,59,16,140,106,220,227,239,190,85,84,86,77,26,68,73,88,216,137,137,154,157,165,205,43,134,204,95,239,163,207,146,201,230,120,168,244,72,113,252,228,63,66,16,151,164,76,253,
+13,89,77,110,123,109,97,184,60,254,153,172,51,51,247,224,202,212,80,109,65,9,254,218,227,239,122,106,180,177,214,43,76,79,130,180,27,157,251,51,21,223,75,36,100,14,211,167,253,31,88,69,159,37,51,87,255,165,83,28,63,61,176,50,14,10,76,82,102,217,65,113,
+228,70,103,184,231,207,243,76,153,31,146,117,102,36,2,136,208,241,216,149,173,33,55,214,154,173,242,83,160,24,255,159,98,70,133,247,116,91,95,31,103,159,217,50,93,50,171,238,106,60,115,50,67,89,142,78,95,39,56,73,25,3,226,165,236,154,253,125,186,61,188,
+206,52,207,141,148,50,68,94,227,103,220,243,239,219,137,96,83,119,251,21,62,51,210,90,43,189,98,70,101,109,194,75,247,245,73,234,253,174,117,95,66,102,158,49,141,132,204,198,191,133,32,54,73,25,29,190,165,236,179,54,196,69,218,172,51,51,42,54,197,222,
+68,225,80,251,38,92,61,61,218,88,122,214,74,180,123,86,167,141,164,34,111,148,215,201,236,146,108,201,237,195,153,80,205,210,159,236,132,243,211,131,107,99,158,224,36,101,150,99,145,223,253,255,126,126,157,105,80,116,38,243,189,16,52,217,161,105,189,
+45,248,160,29,248,100,233,89,43,17,103,115,245,138,25,21,120,153,36,100,166,174,247,247,213,125,179,100,190,52,229,14,76,202,178,5,126,73,146,50,6,97,203,200,131,170,241,192,127,151,103,204,60,87,124,148,193,198,156,4,110,11,14,225,21,166,229,103,114,
+68,108,47,236,0,66,233,206,147,25,27,115,248,245,158,182,80,204,231,187,63,104,119,205,8,38,73,202,44,217,153,238,2,159,255,177,171,137,231,78,200,207,201,58,51,18,1,58,51,81,219,2,29,150,141,127,45,248,89,125,208,123,53,148,42,39,6,204,216,152,175,189,
+187,173,205,179,187,213,188,253,152,232,237,174,87,151,248,68,82,198,32,108,9,111,39,248,25,121,80,246,99,178,93,156,114,88,63,201,177,253,141,234,254,39,79,148,209,217,7,102,80,106,217,124,41,12,179,250,245,150,184,107,23,230,189,71,68,239,155,90,224,
+151,79,36,101,12,134,151,240,110,194,159,147,19,51,23,138,148,193,86,197,186,192,231,126,76,130,214,59,215,203,205,186,148,192,133,178,250,144,175,132,97,118,125,250,54,1,99,102,210,221,241,114,175,57,158,153,192,124,34,41,179,140,199,193,207,127,202,
+39,220,249,21,166,188,101,246,47,138,149,27,96,197,3,107,246,55,8,193,39,79,148,209,226,7,26,48,149,252,32,229,85,242,64,101,41,191,126,213,22,104,15,230,189,79,68,239,15,189,78,150,102,96,75,82,198,64,120,110,135,46,242,123,159,223,210,102,214,140,198,
+140,218,60,12,124,238,239,142,252,183,163,226,179,200,186,50,145,59,202,6,191,148,84,22,223,24,184,46,170,79,159,19,49,214,146,153,255,62,17,253,65,161,77,12,248,31,73,153,101,26,173,200,157,188,57,215,129,24,46,143,127,38,107,77,236,219,225,160,254,
+142,76,173,142,77,162,154,230,187,233,196,206,93,134,30,5,143,47,148,192,214,215,235,200,179,101,206,196,254,94,83,188,5,16,125,231,37,125,26,254,71,82,70,7,111,110,111,103,254,249,121,144,247,67,178,206,12,245,144,164,61,156,117,101,54,158,40,163,179,
+121,168,120,81,128,151,105,185,133,189,249,82,159,204,146,217,69,87,200,207,168,213,69,50,219,159,107,36,101,230,103,145,223,101,60,221,30,26,184,187,61,22,2,109,194,138,142,173,159,94,97,218,248,105,129,65,137,129,6,172,227,108,123,176,30,175,49,46,
+211,86,70,238,15,189,85,132,184,78,82,198,32,120,110,75,190,90,116,145,54,235,204,24,180,161,163,87,158,169,234,165,233,190,155,164,201,137,50,90,236,64,3,14,149,103,199,216,250,154,154,238,69,135,138,254,208,218,88,133,47,72,202,204,47,114,163,51,174,
+208,232,228,36,208,15,6,110,179,220,64,209,30,148,208,1,241,116,233,243,224,77,25,157,94,167,104,177,226,253,65,66,134,40,237,101,244,182,118,80,124,184,78,82,102,254,198,202,250,17,203,203,175,72,252,124,121,60,87,4,161,24,227,68,63,199,22,146,27,115,
+189,194,212,9,173,5,62,89,165,191,248,38,153,169,70,125,229,86,59,187,94,127,136,134,72,202,232,216,205,233,253,202,159,127,158,54,201,25,3,184,47,245,66,32,246,43,248,107,194,159,101,38,220,102,166,204,28,3,184,78,104,13,140,89,188,188,189,82,238,168,
+208,49,75,52,68,222,121,105,84,116,248,154,164,76,185,141,85,11,134,2,190,67,30,188,229,215,153,108,155,13,235,154,50,57,250,187,112,126,50,199,43,76,118,31,242,64,133,101,189,82,230,168,212,49,137,196,46,112,220,188,134,205,55,36,101,116,236,230,84,
+74,34,100,76,155,5,128,47,20,73,229,114,101,143,180,7,147,240,10,211,198,28,137,255,78,88,205,88,96,49,121,13,153,94,24,8,216,159,244,250,18,92,35,41,51,175,200,55,218,177,176,65,83,254,46,121,203,236,95,20,75,3,14,177,95,173,14,78,105,80,156,102,153,
+41,35,105,107,150,43,203,56,79,182,190,166,126,167,11,253,155,214,198,72,240,5,73,153,178,26,169,150,148,250,186,208,111,105,243,58,83,228,167,236,143,84,79,237,66,3,109,130,87,152,54,73,190,39,51,252,76,113,101,74,253,229,241,44,109,102,133,228,197,
+108,255,188,60,254,123,195,241,231,246,207,243,223,59,79,109,63,216,58,187,60,126,85,52,104,64,183,208,191,209,31,162,105,223,9,129,193,215,76,222,23,252,221,114,99,248,243,182,243,103,192,129,216,215,233,117,178,125,108,246,56,77,183,240,113,47,156,
+238,223,19,181,115,57,89,248,83,218,47,105,216,125,53,88,251,245,90,93,207,107,48,92,164,54,30,168,216,250,154,214,218,203,215,7,252,155,168,62,36,175,95,115,3,51,101,230,19,125,54,194,80,248,247,139,156,165,54,224,88,71,167,61,152,188,99,99,23,166,105,
+103,202,72,26,138,197,49,250,180,73,54,252,189,253,245,201,132,101,252,197,246,231,190,74,117,39,15,243,253,247,141,162,66,240,241,142,245,245,224,43,146,50,6,190,81,27,157,200,89,106,131,141,117,116,66,48,57,175,48,109,202,213,84,117,90,194,86,44,14,
+209,167,77,162,33,31,103,51,127,214,147,107,159,213,87,120,239,181,245,53,250,54,177,251,67,146,50,220,72,82,102,222,78,74,84,99,170,35,233,97,182,12,165,119,92,116,66,238,102,166,204,180,245,217,118,216,234,235,62,114,114,225,106,157,152,165,251,60,
+253,246,115,95,85,114,173,78,182,223,87,185,194,253,39,118,31,244,47,69,134,155,72,202,24,240,206,97,168,228,123,154,45,131,65,222,50,62,206,88,135,61,117,154,238,158,99,192,40,22,187,202,51,86,242,194,188,103,5,124,143,63,210,102,33,225,146,189,208,
+55,196,61,200,24,73,159,133,219,72,202,148,221,65,174,213,251,74,190,103,228,134,209,128,99,121,223,235,132,204,226,63,138,150,215,151,102,96,214,208,237,101,45,207,142,41,233,53,156,252,61,94,164,114,95,13,58,75,182,190,70,159,82,255,211,216,131,59,
+72,202,204,35,250,34,191,181,52,56,31,3,95,163,78,53,93,92,244,221,6,230,226,21,166,205,14,76,83,13,110,209,70,222,85,62,150,88,55,230,80,87,235,205,116,133,149,163,23,138,14,250,55,250,66,201,206,75,220,65,82,102,30,125,240,243,31,42,249,158,99,224,
+107,228,41,240,58,3,154,168,198,153,127,118,244,39,79,83,12,66,205,146,17,143,251,226,241,166,130,184,228,239,247,71,65,223,243,101,146,236,164,125,143,102,250,187,173,49,75,134,91,73,202,232,204,69,110,112,198,192,215,169,83,77,181,11,13,213,181,232,
+187,48,77,81,159,13,28,197,227,174,242,85,67,66,230,250,181,43,225,251,230,153,59,189,226,131,246,82,255,179,194,49,18,11,147,148,153,94,244,27,176,164,76,156,65,28,148,82,207,188,194,116,252,0,212,224,81,76,110,27,108,213,184,141,243,85,98,102,205,239,
+237,181,37,180,149,211,223,171,106,102,231,37,110,37,41,83,94,199,184,118,239,43,250,174,99,224,235,212,169,170,6,119,13,213,179,119,193,235,115,154,96,240,249,189,106,202,13,106,154,33,115,83,157,88,43,49,115,230,62,139,126,165,190,231,13,125,21,184,
+145,164,204,244,44,242,107,192,24,101,16,7,187,88,106,81,187,232,179,101,250,35,255,189,53,84,166,143,105,237,90,216,198,249,52,173,51,99,229,95,170,15,193,116,19,253,29,99,36,66,146,148,153,167,3,16,217,80,217,247,29,149,85,196,122,86,75,205,158,139,
+190,53,246,177,139,119,119,170,233,55,34,207,30,234,47,143,103,141,156,203,89,218,172,239,178,100,123,223,171,62,4,108,51,166,248,59,173,178,243,18,119,146,148,49,248,154,82,141,25,224,49,240,245,50,83,70,172,151,234,136,44,213,254,68,174,207,221,202,
+255,222,253,188,173,246,234,101,99,231,180,228,46,72,102,201,16,209,195,137,254,142,49,18,33,73,202,76,171,15,126,254,53,54,56,145,23,221,50,83,102,57,182,128,92,198,160,62,107,11,38,20,53,153,154,103,200,116,13,94,203,95,23,250,172,39,170,14,1,117,19,
+253,29,125,33,66,146,148,49,200,157,210,251,10,191,115,228,169,132,22,246,52,184,107,205,239,202,152,242,233,158,126,244,192,234,215,70,207,109,137,100,83,151,204,58,35,166,126,162,191,211,42,59,47,113,39,73,153,105,69,95,228,119,168,240,59,71,206,92,
+123,58,190,236,64,71,187,48,63,139,253,46,251,239,212,221,246,252,234,252,142,98,150,12,218,75,109,169,241,6,123,147,148,49,200,141,222,224,68,158,41,227,233,184,129,93,139,70,229,12,49,61,248,158,112,214,248,57,158,205,124,77,31,171,50,104,47,221,159,
+26,25,35,177,32,73,153,105,69,78,202,12,26,73,229,21,29,145,2,234,215,168,172,25,72,106,39,15,242,44,200,121,254,223,140,63,187,87,101,8,172,87,55,110,100,231,37,238,37,41,227,70,92,243,224,107,202,198,18,74,27,40,183,210,17,209,22,45,231,208,87,104,
+205,154,19,155,44,202,174,65,115,189,98,116,170,46,17,220,195,3,255,204,24,137,240,36,101,166,211,7,63,255,247,21,127,247,119,202,45,6,117,205,212,173,191,148,181,131,6,147,220,44,202,90,113,185,12,116,65,206,181,155,233,222,231,126,74,116,221,129,127,
+166,47,68,120,146,50,58,110,26,28,51,101,152,127,176,19,213,71,109,209,162,14,25,20,118,170,232,157,162,36,85,163,45,80,251,211,12,63,211,107,128,232,239,76,123,127,106,133,157,151,184,151,164,140,129,151,129,80,221,179,124,214,24,196,177,159,200,91,
+143,143,65,62,179,36,221,204,127,95,27,217,166,199,174,171,178,2,71,58,73,55,39,178,163,223,103,204,148,225,94,146,50,211,53,66,145,27,156,65,17,128,91,69,78,216,142,65,62,179,36,157,242,201,1,250,128,237,114,55,241,207,179,158,12,220,124,79,233,130,
+199,68,82,134,123,73,202,24,116,105,108,98,39,149,76,183,102,78,163,54,169,248,251,145,129,228,253,122,231,231,188,197,16,14,190,7,69,174,31,118,94,98,39,146,50,110,198,83,120,175,8,128,246,225,6,99,176,207,45,193,190,73,22,137,217,233,99,90,155,46,232,
+117,125,92,232,207,130,154,61,220,241,255,69,97,150,12,59,145,148,153,134,69,126,235,54,4,190,118,189,234,203,76,214,124,50,20,57,81,188,239,224,208,76,153,251,181,62,27,182,115,255,115,47,133,25,219,203,46,112,60,36,101,216,137,164,140,14,155,6,7,180,
+13,173,181,11,99,224,184,119,202,232,228,90,127,202,251,56,112,93,153,162,252,91,79,6,238,190,167,244,129,227,97,231,37,118,34,41,115,60,139,252,58,143,22,111,160,76,215,62,68,181,230,76,153,49,112,220,59,229,115,213,152,106,167,234,210,23,242,51,160,
+165,246,228,36,80,251,121,31,15,174,217,137,164,140,1,237,177,222,42,2,58,228,104,31,110,176,230,43,68,239,148,59,229,115,66,157,242,210,172,199,133,252,12,104,181,77,233,130,199,66,82,134,157,72,202,28,175,215,216,52,33,114,114,201,192,108,62,18,94,
+235,136,190,219,193,174,229,174,83,84,194,199,41,122,251,223,23,242,51,160,213,118,37,114,253,176,243,18,59,147,148,57,94,244,39,36,50,192,113,6,112,236,47,242,142,3,131,182,169,248,129,102,167,138,30,52,200,104,73,244,50,112,114,228,181,237,221,67,225,
+206,190,143,157,151,96,7,146,50,58,106,199,200,217,223,81,195,89,189,71,170,177,1,79,131,198,192,231,254,80,221,159,101,240,174,15,211,166,39,71,252,219,94,248,190,233,75,13,194,96,108,164,31,20,126,108,193,158,36,101,142,31,112,69,126,66,210,82,99,227,
+85,7,230,106,35,180,15,235,248,75,185,83,247,103,26,100,180,228,161,75,123,212,140,103,235,201,124,217,143,250,241,242,120,46,20,250,62,215,126,223,7,142,131,157,151,216,153,164,140,78,218,49,90,90,135,229,157,114,204,138,131,227,86,59,232,234,116,217,
+117,186,87,69,119,214,106,2,171,115,105,143,170,7,234,208,231,246,254,199,237,175,67,50,91,70,223,71,251,18,189,31,194,158,36,101,12,102,53,54,101,12,32,13,54,196,85,219,48,173,81,217,83,62,39,212,234,140,136,222,165,253,228,137,216,29,229,233,87,237,
+190,217,50,228,250,209,5,143,193,168,24,176,43,73,25,157,180,218,7,94,206,103,26,157,234,60,185,232,235,77,169,207,101,15,182,205,144,219,79,139,73,44,237,254,113,253,185,94,216,62,201,9,153,215,95,253,191,33,153,45,19,93,167,142,72,202,176,59,73,25,
+131,174,99,6,93,99,131,231,20,249,230,137,65,92,107,29,145,81,157,86,231,221,239,149,129,29,28,50,120,180,158,76,74,191,93,30,23,183,252,153,217,50,177,229,246,197,14,148,176,35,73,153,227,26,27,175,39,56,39,157,115,34,13,226,118,85,202,226,118,163,58,
+173,206,79,168,181,123,190,217,82,95,198,98,223,235,219,7,143,89,158,29,243,203,61,131,82,3,211,184,30,7,191,207,140,138,0,251,144,148,209,153,57,212,219,6,207,233,163,1,28,52,213,25,177,213,253,237,236,186,227,190,175,12,124,105,159,117,101,122,225,
+74,255,217,225,239,152,45,19,187,95,25,185,158,216,121,137,189,72,202,232,156,29,106,48,144,212,57,231,78,145,167,182,151,82,151,34,119,138,238,123,234,223,169,162,7,13,50,244,99,180,217,41,73,202,100,175,119,236,43,14,66,165,189,52,78,130,187,73,202,
+24,112,29,170,197,39,208,99,224,235,105,128,198,148,74,89,159,41,242,76,153,251,6,141,6,228,218,73,101,96,191,58,163,15,120,216,128,211,108,25,34,26,133,128,125,72,202,232,204,28,218,208,124,104,244,188,12,54,208,70,28,239,157,58,93,124,189,182,37,246,
+254,90,155,81,168,12,124,91,95,118,189,23,246,193,99,181,207,43,236,67,50,107,128,152,99,37,216,153,164,204,225,131,45,139,252,106,64,163,12,222,48,224,81,167,219,170,215,189,162,17,190,157,84,6,14,143,139,216,237,159,100,49,91,6,245,3,238,240,93,131,
+131,160,187,158,78,231,100,194,20,51,60,162,79,249,125,223,248,32,174,11,122,93,79,82,236,109,193,167,20,185,141,40,173,51,242,46,240,245,56,189,229,122,72,24,170,215,157,203,121,163,159,210,237,91,60,95,233,133,105,239,118,126,216,30,98,71,4,163,16,
+176,175,154,147,50,185,83,153,87,202,127,180,237,40,237,211,208,15,219,142,250,219,237,239,247,29,136,62,10,94,110,134,134,207,109,12,220,89,61,77,178,251,83,182,79,148,83,167,79,149,195,111,234,58,177,235,117,231,114,222,104,151,190,164,245,100,14,243,
+60,73,202,16,131,157,151,216,91,109,175,47,229,14,209,217,229,241,230,242,248,251,242,120,121,121,60,59,160,145,239,183,255,238,213,246,231,188,218,254,220,93,59,92,209,59,180,45,47,158,57,26,112,96,192,115,148,183,133,125,159,247,129,175,197,109,131,
+71,187,173,205,59,104,175,185,108,68,119,223,140,235,150,202,192,210,109,252,144,60,248,33,6,229,156,189,213,146,148,201,3,156,156,128,249,115,251,235,212,55,196,39,215,126,254,139,29,6,84,145,111,200,99,106,251,21,151,200,217,109,79,207,167,109,179,
+40,167,205,82,14,149,79,190,36,9,127,88,31,239,137,240,28,53,224,180,182,12,250,29,112,131,210,147,50,185,211,112,149,44,57,91,160,19,145,127,254,179,237,231,157,223,242,121,102,201,180,45,242,154,42,223,107,18,39,19,121,38,66,105,109,68,228,206,81,119,
+203,255,151,128,157,103,192,94,19,101,224,118,63,221,241,103,102,24,29,151,148,25,146,89,4,180,111,20,2,246,85,114,82,230,42,57,114,182,210,231,255,186,253,252,39,58,50,95,104,253,85,128,119,129,175,173,78,250,252,131,225,8,62,168,211,197,215,107,179,
+36,14,247,125,163,101,130,207,250,3,255,44,130,97,130,159,97,182,12,234,8,124,165,196,164,76,238,44,230,53,99,94,20,208,113,204,159,255,106,123,92,125,23,139,252,26,80,182,202,64,77,44,167,240,174,192,58,173,94,27,144,79,229,180,193,50,193,183,250,91,
+226,22,189,254,76,177,102,216,96,224,74,195,70,33,224,16,165,37,101,242,205,238,207,84,222,147,136,60,91,230,143,237,247,243,250,146,243,51,216,64,44,111,247,65,189,46,122,112,105,64,126,156,147,6,203,4,223,250,73,220,110,52,76,244,115,204,150,161,85,
+118,94,226,32,37,37,101,206,210,38,241,81,106,135,167,219,126,191,200,55,229,119,41,198,19,231,15,154,6,56,200,232,123,21,231,161,129,229,164,78,27,44,19,124,235,166,122,98,61,153,233,146,50,67,50,91,6,117,4,254,167,148,164,204,89,218,44,232,75,217,222,
+57,207,144,29,81,196,112,87,99,161,223,43,242,147,171,238,171,255,182,160,247,244,49,245,253,219,147,147,111,39,218,246,89,7,155,102,203,160,31,4,91,37,36,101,206,146,132,76,45,222,7,57,79,51,101,160,173,206,136,215,18,111,255,111,246,215,85,254,253,
+123,151,112,239,56,89,79,102,154,245,100,174,27,146,89,5,232,7,193,39,107,39,101,242,90,45,18,50,245,136,50,176,121,31,248,26,235,172,139,225,49,74,157,145,18,185,147,244,245,211,254,78,21,61,218,105,67,229,129,219,61,214,174,127,97,152,225,103,154,45,
+131,58,2,105,221,164,76,238,212,72,200,104,108,128,118,148,58,203,44,250,182,216,215,7,148,157,98,122,180,154,19,27,102,74,237,238,201,181,223,71,95,79,230,195,76,125,192,65,223,146,134,140,66,192,161,214,76,202,188,76,158,216,212,36,210,160,38,114,7,
+193,66,134,199,123,164,157,208,89,42,76,103,64,174,142,43,3,7,213,155,171,186,211,7,143,197,156,253,34,179,101,104,133,157,151,56,216,90,73,153,23,58,6,6,91,208,40,201,230,50,141,193,7,151,202,166,58,158,217,121,105,63,125,178,158,76,246,118,198,159,
+61,36,179,101,104,131,114,204,193,214,72,202,228,27,219,51,161,175,78,164,117,86,34,55,170,189,162,62,73,27,167,67,82,158,200,137,229,71,234,183,118,82,251,116,144,199,234,205,34,109,187,217,50,180,96,20,2,14,181,70,82,230,133,176,87,201,76,25,216,141,
+217,8,101,250,75,153,68,76,173,41,180,167,188,174,140,245,100,230,239,3,14,201,44,3,234,55,10,1,135,90,58,41,147,111,110,189,176,87,105,112,190,97,120,146,106,192,211,98,157,137,156,88,190,186,239,90,51,74,59,217,185,116,123,201,201,183,51,253,191,69,
+152,45,131,122,66,88,75,39,101,126,21,242,42,153,37,19,175,19,138,1,79,107,70,101,83,221,14,222,78,246,46,155,123,226,1,222,46,244,57,131,129,45,250,24,68,181,100,82,38,119,6,60,129,175,83,196,155,228,219,192,215,91,61,61,110,224,27,85,233,201,219,81,
+217,84,183,131,183,147,157,203,70,225,125,64,179,101,168,149,157,151,56,202,146,73,153,127,9,119,181,222,11,65,40,158,166,27,244,28,226,99,5,223,49,242,172,191,159,84,207,73,213,184,139,81,231,178,177,167,37,214,147,185,110,72,102,203,80,39,229,150,163,
+44,149,148,241,78,110,221,222,57,231,80,30,41,242,7,251,94,59,81,180,49,240,245,49,75,102,90,157,182,29,3,205,89,152,45,67,141,70,33,224,24,75,37,101,158,8,181,193,86,101,62,4,190,222,102,202,24,248,182,90,103,34,207,250,235,85,207,73,117,190,51,1,172,
+241,42,247,144,204,58,160,62,163,16,112,140,165,146,50,166,77,215,43,234,141,49,242,76,25,79,212,105,181,67,162,211,196,84,58,109,59,250,128,179,49,91,6,245,132,80,150,74,202,244,66,93,173,168,201,9,51,101,208,214,237,103,244,29,9,230,212,119,165,241,
+126,208,90,125,192,193,64,23,253,31,34,89,34,41,211,25,228,85,45,242,116,255,200,179,101,58,69,159,6,59,36,239,92,42,38,116,226,187,210,176,97,229,207,55,91,134,90,216,121,137,163,45,145,148,241,116,166,110,145,7,49,145,103,203,116,138,254,222,250,192,
+231,62,86,84,167,63,40,170,4,172,243,189,203,197,158,222,174,252,249,67,50,91,134,58,40,167,28,77,82,134,251,188,115,238,33,117,138,62,123,248,160,94,67,209,30,10,1,21,14,52,205,150,65,31,136,16,150,72,202,124,47,204,110,200,149,250,24,248,220,59,197,
+127,111,145,19,208,53,189,230,56,42,170,76,228,177,54,157,134,7,153,37,36,176,7,125,81,42,224,97,15,71,51,83,6,141,140,193,219,77,60,85,221,159,53,27,234,224,221,111,34,214,249,222,229,98,15,175,11,250,46,102,203,96,172,68,243,30,8,1,119,120,31,252,252,
+199,192,231,222,41,254,123,123,20,248,220,7,29,40,2,170,229,161,147,132,49,251,122,91,208,119,25,146,217,50,24,43,208,56,73,25,90,25,104,105,104,167,213,41,254,6,62,234,53,52,81,239,205,88,166,246,254,223,47,46,9,133,122,47,4,76,65,82,134,219,124,48,
+120,145,148,65,204,42,237,192,223,197,76,25,166,116,234,59,210,96,223,167,180,254,79,110,183,189,198,132,62,5,205,146,148,65,35,115,127,231,36,42,51,63,246,211,9,129,122,141,122,95,32,107,132,177,143,161,208,239,117,222,80,223,212,110,61,250,19,240,5,
+73,25,110,243,86,8,194,55,182,158,174,182,53,48,155,203,59,245,26,117,95,91,142,254,223,2,158,166,250,19,26,249,251,255,168,152,233,3,193,117,75,36,101,12,238,53,50,53,139,60,120,51,83,166,173,129,217,156,29,76,237,27,81,213,176,192,119,231,50,177,135,
+161,240,182,251,231,202,239,151,63,186,7,25,43,193,215,204,148,65,67,115,183,200,219,231,122,186,186,187,200,9,172,119,234,53,234,126,209,58,151,137,29,141,169,252,135,81,67,218,204,152,169,209,211,107,247,204,65,113,107,162,190,192,36,150,72,202,104,
+116,234,99,145,223,47,99,17,213,247,46,255,206,34,39,176,62,86,248,157,37,157,137,82,247,123,151,136,6,251,236,23,169,190,196,76,254,190,175,13,232,155,98,231,37,38,243,157,206,47,174,153,88,84,58,216,160,12,163,239,76,96,39,190,31,13,169,105,201,129,
+139,237,175,47,11,255,158,249,225,94,126,229,106,248,234,255,155,177,105,140,0,255,179,196,76,25,179,46,220,148,107,22,121,166,140,206,252,238,30,7,62,247,209,119,38,184,190,224,239,38,185,206,62,134,202,190,239,197,229,241,67,193,125,181,124,175,249,
+241,150,184,14,138,155,254,15,92,89,106,77,25,13,79,93,100,126,197,66,103,158,214,59,37,218,57,34,120,36,4,236,209,150,215,216,158,231,182,252,159,5,142,53,242,171,74,63,220,113,175,177,45,182,49,2,252,207,82,73,153,223,133,90,35,83,49,55,78,238,211,
+7,239,200,251,222,168,255,101,234,92,30,118,52,84,222,79,203,51,82,74,216,50,251,234,117,165,159,239,249,46,250,218,198,74,240,63,75,37,101,94,27,216,86,53,80,49,88,209,240,214,48,216,160,140,142,112,173,44,208,199,84,74,94,20,221,140,71,118,213,194,
+171,235,23,105,51,107,230,183,149,238,135,207,183,159,255,90,255,50,196,120,9,38,179,228,150,216,175,133,187,10,110,16,109,13,60,49,232,209,94,232,80,17,179,13,232,92,26,246,48,52,212,103,251,37,125,78,206,124,88,224,243,174,146,49,231,123,126,158,251,
+80,189,60,216,97,82,75,38,101,158,11,183,70,70,76,170,211,187,252,247,178,32,114,157,116,134,153,74,231,123,209,64,123,56,54,120,78,87,201,153,175,183,163,158,194,235,237,207,253,127,105,255,100,140,254,101,253,60,196,102,82,223,45,248,89,185,113,28,
+12,242,138,55,8,1,236,37,242,76,153,154,167,187,235,80,49,149,174,208,239,165,191,133,190,223,38,89,114,177,61,78,182,245,226,241,246,222,221,239,241,51,222,109,143,183,219,120,77,49,3,199,125,168,94,163,16,48,165,239,22,254,188,231,58,9,6,42,149,118,
+86,126,13,122,238,143,93,254,123,153,41,83,111,71,253,131,235,199,68,186,2,59,233,15,93,22,118,20,101,67,142,220,230,191,78,223,206,154,233,239,233,3,26,216,99,188,196,172,150,78,202,12,219,134,240,137,208,23,105,76,214,79,1,3,159,253,218,244,218,59,
+85,189,34,204,4,186,2,7,88,157,203,66,144,182,188,214,243,55,176,175,183,239,0,147,122,176,194,103,254,98,224,175,145,113,179,174,134,1,171,129,79,203,70,33,96,34,167,190,19,21,247,253,244,203,245,189,209,119,96,69,15,86,42,200,22,253,45,147,5,199,96,
+127,157,206,100,181,254,82,124,153,200,73,129,223,199,171,121,236,98,16,2,3,124,140,151,88,215,131,149,62,55,111,81,103,139,108,55,102,177,169,131,167,173,119,235,2,159,123,237,79,87,61,161,100,42,143,180,219,84,234,173,16,24,224,163,239,192,186,30,172,
+248,217,121,27,185,209,37,208,200,80,60,79,91,197,166,213,246,194,61,136,86,219,2,73,25,118,53,8,129,123,41,250,14,172,107,205,164,76,126,194,250,115,242,30,107,73,13,140,107,113,187,200,79,146,116,238,197,230,182,54,92,103,24,54,250,194,190,143,100,
+58,187,182,129,250,126,238,165,232,59,176,178,7,5,20,234,31,53,72,26,24,138,166,115,207,77,70,231,1,197,182,149,143,93,14,118,48,8,129,107,128,241,18,235,123,80,72,225,150,152,89,159,119,138,53,194,183,121,228,242,223,170,15,124,238,173,44,146,59,42,
+198,76,164,164,153,115,157,203,129,190,159,251,16,174,21,117,120,80,200,247,144,152,41,227,26,112,187,200,101,211,76,25,90,238,152,104,251,104,177,173,236,92,14,118,48,8,129,251,41,123,177,48,51,179,120,80,208,119,201,29,227,127,234,32,187,49,27,184,
+21,199,154,50,183,139,252,138,64,43,157,72,219,98,211,90,91,217,187,20,236,216,175,241,48,180,12,102,44,25,15,16,220,131,194,190,79,190,57,252,144,54,91,102,163,129,41,173,108,70,101,166,12,45,215,9,237,31,83,121,168,205,166,34,131,16,20,99,20,2,215,
+138,216,30,20,250,189,126,73,155,45,179,101,240,13,74,196,169,12,157,203,127,163,83,245,65,7,11,10,107,39,205,110,100,23,102,103,184,15,97,44,64,33,30,20,252,221,46,210,102,157,25,133,127,126,222,143,220,77,228,36,97,231,242,223,200,19,105,157,97,40,
+173,157,180,56,59,187,24,132,192,181,96,47,198,164,204,230,65,5,133,63,39,102,94,187,84,26,25,113,50,216,40,76,228,167,209,131,243,129,98,219,73,237,53,187,244,103,204,70,47,203,40,4,174,17,113,61,168,224,59,230,155,198,207,105,243,74,19,6,36,107,250,
+104,176,193,53,102,201,180,195,224,132,169,156,250,14,232,247,97,192,223,36,111,22,48,155,7,21,125,215,188,248,175,109,179,167,103,150,140,27,230,46,30,186,252,223,232,2,159,123,107,107,17,232,104,49,149,181,147,181,157,75,64,192,54,220,53,193,56,128,
+170,61,168,236,251,14,201,182,217,83,19,75,141,177,142,190,152,168,219,48,141,94,187,68,5,44,11,224,62,132,107,68,65,30,84,248,157,109,155,61,45,79,136,53,198,58,250,135,137,60,123,232,157,186,13,69,234,133,128,123,12,66,224,62,132,186,67,89,30,84,252,
+221,109,155,173,129,113,195,92,78,231,242,139,201,53,173,181,187,218,65,166,242,120,229,207,247,170,41,247,241,154,76,153,204,92,55,6,32,176,7,149,127,255,139,100,219,108,55,1,141,242,82,44,108,43,30,45,183,27,18,252,180,208,46,116,46,1,247,24,132,160,
+216,123,144,251,144,254,63,65,61,104,224,28,108,155,237,198,172,81,94,134,29,61,196,227,122,231,177,53,18,212,180,208,46,104,167,209,247,115,31,98,122,102,152,49,171,7,141,156,135,109,179,53,254,75,25,3,159,187,153,50,180,92,7,70,151,150,202,219,202,
+19,237,52,247,24,132,64,191,28,125,4,202,243,160,177,243,177,109,246,126,44,242,187,191,191,2,159,187,39,176,159,245,58,38,234,54,20,214,86,106,163,185,143,167,253,238,67,232,251,80,160,7,13,158,211,144,54,219,102,15,46,239,189,100,228,247,23,57,225,
+247,189,203,79,195,117,192,61,131,169,116,193,62,23,237,28,250,229,234,14,28,225,65,163,231,149,7,13,121,198,140,109,179,239,142,145,198,223,13,115,31,158,194,126,214,7,62,247,86,103,216,153,97,201,84,186,96,159,139,129,37,250,152,45,27,133,128,185,61,
+104,252,252,242,26,51,63,235,108,187,49,27,184,77,194,90,5,180,92,7,116,134,153,202,163,149,62,247,177,208,163,223,87,253,253,213,152,165,60,163,16,48,183,7,1,206,49,239,202,100,219,236,111,253,46,4,6,110,123,50,83,102,253,65,151,58,160,227,69,249,214,
+74,96,119,66,207,29,172,39,227,30,139,186,67,161,30,4,57,207,171,109,179,47,92,242,255,177,133,248,225,60,197,192,172,161,54,141,66,192,4,214,74,96,119,66,207,29,6,33,168,102,204,130,190,1,193,60,8,116,174,121,32,253,52,217,54,59,187,72,18,11,110,152,
+135,233,93,254,85,7,93,58,246,243,242,52,140,41,172,145,180,53,147,145,200,109,119,75,236,192,84,158,81,8,152,219,131,128,231,156,23,255,253,33,197,78,74,252,71,209,63,138,132,22,102,202,168,219,112,151,126,225,207,235,132,156,59,12,66,80,13,51,101,212,
+31,2,122,16,244,188,115,131,23,117,219,236,65,227,114,180,247,129,207,189,119,249,67,15,126,90,111,59,116,134,169,149,153,50,220,197,44,192,122,140,66,224,122,16,207,131,192,231,30,117,219,236,231,138,61,28,165,19,2,157,47,184,71,191,240,231,61,18,114,
+238,48,8,129,251,16,174,7,229,122,32,4,161,182,205,30,220,152,117,110,142,100,203,213,216,175,46,181,62,147,68,231,139,169,124,175,93,162,16,31,244,253,244,51,57,152,89,102,44,66,82,102,35,194,182,217,87,11,29,3,199,137,252,154,192,71,157,97,40,178,157,
+232,133,28,109,90,51,70,33,112,45,136,69,82,230,179,214,183,205,126,174,97,209,193,209,241,159,196,247,129,207,61,194,154,43,22,251,101,10,93,163,159,69,125,60,233,175,143,29,152,202,97,236,196,34,36,101,190,237,140,183,184,109,246,144,226,173,157,3,
+115,137,60,83,38,66,194,226,189,34,206,4,186,70,63,139,58,251,128,184,102,184,22,20,76,82,230,102,45,109,155,61,166,205,154,57,104,164,167,98,151,143,184,70,231,8,59,235,22,250,156,94,168,185,69,238,199,218,85,206,125,8,215,129,194,73,202,220,174,133,
+109,179,243,205,56,202,34,198,44,39,250,130,146,145,7,64,163,115,132,157,117,11,125,206,247,66,205,45,6,33,112,31,194,117,160,124,146,50,119,187,218,54,251,121,197,223,221,19,146,121,68,126,71,219,76,153,184,237,161,65,12,148,215,86,106,147,209,87,113,
+47,66,253,161,98,146,50,187,57,79,117,205,56,145,144,97,78,145,103,202,244,129,207,61,82,123,98,118,33,53,181,149,146,50,24,216,183,103,20,2,215,128,56,36,101,118,151,183,205,254,161,130,129,137,132,140,1,234,220,30,185,252,33,125,80,191,97,47,143,23,
+248,140,147,228,149,82,110,111,179,181,101,245,178,3,211,250,70,33,96,41,146,50,251,87,206,146,183,205,190,90,7,199,77,216,0,117,238,65,64,84,145,159,72,71,218,149,72,71,12,109,18,181,27,132,192,245,195,53,160,14,146,50,135,13,198,159,110,143,146,6,230,
+121,221,155,86,118,140,170,65,228,196,87,228,65,128,39,210,49,120,66,201,20,250,5,62,163,19,102,110,97,61,140,250,199,27,172,103,20,2,150,36,41,115,184,139,180,73,130,188,46,32,57,144,191,199,185,75,226,102,185,144,200,137,137,200,175,110,13,206,21,138,
+107,47,59,33,70,59,214,36,179,222,215,53,10,1,75,146,148,57,190,194,230,5,128,127,92,225,230,151,63,59,207,214,169,97,157,27,55,204,246,68,29,8,152,41,19,131,39,148,76,101,238,153,133,143,133,152,91,218,48,125,67,253,76,14,103,166,25,139,146,148,153,
+198,144,54,137,153,124,204,61,115,38,55,208,57,25,147,215,142,185,16,122,3,183,149,116,206,59,100,59,167,35,12,251,49,83,6,237,53,135,26,133,64,236,137,65,82,102,250,155,96,158,57,147,19,38,191,76,120,83,204,13,195,111,105,51,43,38,31,23,66,109,224,182,
+178,206,121,163,67,6,247,154,123,166,140,54,137,155,120,202,223,134,247,66,160,15,64,12,223,9,193,108,21,249,183,237,113,178,237,148,245,105,179,30,197,73,186,123,241,191,113,123,188,219,54,198,131,134,161,88,31,3,159,123,196,129,64,228,87,151,34,38,
+32,71,3,94,38,240,112,198,159,109,231,37,110,51,8,129,123,47,234,16,245,144,148,153,223,135,109,197,86,185,219,28,180,25,104,196,17,121,0,20,241,85,189,252,164,185,215,204,113,164,174,210,159,77,221,237,181,193,188,126,38,226,78,69,188,190,4,26,109,131,
+129,221,152,41,19,111,96,3,199,58,173,244,103,83,175,215,66,224,222,139,254,61,117,145,148,1,141,246,33,58,131,171,80,34,190,170,167,51,204,20,230,76,230,62,18,94,110,96,61,25,247,34,212,33,42,35,41,3,135,27,3,159,123,231,242,43,235,206,25,118,50,87,
+66,247,68,104,185,193,32,4,238,69,28,197,76,89,22,39,41,3,110,150,6,4,187,121,172,156,59,103,40,168,173,236,133,150,27,218,45,109,87,91,236,192,180,60,179,147,88,156,164,12,24,184,29,202,122,6,113,68,125,106,52,184,244,76,160,159,225,103,118,194,138,
+54,43,4,9,2,49,39,0,73,25,56,206,24,248,220,163,205,148,233,3,95,235,168,29,20,83,152,41,85,39,4,220,192,90,24,238,67,28,31,111,49,103,113,146,50,112,156,191,2,159,187,153,50,58,132,173,51,109,156,41,204,241,234,163,246,151,155,12,66,224,154,114,20,179,
+100,88,133,164,12,24,176,30,234,251,64,231,26,121,0,20,185,131,50,106,226,152,192,28,179,10,31,10,43,55,180,87,218,44,247,34,244,121,168,144,164,12,104,188,15,21,41,81,97,151,19,29,97,40,169,173,52,83,134,175,13,66,224,94,196,209,254,18,2,214,32,41,3,
+199,137,60,83,38,82,162,34,242,0,40,242,26,5,6,57,76,165,211,38,161,173,198,181,45,158,153,50,172,66,82,6,52,222,6,5,247,51,83,38,46,11,254,49,133,78,155,196,204,6,33,104,214,40,4,250,245,180,77,82,6,12,218,184,95,228,245,27,162,119,244,117,208,152,66,
+55,225,207,234,133,147,27,6,237,6,238,109,95,95,150,233,207,235,211,179,10,73,25,48,104,51,56,88,118,64,133,206,48,241,116,133,254,44,218,48,8,129,235,139,254,60,245,146,148,129,227,201,170,183,47,242,171,2,209,59,41,22,253,99,10,143,38,252,89,157,112,
+242,21,107,142,180,111,20,2,253,29,218,37,41,3,199,123,31,248,220,251,32,231,25,121,81,205,232,73,199,65,19,199,4,166,76,236,62,22,78,180,83,225,140,66,48,59,15,97,88,141,164,12,192,114,131,169,218,120,106,36,41,197,52,166,76,236,90,228,151,175,7,235,
+6,236,237,51,27,74,159,135,134,73,202,192,241,134,192,231,30,225,137,173,89,50,58,105,112,172,41,19,41,182,195,70,31,36,158,81,8,220,239,105,151,164,12,0,58,129,226,192,252,250,9,126,134,132,12,95,251,93,8,220,135,56,154,157,151,88,149,164,12,28,111,
+48,200,112,142,141,242,126,181,206,48,211,153,98,182,76,39,140,232,131,132,100,22,135,248,210,48,73,25,0,110,227,169,209,134,119,249,153,194,105,33,63,131,182,6,146,218,233,56,247,99,215,122,222,186,4,171,145,148,129,105,12,6,26,205,138,188,211,137,78,
+202,231,206,48,28,235,251,9,126,198,67,97,68,223,195,61,153,201,153,25,204,170,36,101,128,99,217,9,164,93,146,17,58,194,76,103,138,4,118,39,140,92,99,22,159,123,17,98,75,3,36,101,64,199,168,132,129,134,243,211,73,41,217,40,4,76,160,155,224,103,244,194,
+200,53,131,16,132,98,54,135,254,14,141,146,148,1,142,117,226,252,104,220,40,4,76,160,91,249,223,211,222,32,210,108,198,120,215,156,233,89,175,135,213,73,202,128,27,229,177,30,53,124,110,145,103,201,12,170,181,120,48,185,110,165,127,139,54,9,125,77,196,
+149,66,73,202,192,52,34,103,216,79,156,27,234,56,236,164,59,226,223,218,121,137,235,172,39,19,243,62,228,94,52,61,73,25,86,39,41,3,26,244,99,181,60,80,232,2,95,87,29,254,47,189,23,2,86,110,47,237,188,196,117,131,16,232,111,50,9,107,245,176,58,73,25,152,
+134,153,50,109,234,20,109,182,70,33,96,229,246,210,76,25,174,15,204,205,152,136,123,237,17,83,26,35,41,3,26,245,41,116,141,158,215,247,202,51,91,163,16,48,129,199,71,252,91,73,25,174,12,66,16,150,89,29,250,59,52,72,82,6,166,19,249,169,85,215,232,121,
+157,42,207,24,4,81,8,107,92,113,197,235,165,113,73,32,76,223,215,209,223,97,117,146,50,224,70,57,133,206,32,72,121,14,210,121,131,99,244,11,255,59,218,52,8,65,88,163,16,232,235,208,30,73,25,152,206,199,192,231,222,53,122,94,102,202,160,243,198,212,14,
+73,246,118,194,198,181,118,72,251,28,215,40,4,238,235,180,71,82,6,220,40,167,96,87,16,101,89,92,96,55,135,36,123,59,97,99,107,16,2,101,64,8,38,99,141,30,138,32,41,3,6,108,83,104,113,192,208,43,203,232,188,49,131,67,102,202,60,22,54,182,172,39,131,123,
+244,116,204,148,161,8,146,50,224,38,57,133,206,229,111,138,169,241,55,27,132,128,9,28,50,83,198,34,191,92,121,45,4,225,121,64,48,29,73,25,138,32,41,3,211,25,3,159,123,215,224,57,245,129,175,231,123,213,249,70,146,85,76,225,144,215,61,109,135,77,54,8,
+1,202,193,164,247,116,247,117,138,32,41,3,211,26,3,159,187,39,185,109,117,84,248,150,39,106,76,161,219,243,239,75,200,112,197,171,75,68,239,107,186,167,211,36,73,25,112,163,156,74,107,3,135,71,58,42,168,227,20,208,86,74,120,115,101,16,2,220,135,244,117,
+104,143,164,12,184,81,78,229,196,249,160,142,195,228,109,75,47,100,108,13,66,128,178,48,153,143,66,64,41,36,101,96,90,145,23,95,59,117,62,58,123,1,120,125,128,165,219,151,135,194,133,118,153,175,140,66,160,78,209,14,73,25,152,86,228,181,56,190,111,236,
+124,204,148,65,29,167,132,246,165,19,46,146,132,48,95,178,3,211,241,70,33,160,20,146,50,48,173,200,239,167,182,52,179,36,242,32,104,80,141,213,113,102,215,207,244,119,91,35,9,170,109,198,189,104,46,163,16,80,10,73,25,208,129,156,74,75,51,75,58,69,25,
+157,56,180,171,171,27,20,1,177,192,189,72,125,162,117,146,50,48,45,51,101,12,132,148,97,29,97,184,207,227,128,237,234,33,158,43,42,6,144,184,87,187,151,211,58,73,25,152,158,233,214,245,139,60,16,178,27,129,1,18,243,219,53,241,27,185,45,26,183,3,79,131,
+39,235,201,112,51,137,153,195,89,147,135,162,72,202,128,155,228,148,250,70,206,227,251,192,215,208,0,232,126,18,175,28,107,215,100,75,228,157,151,174,218,162,65,113,17,3,220,175,213,41,90,38,41,3,6,108,28,62,96,210,201,139,233,189,16,48,129,78,91,116,
+167,171,7,28,102,137,24,64,226,94,164,175,67,211,36,101,192,77,114,74,189,203,175,163,34,70,176,147,110,162,191,211,170,171,215,11,134,224,229,100,80,85,184,133,215,151,220,199,105,132,164,12,192,183,122,29,21,196,136,153,117,19,253,157,214,7,156,99,
+240,58,103,166,16,238,69,211,26,132,128,210,72,202,128,198,126,74,143,93,254,170,121,245,78,29,103,57,221,61,127,222,7,143,207,245,89,0,175,3,199,225,181,170,194,14,117,132,221,141,66,64,105,36,101,0,12,132,116,240,246,39,129,197,177,30,221,243,231,157,
+58,246,63,111,3,199,64,187,140,251,246,180,236,188,68,113,36,101,96,122,67,224,115,239,93,254,102,6,65,232,8,51,175,251,182,197,238,220,71,195,223,87,7,213,132,123,140,66,160,94,81,63,73,25,128,47,69,222,237,196,78,14,58,194,148,211,214,60,82,191,254,
+39,234,140,17,235,201,224,190,237,254,77,0,146,50,48,143,193,64,163,90,39,138,47,59,48,253,153,185,219,154,78,253,250,194,239,250,18,240,141,81,8,196,140,250,73,202,0,75,15,52,74,247,48,240,181,51,0,16,43,150,213,223,241,103,167,234,87,232,58,103,61,
+25,118,49,10,129,123,55,245,147,148,129,121,68,158,114,92,251,64,162,83,124,217,113,192,4,199,58,105,180,29,157,163,126,13,193,234,157,93,151,216,197,32,4,123,25,133,128,18,73,202,0,75,13,50,106,209,233,220,177,3,79,176,153,194,105,163,237,232,92,245,
+43,82,162,226,119,213,131,29,141,66,176,51,175,30,83,36,73,25,48,96,155,90,237,139,83,118,138,47,58,194,44,228,251,91,254,127,239,254,121,163,255,4,137,65,158,17,100,166,12,238,69,211,27,132,128,18,73,202,192,124,29,170,168,78,124,247,230,6,66,232,8,
+51,143,219,102,202,68,94,219,234,195,61,3,170,8,245,238,223,170,6,123,176,75,151,251,54,149,147,148,1,3,220,165,6,25,190,123,189,3,33,116,132,153,71,183,231,255,87,175,82,122,30,32,6,23,170,6,123,24,133,64,172,168,155,164,12,24,224,78,205,76,25,29,21,
+245,28,118,211,221,242,255,123,109,209,173,46,26,111,175,126,211,30,227,254,61,139,65,8,40,149,164,12,204,39,242,108,153,174,210,239,29,121,166,140,197,239,212,113,202,104,47,163,47,242,187,203,0,243,151,70,207,61,39,122,159,171,18,236,105,16,130,201,
+218,22,88,133,164,12,204,219,185,50,200,64,103,69,204,96,159,246,50,250,118,216,187,12,48,95,55,58,16,125,158,204,192,195,253,104,46,30,62,81,44,73,25,152,143,153,50,245,121,172,67,135,152,177,176,211,123,254,59,146,125,18,18,79,83,91,9,140,33,109,94,
+93,2,247,163,249,234,24,20,73,82,6,230,243,49,240,185,119,46,127,211,131,33,116,242,152,206,215,175,43,69,222,121,105,159,135,25,121,16,218,202,107,76,185,253,125,170,42,112,4,11,207,239,214,102,64,145,36,101,64,227,63,135,90,7,21,189,193,16,7,12,166,
+224,24,95,207,208,139,60,83,102,223,118,232,34,181,177,83,209,83,3,70,220,139,244,203,137,75,82,6,52,254,115,232,92,126,157,185,32,222,11,1,218,207,201,28,178,230,67,78,104,212,156,84,206,235,200,188,86,236,57,146,7,43,119,27,132,128,146,73,202,192,124,
+70,131,138,170,120,58,141,122,206,26,250,6,218,207,181,219,162,31,43,109,199,46,46,143,115,85,0,247,113,247,106,98,147,148,1,55,128,57,212,56,168,56,81,100,81,207,89,185,253,233,213,167,131,228,217,126,181,37,102,46,146,117,100,152,206,135,100,214,235,
+93,236,188,68,209,36,101,192,128,109,238,65,70,45,186,192,215,202,2,129,135,27,132,128,9,156,86,218,110,150,116,207,188,74,204,212,80,39,243,43,75,18,50,76,205,108,25,247,106,42,37,41,3,229,118,48,91,25,100,212,162,83,92,57,98,48,8,83,180,63,145,95,163,
+28,38,170,139,57,49,83,234,214,210,87,187,44,157,43,242,204,64,82,70,127,156,74,73,202,128,155,192,92,106,123,226,27,121,27,218,65,85,213,17,102,85,221,246,215,71,238,151,147,200,91,101,255,156,202,74,152,230,118,34,39,140,46,20,119,102,226,21,29,253,
+113,42,37,41,3,110,144,115,49,83,6,157,61,216,205,67,237,208,228,247,203,188,163,209,63,211,250,59,27,229,196,80,126,93,233,135,36,129,203,188,148,175,155,13,66,64,233,36,101,96,254,206,88,84,223,87,246,125,35,175,229,160,35,87,214,96,146,120,186,237,
+175,118,129,155,254,30,156,103,204,172,181,214,204,69,218,36,99,206,21,113,220,203,87,51,10,1,165,147,148,1,55,200,185,156,250,190,213,176,38,202,113,6,33,96,130,246,167,51,112,154,181,142,254,152,150,73,206,228,246,244,34,109,102,233,60,53,32,100,225,
+123,185,251,249,183,60,56,161,120,146,50,96,176,59,151,19,223,53,252,64,72,61,135,221,219,160,46,120,12,150,120,136,49,164,77,98,38,39,76,158,79,252,153,249,53,169,167,73,50,134,246,235,145,152,192,196,190,19,2,112,35,152,201,169,239,90,5,3,7,245,156,
+50,252,159,58,180,104,187,119,190,61,186,203,163,79,155,69,150,79,183,191,191,207,135,237,119,126,187,253,117,72,146,179,148,83,151,122,97,208,207,161,46,146,50,48,191,220,81,59,17,6,116,86,154,143,99,39,12,28,193,43,148,235,213,221,139,91,174,199,201,
+13,127,87,155,73,201,62,10,193,55,60,56,161,120,146,50,176,204,205,160,15,122,238,249,188,135,74,190,103,84,222,181,158,110,96,215,9,3,71,136,92,126,222,26,200,193,36,114,159,235,87,97,80,143,169,139,53,101,96,126,166,52,163,124,26,84,178,155,81,8,92,
+119,64,93,18,15,34,145,148,129,249,189,15,124,238,125,37,223,243,113,224,107,228,41,210,52,36,183,166,49,8,129,129,19,160,46,233,131,19,137,164,12,64,108,146,9,211,144,220,154,198,239,66,16,210,32,4,160,62,185,55,19,149,164,12,184,57,206,169,150,25,40,
+145,23,216,212,97,153,198,40,4,202,35,7,145,24,6,247,35,177,32,52,73,25,0,187,99,161,227,87,130,65,28,67,146,136,131,105,89,192,95,251,66,101,36,101,96,153,129,70,84,125,5,223,177,83,54,17,79,157,104,92,111,112,47,210,182,192,26,36,101,128,232,58,33,
+96,34,94,195,56,206,91,113,12,201,83,125,152,214,40,4,226,64,93,36,101,96,25,67,224,115,47,125,189,150,206,32,152,137,216,229,225,56,87,201,24,79,55,99,113,189,97,90,163,16,184,39,83,23,73,25,96,110,165,175,215,210,185,68,232,8,23,53,56,255,40,20,234,
+13,112,148,65,8,36,124,169,135,164,12,44,35,242,140,132,210,103,202,124,175,195,130,193,101,81,241,51,152,80,111,0,245,74,12,8,67,82,6,152,91,233,51,101,34,111,135,109,237,142,105,13,66,48,73,7,90,185,84,103,128,227,88,171,201,131,39,42,34,41,3,110,12,
+115,123,84,248,247,139,188,29,246,168,106,78,78,66,225,248,54,82,71,90,125,1,244,59,157,63,97,72,202,128,142,231,220,204,148,41,215,168,106,234,8,22,218,70,26,172,199,96,33,78,112,127,119,254,132,39,41,3,6,106,115,59,117,249,117,88,196,149,123,188,213,
+102,186,55,2,234,214,68,36,124,169,138,164,12,44,195,76,153,50,245,129,175,203,168,90,206,194,123,252,211,180,145,202,167,118,8,56,206,59,231,14,117,144,148,1,55,136,37,116,46,127,241,131,96,166,49,8,193,36,237,163,228,150,251,34,112,156,209,185,67,29,
+36,101,192,32,120,9,93,161,223,171,15,124,77,76,237,85,207,75,238,64,235,80,27,52,1,238,243,135,146,240,165,42,146,50,224,6,177,132,206,229,47,142,228,129,122,94,242,0,221,128,61,222,53,7,220,143,156,55,33,73,202,192,114,62,6,62,247,174,208,239,245,40,
+240,53,209,105,49,216,44,57,94,202,103,251,222,10,1,184,23,57,111,144,148,1,55,137,101,60,44,244,123,157,40,150,168,235,69,198,203,76,46,245,4,56,78,212,228,182,215,179,169,142,164,12,232,128,46,161,243,189,138,51,168,146,179,49,3,96,154,129,131,50,234,
+158,8,204,211,190,58,103,40,136,164,12,232,128,46,161,243,189,8,196,44,143,253,124,20,2,131,69,96,22,131,115,134,242,73,202,192,114,198,192,231,222,249,78,6,67,226,203,158,29,104,51,142,218,245,33,73,94,194,18,162,181,163,239,180,45,212,72,82,6,150,53,
+6,62,247,210,214,111,233,130,15,136,80,207,75,47,143,202,105,219,3,39,96,126,67,176,243,253,221,37,167,70,146,50,96,176,182,148,211,194,190,79,228,69,126,13,136,212,243,26,202,163,114,170,13,2,142,147,147,219,23,129,206,247,194,37,167,70,146,50,96,176,
+182,148,210,146,32,167,129,175,133,53,60,230,55,8,193,209,109,162,153,50,218,32,224,120,81,102,143,188,75,30,138,80,41,73,25,88,214,95,129,207,189,180,36,200,247,6,194,204,72,66,225,248,178,104,54,69,187,6,33,128,197,188,14,114,223,255,183,75,77,173,
+36,101,192,64,109,41,165,37,65,34,207,148,25,85,197,217,189,23,130,157,188,83,86,181,65,192,236,158,7,104,83,46,92,102,106,37,41,3,101,13,64,90,118,234,242,27,16,137,49,95,249,40,142,234,7,48,187,139,198,235,221,115,151,152,154,73,202,192,178,34,207,
+148,41,109,77,153,222,128,8,49,94,221,187,35,255,156,250,12,66,0,171,104,53,113,145,239,183,23,46,47,53,147,148,129,178,6,32,45,51,83,166,12,214,58,49,240,172,169,60,90,16,86,27,4,76,227,162,209,123,211,83,151,150,218,73,202,128,14,105,68,125,224,115,
+55,243,64,93,47,201,160,188,134,99,189,37,88,207,211,198,238,77,191,37,15,65,104,128,164,12,24,20,47,169,119,249,87,39,81,160,174,215,84,22,149,87,245,2,152,206,120,121,252,210,80,91,98,45,25,154,32,41,3,6,197,17,69,126,149,202,83,234,101,59,191,28,55,
+56,31,132,73,189,0,38,117,145,234,95,131,37,247,165,91,155,245,67,96,146,50,96,80,188,164,190,144,239,113,162,24,178,128,191,132,192,224,156,111,152,41,3,235,203,9,141,161,226,239,255,179,182,132,150,72,202,0,17,61,12,124,238,131,203,47,214,133,248,75,
+28,195,25,133,0,138,81,107,98,163,246,132,18,124,67,82,6,12,212,150,244,184,144,239,209,41,134,44,192,180,234,187,189,19,199,112,70,33,128,162,238,81,63,166,186,18,51,57,33,115,225,210,209,26,73,25,32,162,206,64,24,177,46,98,64,176,11,235,32,181,227,
+173,16,64,113,237,112,78,204,188,174,224,123,230,153,61,23,46,25,45,146,148,129,229,13,129,207,189,47,228,123,116,6,194,44,100,20,130,163,219,66,49,84,31,128,121,251,5,57,225,81,234,78,70,249,1,71,13,137,35,56,152,164,12,16,77,228,69,126,205,220,48,8,
+21,67,92,75,224,38,231,105,147,252,40,169,158,254,150,234,123,197,10,246,38,41,3,235,24,2,159,251,105,240,207,95,147,89,50,203,243,186,198,241,109,160,129,124,59,12,172,160,252,182,249,135,180,73,134,172,41,183,251,57,25,243,139,190,11,17,72,202,0,75,
+59,9,254,249,107,119,114,88,150,206,228,241,113,81,110,219,185,230,234,3,212,81,87,115,50,228,159,105,249,135,136,107,126,54,172,70,82,6,214,17,249,105,161,153,50,235,249,75,213,83,215,11,241,94,28,213,5,160,104,99,218,204,86,201,51,103,46,22,248,172,
+188,179,82,78,198,252,38,244,68,35,41,3,235,248,24,248,220,79,92,254,85,59,88,136,121,141,113,49,195,66,93,0,214,145,19,170,57,97,242,255,182,191,78,181,224,110,110,19,114,2,38,39,125,114,50,230,66,91,79,84,223,9,1,172,118,131,139,234,209,202,159,255,
+216,160,8,49,175,46,46,185,205,236,133,173,106,102,234,65,221,114,194,228,34,125,158,53,211,111,143,220,175,59,185,167,141,30,183,71,110,203,243,76,201,193,253,17,62,147,148,129,245,110,108,81,153,41,163,220,69,51,36,9,133,175,237,155,152,254,40,100,
+77,212,3,160,173,58,173,94,195,4,188,190,4,117,12,72,90,98,77,25,229,46,26,201,176,227,99,162,227,95,191,81,8,0,224,91,146,50,96,144,182,52,187,47,41,115,209,188,23,130,47,12,202,111,72,163,16,0,192,183,36,101,96,61,145,103,45,116,43,125,174,89,50,24,
+140,174,239,131,242,171,253,1,0,54,36,101,160,174,129,73,43,186,149,62,215,122,54,172,97,20,130,47,28,58,115,200,108,25,117,0,0,154,35,41,3,58,169,107,232,130,125,110,9,222,170,114,171,25,132,224,11,135,38,87,204,182,168,151,87,248,0,224,22,146,50,176,
+158,200,219,131,118,193,62,23,204,242,248,236,208,228,202,40,116,225,174,57,0,52,79,82,6,214,19,121,128,241,48,216,231,26,20,33,254,199,183,125,127,9,93,181,36,37,1,224,22,146,50,80,223,192,164,5,93,176,207,53,40,98,20,130,163,99,33,177,85,175,65,8,0,
+224,102,146,50,96,144,182,134,110,165,207,141,188,208,175,1,237,186,204,242,56,190,28,74,44,186,215,1,64,115,36,101,64,71,117,13,221,74,159,27,121,75,108,3,218,117,13,66,112,116,57,148,88,116,175,3,128,230,72,202,128,206,234,90,78,26,255,60,229,140,235,
+36,197,54,222,138,161,107,14,0,124,38,41,3,6,203,107,57,109,252,243,148,51,174,51,203,99,227,216,196,202,32,132,225,174,57,0,52,77,82,6,116,86,215,114,226,242,47,102,20,2,215,161,16,146,83,174,57,0,112,141,164,12,172,235,125,224,115,95,122,230,74,31,
+56,214,22,153,45,195,40,4,71,199,192,171,48,245,145,148,1,128,59,72,202,192,186,34,207,148,249,126,161,207,233,46,143,39,151,199,99,229,140,149,73,40,28,159,148,81,150,235,107,123,92,51,0,184,195,119,66,0,171,138,252,4,241,116,166,159,153,143,71,215,
+126,239,53,41,79,170,75,26,160,70,54,42,203,218,30,0,224,75,146,50,96,144,182,150,99,147,37,125,250,156,128,233,82,236,215,147,148,51,3,212,26,140,133,252,12,234,186,230,0,208,52,73,25,48,72,91,203,174,51,101,78,182,127,183,79,159,19,48,167,138,142,114,
+102,128,26,178,28,26,228,215,197,122,86,0,112,15,73,25,88,95,158,197,224,21,155,207,174,18,48,143,183,191,239,132,132,70,140,193,207,255,227,132,113,212,46,212,97,16,2,0,184,155,164,12,172,47,63,61,238,131,158,123,191,29,96,229,95,115,18,38,47,200,43,
+65,101,80,212,250,245,232,149,197,163,228,54,163,83,148,170,48,10,1,0,220,77,82,6,88,211,171,36,9,67,44,31,156,251,209,34,39,178,107,51,10,1,0,220,205,150,216,176,190,200,219,228,74,200,204,207,122,50,101,121,175,44,30,237,163,98,164,237,1,128,86,72,
+202,0,180,205,0,182,44,163,243,54,216,119,205,1,128,43,146,50,176,190,65,8,152,145,1,172,129,106,107,231,109,139,247,58,188,23,2,0,184,159,164,12,64,219,12,96,203,50,4,61,239,119,98,232,154,3,0,223,146,148,1,131,52,218,54,10,129,107,82,128,191,38,254,
+121,146,141,229,115,141,0,96,7,146,50,0,18,0,44,107,112,206,71,51,11,67,57,7,128,38,72,202,128,206,43,237,26,133,160,72,209,118,92,203,51,38,222,205,240,51,209,246,0,64,245,36,101,0,12,140,88,214,16,236,124,95,207,240,51,45,34,171,237,1,128,38,72,202,
+64,25,76,197,103,14,102,19,148,59,96,141,84,231,127,55,232,119,79,3,0,110,38,41,3,101,248,40,4,204,192,108,130,114,253,39,200,121,230,196,224,28,51,101,70,69,168,104,127,9,1,0,236,70,82,6,202,224,169,34,115,13,136,41,211,69,144,235,115,49,211,207,29,
+21,33,247,52,0,104,129,164,12,24,60,99,96,196,58,117,254,117,128,243,252,247,76,63,119,84,132,180,61,0,208,2,73,25,208,129,5,214,241,188,241,243,187,72,243,38,79,180,155,101,202,215,220,131,6,0,216,145,164,12,148,65,7,150,57,12,66,80,252,224,245,183,
+134,207,111,238,164,147,118,83,187,3,0,213,147,148,129,114,120,234,11,241,228,196,197,135,70,207,107,156,249,51,222,42,62,69,114,93,0,96,15,146,50,80,14,79,125,153,146,36,95,61,245,254,105,99,231,52,166,101,102,0,141,138,79,145,94,11,1,0,236,78,82,6,
+202,26,200,192,148,131,125,234,25,196,182,52,144,253,121,161,242,55,40,58,69,150,101,109,15,0,236,65,82,6,202,241,151,16,48,33,51,101,234,146,103,203,140,13,156,199,47,11,150,189,49,73,102,151,230,63,66,0,0,251,145,148,129,114,24,92,48,165,143,66,80,
+149,60,187,96,169,25,38,115,185,72,203,47,92,236,85,153,178,238,97,174,7,0,236,73,82,6,202,234,208,130,242,20,87,158,97,242,99,170,51,49,147,191,251,26,107,227,152,153,81,142,231,66,0,0,251,147,148,1,131,104,148,39,202,145,147,27,249,21,160,15,149,125,
+231,31,87,252,108,101,189,140,246,230,66,24,0,96,127,146,50,96,16,141,242,68,89,242,224,182,150,25,51,175,11,248,174,255,86,100,86,247,139,16,0,0,208,130,63,47,143,255,58,28,19,28,212,239,180,240,54,225,69,33,113,58,185,60,254,86,231,87,59,94,169,170,
+0,112,56,51,101,160,44,163,16,48,1,91,210,182,33,191,154,243,67,42,111,241,212,171,69,137,127,41,232,251,152,45,179,94,236,159,10,3,0,28,78,82,6,12,166,105,115,48,79,59,109,194,207,169,156,157,153,134,84,102,162,232,55,237,231,42,158,138,59,0,28,71,82,
+6,202,242,94,8,152,192,40,4,205,201,73,144,127,166,229,183,156,190,94,166,114,98,232,199,66,203,87,78,12,88,215,100,89,207,147,45,176,1,0,104,204,179,100,125,2,199,241,199,51,85,169,105,221,229,241,50,45,179,142,74,94,211,230,172,162,216,188,81,255,23,
+57,94,170,134,0,0,180,168,215,217,119,76,112,156,170,74,33,228,5,110,115,2,238,143,137,203,207,223,219,65,119,95,105,194,202,162,191,18,50,0,80,141,127,8,1,20,229,116,59,192,130,67,229,215,56,254,159,48,132,147,147,17,79,46,143,199,219,118,164,219,243,
+223,15,105,179,22,209,219,84,255,43,41,57,14,118,4,154,199,69,178,176,47,0,76,74,82,6,202,99,59,99,12,154,56,86,158,69,115,53,99,170,191,225,207,199,237,145,147,120,45,46,12,125,150,204,232,152,90,94,207,200,186,61,0,0,52,207,212,123,199,49,199,19,85,
+8,62,121,169,61,152,236,117,54,237,10,0,0,97,88,168,210,113,204,162,172,128,196,204,84,71,190,31,117,138,17,0,204,199,150,216,0,237,248,143,16,192,23,242,171,124,94,185,217,223,135,109,236,74,221,2,29,0,0,102,115,158,60,157,117,28,246,138,193,137,234,
+3,55,122,146,188,26,186,107,59,114,174,45,1,128,229,152,41,3,208,134,127,167,205,211,109,224,91,121,71,169,60,235,227,157,80,220,40,199,37,207,140,201,59,183,157,107,75,0,0,136,172,79,158,214,58,204,146,129,185,156,39,179,102,174,214,139,121,150,172,
+25,3,0,171,250,78,8,0,170,247,60,121,178,13,187,58,79,155,173,227,127,77,155,173,179,91,117,125,187,243,241,242,248,43,125,222,10,125,80,12,0,160,12,255,16,2,40,210,127,133,128,29,229,193,213,143,194,0,7,233,210,38,57,147,215,156,41,125,182,217,245,36,
+75,254,253,251,91,254,191,87,180,0,160,34,146,50,80,38,73,25,118,29,164,253,144,236,142,2,199,202,9,153,156,152,249,87,218,188,66,186,148,225,218,239,223,222,242,255,7,151,7,0,218,37,41,3,101,122,179,240,192,128,58,253,156,54,11,152,2,211,57,217,182,
+191,143,47,143,211,237,177,235,44,154,60,75,229,234,85,66,73,22,0,224,94,146,50,80,38,73,25,238,243,203,229,241,155,48,192,98,110,75,206,92,79,196,0,0,0,13,120,145,236,12,226,184,253,120,169,138,0,0,64,253,30,8,1,20,233,163,16,112,139,139,203,227,169,
+48,0,0,64,253,36,101,160,76,118,207,224,38,249,149,37,9,25,0,0,104,196,119,66,0,69,146,148,225,186,188,94,69,78,198,88,212,23,0,0,26,98,161,95,40,215,223,105,247,29,63,104,87,78,208,229,93,150,70,161,0,0,128,182,120,125,9,202,53,8,65,104,121,118,76,126,
+93,233,135,36,33,3,0,0,77,146,148,129,114,189,21,130,176,46,46,143,127,38,91,94,3,0,0,192,42,186,100,235,231,72,71,126,93,237,197,246,186,3,0,0,0,43,123,35,89,209,252,241,234,242,56,83,212,1,0,32,30,187,47,65,217,254,115,121,244,194,208,140,49,109,22,
+238,125,159,54,107,6,13,66,2,0,0,113,217,125,9,202,247,103,242,74,75,141,222,109,143,191,210,38,249,146,127,255,65,88,0,0,128,43,102,202,64,249,242,108,153,95,133,161,104,67,250,156,128,121,151,204,128,1,0,0,118,96,166,12,148,239,228,242,248,35,153,45,
+83,130,60,211,37,39,93,242,206,88,99,250,60,27,6,0,0,96,111,146,50,80,135,179,203,227,165,48,44,106,76,95,174,255,50,110,15,0,0,128,73,72,202,64,61,242,78,76,189,48,204,226,106,198,203,251,107,191,183,254,11,0,0,48,43,73,25,168,71,151,54,175,49,157,8,
+197,81,134,244,57,1,51,38,235,191,0,0,0,43,145,148,129,186,156,37,175,49,237,234,250,250,47,249,215,49,89,255,5,0,0,0,56,194,139,203,227,191,142,111,142,63,182,177,121,146,204,38,2,0,0,0,102,146,103,203,68,79,194,252,185,141,195,89,146,132,1,0,0,0,22,
+20,45,49,243,119,250,156,132,233,92,126,0,0,0,96,77,45,39,102,114,18,230,213,229,241,236,242,56,117,169,1,0,0,128,210,180,180,198,76,222,246,251,60,217,250,27,0,0,0,168,196,89,218,204,44,169,117,113,222,222,37,4,0,0,0,106,213,165,205,76,19,59,36,1,0,
+0,0,172,224,44,149,51,107,230,250,14,73,157,75,3,0,0,0,180,46,207,66,57,79,203,39,103,174,47,206,219,185,12,0,0,0,64,84,57,57,115,150,54,175,13,205,149,136,177,67,18,0,0,0,192,29,186,180,73,158,28,187,238,140,29,146,0,0,0,38,240,15,33,128,176,250,180,
+73,212,228,227,97,186,249,117,163,15,151,199,251,203,99,220,30,131,176,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+176,175,255,47,192,0,205,180,140,11,223,168,97,120,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::noise_wave_png = (const char*) temp_9db0b117;
+
+//================== saw_wave.png ==================
+static const unsigned char temp_c4474a8[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,4,180,0,0,2,143,8,6,0,0,0,116,54,147,247,0,0,0,9,112,72,89,115,0,0,23,18,0,0,23,18,1,103,159,210,82,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,
+97,100,121,113,201,101,60,0,0,41,190,73,68,65,84,120,218,236,221,141,149,212,102,186,174,225,103,38,129,211,206,64,206,0,71,176,69,6,56,130,45,34,216,16,1,69,4,248,68,208,58,17,152,12,90,19,1,236,8,80,6,144,129,143,100,53,174,6,131,145,212,245,163,159,
+235,90,235,93,94,158,25,51,174,183,170,87,21,55,42,125,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,242,
+47,43,88,180,155,110,158,116,83,222,255,253,127,125,231,127,247,159,251,191,54,221,188,239,230,147,213,1,0,0,0,112,41,207,186,185,237,230,67,55,127,204,156,15,247,191,198,51,235,4,0,0,0,224,28,250,171,176,250,0,245,49,243,35,214,247,230,227,253,175,253,
+196,154,1,0,0,0,120,172,178,155,187,156,62,98,125,111,238,114,252,250,34,0,0,0,0,140,86,228,178,33,75,216,2,0,0,0,96,182,67,174,23,178,132,45,0,0,0,0,70,235,79,44,188,230,85,89,63,10,91,110,32,15,0,0,0,192,95,250,27,178,159,227,134,239,167,158,254,116,
+196,202,211,5,0,0,0,176,111,253,149,79,107,136,89,194,22,0,0,0,0,127,70,161,63,86,60,194,22,0,0,0,192,142,244,95,51,252,99,35,35,108,1,0,0,0,108,220,90,238,153,37,108,1,0,0,0,240,231,105,134,239,178,189,152,245,117,216,122,113,255,88,1,0,0,0,88,185,55,
+217,118,204,122,56,253,85,104,135,8,91,0,0,0,0,171,85,102,63,49,75,216,2,0,0,0,88,185,62,230,244,95,197,251,99,199,35,108,1,0,0,0,172,200,33,251,142,89,194,22,0,0,0,192,138,244,225,102,139,167,26,10,91,0,0,0,0,27,117,136,120,245,163,176,117,219,77,225,
+165,2,0,0,0,176,12,123,191,119,214,148,17,182,0,0,0,0,174,236,89,68,42,97,11,0,0,0,96,69,250,48,35,80,9,91,0,0,0,0,171,225,102,240,194,22,0,0,0,192,106,148,17,162,206,17,182,158,120,105,1,0,0,0,223,243,111,43,120,148,210,10,78,174,234,230,93,55,119,246,
+11,0,0,0,112,122,125,116,113,85,213,121,71,216,2,0,0,0,56,161,15,17,156,132,45,0,0,0,128,21,17,154,132,45,0,0,0,128,213,40,34,46,9,91,0,0,0,0,43,82,70,84,90,74,216,170,188,28,1,0,0,96,63,156,114,200,218,149,221,220,102,184,159,89,101,29,0,0,0,176,125,
+130,22,91,81,68,216,2,0,0,128,93,16,180,216,154,34,194,22,0,0,0,108,154,160,197,86,21,17,182,0,0,0,96,147,4,45,182,174,136,176,5,0,0,0,155,34,104,177,23,69,134,176,245,177,155,67,55,55,86,2,0,0,0,235,36,104,177,55,125,200,122,149,225,138,173,67,132,45,
+0,0,0,88,29,65,139,189,18,182,0,0,0,96,165,4,45,246,78,216,2,0,0,128,149,17,180,96,32,108,1,0,0,192,74,8,90,240,165,175,195,86,97,37,0,0,0,176,44,130,22,124,219,195,176,213,159,142,88,88,9,0,0,0,44,131,160,5,63,86,69,216,2,0,0,128,197,16,180,96,188,42,
+194,22,0,0,0,92,157,160,5,211,85,17,182,0,0,0,224,106,4,45,152,175,138,176,5,0,0,0,23,39,104,193,227,85,57,134,173,210,58,0,0,0,224,188,4,45,56,157,170,155,187,251,41,173,3,0,0,0,206,67,208,130,211,43,35,108,1,0,0,192,217,8,90,112,62,101,132,45,0,0,0,
+56,57,65,11,206,175,140,176,5,0,0,0,39,35,104,193,229,148,17,182,0,0,0,224,209,4,45,184,188,50,67,212,234,79,70,172,172,3,0,0,0,166,17,180,224,122,138,110,110,35,108,1,0,0,192,36,130,22,92,95,17,97,11,0,0,0,70,19,180,96,57,138,8,91,0,0,0,240,67,130,22,
+44,79,17,97,11,0,0,0,190,75,208,130,229,42,242,101,216,186,177,18,0,0,0,16,180,96,13,138,28,195,214,33,194,22,0,0,0,59,39,104,193,122,244,33,235,85,132,45,0,0,0,118,78,208,130,245,17,182,0,0,0,216,53,65,11,214,75,216,2,0,0,96,151,4,45,88,63,97,11,0,0,
+128,93,17,180,96,59,30,134,173,55,25,110,38,15,0,0,0,155,35,104,193,246,244,97,235,69,134,176,213,159,142,88,88,9,0,0,0,91,34,104,193,182,85,17,182,0,0,0,216,24,65,11,246,161,138,176,5,0,0,192,70,8,90,176,47,85,132,45,0,0,0,86,78,208,130,125,170,34,108,
+1,0,0,176,82,130,22,236,91,149,33,108,221,117,83,90,7,0,0,0,107,32,104,1,189,50,67,212,18,182,0,0,0,88,60,65,11,120,168,140,176,5,0,0,192,194,9,90,192,183,148,17,182,0,0,0,88,40,65,11,248,39,101,132,45,0,0,0,22,70,208,2,198,40,115,12,91,207,172,3,0,0,
+128,107,18,180,128,41,202,110,126,207,112,50,98,101,29,0,0,0,92,131,160,5,204,81,116,115,27,97,11,0,0,128,43,16,180,128,199,40,34,108,1,0,0,112,97,130,22,112,10,69,132,45,0,0,0,46,68,208,2,78,169,136,176,5,0,0,192,153,9,90,192,57,20,57,134,173,67,55,
+55,86,2,0,0,192,169,8,90,204,209,90,1,35,21,221,188,138,176,5,0,0,192,9,9,90,204,241,188,155,167,221,52,86,193,72,125,200,18,182,0,0,0,56,9,65,139,185,154,12,81,75,216,98,10,97,11,0,0,128,71,19,180,120,172,38,67,212,250,165,155,218,58,24,73,216,2,0,0,
+96,54,65,139,83,121,159,225,171,136,63,71,216,98,60,97,11,0,0,128,201,4,45,78,173,141,176,197,116,159,195,214,199,12,167,35,22,86,2,0,0,192,247,8,90,156,75,27,97,139,121,170,12,87,108,9,91,0,0,0,124,147,160,197,185,181,17,182,152,167,138,176,5,0,0,192,
+55,8,90,92,74,27,97,139,121,170,8,91,0,0,0,60,32,104,113,105,109,134,176,245,83,55,175,187,249,100,37,140,84,69,216,2,0,0,32,130,22,215,211,135,172,67,134,43,182,132,45,166,168,114,12,91,79,172,3,0,0,96,127,4,45,174,77,216,98,174,170,155,119,221,220,
+117,83,90,7,0,0,192,126,8,90,44,133,176,197,92,101,134,168,37,108,1,0,0,236,132,160,197,210,8,91,204,85,70,216,2,0,0,216,5,65,139,165,122,24,182,94,102,184,153,60,140,81,70,216,2,0,0,216,52,65,139,165,235,195,214,111,25,194,86,127,58,98,107,37,140,84,
+70,216,2,0,0,216,36,65,139,53,169,35,108,49,93,153,33,106,245,55,144,175,172,3,0,0,96,253,4,45,214,168,142,176,197,116,79,186,185,237,230,67,132,45,0,0,128,85,19,180,88,179,58,194,22,211,21,17,182,0,0,0,86,77,208,98,11,234,8,91,76,87,68,216,2,0,0,88,
+37,65,139,45,169,51,132,173,95,187,105,172,131,145,138,8,91,0,0,0,171,34,104,177,69,111,187,121,122,63,141,117,48,82,17,97,11,0,0,96,21,4,45,182,172,137,176,197,116,69,134,176,245,177,155,67,55,55,86,2,0,0,176,44,130,22,123,208,68,216,98,186,62,100,189,
+202,112,197,214,33,194,22,0,0,192,98,8,90,236,73,19,97,139,233,132,45,0,0,128,133,17,180,216,163,38,194,22,211,9,91,0,0,0,11,33,104,177,103,77,134,168,213,159,140,88,91,7,35,9,91,0,0,0,87,38,104,65,210,118,243,60,194,22,211,124,29,182,10,43,1,0,0,184,
+12,65,11,142,218,8,91,76,247,48,108,245,167,35,22,86,2,0,0,112,94,130,22,252,93,27,97,139,121,170,8,91,0,0,0,103,39,104,193,247,181,17,182,152,167,138,176,5,0,0,112,54,130,22,252,88,155,99,216,250,173,155,79,86,194,72,85,132,45,0,0,128,147,19,180,96,
+188,182,155,151,25,194,214,235,8,91,140,87,69,216,2,0,0,56,25,65,11,166,235,67,214,33,194,22,211,85,25,194,214,239,221,148,214,1,0,0,48,143,160,5,243,9,91,204,245,172,155,187,251,41,173,3,0,0,96,26,65,11,30,79,216,98,174,50,194,22,0,0,192,100,130,22,
+156,142,176,197,92,101,132,45,0,0,128,209,4,45,56,189,135,97,171,63,29,177,181,18,70,42,35,108,1,0,0,252,144,160,5,231,211,135,173,58,194,22,211,149,17,182,0,0,0,190,75,208,130,203,168,35,108,49,93,153,33,106,245,39,35,86,214,1,0,0,48,16,180,224,178,
+234,8,91,76,87,116,115,27,97,11,0,0,224,79,130,22,92,71,29,97,139,233,138,8,91,0,0,0,130,22,92,89,157,99,216,122,111,29,140,84,68,216,2,0,0,118,76,208,130,101,168,187,249,165,155,167,221,52,214,193,72,69,132,45,0,0,96,135,4,45,88,150,38,67,212,18,182,
+152,162,200,151,97,235,198,74,0,0,128,45,19,180,96,153,154,8,91,76,87,228,24,182,14,17,182,0,0,128,141,18,180,96,217,154,8,91,76,215,135,172,87,17,182,0,0,128,141,18,180,96,29,154,8,91,76,39,108,1,0,0,155,36,104,193,186,52,57,134,173,218,58,24,73,216,
+2,0,0,54,69,208,130,117,106,186,121,222,205,207,17,182,24,79,216,2,0,0,54,65,208,130,117,107,35,108,49,221,195,176,213,223,68,190,176,18,0,0,96,77,4,45,216,134,54,194,22,211,245,97,171,138,176,5,0,0,172,140,160,5,219,210,70,216,98,158,42,194,22,0,0,176,
+18,130,22,108,83,27,97,139,121,170,8,91,0,0,192,194,9,90,176,109,109,142,97,235,117,55,159,172,132,145,170,8,91,0,0,192,66,9,90,176,15,109,134,83,237,132,45,166,170,34,108,1,0,0,11,35,104,193,190,244,33,235,16,97,139,233,170,12,97,235,174,155,210,58,
+0,0,128,107,18,180,96,159,132,45,230,42,51,68,45,97,11,0,0,184,26,65,11,246,77,216,98,174,50,194,22,0,0,112,37,130,22,208,251,58,108,181,86,194,72,101,132,45,0,0,224,194,4,45,224,161,135,97,171,63,29,177,181,18,70,42,35,108,1,0,0,23,34,104,1,223,83,71,
+216,98,186,50,199,176,85,89,7,0,0,112,14,130,22,240,35,117,132,45,166,43,187,185,205,112,50,98,101,29,0,0,192,41,9,90,192,88,117,132,45,166,43,34,108,1,0,0,39,38,104,1,83,213,17,182,152,174,136,176,5,0,0,156,136,160,5,204,85,231,24,182,26,235,96,164,
+34,194,22,0,0,240,72,130,22,240,88,117,55,79,239,167,177,14,70,42,34,108,1,0,0,51,9,90,192,169,52,17,182,152,174,200,49,108,29,186,185,177,18,0,0,224,71,4,45,224,212,154,8,91,76,87,116,243,42,194,22,0,0,48,130,160,5,156,75,19,97,139,233,250,144,37,108,
+1,0,0,255,72,208,2,206,173,137,176,197,116,194,22,0,0,240,93,130,22,112,41,77,134,168,245,75,134,27,201,195,24,194,22,0,0,240,55,130,22,112,105,239,187,121,222,205,207,17,182,24,79,216,2,0,0,254,34,104,1,215,210,70,216,98,186,207,97,235,99,134,211,17,
+11,43,1,0,128,253,17,180,128,107,107,35,108,49,79,149,225,138,45,97,11,0,0,118,70,208,2,150,162,141,176,197,60,85,132,45,0,0,216,21,65,11,88,154,54,95,134,173,79,86,194,72,85,132,45,0,0,216,5,65,11,88,170,54,199,176,245,58,194,22,227,85,17,182,0,0,96,
+211,4,45,96,233,250,144,117,136,176,197,116,85,142,97,171,180,14,0,0,216,14,65,11,88,11,97,139,185,170,110,238,238,167,180,14,0,0,88,63,65,11,88,27,97,139,185,202,8,91,0,0,176,9,130,22,176,86,194,22,115,149,17,182,0,0,96,213,4,45,96,237,30,134,173,151,
+25,110,38,15,99,148,17,182,0,0,96,149,4,45,96,43,250,176,245,91,134,176,213,159,142,216,90,9,35,149,17,182,0,0,96,85,4,45,96,139,234,8,91,76,87,102,136,90,239,50,220,72,30,0,0,88,40,65,11,216,178,58,194,22,211,61,233,230,182,155,15,17,182,0,0,96,145,
+4,45,96,15,234,8,91,76,87,68,216,2,0,128,69,18,180,128,61,169,35,108,49,93,17,97,11,0,0,22,69,208,2,246,168,206,16,182,158,118,211,88,7,35,21,17,182,0,0,96,17,4,45,96,207,154,12,81,75,216,98,138,34,194,22,0,0,92,149,160,5,32,108,49,79,145,33,108,125,
+236,230,208,205,141,149,0,0,192,101,8,90,0,71,77,132,45,166,235,67,214,171,12,87,108,29,34,108,1,0,192,217,9,90,0,127,215,68,216,98,58,97,11,0,0,46,68,208,2,248,190,38,199,176,245,214,58,24,73,216,2,0,128,51,19,180,0,126,172,233,230,215,12,39,35,214,
+214,193,72,194,22,0,0,156,137,160,5,48,94,219,205,243,8,91,76,243,48,108,189,201,112,51,121,0,0,224,17,4,45,128,233,218,8,91,76,215,135,173,23,25,194,86,127,58,98,97,37,0,0,48,143,160,5,48,95,27,97,139,121,170,8,91,0,0,48,155,160,5,240,120,109,132,45,
+230,169,34,108,1,0,192,100,130,22,192,233,180,57,134,173,223,186,249,100,37,140,84,69,216,2,0,128,209,4,45,128,211,107,187,121,153,33,108,189,142,176,197,120,85,132,45,0,0,248,33,65,11,224,124,250,144,117,136,176,197,116,85,134,176,245,123,55,165,117,
+0,0,192,151,4,45,128,243,19,182,152,235,89,55,119,247,83,90,7,0,0,12,4,45,128,203,17,182,152,171,140,176,5,0,0,127,17,180,0,46,79,216,98,174,50,194,22,0,0,8,90,0,87,244,57,108,253,148,225,116,196,214,74,24,169,140,176,5,0,192,142,9,90,0,203,80,103,184,
+98,75,216,98,138,50,199,176,245,204,58,0,0,216,11,65,11,96,89,234,8,91,76,87,102,56,17,177,63,25,177,178,14,0,0,182,78,208,2,88,166,58,194,22,211,21,221,220,70,216,2,0,96,227,4,45,128,101,171,35,108,49,93,17,97,11,0,128,13,19,180,0,214,161,206,49,108,
+189,183,14,70,42,34,108,1,0,176,65,130,22,192,186,212,221,252,210,205,211,110,26,235,96,164,34,194,22,0,0,27,34,104,1,172,83,147,33,106,9,91,76,81,228,24,182,94,116,115,99,37,0,0,172,145,160,5,176,110,77,132,45,166,43,186,121,147,33,108,29,34,108,1,0,
+176,50,130,22,192,54,52,17,182,152,174,15,89,175,34,108,1,0,176,50,130,22,192,182,52,17,182,152,78,216,2,0,96,85,4,45,128,109,106,114,12,91,181,117,48,146,176,5,0,192,42,8,90,0,219,214,116,243,188,155,159,35,108,49,158,176,5,0,192,162,9,90,0,251,208,
+70,216,98,186,135,97,171,63,29,177,176,18,0,0,150,64,208,2,216,151,54,194,22,211,245,97,171,138,176,5,0,192,66,8,90,0,251,212,70,216,98,158,42,194,22,0,0,87,38,104,1,236,91,27,97,139,121,170,8,91,0,0,92,137,160,5,64,175,205,16,182,126,234,230,117,55,
+159,172,132,145,170,8,91,0,0,92,152,160,5,192,67,125,200,58,100,184,98,75,216,98,138,42,199,176,245,196,58,0,0,56,39,65,11,128,111,17,182,152,171,234,230,93,55,119,221,148,214,1,0,192,57,8,90,0,252,19,97,139,185,202,12,81,75,216,2,0,224,228,4,45,0,198,
+16,182,152,171,140,176,5,0,192,137,9,90,0,76,241,117,216,106,173,132,145,202,8,91,0,0,156,136,160,5,192,28,15,195,86,127,58,98,107,37,140,84,70,216,2,0,224,145,4,45,0,30,171,142,176,197,116,101,142,97,171,178,14,0,0,166,16,180,0,56,149,58,194,22,211,
+149,221,220,118,243,33,194,22,0,0,35,9,90,0,156,90,29,97,139,233,138,8,91,0,0,140,36,104,1,112,46,117,132,45,166,43,34,108,1,0,240,3,130,22,0,231,86,103,8,91,191,118,211,88,7,35,21,17,182,0,0,248,14,65,11,128,75,121,219,205,211,251,105,172,131,145,138,
+8,91,0,0,124,69,208,2,224,210,154,8,91,76,87,228,24,182,14,221,220,88,9,0,192,126,9,90,0,92,75,19,97,139,233,138,110,94,69,216,2,0,216,53,65,11,128,107,107,34,108,49,93,31,178,132,45,0,128,157,18,180,0,88,138,38,194,22,211,9,91,0,0,59,36,104,1,176,52,
+77,134,168,213,159,140,88,91,7,35,9,91,0,0,59,34,104,1,176,84,109,55,207,35,108,49,205,215,97,171,176,18,0,128,237,17,180,0,88,186,54,194,22,211,61,12,91,253,233,136,133,149,0,0,108,135,160,5,192,90,180,17,182,152,167,138,176,5,0,176,41,130,22,0,107,
+211,70,216,98,158,42,194,22,0,192,38,8,90,0,172,85,155,47,195,214,39,43,97,164,42,194,22,0,192,170,9,90,0,172,93,155,99,216,122,29,97,139,241,170,8,91,0,0,171,36,104,1,176,21,125,200,58,68,216,98,186,42,199,176,85,90,7,0,192,242,9,90,0,108,141,176,197,
+92,85,55,119,247,83,90,7,0,192,114,9,90,0,108,149,176,197,92,101,132,45,0,128,69,19,180,0,216,58,97,139,185,202,8,91,0,0,139,36,104,1,176,23,15,195,86,127,19,249,214,74,24,169,140,176,5,0,176,40,130,22,0,123,211,135,173,58,194,22,211,149,17,182,0,0,22,
+65,208,2,96,207,234,8,91,76,87,102,136,90,253,201,136,149,117,0,0,92,158,160,5,0,194,22,243,20,221,220,70,216,2,0,184,56,65,11,0,142,234,8,91,76,87,68,216,2,0,184,40,65,11,0,254,174,142,176,197,116,69,132,45,0,128,139,16,180,0,224,251,234,12,97,235,105,
+55,141,117,48,82,17,97,11,0,224,172,4,45,0,248,177,38,67,212,18,182,152,162,200,151,97,235,198,74,0,0,78,67,208,2,128,241,154,8,91,76,87,228,24,182,14,17,182,0,0,30,77,208,2,128,233,154,8,91,76,215,135,172,87,17,182,0,0,30,77,208,2,128,249,154,8,91,76,
+39,108,1,0,60,146,160,5,0,143,215,228,24,182,222,90,7,35,9,91,0,0,51,9,90,0,112,58,77,55,191,102,56,25,177,182,14,70,18,182,0,0,38,18,180,0,224,244,218,110,158,71,216,98,154,135,97,235,77,134,155,201,3,0,240,13,130,22,0,156,79,27,97,139,233,250,176,245,
+34,67,216,234,79,71,44,172,4,0,224,75,130,22,0,156,95,27,97,139,121,170,8,91,0,0,127,35,104,1,192,229,180,17,182,152,167,138,176,5,0,240,23,65,11,0,46,175,205,49,108,189,238,230,147,149,48,82,21,97,11,0,32,255,178,130,217,202,110,238,118,250,216,251,
+99,233,27,47,1,128,147,249,124,207,164,255,137,19,238,152,166,206,16,69,91,171,0,128,85,127,22,124,242,157,255,238,125,252,225,39,39,86,118,243,199,78,167,244,244,3,156,237,195,204,161,155,143,59,126,143,49,243,230,206,251,51,0,172,66,145,225,15,50,251,
+171,173,223,77,124,175,239,255,153,42,174,210,230,145,202,8,90,0,156,135,176,101,132,45,0,216,142,162,155,55,25,110,27,112,170,247,252,62,134,189,136,184,197,12,101,4,45,0,206,75,216,50,194,22,0,172,187,27,220,93,224,125,255,119,239,251,76,125,97,10,
+90,0,92,130,176,101,132,45,0,88,87,47,184,68,200,250,214,251,254,19,235,103,204,11,84,208,2,224,210,170,156,246,114,117,35,108,1,0,167,209,255,33,228,239,11,120,223,127,19,7,13,33,104,9,90,0,11,85,69,216,50,243,194,214,51,63,62,0,112,114,253,251,235,
+146,174,166,255,224,247,238,8,90,130,22,128,176,101,182,54,31,238,95,59,0,192,227,189,89,240,123,254,193,211,131,160,37,104,1,8,91,70,216,2,0,62,91,202,87,12,127,52,183,158,42,4,45,65,11,64,216,50,194,22,0,208,199,172,119,43,122,175,23,181,16,180,4,45,
+128,213,132,173,53,125,200,50,194,22,0,136,89,162,22,130,150,160,5,192,95,239,87,215,56,54,218,8,91,0,176,85,107,248,154,161,168,133,160,37,104,1,8,91,102,215,97,235,69,28,253,13,0,159,45,249,6,240,99,231,133,167,209,111,12,4,45,0,132,45,179,135,233,
+143,33,63,8,91,0,236,220,51,191,175,71,208,242,194,7,64,216,50,194,22,0,172,197,205,253,251,224,150,174,194,94,245,251,249,191,189,38,1,96,151,154,110,158,222,79,99,29,76,248,48,255,234,254,67,240,33,194,22,0,251,113,187,177,247,189,226,254,61,157,29,
+42,227,10,45,0,182,227,201,253,7,53,87,33,25,87,108,1,192,126,126,255,95,120,122,189,160,5,45,0,182,160,16,182,140,176,5,0,95,216,242,109,26,238,60,189,130,150,160,5,128,176,101,204,240,186,41,252,8,1,224,247,254,126,143,127,78,238,161,5,0,124,75,219,
+205,243,110,126,238,166,182,14,38,168,50,220,99,75,216,2,96,11,246,112,159,169,255,246,52,239,75,25,87,104,1,176,31,69,92,177,101,92,177,5,192,254,62,255,236,229,253,122,117,183,13,112,133,22,0,48,70,27,87,108,49,79,21,87,108,1,176,78,255,179,179,247,
+235,85,17,180,0,128,41,218,12,97,235,167,110,94,119,243,201,74,152,240,65,89,216,2,96,77,158,237,232,177,174,238,107,135,130,22,0,48,71,31,178,14,25,174,216,18,182,152,162,202,49,108,61,177,14,0,22,170,127,143,42,118,246,120,87,245,181,67,65,11,0,120,
+12,97,139,185,170,110,222,101,56,46,188,180,14,0,22,166,244,152,151,77,208,2,0,78,65,216,226,49,31,158,239,34,108,1,176,44,255,229,49,47,155,160,5,0,156,146,176,197,92,101,132,45,0,150,163,216,225,99,94,213,173,0,4,45,0,224,28,30,134,173,151,25,110,38,
+15,99,148,17,182,0,184,190,39,30,243,178,9,90,0,192,57,245,97,235,183,12,97,171,63,29,177,181,18,70,42,35,108,1,112,29,197,78,31,183,155,194,3,0,124,67,29,97,139,233,202,12,81,171,191,129,124,101,29,0,92,64,177,227,199,190,154,168,37,104,1,0,151,86,71,
+216,98,186,254,107,16,183,221,124,136,176,5,0,231,124,191,93,5,65,11,0,184,150,58,194,22,211,21,17,182,0,96,247,4,45,0,224,218,234,8,91,76,87,68,216,2,128,221,18,180,0,128,165,168,51,132,173,95,187,105,172,131,145,138,8,91,0,176,59,130,22,115,124,178,
+2,0,206,232,109,55,79,239,167,177,14,70,42,34,108,1,192,110,8,90,243,237,249,3,246,123,79,63,0,23,122,175,21,182,152,170,200,16,182,62,118,115,200,202,142,32,7,0,198,17,180,152,202,213,89,0,92,90,19,97,139,233,250,144,245,42,195,21,91,135,8,91,0,176,
+41,130,214,227,63,96,239,141,171,179,0,184,230,251,174,176,197,84,194,22,0,108,144,160,245,56,237,14,31,179,160,5,192,181,53,17,182,152,78,216,2,128,13,17,180,30,231,63,59,124,204,255,235,105,7,96,33,154,12,81,171,63,25,177,182,14,70,18,182,0,96,3,4,
+173,199,127,144,222,155,183,158,118,0,22,166,237,230,121,132,45,166,249,58,108,21,86,2,0,235,33,104,61,254,3,244,158,190,130,215,63,86,55,133,7,96,201,239,203,194,22,83,61,12,91,253,233,136,133,149,0,192,242,9,90,143,247,255,60,86,0,88,148,54,194,22,
+243,84,17,182,0,96,21,4,173,199,123,235,177,2,192,34,181,17,182,152,167,138,176,5,0,139,38,104,157,230,195,242,30,66,79,157,125,158,234,8,192,54,222,171,63,135,173,223,226,235,243,140,87,69,216,2,128,69,18,180,78,227,255,238,224,49,250,186,33,0,107,215,
+118,243,50,67,216,122,29,97,139,241,170,8,91,0,192,70,221,117,243,199,70,231,206,211,11,192,6,245,55,3,63,116,243,113,195,239,225,230,60,243,123,55,165,31,33,128,205,42,119,252,30,231,253,109,135,158,108,248,5,93,120,122,1,16,182,140,249,230,31,250,249,
+224,15,32,104,9,90,87,224,43,135,167,243,62,195,125,57,182,166,127,76,173,167,23,128,13,235,191,122,120,136,175,34,50,239,55,60,119,17,182,0,128,149,235,255,132,183,191,191,194,86,202,236,135,251,199,4,0,123,123,63,63,196,21,91,198,21,91,0,123,85,198,
+21,90,120,225,175,122,158,120,58,1,216,121,216,170,178,173,63,172,50,194,22,0,130,150,160,197,119,189,216,192,139,248,133,167,17,0,254,34,108,25,97,11,64,208,18,180,216,133,219,21,191,128,111,61,125,0,32,108,153,147,222,198,161,242,227,3,32,104,9,90,
+136,90,98,22,0,8,91,70,216,2,64,208,18,180,56,131,155,149,69,45,49,11,0,132,45,35,108,1,8,90,130,22,252,105,13,81,75,204,2,0,97,203,8,91,0,8,90,240,133,37,223,40,222,13,224,1,224,116,31,128,239,132,26,35,108,1,8,90,130,22,91,251,161,88,210,159,222,246,
+255,46,79,60,45,0,32,108,153,69,133,173,27,63,66,0,130,150,160,197,210,244,31,80,222,44,224,69,250,198,135,37,0,16,182,204,34,231,99,55,7,159,213,0,4,45,65,139,37,122,114,165,15,184,253,255,103,97,253,0,112,241,15,198,194,150,17,182,0,214,243,190,45,
+104,193,136,31,148,75,220,52,254,214,11,19,0,22,241,190,47,108,25,97,11,96,249,239,215,130,22,140,84,100,184,57,251,187,19,190,16,223,221,255,154,62,252,0,192,242,62,40,175,225,20,100,35,108,1,236,245,125,90,208,130,25,250,15,41,207,50,220,231,234,238,
+254,195,203,152,15,56,119,247,255,204,51,31,116,0,96,21,138,8,91,70,216,2,88,154,50,130,214,226,253,203,235,116,117,31,122,139,175,254,179,246,126,0,128,117,191,199,191,202,112,194,29,140,245,169,155,183,221,188,246,121,16,224,164,202,12,23,140,236,209,
+211,110,26,47,1,0,0,166,40,226,138,45,51,255,126,169,133,31,33,128,147,40,227,10,173,197,251,183,215,41,0,192,98,180,221,60,239,230,231,110,106,235,96,130,170,155,15,17,182,0,216,9,65,11,0,96,121,218,8,91,204,83,69,216,2,96,7,4,45,0,128,229,106,115,12,
+91,253,125,146,62,89,9,35,85,17,182,0,216,48,65,11,0,96,249,218,12,167,218,9,91,76,85,69,216,2,96,131,4,45,0,128,245,232,67,214,33,194,22,211,85,25,194,86,127,106,87,105,29,0,172,157,160,5,0,176,62,194,22,115,149,25,162,150,176,5,192,170,9,90,0,0,235,
+37,108,49,87,25,97,11,128,21,19,180,0,0,214,239,235,176,213,90,9,35,149,17,182,0,88,33,65,11,0,96,59,30,134,173,254,116,196,214,74,24,169,140,176,5,192,138,8,90,0,0,219,84,71,216,98,186,50,199,176,245,204,58,0,88,42,65,11,0,96,219,234,8,91,76,87,118,
+243,123,134,147,17,43,235,0,96,105,4,45,0,128,125,168,35,108,49,93,209,205,109,132,45,0,22,70,208,2,0,216,151,58,194,22,211,21,17,182,0,88,16,65,11,0,96,159,234,28,195,86,99,29,140,84,68,216,2,96,1,4,45,0,128,125,171,187,121,122,63,141,117,48,82,17,97,
+11,128,43,18,180,0,0,232,53,17,182,152,174,200,49,108,29,186,185,177,18,0,46,65,208,2,0,224,161,38,194,22,211,21,221,188,138,176,5,192,133,8,90,0,0,124,75,19,97,139,233,250,144,37,108,1,112,118,130,22,0,0,255,164,137,176,197,116,194,22,0,103,37,104,1,
+0,48,70,147,33,106,253,146,225,70,242,48,134,176,5,192,89,8,90,0,0,76,241,190,155,231,221,252,28,97,139,241,132,45,0,78,74,208,2,0,96,142,54,194,22,211,125,14,91,31,51,156,142,88,88,9,0,115,8,90,0,0,60,70,27,97,139,121,170,12,87,108,9,91,0,76,38,104,
+1,0,112,10,109,132,45,230,169,34,108,1,48,145,160,5,0,192,41,181,249,50,108,125,178,18,70,170,34,108,1,48,146,160,5,0,192,57,180,57,134,173,215,17,182,24,175,138,176,5,192,15,8,90,0,0,156,83,31,178,14,17,182,152,174,202,49,108,149,214,1,192,67,130,22,
+0,0,151,32,108,49,87,213,205,221,253,148,214,1,64,79,208,2,0,224,146,132,45,230,42,35,108,1,112,79,208,2,0,224,26,132,45,230,42,35,108,1,236,158,160,5,0,192,53,61,12,91,47,51,220,76,30,198,40,35,108,1,236,150,160,5,0,192,18,244,97,235,183,12,97,171,63,
+29,177,181,18,70,42,35,108,1,236,142,160,5,0,192,210,212,17,182,152,174,204,16,181,222,101,184,145,60,0,27,38,104,1,0,176,84,117,132,45,166,123,210,205,109,55,31,34,108,1,108,150,160,5,0,192,210,213,17,182,152,174,136,176,5,176,89,130,22,0,0,107,81,71,
+216,98,186,34,194,22,192,230,8,90,0,0,172,77,157,33,108,253,218,77,99,29,140,84,68,216,2,216,12,65,11,0,128,181,122,219,205,211,251,105,172,131,145,138,8,91,0,171,39,104,1,0,176,118,77,132,45,166,43,50,132,173,143,221,28,186,185,177,18,128,245,16,180,
+0,0,216,138,38,194,22,211,245,33,235,85,134,43,182,14,17,182,0,86,65,208,2,0,96,107,154,8,91,76,39,108,1,172,136,160,5,0,192,86,53,57,134,173,183,214,193,72,194,22,192,10,8,90,0,0,108,93,147,225,68,196,254,100,196,218,58,24,73,216,2,88,48,65,11,0,128,
+189,104,187,121,30,97,139,105,30,134,173,55,25,110,38,15,192,149,9,90,0,0,236,77,27,97,139,233,250,176,245,34,67,216,234,79,71,44,172,4,224,122,4,45,0,0,246,170,141,176,197,60,85,132,45,128,171,18,180,0,0,216,187,54,194,22,243,84,17,182,0,174,66,208,
+2,0,128,65,155,99,216,250,173,155,79,86,194,72,85,132,45,128,139,18,180,0,0,224,75,109,55,47,51,132,173,215,17,182,24,175,138,176,5,112,17,130,22,0,0,124,91,31,178,14,17,182,152,174,202,16,182,126,239,166,180,14,128,211,19,180,0,0,224,159,9,91,204,245,
+172,155,187,251,41,173,3,224,116,4,45,0,0,24,71,216,98,174,50,194,22,192,73,9,90,0,0,48,141,176,197,92,101,132,45,128,147,16,180,0,0,96,158,207,97,235,167,12,167,35,182,86,194,72,101,132,45,128,71,17,180,0,0,224,241,234,12,87,108,9,91,76,81,230,24,182,
+158,89,7,192,120,130,22,0,0,156,78,29,97,139,233,202,12,39,34,246,39,35,86,214,1,240,99,130,22,0,0,156,94,29,97,139,233,138,110,110,35,108,1,252,144,160,5,0,0,231,83,71,216,98,186,34,194,22,192,63,18,180,0,0,224,252,234,28,195,214,123,235,96,164,34,194,
+22,192,55,9,90,0,0,112,57,117,55,191,116,243,180,155,198,58,24,169,136,176,5,240,5,65,11,0,0,46,175,201,16,181,132,45,166,40,114,12,91,47,186,185,177,18,96,175,4,45,0,0,184,158,38,194,22,211,21,221,188,201,16,182,14,17,182,128,29,18,180,0,0,224,250,154,
+8,91,76,215,135,172,87,17,182,128,29,18,180,0,0,96,57,154,8,91,76,39,108,1,187,35,104,1,0,192,242,52,57,134,173,218,58,24,73,216,2,118,67,208,2,0,128,229,106,186,121,222,205,207,17,182,24,79,216,2,54,79,208,2,0,128,229,107,35,108,49,221,195,176,213,159,
+142,88,88,9,176,21,130,22,0,0,172,71,27,97,139,233,250,176,85,69,216,2,54,68,208,2,0,128,245,105,35,108,49,79,21,97,11,216,0,65,11,0,0,214,171,141,176,197,60,85,132,45,96,197,4,45,0,0,88,191,54,67,216,250,169,155,215,221,124,178,18,70,170,34,108,1,43,
+36,104,1,0,192,118,244,33,235,144,225,138,45,97,139,41,170,28,195,214,19,235,0,150,78,208,2,0,128,237,17,182,152,171,234,230,93,55,119,221,148,214,1,44,149,160,5,0,0,219,37,108,49,87,153,33,106,9,91,192,34,9,90,0,0,176,125,194,22,115,149,17,182,128,5,
+18,180,0,0,96,63,190,14,91,173,149,48,82,25,97,11,88,16,65,11,0,0,246,231,97,216,234,79,71,108,173,132,145,202,8,91,192,2,8,90,0,0,176,111,117,132,45,166,43,115,12,91,149,117,0,151,38,104,1,0,0,189,58,194,22,211,149,221,220,118,243,33,194,22,112,65,130,
+22,0,0,240,80,29,97,139,233,138,8,91,192,5,9,90,0,0,192,183,212,17,182,152,174,136,176,5,92,128,160,5,0,0,252,147,58,199,176,213,88,7,35,21,17,182,128,51,18,180,0,0,128,49,234,110,158,222,79,99,29,140,84,68,216,2,206,64,208,2,0,0,166,104,34,108,49,93,
+145,99,216,58,116,115,99,37,192,99,8,90,0,0,192,28,77,132,45,166,43,186,121,21,97,11,120,36,65,11,0,0,120,140,38,194,22,211,245,33,75,216,2,102,19,180,0,0,128,83,104,34,108,49,157,176,5,204,34,104,1,0,0,167,212,100,136,90,253,201,136,181,117,48,146,176,
+5,76,34,104,1,0,0,231,208,118,243,60,194,22,211,124,29,182,10,43,1,190,69,208,2,0,0,206,169,141,176,197,116,15,195,86,127,58,98,97,37,192,67,130,22,0,0,112,9,109,132,45,230,169,34,108,1,95,17,180,0,0,128,75,106,35,108,49,79,21,97,11,184,39,104,1,0,0,
+215,208,230,203,176,245,201,74,24,169,138,176,5,187,39,104,1,0,0,215,212,230,24,182,94,71,216,98,188,42,194,22,236,150,160,5,0,0,44,65,31,178,14,17,182,152,174,202,49,108,149,214,1,251,32,104,1,0,0,75,34,108,49,87,213,205,221,253,148,214,1,219,38,104,
+1,0,0,75,36,108,49,87,25,97,11,54,79,208,2,0,0,150,76,216,98,174,50,194,22,108,150,160,5,0,0,172,193,195,176,213,223,68,190,181,18,70,42,35,108,193,230,8,90,0,0,192,154,244,97,171,142,176,197,116,101,132,45,216,12,65,11,0,0,88,171,58,194,22,211,149,25,
+162,214,187,12,55,146,7,86,72,208,2,0,0,214,174,142,176,197,116,79,186,185,237,230,67,132,45,88,29,65,11,0,0,216,138,58,194,22,211,21,17,182,96,117,4,45,0,0,96,107,234,8,91,76,87,68,216,130,213,16,180,0,0,128,173,170,51,132,173,167,221,52,214,193,72,
+69,132,45,88,60,65,11,0,0,216,186,38,67,212,18,182,152,162,200,151,97,235,198,74,96,57,4,45,0,0,96,47,154,8,91,76,87,228,24,182,14,17,182,96,17,4,45,0,0,96,111,154,8,91,76,215,135,172,87,17,182,96,17,4,45,0,0,96,175,154,8,91,76,39,108,193,2,8,90,0,0,
+192,222,53,57,134,173,183,214,193,72,194,22,92,145,160,5,0,0,48,104,186,249,53,195,201,136,181,117,48,146,176,5,87,32,104,1,0,0,124,169,237,230,121,132,45,166,121,24,182,222,100,184,153,60,112,38,130,22,0,0,192,183,181,17,182,152,174,15,91,47,50,132,
+173,254,116,196,194,74,224,244,4,45,0,0,128,127,214,70,216,98,158,42,194,22,156,133,160,5,0,0,48,78,27,97,139,121,170,8,91,112,82,130,22,0,0,192,52,109,142,97,235,117,55,159,172,132,145,170,8,91,112,18,130,22,0,0,192,60,109,134,83,237,132,45,166,170,
+34,108,193,163,8,90,0,0,0,143,211,135,172,67,132,45,166,171,50,132,173,187,110,74,235,128,241,4,45,0,0,128,211,16,182,152,171,204,16,181,132,45,24,73,208,2,0,0,56,45,97,139,185,202,8,91,48,138,160,5,0,0,112,30,194,22,115,149,17,182,224,31,9,90,0,0,0,
+231,245,57,108,253,148,225,116,196,214,74,24,169,140,176,5,223,36,104,1,0,0,92,78,157,225,138,45,97,139,41,202,28,195,214,51,235,0,65,11,0,0,224,26,234,8,91,76,87,118,243,123,134,147,17,43,235,96,207,4,45,0,0,128,235,169,35,108,49,93,209,205,109,132,
+45,118,76,208,2,0,0,184,190,58,194,22,211,21,17,182,216,41,65,11,0,0,96,57,234,28,195,214,123,235,96,164,34,194,22,59,35,104,1,0,0,44,79,221,205,47,221,60,237,166,177,14,70,42,34,108,177,19,130,22,0,0,192,114,53,25,162,150,176,197,20,69,142,97,235,69,
+55,55,86,194,214,8,90,0,0,0,203,215,68,216,98,186,162,155,55,25,194,214,33,194,22,27,34,104,1,0,0,172,71,19,97,139,233,250,144,245,42,194,22,27,34,104,1,0,0,172,79,19,97,139,233,132,45,54,67,208,2,0,0,88,175,38,67,212,234,111,32,95,91,7,35,9,91,172,158,
+160,5,0,0,176,126,239,187,121,222,205,207,17,182,24,79,216,98,181,4,45,0,0,128,237,104,35,108,49,221,231,176,245,49,195,233,136,133,149,176,116,130,22,0,0,192,246,180,17,182,152,167,202,112,197,150,176,197,162,9,90,0,0,0,219,213,70,216,98,158,42,194,
+22,11,38,104,1,0,0,108,95,27,97,139,121,170,8,91,44,144,160,5,0,0,176,31,109,134,176,245,83,55,175,187,249,100,37,140,84,69,216,98,65,4,45,0,0,128,253,233,67,214,33,195,21,91,194,22,83,84,57,134,173,39,214,193,181,8,90,0,0,0,251,37,108,49,87,213,205,
+187,110,238,186,41,173,131,75,19,180,0,0,0,16,182,152,171,204,16,181,132,45,46,74,208,2,0,0,224,51,97,139,185,202,8,91,92,144,160,5,0,0,192,215,30,134,173,151,25,110,38,15,99,148,17,182,184,0,65,11,0,0,128,239,233,195,214,111,25,194,86,127,58,98,107,
+37,140,84,70,216,226,140,4,45,0,0,0,198,168,35,108,49,93,153,99,216,170,172,131,83,17,180,0,0,0,152,162,142,176,197,116,101,55,183,221,124,136,176,197,9,8,90,0,0,0,204,81,71,216,98,186,34,194,22,39,32,104,1,0,0,240,24,117,132,45,166,43,34,108,241,8,130,
+22,0,0,0,167,80,103,8,91,191,118,211,88,7,35,21,17,182,152,65,208,2,0,0,224,148,222,118,243,244,126,26,235,96,164,34,194,22,19,8,90,0,0,0,156,67,19,97,139,233,138,12,97,235,99,55,135,110,110,172,132,111,17,180,0,0,0,56,167,38,194,22,211,245,33,235,85,
+134,43,182,14,17,182,248,138,160,5,0,0,192,37,52,17,182,152,78,216,226,155,4,45,0,0,0,46,169,137,176,197,116,194,22,95,16,180,0,0,0,184,134,38,67,212,234,79,70,172,173,131,145,132,45,254,36,104,1,0,0,112,77,109,55,207,35,108,49,205,215,97,171,176,146,
+125,17,180,0,0,0,88,130,54,194,22,211,61,12,91,253,233,136,133,149,236,131,160,5,0,0,192,146,180,17,182,152,167,138,176,181,27,130,22,0,0,0,75,212,70,216,98,158,42,194,214,230,9,90,0,0,0,44,89,155,99,216,250,173,155,79,86,194,72,85,132,173,205,18,180,
+0,0,0,88,131,182,155,151,25,194,214,235,8,91,140,87,69,216,218,28,65,11,0,0,128,53,233,67,214,33,194,22,211,85,25,194,214,239,221,148,214,177,110,130,22,0,0,0,107,36,108,49,215,179,110,238,238,167,180,142,117,18,180,0,0,0,88,51,97,139,185,202,8,91,171,
+37,104,1,0,0,176,5,194,22,115,149,17,182,0,0,0,128,5,184,201,241,158,73,127,24,51,97,246,252,154,41,215,242,3,238,10,45,0,0,0,182,168,191,66,171,206,112,197,214,243,12,167,36,194,24,133,21,44,159,160,5,0,0,192,214,213,17,182,96,83,4,45,0,0,0,246,162,
+142,176,5,155,32,104,1,0,0,176,55,117,132,45,88,53,65,11,0,0,128,189,170,35,108,193,42,9,90,0,0,0,236,93,157,33,108,61,237,166,177,14,88,62,65,11,0,0,0,6,77,134,168,37,108,193,194,9,90,0,0,0,240,165,38,194,22,44,154,160,5,0,0,0,223,214,68,216,130,69,
+18,180,0,0,0,224,159,53,17,182,96,81,4,45,0,0,0,24,167,201,49,108,213,214,1,215,35,104,1,0,0,192,52,77,55,207,51,156,140,88,91,7,92,158,160,5,0,0,0,243,180,17,182,224,42,4,45,0,0,0,120,156,54,194,22,92,148,160,5,0,0,0,167,209,70,216,130,139,16,180,0,
+0,0,224,180,218,8,91,112,86,130,22,0,0,0,156,71,155,99,216,122,221,205,39,43,129,211,16,180,0,0,0,224,188,218,110,14,17,182,224,100,4,45,0,0,0,184,140,62,100,29,34,108,193,163,9,90,0,0,0,112,89,194,22,60,146,160,5,0,0,0,215,33,108,193,76,130,22,0,0,0,
+92,151,176,5,19,9,90,0,0,0,176,12,159,195,214,79,25,78,71,108,173,4,190,77,208,2,0,0,128,229,169,51,92,177,37,108,193,55,8,90,0,0,0,176,92,117,132,45,248,27,65,11,0,0,0,150,175,142,176,5,127,17,180,0,0,0,96,61,234,8,91,32,104,1,0,0,192,10,213,57,134,
+173,198,58,216,27,65,11,0,0,0,214,171,238,230,233,253,52,214,193,94,8,90,0,0,0,176,126,77,132,45,118,68,208,2,0,0,128,237,104,34,108,177,3,130,22,0,0,0,108,79,19,97,139,13,19,180,0,0,0,96,187,154,8,91,108,144,160,5,0,0,0,219,215,100,136,90,191,100,184,
+145,60,172,154,160,5,0,0,0,251,241,190,155,231,221,252,28,97,139,21,19,180,0,0,0,96,127,218,8,91,172,152,160,5,0,0,0,251,213,70,216,98,133,4,45,0,0,0,160,141,176,197,138,8,90,0,0,0,192,103,109,190,12,91,159,172,132,37,18,180,0,0,0,128,175,181,57,134,
+173,215,17,182,88,24,65,11,0,0,0,248,158,62,100,29,34,108,177,48,130,22,0,0,0,240,35,194,22,139,34,104,1,0,0,0,99,9,91,44,130,160,5,0,0,0,76,37,108,113,85,130,22,0,0,0,48,215,195,176,245,50,195,205,228,225,236,4,45,0,0,0,224,177,250,176,245,91,134,176,
+213,159,142,216,90,9,231,36,104,1,0,0,0,167,84,71,216,226,204,4,45,0,0,0,224,28,234,8,91,156,137,160,5,0,0,0,156,83,29,97,139,19,19,180,0,0,0,128,75,168,35,108,113,34,130,22,0,0,0,112,73,117,134,176,245,107,55,141,117,0,0,0,0,176,54,101,55,119,221,252,
+97,174,62,79,188,28,1,0,0,0,198,43,35,108,93,123,0,0,0,0,152,161,140,176,37,104,1,0,0,0,172,80,25,97,235,146,115,183,166,23,135,155,194,3,0,0,0,75,212,116,243,244,126,222,90,199,217,181,107,250,151,21,180,0,0,0,128,37,107,50,156,136,216,159,140,88,91,
+199,217,252,175,21,0,0,0,0,156,71,209,205,109,124,69,208,9,135,0,0,0,0,43,83,68,216,58,213,124,240,114,2,0,0,0,184,156,34,194,214,99,231,141,151,17,0,0,0,192,229,21,17,182,124,221,16,0,0,0,96,133,138,12,87,28,125,140,80,53,102,222,121,201,0,0,0,0,44,
+195,77,55,135,8,91,63,154,202,75,5,0,0,0,96,89,132,45,55,131,7,0,0,0,88,37,97,203,213,89,0,0,0,0,171,36,108,185,119,22,0,0,0,192,42,237,61,108,57,217,16,0,0,0,96,165,250,176,85,101,184,159,212,94,98,214,193,211,14,0,0,0,176,13,85,182,31,182,238,60,205,
+0,0,0,0,219,83,101,155,97,171,127,76,55,158,94,0,0,0,128,237,170,178,157,176,213,223,43,204,125,179,0,0,0,0,118,162,202,186,195,150,152,5,0,0,0,176,83,85,55,239,34,102,1,0,0,0,176,50,101,134,155,171,47,61,102,245,241,77,204,2,0,0,0,224,47,101,150,27,
+182,126,143,27,192,3,0,0,0,240,29,101,150,19,182,250,175,24,62,243,148,0,0,0,0,48,70,153,235,134,173,219,184,42,11,0,0,0,128,25,202,92,54,108,245,33,171,176,118,0,0,0,0,30,171,232,230,77,134,175,1,158,58,98,125,232,230,16,33,11,0,0,0,128,51,233,239,107,
+213,199,173,254,228,193,199,156,90,216,255,26,187,63,185,240,95,94,79,0,0,0,0,23,87,102,184,186,170,159,255,147,191,71,170,255,220,255,181,189,159,198,202,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,231,254,191,0,3,0,11,98,146,161,132,82,43,233,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::saw_wave_png = (const char*) temp_c4474a8;
+
+//================== sine_wave.png ==================
+static const unsigned char temp_77db788[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,4,180,0,0,2,171,8,6,0,0,0,232,11,212,215,0,0,0,9,112,72,89,115,0,0,23,18,0,0,23,18,1,103,159,210,82,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,
+97,100,121,113,201,101,60,0,0,49,204,73,68,65,84,120,218,236,221,175,151,36,199,149,40,224,24,205,3,122,200,13,197,156,203,196,92,102,102,78,49,9,109,137,237,178,52,123,102,229,191,96,211,232,157,69,101,182,176,198,200,107,84,18,178,141,170,133,158,88,
+143,153,30,170,22,211,67,51,98,54,242,203,112,85,107,122,52,61,221,153,89,249,43,50,191,239,156,123,122,108,31,219,163,232,200,31,113,51,238,141,15,2,0,0,0,0,36,228,3,67,0,0,0,0,64,74,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,
+0,0,0,0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,
+64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,
+66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,
+0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,32,61,87,
+85,228,134,1,0,0,88,170,255,97,8,0,6,19,19,81,171,123,63,127,114,254,121,255,63,187,212,245,189,63,191,174,226,175,247,254,245,237,57,226,191,255,210,175,3,0,0,72,213,51,67,0,208,169,152,148,202,206,63,127,122,254,243,93,76,205,237,57,190,186,247,231,
+107,191,66,0,0,96,234,36,180,0,218,203,194,41,113,245,203,243,207,124,38,255,92,113,247,214,109,56,237,238,122,121,239,95,3,0,0,76,130,132,22,64,61,119,37,129,121,21,63,59,255,188,90,208,63,127,44,83,188,14,167,221,92,241,167,146,69,0,0,96,52,18,90,0,
+15,187,107,188,254,203,243,207,149,33,121,203,109,120,59,193,117,107,72,0,0,128,161,72,104,1,188,17,147,88,235,42,254,245,252,147,250,226,142,173,235,112,74,112,125,97,56,0,0,0,0,250,147,85,177,169,226,80,197,63,68,103,177,175,162,8,211,108,134,15,0,
+0,0,144,156,44,156,146,88,55,65,226,105,200,228,214,149,169,7,0,0,0,80,95,22,36,177,166,148,220,2,0,0,0,224,61,98,47,44,229,132,211,139,87,85,236,130,94,101,0,0,0,0,255,148,85,81,86,113,12,18,71,41,37,183,156,36,9,0,0,0,44,78,220,237,19,75,218,36,137,
+210,141,88,18,90,152,202,0,0,0,192,156,197,70,227,177,55,150,221,88,243,138,248,251,44,130,70,242,0,0,0,192,140,196,242,180,88,166,38,249,51,255,114,196,50,72,108,1,0,0,0,9,203,131,38,239,18,91,0,0,0,0,9,200,131,68,150,56,69,220,153,151,185,36,0,0,0,
+128,169,202,131,68,150,144,216,2,0,0,0,18,144,7,137,44,33,177,5,0,0,0,36,32,15,18,89,162,93,148,65,143,45,0,0,0,96,64,121,144,200,18,154,199,3,0,0,0,9,200,170,216,7,137,24,209,109,28,171,40,92,94,0,0,0,64,151,226,14,154,50,156,118,212,72,192,136,62,19,
+91,185,203,13,0,0,0,184,212,58,156,18,13,18,46,98,168,136,229,172,185,75,15,0,0,0,104,42,11,250,100,137,241,79,68,212,95,11,0,0,0,120,210,93,121,161,132,138,152,74,227,248,141,203,18,0,0,0,120,159,34,40,47,20,211,45,67,92,185,68,1,0,0,128,59,49,81,160,
+188,80,164,16,165,203,21,0,0,0,40,131,36,137,112,26,34,0,0,0,144,128,184,43,235,38,72,142,8,77,227,1,0,0,128,4,196,38,219,18,34,98,46,77,227,215,46,105,0,0,0,152,175,44,232,149,37,230,219,52,62,115,137,3,0,192,244,60,55,4,192,5,226,46,150,63,85,241,177,
+161,96,134,178,112,58,165,243,255,85,241,210,112,0,0,0,64,218,98,143,161,125,176,131,71,44,39,246,65,111,45,0,0,152,140,103,134,0,104,40,183,184,103,161,110,171,248,60,216,173,5,0,0,163,251,192,16,0,53,197,4,214,54,156,250,10,73,102,177,68,89,56,157,
+226,185,49,20,0,0,48,46,59,180,128,58,86,85,236,206,63,129,16,174,195,105,183,214,107,67,1,0,0,195,179,67,11,120,74,17,78,187,178,36,179,224,141,188,138,227,249,39,0,0,48,48,9,45,224,125,98,89,225,238,28,74,12,225,225,107,36,38,123,183,134,2,0,0,134,
+165,228,16,120,72,22,78,141,223,237,202,130,122,98,163,248,88,130,120,107,40,0,0,160,127,118,104,1,63,182,14,167,198,215,146,89,80,223,234,124,221,172,13,5,0,0,244,239,185,33,0,238,137,165,83,191,171,226,67,67,1,141,197,235,230,223,194,169,20,241,47,
+134,3,0,0,250,163,228,16,8,231,5,120,44,49,204,13,5,116,226,58,56,5,17,0,0,122,163,228,16,200,131,211,218,160,143,235,202,233,160,0,0,208,19,9,45,88,182,242,188,232,118,138,33,116,111,117,190,190,244,213,2,0,128,142,233,161,5,203,20,19,88,127,168,226,
+127,25,10,232,213,93,95,173,88,226,127,109,56,0,0,160,27,18,90,176,60,49,153,21,119,141,228,134,2,6,19,175,183,172,138,175,170,248,155,225,0,0,128,203,104,10,15,203,114,87,2,165,196,16,198,241,50,156,154,197,223,26,10,0,0,104,79,15,45,88,142,34,72,102,
+193,216,98,82,249,38,216,33,9,0,0,23,145,208,130,101,216,84,177,11,146,89,48,5,119,101,191,133,161,0,0,128,118,148,28,194,252,237,44,156,97,178,94,84,241,43,195,0,0,0,205,104,10,15,243,21,119,129,252,159,42,62,53,20,48,89,177,4,49,171,226,75,67,1,0,0,
+245,41,57,132,249,46,146,15,231,159,192,180,21,225,212,87,75,73,48,0,0,212,36,161,5,243,147,7,201,44,72,205,93,18,58,51,20,0,0,240,52,9,45,152,151,34,56,201,16,82,117,119,2,162,100,52,0,0,60,65,66,11,230,227,238,36,67,32,93,119,39,32,230,134,2,0,0,222,
+207,41,135,48,15,78,50,132,249,137,167,31,190,48,12,0,0,240,46,167,28,66,250,36,179,96,158,214,225,244,225,233,218,80,0,0,192,219,36,180,32,109,146,89,48,111,121,56,53,138,255,210,80,0,0,192,27,18,90,144,166,216,103,231,79,225,180,131,3,152,183,213,57,
+254,82,197,223,12,7,0,0,232,161,5,41,186,107,26,237,36,52,88,150,151,85,124,82,197,107,67,1,0,192,210,57,229,16,210,34,153,5,203,181,58,95,255,87,134,2,0,128,165,147,208,130,116,100,65,50,11,150,78,82,11,0,0,130,146,67,176,136,101,74,98,41,217,203,243,
+159,191,106,240,223,251,73,120,59,209,153,157,131,249,82,126,8,0,192,162,73,104,193,244,73,102,205,207,203,115,252,245,252,243,126,34,171,75,121,120,147,220,250,101,144,232,154,227,60,146,212,2,0,96,145,36,180,96,218,36,179,210,23,147,13,215,225,148,
+188,138,63,239,18,88,99,137,115,41,15,167,4,87,30,148,176,166,78,82,11,0,128,69,146,208,130,233,146,204,74,215,109,21,95,84,241,251,208,207,206,171,46,101,225,77,130,107,109,190,37,73,82,11,0,0,128,73,136,201,172,87,85,252,67,36,19,55,85,148,33,253,29,
+79,241,239,191,173,226,232,119,154,220,252,147,140,4,0,0,96,212,132,130,100,86,26,17,147,62,101,152,111,95,170,188,138,157,249,40,169,5,0,0,0,143,145,204,74,35,246,225,84,158,183,36,241,159,87,114,75,82,11,0,0,0,222,34,153,101,55,86,10,174,206,227,96,
+174,78,55,94,5,205,254,1,0,0,24,128,100,214,116,35,54,230,95,155,162,239,184,75,108,233,181,53,221,164,150,157,90,0,0,0,244,70,50,107,186,137,172,220,244,172,165,8,18,91,202,15,1,0,0,88,12,201,44,137,172,57,41,130,196,150,164,22,0,0,0,179,38,153,37,145,
+53,87,69,144,216,146,212,2,0,0,96,118,36,179,36,178,230,78,243,120,73,45,0,0,0,102,68,50,107,58,167,22,230,166,99,239,238,18,91,230,220,52,146,90,0,0,0,208,152,100,214,52,78,127,43,77,197,193,101,85,236,204,191,209,99,103,42,2,0,0,208,132,100,214,248,
+177,63,39,86,24,247,58,56,152,139,146,90,0,0,0,76,95,44,187,186,177,144,86,94,200,15,54,65,130,87,82,11,0,0,128,201,146,204,26,183,188,112,99,10,78,86,22,78,187,230,204,85,73,45,0,0,0,38,68,50,107,220,211,11,51,83,48,9,235,112,218,69,103,222,14,31,91,
+211,15,0,0,128,31,179,251,100,156,176,43,43,61,49,249,187,53,119,71,137,194,244,3,0,0,224,142,19,221,134,143,184,27,110,101,234,37,45,15,118,53,74,106,1,0,0,48,10,201,44,165,83,92,198,110,45,73,45,0,0,0,6,84,90,24,59,193,144,78,196,222,90,78,66,28,246,
+16,5,59,28,1,0,0,22,168,176,40,30,252,148,182,43,211,110,214,226,239,247,96,174,75,106,1,0,0,208,143,194,98,120,208,69,119,97,202,45,74,105,222,15,122,125,101,166,28,0,0,192,252,229,22,193,26,191,51,200,117,118,116,13,12,118,157,217,253,8,0,0,48,99,49,
+185,162,207,207,48,177,183,200,94,188,171,243,60,112,61,72,106,1,0,0,112,193,226,90,50,107,152,216,152,110,220,179,113,77,12,18,7,83,13,0,0,96,94,98,50,235,198,130,87,147,106,70,147,7,9,229,161,14,95,0,0,0,96,38,148,61,13,179,59,68,201,19,143,201,130,
+196,178,164,22,0,0,0,181,236,44,112,123,143,210,52,163,166,43,215,164,178,95,0,0,0,30,167,119,79,255,37,134,107,211,140,22,74,215,79,239,81,152,102,0,0,0,233,41,44,104,245,203,98,210,214,65,95,173,190,35,55,205,0,0,0,210,177,178,144,237,53,98,31,36,253,
+178,232,234,90,61,186,166,36,158,1,0,0,44,144,237,250,232,187,225,180,100,22,93,138,243,233,224,218,234,45,142,174,89,0,0,128,233,47,140,157,162,214,95,108,77,49,122,164,89,124,191,187,42,1,0,0,152,32,201,44,13,166,73,223,214,181,214,235,238,74,0,0,0,
+38,198,238,142,254,122,240,228,166,23,3,42,92,119,189,69,105,122,1,0,0,76,71,105,161,218,91,153,146,134,210,140,193,9,136,118,91,2,0,0,204,90,97,129,234,36,67,102,201,1,15,253,133,68,53,0,0,128,5,175,100,22,244,120,141,235,141,215,79,41,177,164,22,0,
+0,192,8,174,130,100,86,31,113,8,146,89,76,239,90,151,212,146,184,6,0,0,176,192,21,78,65,35,185,107,222,193,15,253,36,181,0,0,0,24,136,133,173,100,22,174,125,225,218,7,0,0,72,70,105,1,106,65,203,162,73,106,117,31,165,105,5,0,0,208,159,194,194,179,243,
+216,152,86,36,72,82,171,251,88,155,86,0,0,0,221,115,162,97,247,81,152,86,36,76,82,203,201,135,0,0,0,147,230,68,67,201,44,120,136,164,150,147,15,1,0,0,38,201,137,134,146,89,240,24,73,173,110,99,111,74,1,0,0,88,172,74,102,129,251,132,222,122,0,0,0,11,82,
+90,88,74,102,65,77,146,90,221,70,110,74,1,0,0,52,183,182,160,148,204,130,134,36,181,186,109,18,159,153,82,0,0,0,245,57,209,80,50,11,218,146,212,210,36,30,0,0,96,112,154,192,75,102,193,165,36,181,186,139,157,233,4,0,0,240,180,189,5,164,100,22,116,64,82,
+75,147,120,0,0,128,65,108,44,28,37,179,160,67,146,90,154,196,3,0,0,244,42,183,96,148,204,130,30,216,245,169,73,60,0,0,64,47,178,160,9,188,100,22,244,67,95,62,77,226,1,0,0,44,54,131,100,22,184,207,104,18,15,0,0,176,104,122,220,88,100,194,16,36,181,36,
+207,1,0,0,58,81,88,24,74,102,193,128,36,181,186,139,149,233,4,0,0,44,209,202,130,80,50,11,70,16,147,90,71,247,142,139,227,24,244,211,2,0,0,22,184,160,212,4,190,155,6,205,64,115,43,247,160,78,226,96,42,1,0,0,75,114,176,16,116,218,24,140,76,82,171,155,
+216,154,74,0,0,192,18,108,45,0,37,179,96,34,148,62,119,19,107,83,9,0,0,152,179,181,133,223,197,17,119,148,100,166,18,116,166,112,95,233,228,190,164,73,60,0,0,48,75,89,80,222,99,209,8,211,84,184,191,216,57,10,0,64,63,158,27,2,18,23,251,102,101,134,161,
+181,215,85,124,82,197,75,67,1,157,139,215,213,179,42,114,67,209,218,71,231,248,210,80,0,0,0,115,161,111,214,229,81,152,70,208,187,157,123,205,197,177,49,141,0,0,128,57,208,55,75,50,11,82,34,169,117,121,40,141,6,0,0,146,22,23,53,250,102,93,22,59,211,8,
+6,119,227,222,115,113,191,63,253,180,0,0,128,36,93,89,20,94,28,123,211,8,220,191,18,141,131,105,4,0,0,164,72,217,142,19,195,32,101,146,90,151,71,105,26,1,0,0,41,41,44,228,46,138,99,144,204,130,41,80,54,125,121,228,166,17,0,0,96,1,184,140,222,51,26,42,
+195,180,238,105,238,77,250,105,1,0,0,51,166,68,199,110,6,152,163,194,189,73,63,45,0,0,218,121,110,8,72,192,127,85,241,169,97,104,237,87,85,124,97,24,96,114,94,86,241,44,72,56,183,149,157,199,239,218,80,0,0,0,83,83,4,187,16,52,79,134,121,115,216,133,29,
+168,0,0,192,140,232,155,117,89,236,76,33,72,134,178,106,253,180,0,0,128,25,208,55,235,178,184,49,133,192,61,47,232,167,5,0,0,48,40,37,56,237,227,24,236,86,128,20,217,149,170,196,26,0,0,72,88,97,97,118,81,233,205,202,20,130,100,229,238,99,250,105,1,0,
+0,233,177,67,225,178,88,155,66,144,188,194,189,76,63,45,0,0,32,29,122,200,92,22,27,83,8,102,99,235,158,166,159,22,0,0,96,1,231,68,67,32,53,123,247,54,253,180,0,0,128,105,91,91,128,57,209,16,120,139,93,171,151,133,126,130,0,0,64,175,178,160,111,150,19,
+13,129,135,232,43,232,254,8,0,0,76,148,29,8,78,52,4,222,207,14,214,246,177,55,125,0,0,128,62,232,155,229,68,67,224,105,165,123,158,123,37,0,0,48,13,118,29,56,209,16,168,79,147,248,246,187,89,51,211,7,0,0,232,66,22,244,133,113,162,33,208,132,38,241,237,
+227,96,250,0,0,0,93,56,88,96,181,62,209,80,147,99,88,46,77,226,219,71,105,250,0,0,0,151,40,45,172,148,205,0,173,41,215,110,31,14,210,0,0,0,90,201,45,168,52,54,6,46,86,186,39,182,138,99,176,203,21,0,0,104,232,234,188,152,176,168,82,42,3,92,78,147,120,
+125,8,1,0,0,139,175,201,198,222,212,1,30,160,73,188,29,175,0,0,64,207,244,124,81,30,3,116,79,147,120,61,9,1,0,128,158,100,22,92,173,23,92,26,24,3,79,41,220,47,91,197,193,212,1,0,72,215,115,67,192,0,98,201,220,199,134,161,177,95,87,241,103,195,0,60,225,
+101,56,237,228,252,133,161,104,36,171,226,89,21,215,134,2,0,0,248,177,77,176,11,160,77,108,77,29,160,33,253,180,218,133,157,176,0,0,192,91,86,22,74,173,226,198,212,1,90,136,187,180,148,119,183,187,231,234,85,8,0,0,252,192,110,129,118,125,179,44,172,128,
+182,114,247,81,187,98,1,0,128,246,182,22,72,74,95,128,81,40,245,110,23,107,83,7,0,0,150,45,183,48,106,21,27,83,7,232,200,206,61,213,14,89,0,0,160,190,184,24,56,90,24,53,142,189,169,3,116,124,47,86,246,221,60,14,166,14,0,0,44,211,222,130,168,113,28,131,
+93,1,64,247,98,9,179,38,241,118,203,2,0,0,79,40,44,132,244,205,2,38,101,237,30,235,190,12,0,0,188,95,22,236,4,176,19,0,152,34,135,116,52,143,88,174,105,231,44,0,0,44,192,193,2,168,113,236,76,27,192,61,122,178,177,53,109,0,0,96,222,28,17,239,235,63,48,
+109,241,126,99,23,109,243,88,155,58,0,0,48,79,43,11,158,86,71,195,235,207,2,12,45,119,255,109,117,191,246,241,1,0,0,102,200,177,240,205,163,48,109,128,145,148,238,193,141,227,96,218,0,0,192,188,104,52,172,111,22,144,30,253,180,28,224,1,0,0,139,149,91,
+224,232,155,5,36,73,63,173,118,161,84,28,0,0,102,176,24,58,90,220,232,155,5,36,43,119,95,246,81,2,0,32,101,207,13,1,45,252,215,121,49,68,125,191,174,226,207,134,1,152,136,219,42,158,185,151,55,242,81,21,31,86,241,23,67,1,0,0,233,137,71,152,251,82,175,
+111,22,48,15,250,105,53,143,220,180,1,0,128,180,232,187,162,68,5,112,95,95,122,28,221,215,1,0,32,45,123,11,25,125,179,128,217,201,221,175,237,188,5,0,128,185,218,88,192,52,142,194,180,1,18,81,186,103,55,142,181,105,3,0,0,211,150,5,37,41,190,222,3,115,
+167,159,86,243,93,184,74,15,1,0,96,194,110,44,92,244,87,1,102,79,63,173,230,177,55,109,0,0,96,154,74,11,150,198,161,111,22,144,170,220,61,92,233,33,0,0,164,110,101,161,210,56,54,166,13,144,184,173,123,185,210,67,0,0,72,153,82,67,165,39,128,251,191,112,
+255,7,0,128,100,148,22,40,250,102,1,139,101,135,174,147,109,1,0,32,57,185,133,137,190,89,192,226,109,220,219,27,151,30,102,166,13,0,0,140,35,238,50,58,90,152,232,155,5,80,57,184,199,55,138,131,41,3,0,0,227,208,12,216,226,5,224,78,252,200,241,202,189,
+222,71,14,0,0,152,178,220,66,196,201,86,0,63,178,118,191,87,122,8,0,0,83,165,212,176,121,228,166,13,176,16,118,239,218,189,11,0,0,147,180,179,0,105,20,91,83,6,88,144,248,209,227,198,189,95,233,33,0,0,76,137,114,146,102,113,19,148,26,2,203,179,114,255,
+87,122,8,0,0,83,161,225,111,243,88,153,54,192,66,109,60,3,148,30,2,0,192,20,236,45,56,26,69,105,202,0,11,119,240,44,80,122,8,0,0,99,82,106,232,75,59,64,83,118,246,42,61,4,0,0,11,18,11,18,128,228,248,32,226,131,8,0,192,168,158,27,130,197,250,83,21,31,
+27,134,218,254,189,138,175,13,3,192,63,125,19,78,73,126,61,5,235,137,99,245,172,138,107,67,1,0,0,237,105,234,219,44,246,166,12,192,59,226,78,223,163,103,132,67,69,0,0,96,8,89,80,106,216,36,142,231,69,27,0,239,90,121,78,52,138,27,83,6,0,160,27,74,14,151,
+39,238,54,82,106,88,223,231,225,84,90,3,192,187,190,11,167,82,186,220,80,212,242,81,80,122,8,0,0,141,41,53,108,22,91,83,6,160,150,131,103,134,210,67,0,0,232,67,22,148,26,42,11,1,240,140,241,140,1,0,152,1,37,135,203,161,212,176,153,207,194,169,148,6,128,
+167,189,174,226,255,86,241,111,134,162,22,165,135,0,0,80,195,58,248,26,222,36,54,166,12,64,43,59,207,16,165,135,0,0,208,133,120,66,159,50,144,250,113,48,101,0,46,122,230,28,61,75,148,30,2,0,192,165,246,22,12,181,35,38,254,50,83,6,224,34,43,207,147,70,
+81,154,50,0,0,240,54,165,134,205,98,109,202,0,116,162,244,76,81,122,8,0,0,109,40,53,108,22,123,83,6,160,83,7,207,22,165,135,0,0,208,148,82,195,102,165,134,87,166,12,64,167,178,224,195,138,210,67,0,0,104,64,169,97,179,200,77,25,0,207,163,160,244,16,0,
+0,70,163,212,176,89,108,77,25,128,94,237,60,107,148,30,2,0,192,83,148,26,214,143,120,180,188,82,67,128,126,93,157,239,183,158,59,74,15,1,0,224,65,74,59,148,118,0,76,81,238,153,227,249,4,0,0,15,81,106,232,11,56,192,148,109,61,123,148,30,2,0,192,143,41,
+53,180,80,0,152,50,165,135,62,188,0,0,192,91,148,26,214,143,184,139,77,41,7,192,56,114,207,33,165,135,0,0,16,41,53,108,22,27,83,6,96,84,74,15,237,40,6,0,0,199,161,55,136,131,233,2,48,58,165,135,74,15,1,0,88,184,220,139,126,163,82,195,204,148,1,152,132,
+149,231,146,210,67,0,0,150,201,23,238,102,177,54,101,0,38,165,244,108,82,122,8,0,192,242,232,65,82,63,246,166,11,192,36,221,120,70,41,61,4,0,96,57,114,47,246,141,74,13,175,76,25,128,73,82,122,168,244,16,0,128,133,80,106,168,212,16,96,78,74,207,42,165,
+135,0,0,204,159,82,67,165,134,0,115,163,244,80,233,33,0,0,51,150,123,145,175,29,113,23,155,82,67,128,52,40,61,108,22,153,41,3,0,64,74,124,193,174,31,185,233,2,144,148,210,179,171,118,28,76,23,0,0,188,232,207,47,182,166,11,64,146,14,158,97,181,99,99,186,
+0,0,48,117,74,49,148,26,2,44,65,22,78,167,211,122,158,213,59,197,55,51,101,0,0,152,50,165,134,74,13,1,150,98,227,89,166,244,16,0,128,244,149,94,216,149,26,2,44,140,210,67,165,135,0,0,36,76,169,97,253,184,49,93,0,102,35,11,74,15,149,30,2,0,144,44,165,
+134,245,99,101,186,0,204,138,210,67,165,135,0,0,36,168,244,130,94,59,74,211,5,96,150,148,30,214,143,181,233,2,0,192,216,148,26,42,53,4,64,233,97,211,210,67,167,252,2,0,139,241,220,16,76,210,31,130,126,24,117,125,86,197,119,134,1,96,150,94,87,241,247,
+42,62,53,20,79,250,176,138,143,171,248,163,161,0,0,96,12,122,134,40,53,4,224,109,74,15,149,30,2,0,48,97,89,80,90,161,212,16,0,207,71,165,135,0,0,143,82,114,56,45,251,112,42,23,224,105,74,13,1,150,67,233,97,125,74,15,1,0,24,148,82,67,165,134,0,60,78,233,
+161,210,67,0,0,38,36,11,74,41,148,26,2,224,121,169,244,16,0,160,22,37,135,211,160,212,176,62,165,134,0,203,165,244,176,190,88,122,248,81,21,95,26,10,0,0,250,160,212,80,169,33,0,205,40,61,172,31,185,233,2,0,64,215,178,160,116,162,110,28,77,23,0,60,63,
+91,61,63,149,30,2,0,179,163,228,112,92,74,13,235,251,188,138,91,195,0,64,80,122,216,68,76,102,197,242,195,191,24,10,0,0,186,160,212,176,126,108,77,23,0,30,160,244,80,233,33,0,0,3,138,95,75,149,74,40,149,0,224,50,153,231,169,231,41,0,176,76,207,12,193,
+40,98,169,225,218,48,212,242,73,21,215,134,1,128,247,136,59,158,237,228,173,231,119,85,252,198,48,0,192,100,100,231,200,207,255,250,39,85,172,238,253,231,95,157,127,198,118,11,47,207,241,218,176,49,150,152,200,242,165,88,169,33,0,221,81,122,168,244,16,
+0,82,16,119,75,23,225,180,201,165,237,46,243,184,235,122,119,254,223,177,251,154,65,39,175,210,8,165,17,0,116,43,243,124,245,124,5,128,9,43,194,41,137,213,199,179,61,254,239,230,134,152,190,237,188,72,251,130,12,64,47,28,182,98,7,52,0,76,241,253,228,
+24,134,251,104,85,24,114,250,144,123,129,246,162,13,64,175,148,30,250,112,4,0,83,80,132,225,18,89,15,37,182,60,231,233,204,213,136,147,89,41,4,0,75,145,5,165,135,158,183,0,48,238,187,200,84,62,176,237,61,235,233,194,214,139,179,47,198,0,12,66,233,97,
+253,40,77,23,0,232,76,17,166,247,97,237,149,53,54,151,200,189,48,215,142,157,233,2,64,7,148,30,214,143,149,233,2,0,23,155,250,38,150,194,175,136,54,110,188,44,215,206,28,219,14,9,64,23,178,160,244,176,110,220,152,46,0,112,145,84,14,127,179,129,132,70,
+74,47,202,181,99,109,186,0,208,33,165,135,74,15,1,160,111,169,109,96,145,212,162,150,149,23,228,70,205,234,0,160,107,74,15,235,239,146,206,76,23,0,104,36,149,157,89,146,90,52,166,212,80,169,33,0,227,202,130,210,195,186,113,48,93,0,160,182,84,147,89,122,
+106,241,164,210,139,177,82,67,0,38,65,233,97,253,216,152,46,0,240,164,98,38,207,253,220,175,146,31,203,130,175,193,74,13,1,152,18,165,135,118,77,3,64,23,86,51,90,239,123,238,227,165,217,197,3,192,196,101,158,187,62,54,1,64,7,230,214,90,200,115,159,31,
+20,94,132,149,53,0,48,73,165,103,175,118,0,0,112,129,185,182,49,200,253,106,137,187,141,148,26,106,60,11,192,116,57,176,165,94,28,131,93,212,0,112,95,54,227,245,254,209,175,151,210,11,176,163,193,1,152,180,149,231,112,237,216,154,46,0,240,131,185,183,
+22,42,252,138,151,203,238,44,165,134,0,164,161,244,44,86,130,0,0,13,44,225,196,100,187,180,22,172,240,210,171,212,16,128,100,40,61,244,114,11,0,117,100,97,57,155,87,244,208,244,98,44,130,82,67,0,166,77,233,97,253,40,77,23,0,22,108,238,165,134,78,60,92,
+184,204,203,174,82,67,0,146,83,122,54,215,142,149,233,2,192,2,45,161,212,240,199,225,80,24,147,92,4,165,134,0,76,91,124,97,59,122,70,215,138,27,211,5,128,133,201,194,50,251,100,23,41,253,146,62,48,79,47,246,175,134,224,81,175,171,248,149,97,0,192,243,
+41,89,113,135,150,157,214,0,44,201,46,44,115,183,210,47,253,234,151,197,151,91,165,134,0,164,107,235,89,173,23,38,0,220,179,228,42,44,7,194,44,72,238,5,87,137,2,0,73,83,122,168,133,0,0,220,201,194,50,75,13,239,71,150,202,47,75,201,225,229,147,157,247,
+83,202,1,192,212,41,61,172,47,15,118,94,3,48,111,113,231,246,210,27,163,103,169,252,69,37,180,22,242,139,30,193,111,171,120,105,24,0,72,192,117,21,191,51,12,181,252,135,23,125,0,102,106,125,142,165,203,83,249,139,74,104,93,230,103,134,224,65,49,145,85,
+26,6,0,18,18,63,196,220,26,134,39,197,100,214,206,48,0,224,249,198,216,36,180,46,159,244,188,75,233,6,0,169,81,122,88,159,47,216,0,204,205,82,79,53,124,200,79,83,249,139,74,104,209,53,165,134,0,164,234,58,40,61,244,226,15,192,210,248,80,243,182,204,16,
+44,67,60,237,199,169,71,78,53,4,96,62,156,122,88,63,246,166,11,0,51,120,238,47,253,84,195,100,79,53,182,67,139,46,41,213,0,32,117,177,244,240,55,134,161,150,248,53,59,55,12,0,36,204,142,227,132,73,104,209,21,165,134,0,204,197,23,231,192,66,0,128,249,
+202,131,82,195,135,220,166,242,23,149,208,162,171,9,95,26,6,0,102,36,238,58,126,109,24,158,148,85,241,31,134,1,128,196,56,213,240,253,190,77,229,47,42,161,117,153,175,12,193,15,47,253,0,48,39,78,61,172,111,19,148,30,2,144,150,248,49,38,51,12,44,253,5,
+110,233,13,227,182,166,1,0,51,182,247,172,175,21,71,83,5,128,68,228,158,219,143,70,110,138,184,16,150,242,242,170,111,6,0,115,230,244,163,250,81,154,46,0,36,192,105,198,143,71,102,138,44,135,204,45,0,204,219,218,203,109,237,88,153,46,0,76,88,233,89,253,
+104,188,50,69,150,229,102,161,19,125,239,87,15,192,130,40,61,172,23,55,166,10,0,19,181,242,156,158,215,58,95,83,248,203,93,47,240,159,89,163,92,0,150,198,169,135,245,23,11,165,97,0,96,130,156,106,248,52,7,223,45,240,197,109,105,89,219,181,95,59,0,11,
+84,4,95,110,149,30,2,144,162,210,179,89,255,44,30,182,164,166,114,74,13,1,88,178,131,151,93,165,135,0,36,37,243,92,174,21,135,212,126,177,74,14,187,241,251,133,252,115,42,53,4,96,233,148,30,214,163,244,16,128,169,80,106,88,207,239,13,193,50,45,229,72,
+239,141,95,53,0,252,243,121,232,75,174,210,67,0,60,179,157,110,200,44,236,130,237,135,0,176,20,75,61,229,88,233,33,0,169,200,194,50,54,158,116,17,165,233,178,108,115,222,165,245,42,104,14,7,0,247,57,250,219,75,50,0,211,166,239,101,253,245,254,149,233,
+66,25,148,26,2,128,231,190,80,122,8,192,152,148,26,214,143,194,116,225,206,220,78,60,84,42,0,0,15,187,10,203,58,233,216,251,4,0,41,200,130,82,67,173,133,104,37,15,243,218,122,232,139,42,0,44,227,185,175,244,16,128,57,80,106,168,181,16,23,40,131,173,135,
+0,176,20,91,47,197,74,15,1,152,4,165,134,90,11,209,129,125,226,147,123,231,87,8,0,181,204,249,96,24,165,135,0,164,34,243,60,86,106,72,119,47,183,55,38,55,0,44,194,218,203,177,210,67,0,70,165,212,208,142,105,58,148,98,82,235,38,56,178,19,0,218,72,125,
+119,182,23,105,0,82,165,212,208,135,37,122,144,82,82,75,50,11,0,46,123,230,43,117,80,122,8,192,176,50,207,95,207,95,250,125,193,157,250,87,91,61,179,0,224,114,190,16,251,66,12,192,176,148,26,218,33,205,0,202,224,116,3,0,240,98,45,188,88,3,208,5,31,146,
+124,72,98,64,121,21,199,48,157,237,134,94,36,1,160,91,89,80,250,160,244,1,0,207,91,207,219,94,61,119,13,12,238,182,138,223,87,241,247,112,74,38,125,56,194,223,225,117,21,255,89,197,191,87,241,157,95,9,0,116,254,156,253,159,225,244,17,139,199,125,84,197,
+179,42,174,13,5,0,13,197,182,62,31,27,134,90,62,179,246,167,107,89,56,245,174,26,42,43,27,179,215,219,160,241,59,0,12,33,181,147,142,199,138,87,231,119,34,0,168,75,169,161,82,67,38,34,59,79,178,190,74,17,143,231,255,125,137,44,0,24,206,202,75,116,237,
+56,152,46,0,52,88,63,43,53,84,218,207,68,95,126,227,46,170,99,7,19,119,27,244,200,2,128,49,149,94,166,29,82,3,64,167,28,190,226,240,149,127,122,230,90,152,180,171,243,4,204,171,248,201,19,147,241,101,21,223,135,83,15,138,248,231,215,134,15,0,38,33,126,
+164,202,12,195,147,226,187,203,207,195,169,223,40,0,60,36,126,252,216,26,134,90,126,27,148,27,2,0,112,129,60,248,66,172,244,16,128,75,101,65,169,97,147,182,67,179,231,148,67,0,128,126,221,134,211,174,235,95,24,138,90,139,149,184,227,252,107,67,1,192,
+143,56,213,176,190,207,131,29,207,0,0,116,32,38,180,250,58,252,197,169,135,0,204,221,218,243,177,118,40,201,4,0,160,83,185,151,236,218,177,55,93,0,56,139,31,133,148,26,214,47,53,188,50,101,0,0,232,218,206,203,118,237,88,155,46,0,132,211,71,14,207,197,
+122,145,155,46,0,0,244,193,87,230,102,165,135,190,50,3,44,155,82,195,250,177,51,93,0,0,240,114,174,244,16,128,113,249,8,228,35,16,0,0,19,163,124,66,233,33,0,158,149,158,149,0,0,36,197,87,103,95,157,1,120,63,187,153,237,102,126,210,115,215,9,0,192,224,
+254,86,197,223,171,248,212,80,60,233,195,42,62,174,226,143,134,2,96,17,226,71,140,195,249,254,207,227,94,87,241,201,249,189,2,0,0,6,19,95,216,125,93,86,78,1,192,27,74,13,235,199,198,116,1,0,96,12,89,80,122,168,244,16,128,59,74,13,235,199,193,116,1,0,
+96,76,27,47,229,250,132,0,160,191,100,104,246,145,39,51,101,0,0,24,155,210,67,165,135,0,75,167,212,80,169,33,0,0,137,201,130,175,210,74,15,1,150,75,169,161,82,67,0,0,18,165,244,80,233,33,192,18,41,53,108,22,43,83,6,0,128,169,81,122,88,63,10,211,5,96,
+22,148,26,214,143,210,116,1,0,96,138,178,224,43,181,134,184,0,203,161,212,176,126,220,152,46,0,0,76,153,210,67,125,68,0,150,64,169,161,82,67,0,0,102,70,233,161,147,158,0,230,78,169,161,82,67,0,0,102,38,11,190,90,43,61,4,152,47,165,134,74,13,1,0,152,41,
+165,135,74,15,1,230,72,169,161,82,67,0,0,102,78,233,161,210,67,128,185,81,106,168,212,16,0,128,153,203,130,175,216,74,15,1,230,67,169,161,82,67,0,0,22,66,233,161,151,127,128,57,80,106,168,212,16,0,128,133,81,122,168,60,3,32,117,74,13,61,203,0,0,88,152,
+44,248,170,237,171,54,64,186,236,54,182,219,24,0,0,139,1,81,99,49,112,101,202,0,76,66,22,124,148,241,81,6,0,128,69,83,122,88,63,182,166,11,128,103,87,80,106,8,0,0,163,203,130,175,220,77,34,55,101,0,70,101,119,177,82,67,0,0,176,56,104,24,199,160,244,16,
+96,44,177,116,206,71,24,165,134,0,0,240,3,229,27,245,99,103,186,0,140,226,198,51,72,169,33,0,0,220,183,242,242,223,40,214,166,12,192,160,74,207,30,165,134,0,0,96,177,112,89,196,146,23,165,135,0,195,200,61,119,148,26,2,0,192,99,148,115,212,143,189,233,
+2,208,187,248,241,224,232,153,163,212,16,0,0,30,163,244,176,89,108,76,25,128,94,237,61,107,148,26,2,0,64,29,165,69,65,163,210,195,204,148,1,232,197,218,115,70,169,33,0,0,52,161,244,176,126,28,76,23,128,206,101,225,244,209,192,115,70,169,33,0,0,212,166,
+244,208,66,2,96,76,7,207,22,165,134,0,0,208,198,214,34,65,169,7,192,8,74,207,20,207,31,0,0,104,203,201,82,205,226,120,30,51,0,218,179,67,216,14,97,0,0,184,88,110,177,208,40,182,166,12,64,107,241,163,128,30,142,205,62,164,0,0,0,239,161,244,176,89,172,
+77,25,0,207,155,1,34,55,101,0,0,224,253,148,30,54,139,87,65,233,33,64,83,107,207,15,59,130,1,0,160,107,185,197,67,163,216,155,50,0,181,197,143,0,175,60,59,244,108,28,219,115,67,0,0,48,59,183,231,151,231,95,24,138,90,62,174,226,251,42,190,54,20,0,79,250,
+67,112,82,95,19,159,87,241,141,97,0,0,128,122,52,235,109,94,122,152,153,54,0,143,218,120,94,40,53,4,0,128,190,57,78,189,89,220,152,50,0,239,149,5,165,134,74,13,39,68,201,33,0,192,124,125,87,197,179,224,100,165,186,62,58,143,215,181,161,0,120,199,33,216,
+201,218,132,82,67,0,0,184,144,210,67,71,171,3,92,162,244,108,80,106,8,0,0,67,83,122,168,76,4,160,173,220,115,193,51,100,138,148,28,2,0,204,159,210,195,102,226,66,36,150,31,126,105,40,0,247,195,240,167,32,65,211,132,82,67,0,0,232,152,210,195,102,177,54,
+101,128,133,219,121,22,40,53,4,0,128,177,41,61,108,22,241,52,175,204,180,1,22,106,237,57,160,212,16,0,0,166,162,180,232,104,20,7,83,6,88,160,152,152,121,229,25,224,64,17,0,0,152,18,165,135,205,162,52,101,128,133,57,184,247,43,53,4,0,128,169,81,122,216,
+60,86,166,13,176,16,27,247,252,70,113,99,202,0,0,192,112,74,139,16,189,81,0,126,36,38,239,149,26,250,224,1,0,0,147,166,244,80,73,9,192,157,43,207,5,37,233,0,0,144,130,44,248,18,223,52,214,166,13,48,83,91,247,120,165,134,0,0,144,10,189,82,154,69,76,0,
+42,61,4,230,102,237,254,174,212,16,0,0,82,227,52,171,102,113,48,101,128,25,201,130,221,186,74,13,1,0,32,65,87,22,51,141,99,99,218,0,51,225,163,134,82,67,0,0,72,150,114,19,229,38,192,242,148,238,229,238,253,0,0,144,186,189,133,74,227,175,244,250,105,1,
+169,202,221,199,149,26,2,0,192,28,40,61,108,30,59,211,6,72,244,126,127,116,15,87,106,8,0,0,115,145,91,180,52,142,194,180,1,18,99,71,110,243,19,110,51,211,6,0,0,166,109,107,241,210,120,161,163,167,10,144,138,141,251,182,15,23,0,0,48,71,74,81,244,211,2,
+230,41,38,223,149,150,55,139,189,105,3,0,0,105,45,122,44,100,44,122,128,249,136,73,247,27,247,234,198,59,112,125,172,152,168,231,134,0,0,128,7,124,87,197,179,112,234,169,69,61,31,87,241,125,21,95,27,10,96,130,254,119,21,107,195,208,200,103,85,124,99,
+24,0,0,32,61,190,230,55,15,253,180,128,169,41,220,155,27,199,214,180,1,0,128,116,233,183,210,60,98,255,49,37,42,128,251,120,218,125,17,1,0,128,196,57,17,75,63,45,32,77,250,102,217,105,11,0,0,139,118,176,192,105,28,27,211,6,24,217,206,189,216,189,27,0,
+0,150,44,126,229,87,178,210,60,114,83,7,24,137,221,181,205,227,96,218,0,0,192,252,172,45,118,28,249,14,36,97,229,254,235,126,13,0,0,188,161,124,197,23,127,96,218,98,82,230,232,222,219,56,214,166,14,0,0,88,40,137,183,163,52,117,128,129,232,121,216,60,
+118,166,13,0,0,204,159,82,22,253,180,128,105,42,221,107,27,71,252,72,163,212,16,0,0,44,154,68,120,127,127,150,204,212,1,122,146,187,207,182,138,149,169,3,0,0,203,114,99,33,212,56,110,76,27,160,7,89,112,18,173,114,112,0,0,192,2,170,199,216,154,58,64,199,
+124,96,240,129,97,113,158,27,2,0,0,90,122,93,197,223,171,248,212,80,52,242,139,42,190,173,226,165,161,0,58,16,147,228,78,232,107,254,252,250,228,252,19,0,0,88,168,125,240,165,191,77,63,45,125,91,128,75,21,238,167,173,98,99,234,0,0,0,241,116,40,165,135,
+237,202,93,156,172,5,180,181,114,239,109,21,123,83,7,0,0,184,179,182,72,106,21,59,83,7,104,33,38,195,245,205,106,183,59,214,135,4,0,0,224,45,91,139,165,86,81,152,58,64,67,74,189,219,133,94,99,0,0,192,59,236,24,104,31,250,105,1,117,149,238,153,78,152,
+5,0,0,186,181,178,104,106,21,199,160,12,6,120,90,238,126,233,30,11,0,0,244,99,99,241,164,81,49,208,185,44,104,2,111,23,44,0,0,208,171,131,5,84,171,40,77,29,224,1,74,186,221,87,1,0,128,129,22,95,118,18,104,90,12,116,99,231,222,216,42,14,166,14,0,0,208,
+212,218,98,170,245,177,242,202,99,128,59,202,184,219,223,75,51,211,7,0,0,104,195,174,130,118,17,75,139,52,48,6,28,180,209,62,10,211,7,0,0,104,43,38,101,142,22,86,154,196,3,173,238,159,74,183,219,197,206,244,1,0,0,46,101,135,129,102,198,64,115,154,192,
+183,139,248,17,197,14,87,0,0,160,19,165,69,86,235,200,77,31,88,28,229,218,237,67,15,66,0,0,160,83,7,11,45,141,141,129,39,21,238,123,173,99,99,250,0,0,0,93,203,130,126,48,154,196,3,143,201,221,239,90,199,193,244,1,0,0,250,178,182,232,210,228,24,120,80,
+22,36,253,47,217,201,42,233,191,48,207,13,1,0,0,3,250,230,188,104,211,227,164,185,56,102,223,87,241,181,161,128,217,137,201,152,63,5,229,197,109,125,118,126,190,0,0,0,244,186,112,115,122,151,38,241,192,27,123,247,182,214,177,53,125,0,0,128,161,196,221,
+70,74,107,218,151,214,216,225,6,243,81,186,175,93,212,95,16,0,0,96,80,133,197,88,235,56,6,253,98,192,125,80,114,63,51,133,0,0,128,49,236,44,202,156,124,8,11,101,167,234,101,81,152,66,0,0,192,152,244,211,106,31,123,211,7,146,20,147,209,71,247,48,167,190,
+2,0,0,233,202,130,93,10,22,118,176,44,18,249,74,174,1,0,128,25,88,91,164,41,189,129,133,80,106,125,89,56,20,3,0,0,152,148,173,133,154,164,22,204,220,198,189,202,125,14,0,0,152,31,101,56,151,157,248,101,231,2,76,87,225,62,165,188,26,0,0,152,167,44,232,
+167,37,169,5,243,147,187,63,57,213,21,0,0,152,55,253,180,44,252,96,78,98,146,89,162,94,162,30,0,0,88,128,210,34,238,226,164,22,48,190,152,92,150,204,186,44,214,166,17,0,0,144,146,131,133,156,126,51,144,176,152,204,210,23,240,178,216,154,70,0,0,64,138,
+139,65,59,27,36,181,32,85,146,89,118,154,2,0,0,11,149,91,212,93,28,27,211,8,6,183,115,239,185,184,111,150,94,128,0,0,64,210,74,139,187,139,163,48,141,96,48,91,247,156,139,35,55,141,0,0,128,57,216,91,224,89,32,66,2,10,247,154,139,163,52,141,0,0,128,185,
+136,165,39,71,11,189,139,75,120,86,166,18,244,166,112,159,185,56,246,166,17,0,0,48,55,43,139,189,78,146,90,153,169,4,189,220,159,28,98,113,89,196,143,22,250,102,1,0,0,179,84,88,244,117,114,114,152,69,35,116,71,50,171,155,176,131,20,0,0,152,53,167,135,
+73,106,193,84,72,102,57,184,2,0,0,160,150,152,136,185,177,0,212,171,6,220,139,102,17,59,83,9,0,0,88,10,187,34,44,36,97,76,146,89,118,139,2,0,0,180,82,88,12,74,106,193,8,36,179,28,82,193,4,60,55,4,0,0,36,234,229,121,97,249,11,67,113,145,184,219,237,251,
+42,190,54,20,80,203,31,170,200,13,195,197,62,59,223,199,1,0,0,22,201,78,9,77,153,97,40,14,165,232,38,74,83,9,0,0,88,186,44,232,167,37,169,5,253,147,204,114,32,5,0,0,64,167,114,139,68,73,45,232,81,233,222,160,9,60,0,0,128,5,167,164,22,164,162,112,79,232,
+172,9,252,202,116,2,0,0,120,215,222,162,177,179,176,240,4,201,44,137,114,0,0,128,1,196,82,22,77,226,237,166,128,46,20,238,3,157,197,214,116,2,0,0,120,92,76,194,104,18,47,169,5,151,40,92,255,157,197,193,116,2,0,0,168,103,109,17,41,169,5,45,21,174,251,
+206,226,24,52,129,7,0,0,104,164,180,152,148,212,130,134,10,215,187,94,124,0,0,0,99,211,36,94,82,11,234,42,92,231,154,192,3,0,0,76,129,38,241,146,90,80,71,225,250,214,4,30,0,0,96,74,52,137,151,212,130,199,20,174,107,77,224,1,0,0,166,72,147,120,73,45,120,
+72,225,122,238,52,226,142,88,77,224,1,0,0,58,84,90,108,118,158,212,90,155,86,36,172,112,29,75,116,3,0,0,164,64,147,120,141,159,33,4,201,172,62,66,130,27,0,0,160,39,154,196,75,106,193,214,53,219,121,108,76,43,0,0,128,126,105,18,47,169,197,114,237,92,171,
+157,199,206,180,2,0,0,24,198,202,34,84,82,139,197,145,204,210,4,30,0,0,32,121,133,197,104,47,177,53,181,152,24,165,198,253,53,129,151,204,2,0,0,24,193,198,162,84,9,18,179,38,153,213,95,56,209,16,0,0,96,68,202,144,250,137,125,176,123,131,113,101,65,50,
+75,121,49,0,0,192,140,237,45,80,245,215,97,86,28,254,160,172,24,0,0,96,246,148,37,245,155,212,202,76,49,6,180,14,146,89,125,238,188,4,0,0,96,66,174,44,130,123,109,30,173,223,14,67,208,23,207,142,75,0,0,128,197,81,166,36,169,69,186,244,195,235,47,142,
+65,50,11,0,0,96,210,114,139,87,205,164,73,74,76,180,28,92,91,146,209,0,0,0,75,87,88,196,106,42,77,18,178,160,255,157,100,22,0,0,0,63,40,45,102,123,111,46,173,132,137,75,40,17,182,163,18,0,0,128,7,232,201,211,127,147,105,187,63,104,163,112,253,72,102,
+1,0,0,240,126,122,243,244,95,210,148,155,102,52,176,117,221,244,30,59,211,12,0,0,32,109,177,44,78,143,158,254,99,99,170,81,227,90,148,96,150,204,2,0,0,160,193,66,250,104,161,59,200,66,90,95,45,30,178,114,13,14,86,6,12,0,0,192,204,22,212,26,80,15,179,
+160,150,212,226,190,194,117,225,218,3,0,0,160,61,73,173,225,250,106,173,77,183,197,139,201,21,7,51,12,119,205,101,166,28,0,0,192,124,173,45,126,7,139,109,176,99,100,169,178,160,119,221,144,201,44,167,141,2,0,0,44,64,97,17,60,104,25,148,197,246,178,196,
+164,177,157,144,195,133,235,11,0,0,96,65,74,11,97,167,32,226,186,74,60,10,83,14,0,0,96,121,244,247,25,54,14,65,9,226,92,197,93,66,74,12,37,179,0,0,0,24,136,164,150,134,241,92,166,52,175,37,179,0,0,0,24,86,220,49,100,103,137,134,241,52,103,87,214,56,177,
+51,245,0,0,0,136,36,181,198,137,99,176,91,43,85,177,39,154,198,239,146,89,0,0,0,140,76,82,107,188,216,7,187,181,82,145,133,83,47,52,243,86,50,11,0,0,128,9,45,214,237,58,25,175,183,86,97,10,78,154,93,89,227,197,141,233,7,0,0,192,99,86,22,237,163,159,132,
+152,153,134,147,146,7,187,23,199,78,102,217,193,8,0,0,192,147,36,181,198,223,173,181,49,13,71,151,5,167,128,74,102,1,0,0,144,20,73,173,105,52,141,207,77,197,81,148,230,255,36,18,187,146,89,0,0,0,52,38,169,53,157,50,196,220,116,28,68,28,231,163,57,55,
+137,100,214,202,116,4,0,0,160,173,181,197,245,164,78,67,204,76,201,94,100,231,241,53,207,36,179,0,0,0,152,137,194,34,123,82,17,251,58,41,197,234,70,22,244,201,146,204,2,0,0,96,182,10,139,237,201,45,252,203,32,177,213,86,22,36,178,36,179,0,0,0,88,132,
+194,162,123,146,73,128,93,80,138,88,87,22,36,178,36,179,0,0,0,88,156,194,226,123,210,165,136,153,41,250,160,85,144,200,146,204,2,0,0,96,209,10,139,112,167,34,38,224,234,60,87,111,204,9,201,44,0,0,0,8,65,82,43,133,184,57,255,158,150,214,103,235,110,55,
+214,43,115,64,50,11,0,0,0,126,172,176,40,79,38,246,97,222,201,45,187,177,36,179,0,0,0,160,182,194,226,60,201,38,242,235,25,204,189,236,60,255,246,126,175,146,89,0,0,0,208,84,97,145,158,108,98,225,110,231,86,150,200,92,139,127,207,77,176,19,43,229,200,
+221,50,33,132,103,134,0,0,0,38,33,38,69,118,134,33,105,183,85,124,81,197,87,85,92,87,241,122,2,127,167,44,156,18,32,63,59,255,180,179,39,93,113,62,253,166,138,23,134,2,36,180,0,0,96,74,138,32,169,53,39,47,195,41,201,245,215,123,127,126,217,227,255,95,
+236,131,21,19,86,121,120,147,192,186,242,107,152,133,152,204,250,164,231,249,3,73,145,208,2,0,128,105,137,9,137,67,144,136,152,179,152,148,136,9,138,219,42,190,189,247,239,95,55,152,35,113,126,252,52,156,118,96,221,5,243,36,153,5,15,144,208,2,0,128,233,
+145,212,2,162,219,42,62,15,146,89,240,14,9,45,0,0,152,38,73,45,88,182,152,196,138,59,179,94,27,10,120,215,7,134,0,0,0,44,102,1,215,63,164,68,66,11,0,0,44,106,129,233,184,118,221,195,211,36,180,0,0,96,218,98,82,235,95,130,30,58,176,4,47,130,100,22,212,
+34,161,5,0,0,211,231,148,51,152,191,23,85,252,202,48,64,61,18,90,0,0,144,134,187,164,214,11,67,1,179,243,219,32,153,5,141,60,55,4,0,0,144,140,191,85,241,101,21,89,56,157,130,8,164,47,38,178,126,103,24,160,25,9,45,0,0,72,79,76,106,61,171,34,55,20,144,
+172,184,235,242,215,193,174,75,104,229,153,33,0,0,128,100,21,85,236,12,3,36,71,95,60,184,144,29,90,0,0,144,174,184,24,254,54,156,118,106,125,104,56,32,153,235,54,38,179,190,49,20,208,158,29,90,0,0,144,190,216,79,235,80,197,149,161,128,73,251,34,156,122,
+102,189,54,20,112,25,167,28,2,0,64,250,238,118,124,220,26,10,152,172,23,85,124,30,36,179,160,19,118,104,1,0,192,124,196,29,90,113,167,150,19,16,97,90,226,174,172,23,134,1,186,163,135,22,0,0,204,199,223,170,248,99,21,31,5,73,45,152,130,184,27,235,179,
+112,42,53,4,58,36,161,5,0,0,243,18,147,90,95,86,241,125,21,159,26,14,24,205,109,56,37,179,190,54,20,208,61,37,135,0,0,48,95,121,21,251,160,89,60,12,237,174,175,157,126,89,208,19,77,225,1,0,96,190,174,207,139,234,151,134,2,6,243,162,138,159,7,201,44,232,
+149,132,22,0,0,204,219,221,78,17,61,124,160,127,191,9,167,6,240,64,207,244,208,2,0,128,249,187,107,22,31,91,142,228,134,3,58,119,215,252,253,191,13,5,12,67,66,11,0,0,150,227,186,138,111,195,41,169,245,161,225,128,78,196,93,144,177,196,240,27,67,1,195,
+81,114,8,0,0,203,242,34,156,74,16,111,13,5,92,236,119,65,191,44,24,133,83,14,1,0,96,153,226,201,135,241,4,196,220,80,64,99,49,129,21,251,101,189,48,20,48,14,37,135,0,0,176,76,177,175,214,239,131,190,90,208,84,44,49,252,188,138,63,27,10,24,143,29,90,0,
+0,192,42,156,118,107,101,134,2,30,21,79,11,141,167,24,42,49,132,145,233,161,5,0,0,220,53,181,126,97,40,224,189,98,137,97,220,153,37,153,5,19,96,135,22,0,0,112,223,186,138,93,56,245,216,2,78,9,172,152,200,186,54,20,48,29,118,104,1,0,0,247,197,146,170,
+159,91,188,195,15,215,195,191,184,30,0,0,0,32,29,101,21,255,16,98,129,241,42,156,118,43,2,19,165,228,16,0,0,120,140,134,241,44,205,117,56,53,126,191,53,20,48,93,74,14,1,0,128,199,104,24,207,82,196,94,89,177,241,251,39,65,50,11,0,0,0,102,35,150,96,197,
+82,44,37,105,98,110,113,8,118,33,2,0,0,192,108,197,211,15,183,65,2,68,204,39,74,151,53,0,0,0,44,67,94,197,49,72,134,136,116,227,38,156,122,196,1,0,0,0,11,98,183,150,176,43,11,0,0,0,72,82,220,229,18,119,187,72,148,136,20,122,101,217,149,5,0,0,0,252,160,
+12,18,38,98,154,17,15,51,40,92,162,0,0,0,192,67,178,112,218,5,35,137,34,166,18,177,44,246,202,165,9,0,0,0,60,165,8,167,93,49,18,42,98,204,242,194,204,165,8,0,0,0,52,17,119,197,148,65,98,69,12,27,241,244,205,181,203,15,0,0,0,184,68,86,197,46,72,180,136,
+97,78,47,84,94,8,0,0,0,116,38,11,250,107,9,229,133,0,0,0,64,130,242,32,177,37,186,75,100,229,46,41,0,0,0,96,40,69,56,245,59,146,152,17,18,89,0,0,0,64,82,54,193,137,136,66,195,119,0,0,0,32,49,119,39,34,74,108,137,247,37,178,10,151,9,0,0,0,48,85,69,80,
+138,40,36,178,0,0,0,128,4,21,85,220,4,73,29,137,44,0,0,0,128,196,228,193,169,136,75,106,246,94,152,242,0,0,0,192,92,228,85,236,130,164,207,220,226,213,249,247,186,50,197,1,0,0,128,185,202,194,41,1,162,129,124,218,17,203,73,139,112,58,16,0,0,0,0,96,17,
+98,34,164,8,250,108,217,141,5,0,0,0,144,160,172,138,109,112,58,162,221,88,0,0,0,0,9,138,187,127,148,36,78,227,164,194,109,176,27,11,0,0,0,160,145,117,208,72,94,18,11,0,0,0,32,65,119,253,182,246,193,206,45,73,44,0,0,0,128,4,229,225,148,132,209,80,190,
+125,79,172,77,56,245,46,3,24,220,51,67,0,0,0,44,92,220,189,21,75,19,127,25,78,137,174,204,144,188,227,117,21,215,85,124,121,254,121,107,72,128,49,73,104,1,0,0,188,45,150,206,229,225,77,130,107,137,39,243,189,60,199,87,247,254,12,48,25,18,90,0,0,0,143,
+91,157,227,103,247,254,60,167,36,87,220,125,117,151,188,186,62,255,249,181,95,59,48,101,18,90,0,0,0,205,197,132,214,93,114,235,167,33,141,68,215,93,226,42,254,252,235,249,207,183,193,238,43,32,65,18,90,0,0,0,221,185,75,116,221,253,140,126,22,222,78,116,
+229,61,253,127,223,37,171,110,171,248,246,252,243,54,188,73,100,1,204,134,132,22,0,0,192,120,238,39,190,218,184,54,132,0,0,0,0,0,48,113,31,24,2,0,0,0,0,82,34,161,5,0,0,0,64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,
+0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,
+36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,
+0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,0,0,0,
+72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,0,0,0,128,164,72,
+104,1,0,0,0,144,20,9,45,0,0,0,0,146,34,161,5,0,0,0,64,82,36,180,0,0,0,0,72,138,132,22,0,0,0,0,73,145,208,2,0,0,0,32,41,18,90,0,0,0,0,36,69,66,11,0,0,0,128,164,72,104,1,0,0,0,144,20,9,45,0,0,0,0,146,242,255,5,24,0,142,248,78,14,98,33,228,71,0,0,0,0,73,
+69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::sine_wave_png = (const char*) temp_77db788;
+
+//================== square_wave.png ==================
+static const unsigned char temp_5a5e8e78[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,4,164,0,0,2,171,8,6,0,0,0,207,165,85,63,0,0,0,9,112,72,89,115,0,0,23,18,0,0,23,18,1,103,159,210,82,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,
+97,100,121,113,201,101,60,0,0,23,205,73,68,65,84,120,218,236,221,63,146,148,199,1,198,225,214,138,64,153,55,116,230,225,4,94,157,128,209,9,88,78,160,37,115,6,156,0,113,2,164,208,17,67,228,114,36,136,28,50,202,156,105,201,148,121,148,217,25,206,164,204,
+221,254,190,45,244,7,73,32,161,151,233,238,231,169,234,98,237,64,59,221,223,4,83,191,237,238,41,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,114,222,179,4,111,221,214,18,0,192,180,46,235,120,97,25,0,0,126,158,32,245,235,156,150,37,60,157,213,113,163,142,205,58,0,0,154,22,165,46,215,241,188,142,125,29,7,203,2,0,176,16,164,94,95,139,80,231,117,220,92,255,5,0,120,19,135,58,158,212,
+241,89,17,167,0,128,201,9,82,191,108,83,199,253,178,68,168,83,203,1,0,188,5,251,58,30,215,177,179,20,0,192,140,4,169,159,182,41,75,136,186,176,20,0,192,239,228,80,199,131,34,76,1,0,147,17,164,126,172,237,130,186,91,150,24,5,0,144,176,175,227,94,89,238,
+156,2,0,24,222,251,150,224,123,218,37,229,207,138,59,162,0,128,172,77,29,127,41,203,31,11,247,150,3,0,24,157,29,82,47,181,93,81,15,45,3,0,240,142,237,235,184,85,150,111,234,3,0,24,146,32,181,120,84,220,21,5,0,28,143,118,116,239,118,113,132,15,0,24,148,
+32,37,70,1,0,199,169,237,144,250,168,136,82,0,192,128,102,15,82,98,20,0,112,204,68,41,0,96,72,51,7,41,49,10,0,232,65,139,82,215,139,59,165,0,128,129,156,76,58,239,118,129,249,133,199,15,0,116,224,180,44,223,2,124,106,41,0,128,81,188,63,225,156,183,117,
+252,205,163,7,0,58,242,199,117,60,181,20,0,192,8,102,11,82,237,47,139,255,40,254,194,8,0,244,231,172,142,231,117,124,101,41,0,128,222,205,118,100,239,126,29,27,143,29,0,232,84,187,3,211,31,214,0,128,238,205,180,67,170,253,85,113,231,145,3,0,29,251,160,
+142,111,235,216,91,10,0,160,103,51,125,203,94,187,12,116,235,145,3,0,3,104,223,186,119,176,12,0,64,175,102,57,178,183,45,98,20,0,48,142,251,150,0,0,232,217,44,65,234,99,143,26,0,24,200,69,113,151,20,0,208,177,25,238,144,218,20,119,71,1,0,227,249,79,29,
+255,180,12,0,64,143,102,216,33,117,238,49,3,0,3,186,99,9,0,128,94,205,16,164,28,215,3,0,70,180,41,203,183,8,3,0,116,103,244,32,229,131,26,0,48,50,59,193,1,128,46,141,30,164,182,30,49,0,48,176,27,150,0,0,232,209,232,65,202,135,52,0,96,100,91,75,0,0,244,
+104,134,35,123,0,0,35,115,61,1,0,208,29,71,246,0,0,250,182,177,4,0,64,111,70,14,82,167,30,47,0,48,1,59,164,0,128,238,140,28,164,124,56,3,0,0,0,56,66,39,150,0,0,160,107,127,182,4,0,64,111,4,41,0,128,190,185,166,0,0,232,142,32,5,0,0,0,64,148,32,5,0,0,0,
+64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,
+0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,
+0,0,64,148,32,5,0,0,0,64,212,53,75,48,164,123,117,92,90,6,0,38,243,176,142,51,203,0,0,112,252,4,169,49,181,24,181,183,12,0,76,230,133,37,0,0,232,131,35,123,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,
+0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,
+9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,
+0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,
+0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,
+9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,
+0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,
+0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,
+9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,
+0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,
+0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,
+9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,
+0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,9,82,0,0,0,0,68,93,179,4,0,0,0,0,223,115,90,199,217,58,218,207,127,88,127,254,174,203,58,254,91,199,97,29,123,203,246,250,4,41,0,0,0,128,82,206,235,184,81,199,182,252,
+56,62,189,202,246,21,255,95,139,84,251,58,30,175,63,243,19,4,41,0,0,0,96,86,155,58,238,151,37,70,157,190,133,255,222,213,174,170,187,101,217,53,213,194,212,110,253,153,239,112,135,20,0,0,0,48,155,109,29,207,234,248,87,29,23,229,237,196,168,31,218,148,
+37,118,181,223,241,104,253,223,172,4,41,0,0,0,96,22,155,58,62,47,75,140,218,6,127,239,69,121,25,166,78,61,6,65,10,0,0,0,152,67,59,70,247,101,89,142,231,189,43,23,101,9,83,231,179,63,12,65,10,0,0,0,24,89,219,145,212,118,68,61,44,199,177,59,169,189,134,
+182,75,107,234,221,82,130,20,0,0,0,48,170,118,193,120,219,145,180,61,194,215,118,81,150,80,182,153,241,193,8,82,0,0,0,192,136,218,177,184,22,124,142,121,23,82,11,102,95,174,255,78,69,144,2,0,0,0,70,115,81,150,99,113,61,28,137,187,58,82,56,85,148,18,164,
+0,0,0,128,145,180,176,243,168,179,215,60,93,148,18,164,0,0,0,128,81,180,160,243,172,211,215,126,117,217,249,20,23,157,11,82,0,0,0,192,8,90,200,233,253,155,235,54,101,137,82,195,19,164,0,0,0,128,17,180,24,53,194,145,183,109,29,159,140,254,176,4,41,0,0,
+0,160,119,231,235,24,197,253,50,248,125,82,130,20,0,0,0,208,179,118,68,239,225,128,243,122,56,242,67,19,164,0,0,0,128,158,221,45,203,221,75,163,217,214,113,49,234,67,19,164,0,0,0,128,94,181,221,81,119,6,158,223,253,81,39,38,72,1,0,0,0,189,106,187,163,
+78,7,158,223,166,12,186,75,74,144,2,0,0,0,122,117,199,28,251,36,72,1,0,0,0,61,186,40,99,239,142,186,114,86,6,252,198,61,65,10,0,0,0,232,209,205,137,230,250,241,104,19,18,164,0,0,0,128,222,180,157,81,231,19,205,119,184,185,10,82,0,0,0,64,111,182,147,205,
+119,179,142,97,8,82,0,0,0,64,111,110,76,56,231,237,72,147,17,164,0,0,0,128,222,156,77,56,231,161,34,156,32,5,0,0,0,244,102,198,32,181,25,105,50,130,20,0,0,0,208,155,211,9,231,188,29,105,50,130,20,0,0,0,208,147,173,37,232,159,32,5,0,0,0,208,135,97,118,
+134,9,82,0,0,0,0,125,24,230,238,44,65,10,0,0,0,128,40,65,10,0,0,0,128,40,65,10,0,0,0,128,168,145,131,212,139,137,159,235,222,91,27,0,0,0,56,86,35,7,169,75,143,23,0,0,0,224,248,140,126,100,111,198,93,82,66,28,0,0,0,112,212,70,15,82,51,198,153,131,183,
+53,0,0,0,112,204,70,15,82,95,76,248,76,159,123,91,3,0,0,0,199,204,14,169,241,60,241,182,6,0,0,0,142,217,232,65,106,63,217,243,108,119,102,185,67,10,0,0,0,56,106,51,92,106,62,211,142,33,187,163,0,0,0,128,163,119,50,193,28,159,78,244,60,159,122,75,3,0,
+0,0,199,110,134,32,181,43,203,78,169,209,29,138,29,82,0,0,0,64,7,78,38,153,231,103,230,8,0,0,0,112,28,102,9,82,159,150,177,119,73,181,185,237,188,157,1,0,0,128,30,204,18,164,90,176,25,121,7,209,103,101,142,99,137,0,0,0,192,0,78,38,154,235,168,187,164,
+14,117,124,226,173,12,0,0,0,244,98,166,32,213,98,212,237,1,231,117,219,219,24,0,0,0,232,201,201,100,243,125,82,198,250,38,186,182,235,107,239,109,12,0,0,0,244,228,100,194,57,183,29,69,135,1,230,113,89,199,3,111,97,0,0,0,160,55,51,6,169,118,116,239,86,
+233,251,62,169,171,227,135,46,50,7,0,0,0,186,115,50,233,188,219,238,162,123,29,191,254,143,214,57,0,0,0,0,116,231,100,226,185,239,74,159,23,130,183,215,44,70,1,0,0,0,221,58,153,124,254,187,210,79,148,186,58,106,184,243,182,5,0,0,0,122,118,98,9,254,31,
+120,218,17,184,99,190,143,233,197,250,26,159,120,92,0,0,0,64,239,4,169,197,190,142,15,203,113,30,133,107,175,237,122,113,76,15,0,0,0,24,132,32,245,210,161,44,81,234,193,17,189,166,246,90,142,125,247,22,0,0,0,192,27,17,164,126,236,147,178,132,169,253,
+59,124,13,237,119,95,95,95,11,0,0,0,192,80,4,169,87,107,199,227,218,206,164,91,37,123,84,110,191,254,222,54,14,30,3,0,0,0,48,34,65,234,231,181,75,196,219,110,169,22,136,118,191,227,239,217,149,151,33,106,111,217,1,0,0,128,145,93,179,4,175,101,191,142,
+123,117,156,215,113,179,142,109,29,167,191,242,191,215,238,132,106,177,235,139,245,95,119,68,1,0,0,0,211,16,164,222,76,11,71,187,242,114,183,212,89,29,155,245,223,63,173,63,191,202,161,142,175,203,114,252,239,178,56,142,7,0,0,0,76,76,144,250,109,174,
+2,211,19,75,1,0,0,0,240,122,220,33,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,212,53,75,0,0,208,181,211,58,182,150,1,128,137,156,89,130,254,9,82,0,0,253,127,40,127,102,25,0,128,158,56,178,7,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,
+0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,
+0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,5,0,0,0,64,148,32,
+5,0,0,0,64,148,32,5,0,0,0,208,135,253,40,19,17,164,0,128,81,188,176,4,0,0,125,16,164,0,128,81,60,183,4,0,192,192,14,35,77,70,144,2,0,124,72,3,0,240,89,39,74,144,2,0,70,113,105,9,0,128,129,125,49,210,100,4,41,0,96,20,45,72,185,71,10,0,24,249,179,206,48,
+4,41,0,96,36,123,75,0,0,248,156,115,252,4,41,0,96,36,79,45,1,0,48,160,39,101,176,157,224,130,20,0,48,218,135,53,0,128,209,12,247,71,55,65,10,0,24,73,251,203,225,206,50,0,0,131,125,190,25,238,143,110,130,20,0,48,154,199,150,0,0,24,200,112,199,245,154,
+247,60,87,0,96,64,207,234,216,90,6,0,96,0,215,235,56,140,54,41,59,164,0,128,17,61,176,4,0,192,0,118,101,192,24,213,216,33,5,0,140,202,46,41,0,160,119,67,238,142,106,236,144,2,0,70,117,207,18,0,0,29,107,59,190,15,163,78,238,125,207,23,0,24,212,191,203,
+178,27,124,107,41,0,128,206,28,234,184,93,199,55,163,78,208,145,61,0,96,116,95,214,113,102,25,0,128,142,124,88,199,229,200,19,116,100,15,0,24,221,173,50,224,87,37,3,0,195,106,215,14,92,142,62,73,65,10,0,24,221,161,44,81,10,0,224,216,237,234,248,116,134,
+137,186,67,10,0,152,193,161,142,175,235,56,183,20,0,192,145,218,149,229,222,168,41,8,82,0,192,44,218,214,119,81,10,0,56,70,187,50,81,140,106,4,41,0,96,38,87,81,106,91,199,7,150,3,0,56,2,187,50,89,140,106,124,203,30,0,48,163,246,173,123,159,215,177,177,
+20,0,192,59,212,46,48,255,116,198,137,11,82,0,192,172,78,235,120,84,28,225,3,0,242,14,101,249,210,149,203,89,23,192,183,236,1,0,179,122,177,126,16,188,181,254,12,0,144,208,118,68,125,88,38,142,81,141,59,164,0,128,217,125,85,199,95,235,248,182,44,71,249,
+220,45,5,0,252,30,246,117,124,84,199,223,235,248,102,246,197,112,100,15,0,224,165,118,140,239,110,29,119,214,159,1,0,126,171,93,29,143,203,18,164,88,9,82,0,0,175,118,81,199,205,226,142,41,0,224,205,181,227,120,45,66,61,41,203,125,81,252,128,32,5,0,240,
+203,182,235,184,81,150,99,125,118,79,1,0,223,181,47,75,132,122,190,254,124,176,36,63,79,144,2,0,248,117,132,41,0,160,69,40,95,142,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,14,253,79,128,1,0,153,2,27,8,33,213,49,244,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::square_wave_png = (const char*) temp_5a5e8e78;
+
+//================== triangle_wave.png ==================
+static const unsigned char temp_d696456d[] =
+{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,4,172,0,0,2,113,8,6,0,0,0,111,215,42,130,0,0,0,9,112,72,89,115,0,0,23,18,0,0,23,18,1,103,159,210,82,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,
+97,100,121,113,201,101,60,0,0,32,173,73,68,65,84,120,218,236,221,251,145,85,199,122,198,225,214,113,2,100,224,9,129,12,204,201,128,16,94,101,64,8,100,160,16,80,6,132,128,28,1,114,4,216,17,72,25,224,189,197,12,12,48,151,125,89,151,175,187,159,167,170,
+171,252,199,41,219,181,46,189,250,251,157,13,180,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,206,126,113,9,0,190,122,113,88,47,15,235,230,118,61,
+228,239,195,250,243,176,254,247,118,1,0,0,0,192,98,142,129,42,135,245,238,176,62,29,214,231,51,215,95,135,245,254,176,222,180,199,3,23,0,0,0,0,60,43,237,75,104,250,188,240,250,216,190,196,171,23,46,49,0,0,0,0,207,57,70,164,183,237,203,175,162,62,111,
+176,142,191,218,186,113,217,1,0,0,0,120,200,241,87,79,91,133,170,31,215,111,205,47,174,0,0,0,0,184,117,252,11,212,143,127,76,239,243,206,235,24,203,94,187,29,0,0,0,0,115,123,219,246,15,85,63,174,227,223,155,229,215,86,0,0,0,0,147,57,6,161,53,254,66,245,
+37,255,98,246,151,110,19,0,0,0,192,28,142,177,170,194,31,1,60,229,143,8,138,86,0,0,0,0,131,235,37,86,137,86,0,0,0,0,19,232,45,86,137,86,0,0,0,0,3,235,53,86,137,86,0,0,0,0,3,234,61,86,137,86,0,0,0,0,3,25,37,86,137,86,0,0,0,0,3,24,45,86,137,86,0,0,0,0,
+29,27,53,86,137,86,0,0,0,0,29,26,61,86,137,86,0,0,0,0,29,153,37,86,137,86,0,0,0,0,29,152,45,86,137,86,0,0,0,0,133,205,26,171,68,43,0,0,0,128,130,102,143,85,162,21,0,0,0,64,33,98,149,104,5,0,0,0,80,134,88,37,90,1,0,0,0,148,33,86,137,86,0,0,0,0,101,136,
+85,162,21,0,0,0,64,25,98,149,104,5,0,0,0,80,134,88,37,90,1,0,0,0,148,33,86,137,86,0,0,0,0,101,136,85,162,21,0,0,0,64,25,98,149,104,5,0,0,0,80,134,88,37,90,1,0,0,0,148,33,86,137,86,0,0,0,0,101,136,85,162,21,0,0,0,64,25,98,149,104,5,0,0,0,80,134,88,37,
+90,1,0,0,0,148,33,86,137,86,0,0,0,0,101,136,85,162,21,0,0,0,64,25,98,149,104,5,0,0,0,80,134,88,37,90,1,0,0,0,148,33,86,137,86,0,0,0,0,101,136,85,162,21,0,0,0,64,25,98,149,104,5,0,0,0,80,134,88,37,90,1,0,0,0,148,33,86,137,86,0,0,0,0,101,136,85,162,21,
+0,0,0,64,25,98,149,104,5,0,0,0,80,134,88,37,90,1,0,0,0,148,33,86,137,86,0,0,0,0,101,136,85,162,21,0,0,0,64,25,98,149,104,5,0,0,0,80,134,88,37,90,1,0,0,0,148,33,86,137,86,162,21,0,0,0,80,134,88,101,137,86,0,0,192,230,126,113,9,128,71,28,99,213,135,38,
+84,240,197,223,135,245,239,195,250,211,165,0,0,0,214,38,88,1,15,17,171,120,136,104,5,0,0,108,66,176,2,126,36,86,241,20,209,10,0,0,88,157,96,5,220,39,86,113,10,209,10,0,0,88,149,96,5,220,17,171,56,135,104,5,0,0,172,70,176,2,142,196,42,46,33,90,1,0,0,171,
+16,172,0,177,138,107,136,86,0,0,192,226,4,43,152,155,88,197,18,68,43,0,0,96,81,130,21,204,75,172,98,73,162,21,0,0,176,24,193,10,230,36,86,177,6,209,10,0,0,88,132,96,5,243,17,171,88,147,104,5,0,0,92,77,176,130,185,136,85,108,65,180,2,0,0,174,34,88,193,
+60,196,42,182,36,90,1,0,0,23,19,172,96,14,98,21,123,16,173,0,0,128,139,8,86,48,62,177,138,61,137,86,0,0,192,217,4,43,24,155,88,69,5,162,21,0,0,112,22,193,10,198,37,86,81,137,104,5,0,0,156,76,176,130,49,137,85,84,36,90,1,0,0,39,17,172,96,60,98,21,149,
+137,86,0,0,192,179,4,43,24,139,88,69,15,68,43,0,0,224,73,130,21,140,67,172,162,39,162,21,0,0,240,40,193,10,198,32,86,209,35,209,10,0,0,120,144,96,5,253,19,171,232,153,104,5,0,0,252,228,95,46,1,116,77,172,90,223,239,135,245,171,203,224,25,6,0,0,0,78,27,
+244,63,30,214,103,107,181,245,238,222,245,142,235,177,234,250,171,137,86,0,0,0,208,53,177,106,219,88,117,39,174,139,104,5,0,0,0,252,76,172,218,39,86,221,137,235,35,90,1,0,0,0,223,136,85,251,198,170,59,113,157,68,43,0,0,0,64,172,170,18,171,238,196,245,
+18,173,0,0,0,96,102,98,85,173,88,117,39,174,155,104,5,0,0,0,51,18,171,106,198,170,59,113,253,68,43,0,0,0,152,137,88,85,59,86,221,137,235,40,90,1,0,0,192,12,196,170,62,98,213,157,184,158,162,21,0,0,0,140,76,172,234,43,86,221,137,235,42,90,1,0,0,192,136,
+196,170,62,99,213,157,184,190,162,21,0,0,0,140,68,172,234,59,86,221,137,235,44,90,1,0,0,192,8,196,170,49,98,213,157,184,222,162,21,0,0,0,244,76,172,26,43,86,221,137,235,46,90,1,0,0,64,143,196,170,49,99,213,157,184,254,162,21,0,0,0,244,68,172,26,59,86,
+221,137,251,32,90,1,0,0,64,15,196,170,57,98,213,157,184,31,162,21,0,0,0,84,38,86,205,21,171,238,196,125,17,173,0,0,0,160,34,177,106,206,88,117,39,238,143,104,5,0,0,0,149,136,85,115,199,170,59,113,159,68,43,0,0,0,168,64,172,18,171,238,139,251,37,90,1,
+0,0,192,158,196,42,177,234,33,113,223,68,43,0,0,0,216,131,88,37,86,61,37,238,159,104,5,0,0,0,91,18,171,196,170,83,196,125,20,173,0,0,0,96,11,98,149,88,117,142,184,159,162,21,0,0,0,172,73,172,18,171,46,17,247,85,180,2,0,0,128,53,136,85,98,213,53,226,254,
+138,86,0,0,0,176,36,177,74,172,90,66,220,103,209,10,0,0,0,150,32,86,137,85,75,138,251,45,90,1,0,0,192,53,196,42,177,106,13,113,223,69,43,0,0,0,184,132,88,37,86,173,41,238,191,104,5,0,0,0,231,16,171,196,170,45,196,115,32,90,1,0,0,192,41,196,42,177,106,
+75,241,60,136,86,0,0,0,240,20,177,74,172,218,67,60,23,162,21,0,0,0,60,68,172,18,171,246,20,207,135,104,5,0,0,0,247,137,85,98,85,5,241,156,136,86,0,0,0,112,36,86,137,85,149,196,243,34,90,1,0,0,48,55,177,74,172,170,40,158,27,209,10,0,0,128,57,137,85,98,
+85,101,241,252,136,86,0,0,0,204,69,172,18,171,122,16,207,145,104,5,0,0,192,28,196,42,177,170,39,241,60,137,86,0,0,0,140,77,172,18,171,122,20,207,149,104,5,0,0,192,152,196,42,177,170,103,241,124,137,86,0,0,0,140,69,172,18,171,70,16,207,153,104,5,0,0,192,
+24,196,42,177,106,36,241,188,137,86,0,0,0,244,77,172,18,171,70,20,207,157,104,5,0,0,64,159,196,42,177,106,100,241,252,137,86,0,0,0,244,69,172,18,171,102,16,207,161,104,5,0,0,64,31,196,42,177,106,38,241,60,138,86,0,0,0,212,38,86,137,85,51,138,231,82,180,
+2,0,0,160,38,177,74,172,154,89,60,159,162,21,0,0,0,181,136,85,98,21,162,149,104,5,0,0,64,25,98,149,88,197,55,241,188,138,86,0,0,0,236,75,172,18,171,248,89,60,183,162,21,0,0,0,251,16,171,196,42,30,23,207,175,104,5,0,0,192,182,196,42,177,138,231,197,115,
+44,90,1,0,0,176,13,177,74,172,226,116,241,60,139,86,0,0,0,172,75,172,18,171,56,95,60,215,162,21,0,0,0,235,16,171,196,42,46,23,207,183,104,5,0,0,192,178,196,42,177,138,235,197,115,46,90,1,0,0,176,12,177,74,172,98,57,241,188,139,86,0,0,0,92,71,172,18,171,
+88,94,60,247,162,21,0,0,0,151,17,171,196,42,214,19,207,191,104,5,0,0,192,121,196,42,177,138,245,197,123,32,90,1,0,0,112,26,177,74,172,98,59,241,62,136,86,0,0,0,60,77,172,18,171,216,94,188,23,162,21,0,0,0,15,19,171,196,42,246,19,239,135,104,5,0,0,192,
+247,196,42,177,138,253,197,123,34,90,1,0,0,240,133,88,37,86,81,71,188,47,162,21,0,0,192,236,196,42,177,138,122,226,189,17,173,0,0,0,102,37,86,137,85,212,21,239,143,104,5,0,0,48,27,177,74,172,162,190,120,143,68,43,0,0,128,89,136,85,98,21,253,136,247,73,
+180,2,0,0,24,157,88,37,86,209,159,120,175,68,43,0,0,128,81,137,85,98,21,253,138,247,75,180,2,0,0,24,141,88,37,86,209,191,120,207,68,43,0,0,128,81,136,85,98,21,227,136,247,77,180,2,0,0,232,157,88,37,86,49,158,120,239,68,43,0,0,128,94,137,85,98,21,227,
+138,247,79,180,2,0,0,232,141,88,37,86,49,190,120,15,69,43,0,0,128,94,136,85,98,21,243,136,247,81,180,2,0,0,168,78,172,18,171,152,79,188,151,162,21,0,0,64,85,98,149,88,197,188,226,253,20,173,0,0,0,170,17,171,196,42,136,247,84,180,2,0,0,168,66,172,18,171,
+224,78,188,175,162,21,0,0,192,222,196,42,177,10,126,20,239,173,104,5,0,0,176,23,177,74,172,130,199,196,251,43,90,1,0,0,108,77,172,18,171,224,57,241,30,139,86,0,0,0,91,17,171,196,42,56,85,188,207,162,21,0,0,192,218,196,42,177,10,206,21,239,181,104,5,0,
+0,176,22,177,74,172,130,75,197,251,45,90,1,0,0,44,77,172,18,171,224,90,241,158,139,86,0,0,0,75,17,171,196,42,88,74,188,239,162,21,0,0,192,181,196,42,177,10,150,22,239,189,104,5,0,0,112,41,177,74,172,130,181,196,251,47,90,1,0,0,156,75,172,18,171,96,109,
+177,15,136,86,0,0,0,167,18,171,196,42,216,74,236,7,162,21,0,0,192,115,196,42,177,10,182,22,251,130,104,5,0,0,240,24,177,74,172,130,189,196,254,32,90,1,0,0,252,72,172,18,171,96,111,177,79,136,86,0,0,0,119,196,42,177,10,170,136,253,66,180,2,0,0,16,171,
+196,42,168,38,246,13,209,10,0,0,152,151,88,37,86,65,85,177,127,136,86,0,0,192,124,196,42,177,10,170,139,125,68,180,2,0,0,230,33,86,137,85,208,139,216,79,68,43,0,0,96,124,98,149,88,5,189,137,125,69,180,2,0,0,198,37,86,137,85,208,171,216,95,68,43,0,0,96,
+60,98,149,88,5,189,139,125,70,180,2,0,0,198,33,86,137,85,48,138,216,111,68,43,0,0,160,127,98,149,88,5,163,137,125,71,180,2,0,0,250,37,86,137,85,48,170,216,127,68,43,0,0,160,63,98,149,88,5,163,139,125,72,180,2,0,0,250,33,86,137,85,48,139,216,143,68,43,
+0,0,160,62,177,74,172,130,217,196,190,36,90,1,0,0,117,137,85,98,21,204,42,246,39,209,10,0,0,168,71,172,18,171,96,118,177,79,137,86,0,0,64,29,98,149,88,5,124,17,251,149,104,5,0,0,236,79,172,18,171,128,239,197,190,37,90,1,0,0,251,17,171,196,42,224,97,177,
+127,137,86,0,0,192,246,196,42,177,10,120,90,236,99,162,21,0,0,176,29,177,74,172,2,78,19,251,153,104,5,0,0,172,79,172,18,171,128,243,196,190,38,90,1,0,0,235,17,171,196,42,224,50,177,191,137,86,0,0,192,242,196,42,177,10,184,78,236,115,162,21,0,0,176,28,
+177,74,172,2,150,17,251,157,104,5,0,0,92,79,172,18,171,128,101,197,190,39,90,1,0,0,151,19,171,196,42,96,29,177,255,137,86,0,0,192,249,196,42,177,10,88,87,236,131,162,21,0,0,112,58,177,74,172,2,182,17,251,161,104,5,0,0,60,79,172,18,171,128,109,197,190,
+40,90,1,0,0,143,19,171,196,42,96,31,177,63,138,86,0,0,192,207,196,42,177,10,216,87,236,147,162,21,0,0,240,141,88,37,86,1,53,196,126,41,90,1,0,0,98,149,88,5,84,19,251,166,104,5,0,0,51,19,171,196,42,160,166,216,63,69,43,0,0,152,145,88,37,86,1,181,197,62,
+42,90,1,0,192,76,196,42,177,10,232,67,236,167,162,21,0,0,204,64,172,18,171,128,190,196,190,42,90,1,0,192,200,196,42,177,10,232,83,236,175,162,21,0,0,140,72,172,18,171,128,190,197,62,43,90,1,0,192,72,196,42,177,10,24,67,236,183,162,21,0,0,140,64,172,18,
+171,128,177,196,190,43,90,1,0,64,207,196,42,177,10,24,83,236,191,162,21,0,0,244,72,172,18,171,128,177,197,62,44,90,1,0,64,79,196,42,177,10,152,67,236,199,162,21,0,0,244,64,172,18,171,128,185,196,190,44,90,1,0,64,101,98,149,88,5,204,41,246,103,209,10,
+0,0,42,18,171,196,42,96,110,177,79,139,86,0,0,80,137,88,37,86,1,28,197,126,45,90,1,0,64,5,98,149,88,5,112,95,236,219,162,21,0,0,236,73,172,18,171,0,30,18,251,183,104,5,0,0,123,16,171,196,42,128,167,196,62,46,90,1,0,192,150,196,42,177,10,224,20,177,159,
+139,86,0,0,176,5,177,74,172,2,56,71,236,235,162,21,0,0,172,73,172,18,171,0,46,17,251,187,104,5,0,0,107,16,171,196,42,128,107,196,62,47,90,1,0,192,146,196,42,177,10,96,9,177,223,139,86,0,0,176,4,177,74,172,2,88,82,236,251,162,21,0,0,92,67,172,18,171,0,
+214,16,251,191,104,5,0,0,151,16,171,196,42,128,53,197,119,64,180,2,0,128,115,136,85,98,21,192,22,226,123,32,90,1,0,192,41,196,42,177,10,96,75,241,93,16,173,0,0,224,41,98,149,88,5,176,135,248,62,136,86,0,0,240,16,177,74,172,2,216,83,124,39,68,43,0,0,184,
+79,172,18,171,0,42,136,239,133,104,5,0,0,71,98,149,88,5,80,73,124,55,68,43,0,0,230,38,86,137,85,0,21,197,247,67,180,2,0,96,78,98,149,88,5,80,89,124,71,68,43,0,0,230,34,86,137,85,0,61,136,239,137,104,5,0,192,28,196,42,177,10,160,39,241,93,17,173,0,0,24,
+155,88,37,86,1,244,40,190,47,162,21,0,0,99,18,171,196,42,128,158,197,119,70,180,2,0,96,44,98,149,88,5,48,130,248,222,136,86,0,0,140,65,172,18,171,0,70,18,223,29,209,10,0,128,190,137,85,98,21,192,136,226,251,35,90,1,0,208,39,177,74,172,2,24,89,124,135,
+68,43,0,0,250,34,86,137,85,0,51,136,239,145,104,5,0,64,31,196,42,177,10,96,38,241,93,18,173,0,128,39,29,191,229,175,110,23,236,66,172,18,171,0,102,20,223,39,209,10,0,38,119,115,123,38,250,237,176,62,220,126,191,159,251,190,127,184,157,113,227,91,207,
+154,196,42,177,10,96,102,241,157,18,173,0,96,50,55,237,75,160,250,180,208,247,254,211,237,255,62,223,124,22,35,86,137,85,0,136,86,162,21,0,204,115,230,249,176,242,119,255,211,237,255,29,184,152,88,37,86,1,240,253,1,206,183,75,180,2,128,81,207,57,75,253,
+154,74,184,98,85,98,149,88,5,192,195,135,57,223,48,209,10,0,70,113,252,238,174,253,139,170,231,214,177,61,188,114,43,56,133,88,37,86,1,240,184,248,142,137,86,0,48,128,55,197,206,0,191,185,37,60,69,172,18,171,0,120,94,124,207,68,43,0,232,120,238,223,251,
+87,85,79,253,218,234,198,45,226,161,135,86,172,18,171,0,56,77,124,215,68,43,0,232,204,203,14,230,126,103,0,190,35,86,137,85,0,156,47,190,111,14,172,0,208,137,151,183,223,86,103,0,186,33,86,137,85,0,92,46,190,115,14,172,0,80,92,79,177,202,25,128,175,222,
+59,12,139,85,0,92,37,190,119,14,172,0,80,84,143,177,202,25,128,246,214,33,88,172,2,96,17,241,221,115,96,5,128,98,122,142,85,247,207,0,47,220,202,249,30,92,7,96,177,10,128,229,196,247,79,180,2,0,177,106,241,245,193,237,156,139,191,183,74,172,2,96,121,
+241,29,20,173,0,64,172,90,124,189,113,91,231,240,214,129,87,172,2,64,180,18,173,0,64,172,234,104,221,184,189,99,123,49,240,195,43,86,1,32,90,137,86,0,32,86,141,185,252,209,192,193,189,117,200,21,171,0,16,173,68,43,0,16,171,58,92,175,220,234,49,249,117,
+149,88,5,128,104,37,90,1,128,88,229,87,86,56,52,139,85,0,248,254,250,102,138,86,0,32,86,53,191,178,226,17,254,101,64,177,10,0,209,74,180,2,0,177,202,44,78,25,55,14,179,94,16,0,68,43,209,10,0,196,170,1,214,11,143,192,56,222,56,200,138,85,0,136,86,162,
+21,0,136,85,3,172,120,12,198,241,222,33,86,172,2,64,180,18,173,0,64,172,50,155,83,137,7,218,11,1,128,104,37,90,1,128,88,53,202,183,158,1,220,120,152,197,42,0,68,43,209,10,0,196,170,129,214,141,199,162,127,175,60,200,98,21,0,162,149,104,5,0,98,213,64,
+235,181,71,227,155,127,117,252,112,115,153,223,15,235,87,151,1,0,223,153,46,29,255,5,161,15,206,66,0,116,236,229,237,183,204,191,138,247,240,181,225,86,175,193,202,131,109,136,0,192,247,102,86,162,21,0,189,18,171,158,246,159,46,193,55,255,114,9,12,15,
+0,224,187,211,29,209,10,128,222,136,85,207,187,113,9,190,17,172,12,13,0,224,251,211,39,209,10,128,94,136,85,156,77,176,50,44,0,128,239,80,191,68,43,0,170,19,171,184,136,96,101,72,0,0,223,163,190,137,86,0,84,37,86,113,49,193,202,112,0,0,190,75,253,19,
+173,0,168,70,172,226,42,130,149,161,0,0,124,159,198,32,90,1,80,133,88,197,180,94,29,214,103,235,193,245,206,227,1,64,113,241,189,94,117,253,213,68,43,0,246,243,242,246,91,228,155,124,254,122,239,241,249,166,215,95,88,253,237,214,61,232,247,230,191,185,
+6,192,247,106,118,126,105,5,192,94,252,178,234,58,255,227,18,140,65,125,245,203,42,0,250,22,223,111,191,180,2,96,24,126,89,117,253,138,199,104,12,31,60,204,98,21,0,162,149,37,90,1,32,86,13,178,124,179,7,241,214,195,44,86,1,32,90,89,162,21,0,98,213,32,
+139,129,94,10,177,10,0,68,43,75,180,2,64,172,242,23,174,83,202,39,177,10,0,68,43,75,180,2,64,172,234,124,189,241,72,141,229,173,88,5,0,162,149,37,90,1,32,86,117,190,110,60,86,99,185,17,171,0,64,180,178,68,43,0,196,170,230,143,3,82,204,59,177,10,0,68,
+43,75,180,2,64,172,234,116,189,246,104,141,233,70,172,2,0,209,202,18,173,0,16,171,58,92,159,60,90,99,27,253,87,86,98,21,0,162,149,37,90,1,32,86,141,183,226,241,26,219,139,129,95,30,177,10,0,209,202,97,86,180,2,64,172,26,111,125,244,120,205,225,141,88,
+5,0,162,149,37,90,1,32,86,117,178,94,121,196,230,241,94,172,2,128,97,197,193,86,180,2,64,172,26,100,253,230,17,155,203,241,143,6,126,18,171,0,96,88,113,192,21,173,0,16,171,90,255,127,20,240,133,199,204,139,37,86,1,192,88,226,160,43,90,1,96,166,246,157,
+165,215,23,76,172,2,128,113,197,129,215,97,26,128,85,102,105,177,202,191,10,200,6,7,217,158,94,52,177,10,0,206,255,214,59,248,138,86,0,44,67,172,18,171,240,194,253,180,222,186,85,0,112,145,56,252,138,86,0,76,51,59,139,85,12,247,226,125,44,124,8,244,208,
+2,192,117,226,16,44,90,1,112,213,204,44,86,137,85,236,228,248,183,239,191,47,246,192,126,116,248,3,128,197,196,97,88,180,2,224,108,98,149,88,69,17,175,139,188,140,111,221,10,0,88,92,28,138,69,43,0,78,38,86,137,85,20,115,252,181,213,219,157,94,204,15,
+135,117,227,22,0,192,106,226,112,44,90,1,240,44,177,74,172,162,176,155,182,93,184,58,254,113,196,87,46,57,0,108,34,14,201,162,21,0,143,18,171,196,42,58,241,226,246,97,90,250,239,184,250,212,190,4,177,27,151,24,0,54,23,135,101,209,10,128,159,136,85,98,
+21,157,186,139,87,239,218,249,255,178,224,49,80,29,163,215,155,38,82,1,64,5,113,104,22,173,0,248,74,172,18,171,186,242,139,75,240,172,155,246,45,64,29,95,240,23,183,255,243,31,247,254,51,127,184,76,0,80,210,241,224,248,206,101,88,205,223,135,245,239,
+195,250,211,165,0,40,237,56,203,126,184,55,207,178,188,95,15,235,119,151,1,0,128,83,165,249,111,124,253,210,10,96,94,126,89,229,151,85,0,0,20,21,135,105,209,10,96,66,98,149,88,5,0,64,113,113,168,22,173,0,38,34,86,137,85,0,0,116,34,14,215,162,21,192,4,
+196,42,177,10,0,128,206,196,33,91,180,2,24,152,88,37,86,1,0,208,169,56,108,139,86,0,3,18,171,196,42,0,0,58,23,135,110,209,10,96,32,98,149,88,5,0,192,32,226,240,45,90,1,12,64,172,18,171,0,0,24,76,28,194,69,43,128,142,137,85,98,21,0,0,131,138,195,184,104,
+5,208,33,177,74,172,2,0,96,112,113,40,23,173,0,58,34,86,137,85,0,0,76,34,14,231,162,21,64,7,196,42,177,10,0,128,201,196,33,93,180,2,40,76,172,18,171,0,0,152,84,28,214,69,43,128,130,196,42,177,10,0,128,201,197,161,93,180,2,40,68,172,18,171,0,0,224,31,
+113,120,23,173,0,10,16,171,196,42,0,0,248,78,28,226,69,43,128,29,137,85,98,21,0,0,60,40,14,243,162,21,192,14,196,42,177,10,0,0,158,20,135,122,209,10,96,67,98,149,88,5,0,0,39,137,195,189,104,5,176,1,177,74,172,2,0,128,179,196,33,95,180,2,88,145,88,37,
+86,1,0,192,69,226,176,47,90,1,172,64,172,18,171,0,0,224,42,113,232,23,173,0,22,36,86,137,85,0,0,176,136,56,252,139,86,0,11,16,171,196,42,0,0,88,84,12,1,162,21,192,21,196,42,177,10,0,0,86,17,195,128,104,5,112,1,177,74,172,2,0,128,85,197,80,32,90,1,156,
+65,172,18,171,0,0,96,19,49,28,136,86,0,39,16,171,196,42,0,0,216,84,12,9,162,21,192,19,196,42,177,10,0,0,118,17,195,130,104,5,240,0,177,74,172,2,0,128,93,197,208,32,90,1,220,35,86,137,85,0,0,80,66,12,15,162,21,64,19,171,196,42,0,0,40,38,134,8,209,10,152,
+154,88,37,86,1,0,64,73,49,76,136,86,192,148,196,42,177,10,0,0,74,139,161,66,180,2,166,34,86,137,85,0,0,208,133,24,46,68,43,96,10,98,149,88,5,0,0,93,137,33,67,180,2,134,38,86,137,85,0,0,208,165,24,54,68,43,96,72,98,149,88,5,0,0,93,139,161,67,180,2,134,
+34,86,137,85,0,0,48,132,24,62,68,43,96,8,98,149,88,5,0,0,67,137,33,68,180,2,186,38,86,137,85,0,0,48,164,24,70,68,43,160,75,98,149,88,5,0,0,67,139,161,68,180,2,186,34,86,137,85,0,0,48,133,24,78,68,43,160,11,98,149,88,5,0,0,83,137,33,69,180,2,74,19,171,
+196,42,0,0,152,82,12,43,162,21,80,146,88,37,86,1,0,192,212,98,104,17,173,128,82,196,42,177,10,0,0,104,162,149,104,5,84,33,86,137,85,0,0,192,61,49,196,136,86,192,174,196,42,177,10,0,0,120,64,12,51,162,21,176,11,177,74,172,2,0,0,158,16,67,141,104,5,108,
+74,172,18,171,0,0,128,19,196,112,35,90,1,155,16,171,196,42,0,0,224,12,49,228,136,86,192,170,196,42,177,10,0,0,184,64,12,59,162,21,176,10,177,74,172,2,0,0,174,16,67,143,104,5,44,74,172,18,171,0,0,128,5,196,240,35,90,1,139,16,171,196,42,0,0,96,65,49,4,
+137,86,192,85,196,42,177,10,0,0,88,65,12,67,162,21,112,17,177,74,172,2,0,0,86,20,67,145,104,5,156,69,172,18,171,0,0,128,13,196,112,36,90,1,39,17,171,196,42,0,0,96,67,49,36,137,86,192,147,196,42,177,10,0,0,216,65,12,75,162,21,240,32,177,74,172,2,0,0,118,
+20,67,147,104,5,124,71,172,18,171,0,0,128,2,98,120,18,173,128,127,136,85,98,21,0,0,80,72,12,81,162,21,76,78,172,18,171,0,0,128,130,98,152,18,173,96,82,98,149,88,5,0,0,20,22,67,149,104,5,147,17,171,196,42,0,0,160,3,49,92,137,86,48,9,177,74,172,2,0,0,58,
+18,67,150,104,5,131,19,171,196,42,0,0,160,67,49,108,137,86,48,40,177,74,172,2,0,0,58,22,67,151,104,5,131,17,171,196,42,0,0,96,0,49,124,137,86,48,8,177,74,172,2,0,0,6,18,67,152,104,5,157,19,171,196,42,0,0,96,64,49,140,137,86,208,41,177,74,172,2,0,0,6,
+22,67,153,104,5,157,17,171,196,42,0,0,96,2,49,156,137,86,208,9,177,74,172,2,0,0,38,18,67,154,104,5,197,137,85,98,21,0,0,48,161,24,214,68,43,40,74,172,18,171,0,0,128,137,197,208,38,90,65,49,98,149,88,5,0,0,32,90,53,209,10,170,16,171,196,42,0,0,128,175,
+98,136,19,173,96,103,98,149,88,5,0,0,240,147,24,230,68,43,216,137,88,37,86,1,0,0,60,42,134,58,209,10,54,38,86,137,85,0,0,0,207,138,225,78,180,130,141,136,85,98,21,0,0,192,201,98,200,19,173,96,101,98,149,88,5,0,0,112,182,24,246,68,43,88,137,88,37,86,1,
+0,0,92,44,134,62,209,10,22,38,86,137,85,0,0,0,87,139,225,79,180,130,133,136,85,98,21,0,0,192,98,98,8,20,173,224,74,98,149,88,5,0,0,176,184,24,6,69,43,184,144,88,37,86,1,0,0,172,38,134,66,209,10,206,36,86,137,85,0,0,0,171,139,225,80,180,130,19,137,85,
+98,21,0,0,192,102,98,72,20,173,224,25,98,149,88,5,0,0,176,185,24,22,69,43,120,132,88,37,86,1,0,0,236,38,134,70,209,10,126,32,86,137,85,0,0,0,187,139,225,81,180,130,91,98,149,88,5,0,0,80,70,12,145,162,21,211,19,171,196,42,0,0,128,114,98,152,20,173,152,
+150,88,37,86,1,0,0,148,21,67,165,104,197,116,196,42,177,10,0,0,160,188,24,46,69,43,166,33,86,137,85,0,0,0,221,136,33,83,180,98,120,98,149,88,5,0,0,208,157,24,54,69,43,134,37,86,137,85,0,0,0,221,138,161,83,180,98,56,98,149,88,5,0,0,208,189,24,62,69,43,
+134,33,86,137,85,0,0,0,195,136,33,84,180,162,123,98,149,88,5,0,0,48,156,24,70,69,43,186,37,86,137,85,0,0,0,195,138,161,84,180,162,59,98,149,88,5,0,0,48,188,24,78,69,43,186,33,86,137,85,0,0,0,211,136,33,85,180,162,60,177,74,172,2,0,0,152,78,12,171,162,
+21,101,137,85,98,21,0,0,192,180,98,104,21,173,40,71,172,18,171,0,0,0,166,23,195,171,104,69,25,98,149,88,5,0,0,192,173,24,98,69,43,118,39,86,137,85,0,0,0,252,32,134,89,209,138,221,136,85,98,21,0,0,0,143,136,161,86,180,98,115,98,149,88,5,0,0,192,51,98,
+184,21,173,216,140,88,37,86,1,0,0,112,162,24,114,69,43,86,39,86,137,85,0,0,0,156,41,134,93,209,138,213,136,85,98,21,0,0,0,23,138,161,87,180,98,113,98,149,88,5,0,0,192,149,98,248,21,173,88,140,88,37,86,1,0,0,176,144,24,130,69,43,174,38,86,137,85,0,0,0,
+44,44,134,97,209,138,139,137,85,98,21,0,0,0,43,137,161,88,180,226,108,98,149,88,5,0,0,192,202,98,56,22,173,56,153,88,37,86,1,0,0,176,145,24,146,69,43,158,37,86,137,85,0,0,0,108,44,134,101,209,138,71,137,85,98,21,0,0,0,59,137,161,89,180,226,39,98,149,
+88,5,0,0,192,206,98,120,22,173,248,74,172,18,171,0,0,0,40,34,134,104,209,10,177,170,137,85,0,0,0,20,19,195,180,104,53,49,177,74,172,2,0,0,160,168,24,170,69,171,9,137,85,98,21,0,0,0,197,197,112,45,90,77,68,172,18,171,0,0,0,232,68,12,217,162,213,4,196,
+42,177,10,0,0,128,206,196,176,45,90,13,76,172,18,171,0,0,0,232,84,12,221,162,213,128,196,42,177,10,0,0,128,206,197,240,45,90,13,68,172,18,171,0,0,0,24,68,12,225,162,213,0,196,42,177,10,0,0,128,193,196,48,46,90,117,76,172,18,171,0,0,0,24,84,12,229,162,
+85,135,196,42,177,10,0,0,128,193,197,112,46,90,117,68,172,18,171,0,0,0,152,68,12,233,162,85,7,196,42,177,10,0,0,128,201,196,176,46,90,21,38,86,137,85,0,0,0,76,42,134,118,209,170,32,177,74,172,2,0,0,96,114,49,188,139,86,133,136,85,98,21,0,0,0,252,35,134,
+120,209,170,0,177,74,172,2,0,0,128,239,196,48,47,90,237,72,172,18,171,0,0,0,224,65,49,212,139,86,59,16,171,196,42,0,0,0,120,82,12,247,162,213,134,196,42,177,10,0,0,0,78,18,67,190,104,181,1,177,74,172,2,0,0,128,179,196,176,47,90,173,72,172,18,171,0,0,
+0,224,34,49,244,139,86,43,16,171,196,42,0,0,0,184,74,12,255,162,213,130,196,42,177,10,0,0,0,22,17,17,64,180,90,128,88,37,86,1,0,0,192,162,34,6,136,86,87,16,171,196,42,0,0,0,88,69,68,1,209,234,2,98,149,88,5,0,0,0,171,138,56,32,90,157,65,172,18,171,0,0,
+0,96,19,17,9,68,171,19,136,85,98,21,0,0,0,108,42,98,129,104,245,4,177,74,172,2,0,0,128,93,68,52,16,173,30,32,86,137,85,0,0,0,176,171,136,7,162,213,61,98,149,88,5,0,0,0,37,68,68,16,173,154,88,37,86,1,0,0,64,49,17,19,166,142,86,98,149,88,5,0,0,0,37,69,
+84,152,50,90,137,85,98,21,0,0,0,148,22,113,97,170,104,37,86,137,85,0,0,0,208,133,136,12,83,68,43,177,74,172,2,0,0,128,174,68,108,24,58,90,137,85,98,21,0,0,0,116,41,162,195,144,209,74,172,18,171,0,0,0,160,107,17,31,134,138,86,98,149,88,5,0,0,0,67,136,
+8,49,68,180,18,171,196,42,0,0,0,24,74,196,136,174,163,149,88,37,86,1,0,0,192,144,34,74,116,25,173,196,42,177,10,0,0,0,134,22,113,162,171,104,37,86,137,85,0,0,0,48,133,136,20,93,68,43,177,74,172,2,0,0,128,169,68,172,40,29,173,196,42,177,10,0,0,0,166,20,
+209,162,100,180,18,171,196,42,0,0,0,152,90,196,139,82,209,74,172,18,171,0,0,0,128,38,90,85,137,86,98,149,88,5,0,0,0,220,147,38,102,236,25,173,196,42,177,10,0,0,0,120,64,154,168,177,71,180,18,171,196,42,0,0,0,224,9,105,226,198,150,209,74,172,18,171,0,
+0,0,128,19,164,137,28,91,68,43,177,74,172,2,0,0,0,206,144,38,118,172,29,173,196,42,177,10,0,0,0,56,83,154,232,97,137,85,192,192,254,195,37,0,0,128,238,252,121,88,255,119,88,175,93,10,58,242,235,97,253,238,50,0,167,16,172,0,0,160,79,162,21,61,17,171,128,
+179,8,86,0,0,208,47,209,138,30,136,85,192,217,4,43,0,0,232,155,104,69,101,98,21,112,17,193,10,0,0,250,39,90,81,145,88,5,92,76,176,2,0,128,49,136,86,84,34,86,1,0,0,0,95,229,176,62,91,214,142,43,94,67,0,0,0,224,71,105,162,137,37,86,1,0,0,0,197,164,137,
+39,150,88,5,0,0,0,20,147,38,162,88,98,21,0,0,0,80,76,154,152,98,137,85,0,0,0,64,49,105,162,138,37,86,1,0,0,0,197,164,137,43,150,88,5,0,0,0,20,147,38,178,88,98,21,0,0,0,80,76,154,216,98,137,85,0,0,0,64,49,105,162,139,37,86,1,0,0,0,197,164,137,47,150,88,
+5,0,0,0,20,147,38,194,88,98,21,0,0,0,80,76,154,24,99,137,85,0,0,0,64,49,105,162,140,37,86,1,0,0,0,197,164,137,51,150,88,5,0,0,0,20,147,38,210,88,98,21,0,0,0,80,76,154,88,35,86,1,0,0,0,20,147,38,218,136,85,0,0,0,0,197,164,137,55,98,21,0,0,0,64,49,105,
+34,142,88,5,0,0,0,80,76,154,152,35,86,1,0,0,0,20,147,38,234,136,85,0,0,0,0,197,164,137,59,98,21,0,0,0,64,49,105,34,143,88,5,0,0,0,80,76,154,216,35,86,1,0,0,0,20,147,38,250,136,85,0,0,0,0,197,164,137,63,98,21,0,0,0,64,49,105,34,144,88,5,0,0,0,80,76,154,
+24,36,86,1,0,0,0,20,147,38,10,137,85,0,0,0,0,197,164,137,67,98,21,0,0,0,64,49,105,34,145,88,5,0,0,0,80,76,154,88,36,86,1,0,0,0,20,147,38,26,137,85,0,0,0,0,197,164,137,71,98,21,0,0,0,64,49,105,34,146,88,5,0,0,0,80,76,154,152,36,86,1,0,0,0,20,147,38,42,
+137,85,0,0,0,0,197,164,137,75,98,21,0,0,0,64,49,105,34,147,88,5,0,0,0,80,76,154,216,36,86,1,0,0,0,20,147,38,58,137,85,0,0,0,0,197,164,137,79,98,21,0,0,0,64,49,105,34,148,88,5,0,0,0,80,76,154,24,37,86,1,0,0,0,20,147,38,74,137,85,0,0,0,0,197,164,137,83,
+98,21,0,0,0,64,49,105,34,149,88,5,0,0,0,80,76,154,88,21,143,1,0,0,0,64,45,105,98,21,0,0,0,0,197,164,137,85,0,0,0,0,20,147,38,86,1,0,0,0,80,76,154,88,5,0,0,0,64,49,105,98,21,0,0,0,0,197,164,137,85,0,0,0,0,20,147,38,86,1,0,0,0,80,76,154,88,5,0,0,0,64,49,
+105,98,21,0,0,0,0,197,164,137,85,0,0,0,0,20,147,38,86,1,0,0,0,80,204,203,195,250,171,213,13,85,199,255,223,226,54,1,0,0,0,204,229,230,176,62,182,122,177,234,83,251,18,212,0,0,0,0,152,212,219,86,39,86,253,118,88,47,220,18,0,0,0,0,142,191,104,250,208,246,
+253,85,213,43,183,1,0,0,0,128,31,189,110,95,226,209,150,161,42,46,59,0,0,0,0,207,121,117,88,239,219,122,161,234,248,107,174,184,204,0,0,0,0,156,235,248,247,73,165,125,137,87,215,254,171,130,199,72,245,166,125,249,203,222,1,88,193,47,46,1,0,0,48,161,151,
+183,235,230,176,254,235,153,255,236,127,31,214,223,135,245,231,97,253,225,210,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,244,239,255,5,24,0,2,125,7,137,153,101,243,194,0,0,0,0,73,69,78,68,174,66,96,130,0,0 };
+
+const char* BinaryData::triangle_wave_png = (const char*) temp_d696456d;
+
 //================== wifi.png ==================
 static const unsigned char temp_43e5b62e[] =
 { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,64,0,0,0,247,8,6,0,0,0,108,40,141,211,0,0,0,9,112,72,89,115,0,0,46,35,0,0,46,35,1,120,165,63,118,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109,97,103,101,82,101,
diff --git a/JuceLibraryCode/BinaryData.h b/JuceLibraryCode/BinaryData.h
index d811f05d43fe17554b9690e2e075e8cebac80de0..891b5212ef6e86f2ee78e96af85b23d6545cc68a 100644
--- a/JuceLibraryCode/BinaryData.h
+++ b/JuceLibraryCode/BinaryData.h
@@ -46,6 +46,81 @@ namespace BinaryData
     extern const char*   silkscreen_ttf;
     const int            silkscreen_ttfSize = 18336;
 
+    extern const char*   RadioButtons01_png;
+    const int            RadioButtons01_pngSize = 818;
+
+    extern const char*   RadioButtons02_png;
+    const int            RadioButtons02_pngSize = 824;
+
+    extern const char*   RadioButtons03_png;
+    const int            RadioButtons03_pngSize = 704;
+
+    extern const char*   RadioButtons04_png;
+    const int            RadioButtons04_pngSize = 792;
+
+    extern const char*   RadioButtons05_png;
+    const int            RadioButtons05_pngSize = 942;
+
+    extern const char*   RadioButtons_neutral01_png;
+    const int            RadioButtons_neutral01_pngSize = 730;
+
+    extern const char*   RadioButtons_neutral02_png;
+    const int            RadioButtons_neutral02_pngSize = 681;
+
+    extern const char*   RadioButtons_neutral03_png;
+    const int            RadioButtons_neutral03_pngSize = 536;
+
+    extern const char*   RadioButtons_neutral04_png;
+    const int            RadioButtons_neutral04_pngSize = 654;
+
+    extern const char*   RadioButtons_neutral05_png;
+    const int            RadioButtons_neutral05_pngSize = 821;
+
+    extern const char*   RadioButtons_selected01_png;
+    const int            RadioButtons_selected01_pngSize = 761;
+
+    extern const char*   RadioButtons_selected02_png;
+    const int            RadioButtons_selected02_pngSize = 729;
+
+    extern const char*   RadioButtons_selected03_png;
+    const int            RadioButtons_selected03_pngSize = 561;
+
+    extern const char*   RadioButtons_selected04_png;
+    const int            RadioButtons_selected04_pngSize = 727;
+
+    extern const char*   RadioButtons_selected05_png;
+    const int            RadioButtons_selected05_pngSize = 869;
+
+    extern const char*   RadioButtons_selected_over01_png;
+    const int            RadioButtons_selected_over01_pngSize = 866;
+
+    extern const char*   RadioButtons_selected_over02_png;
+    const int            RadioButtons_selected_over02_pngSize = 843;
+
+    extern const char*   RadioButtons_selected_over03_png;
+    const int            RadioButtons_selected_over03_pngSize = 728;
+
+    extern const char*   RadioButtons_selected_over04_png;
+    const int            RadioButtons_selected_over04_pngSize = 838;
+
+    extern const char*   RadioButtons_selected_over05_png;
+    const int            RadioButtons_selected_over05_pngSize = 977;
+
+    extern const char*   noise_wave_png;
+    const int            noise_wave_pngSize = 19800;
+
+    extern const char*   saw_wave_png;
+    const int            saw_wave_pngSize = 10801;
+
+    extern const char*   sine_wave_png;
+    const int            sine_wave_pngSize = 12863;
+
+    extern const char*   square_wave_png;
+    const int            square_wave_pngSize = 6208;
+
+    extern const char*   triangle_wave_png;
+    const int            triangle_wave_pngSize = 8480;
+
     extern const char*   wifi_png;
     const int            wifi_pngSize = 3412;
 
diff --git a/JuceLibraryCode/src/gui/components/lookandfeel/juce_LookAndFeel.cpp b/JuceLibraryCode/src/gui/components/lookandfeel/juce_LookAndFeel.cpp
index dbc9a72515c59cfdb60c1757f001f4eb9d191c1e..07b58308d8881df465225b0d3f95717668120385 100755
--- a/JuceLibraryCode/src/gui/components/lookandfeel/juce_LookAndFeel.cpp
+++ b/JuceLibraryCode/src/gui/components/lookandfeel/juce_LookAndFeel.cpp
@@ -323,7 +323,7 @@ const Colour LookAndFeel::findColour (const int colourId) const throw()
     if (index >= 0)
         return colours [index];
 
-    jassertfalse;
+    //jassertfalse;
     return Colours::black;
 }
 
diff --git a/Resources/Images/Icons/RadioButtons-01.png b/Resources/Images/Icons/RadioButtons-01.png
new file mode 100644
index 0000000000000000000000000000000000000000..c50f3baedbb32bbbaacf2d51699be465c6d9e5a1
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons-01.png differ
diff --git a/Resources/Images/Icons/RadioButtons-02.png b/Resources/Images/Icons/RadioButtons-02.png
new file mode 100644
index 0000000000000000000000000000000000000000..76348bea6c93c0dd4b82713f4ed6fa3ae681f2ee
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons-02.png differ
diff --git a/Resources/Images/Icons/RadioButtons-03.png b/Resources/Images/Icons/RadioButtons-03.png
new file mode 100644
index 0000000000000000000000000000000000000000..7974f07ac0325bd633b0b0c48867702da4145859
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons-03.png differ
diff --git a/Resources/Images/Icons/RadioButtons-04.png b/Resources/Images/Icons/RadioButtons-04.png
new file mode 100644
index 0000000000000000000000000000000000000000..e431c90ed86833d9cce9e7848a494a9d42a24906
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons-04.png differ
diff --git a/Resources/Images/Icons/RadioButtons-05.png b/Resources/Images/Icons/RadioButtons-05.png
new file mode 100644
index 0000000000000000000000000000000000000000..db8ae6e6adf855ba3d02d98b5d94a53c82e444f6
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons-05.png differ
diff --git a/Resources/Images/Icons/RadioButtons_neutral-01.png b/Resources/Images/Icons/RadioButtons_neutral-01.png
new file mode 100644
index 0000000000000000000000000000000000000000..7e4738da8aff468fe392bf56b7d325bab1d42c92
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_neutral-01.png differ
diff --git a/Resources/Images/Icons/RadioButtons_neutral-02.png b/Resources/Images/Icons/RadioButtons_neutral-02.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2426a7f3740247ec1b7df8c142406c4a11de65f
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_neutral-02.png differ
diff --git a/Resources/Images/Icons/RadioButtons_neutral-03.png b/Resources/Images/Icons/RadioButtons_neutral-03.png
new file mode 100644
index 0000000000000000000000000000000000000000..e130a8e5928edc92a56c511ad324d1f7449ec0ff
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_neutral-03.png differ
diff --git a/Resources/Images/Icons/RadioButtons_neutral-04.png b/Resources/Images/Icons/RadioButtons_neutral-04.png
new file mode 100644
index 0000000000000000000000000000000000000000..584cdb75e5c910874cfe612394426f2e1f3e0275
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_neutral-04.png differ
diff --git a/Resources/Images/Icons/RadioButtons_neutral-05.png b/Resources/Images/Icons/RadioButtons_neutral-05.png
new file mode 100644
index 0000000000000000000000000000000000000000..79f59c74ce3beb09cf080115a5c5b4f98ff2cd88
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_neutral-05.png differ
diff --git a/Resources/Images/Icons/RadioButtons_selected-01.png b/Resources/Images/Icons/RadioButtons_selected-01.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2638b271b558747cbf9981e4575925f35583b8c
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_selected-01.png differ
diff --git a/Resources/Images/Icons/RadioButtons_selected-02.png b/Resources/Images/Icons/RadioButtons_selected-02.png
new file mode 100644
index 0000000000000000000000000000000000000000..6153bcb5150b44b97ab47fb6eb775df8a94e2791
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_selected-02.png differ
diff --git a/Resources/Images/Icons/RadioButtons_selected-03.png b/Resources/Images/Icons/RadioButtons_selected-03.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ed1e7ba021340fbd4463b8dbc4c6730f2a3c1a9
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_selected-03.png differ
diff --git a/Resources/Images/Icons/RadioButtons_selected-04.png b/Resources/Images/Icons/RadioButtons_selected-04.png
new file mode 100644
index 0000000000000000000000000000000000000000..da4e6739bcbb479b5cdb209e17ad03862d265b08
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_selected-04.png differ
diff --git a/Resources/Images/Icons/RadioButtons_selected-05.png b/Resources/Images/Icons/RadioButtons_selected-05.png
new file mode 100644
index 0000000000000000000000000000000000000000..c43e401f0661087e752959e006418d3f6bc9c1b9
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_selected-05.png differ
diff --git a/Resources/Images/Icons/RadioButtons_selected_over-01.png b/Resources/Images/Icons/RadioButtons_selected_over-01.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f6634a242e6c4db6213729ec55fda6d0cbe1e64
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_selected_over-01.png differ
diff --git a/Resources/Images/Icons/RadioButtons_selected_over-02.png b/Resources/Images/Icons/RadioButtons_selected_over-02.png
new file mode 100644
index 0000000000000000000000000000000000000000..836d50993d2f9241c2f8d6d7a41fbd425376d093
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_selected_over-02.png differ
diff --git a/Resources/Images/Icons/RadioButtons_selected_over-03.png b/Resources/Images/Icons/RadioButtons_selected_over-03.png
new file mode 100644
index 0000000000000000000000000000000000000000..20cbdfdff27a2d873f28c19aa27ddef5ebe87fe6
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_selected_over-03.png differ
diff --git a/Resources/Images/Icons/RadioButtons_selected_over-04.png b/Resources/Images/Icons/RadioButtons_selected_over-04.png
new file mode 100644
index 0000000000000000000000000000000000000000..b1eedc7d2b81f9257106461c2e2f50f532cde9bf
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_selected_over-04.png differ
diff --git a/Resources/Images/Icons/RadioButtons_selected_over-05.png b/Resources/Images/Icons/RadioButtons_selected_over-05.png
new file mode 100644
index 0000000000000000000000000000000000000000..b57027d3c16b3c005f9c74dd965c07ddd1467fa4
Binary files /dev/null and b/Resources/Images/Icons/RadioButtons_selected_over-05.png differ
diff --git a/Resources/Images/Icons/noise_wave.png b/Resources/Images/Icons/noise_wave.png
new file mode 100644
index 0000000000000000000000000000000000000000..59e59bdedc317b077dbcfd3988bafd29e725c690
Binary files /dev/null and b/Resources/Images/Icons/noise_wave.png differ
diff --git a/Resources/Images/Icons/saw_wave.png b/Resources/Images/Icons/saw_wave.png
new file mode 100644
index 0000000000000000000000000000000000000000..38bdada85a159b0a39208d60be5283daf6f70314
Binary files /dev/null and b/Resources/Images/Icons/saw_wave.png differ
diff --git a/Resources/Images/Icons/sine_wave.png b/Resources/Images/Icons/sine_wave.png
new file mode 100644
index 0000000000000000000000000000000000000000..3eec7a0f53fb080fc0965ed93039d91f3b9f1de0
Binary files /dev/null and b/Resources/Images/Icons/sine_wave.png differ
diff --git a/Resources/Images/Icons/square_wave.png b/Resources/Images/Icons/square_wave.png
new file mode 100644
index 0000000000000000000000000000000000000000..eb06b269386aa0a4742f466883fe049e21fd460c
Binary files /dev/null and b/Resources/Images/Icons/square_wave.png differ
diff --git a/Resources/Images/Icons/triangle_wave.png b/Resources/Images/Icons/triangle_wave.png
new file mode 100644
index 0000000000000000000000000000000000000000..179713b3f3a41a3b027e5d6f03624c570b8f1e62
Binary files /dev/null and b/Resources/Images/Icons/triangle_wave.png differ
diff --git a/Source/AccessClass.cpp b/Source/AccessClass.cpp
index 7816f8245e9f56d42ae9bcfcf9bd2d50f17e59b5..bf3e615725cf68b4c7686e84fb53db431668af93 100644
--- a/Source/AccessClass.cpp
+++ b/Source/AccessClass.cpp
@@ -1,11 +1,24 @@
-/*
-  ==============================================================================
+ /*
+    ------------------------------------------------------------------
 
-    AccessClass.cpp
-    Created: 1 Mar 2012 1:36:31pm
-    Author:  jsiegle
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
 
-  ==============================================================================
 */
 
 #include "AccessClass.h"
@@ -14,7 +27,6 @@
 #include "UI/EditorViewport.h"
 #include "UI/ProcessorList.h"
 #include "UI/DataViewport.h"
-#include "UI/Configuration.h"
 #include "UI/ControlPanel.h"
 #include "UI/MessageCenter.h"
 #include "Audio/AudioComponent.h"
@@ -22,6 +34,7 @@
 
 void AccessClass::setUIComponent(UIComponent* ui_)
 {
+
 	ui = ui_;
 
 	ev = ui->getEditorViewport();
@@ -30,7 +43,6 @@ void AccessClass::setUIComponent(UIComponent* ui_)
 	pg = ui->getProcessorGraph();
 	cp = ui->getControlPanel();
 	mc = ui->getMessageCenter();
-	cf = ui->getConfiguration();
 	ac = ui->getAudioComponent();
 
 	addActionListener(mc);
diff --git a/Source/AccessClass.h b/Source/AccessClass.h
index 582112bdbafa3e731d00ce7669e1c8c0ef860edf..566d1a00d34e1b6b9a4bf96f90998911384f3ecd 100644
--- a/Source/AccessClass.h
+++ b/Source/AccessClass.h
@@ -1,11 +1,24 @@
 /*
-  ==============================================================================
+    ------------------------------------------------------------------
 
-    AccessClass.h
-    Created: 1 Mar 2012 1:17:45pm
-    Author:  jsiegle
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
 
-  ==============================================================================
 */
 
 #ifndef __ACCESSCLASS_H_CE1DC2DE__
@@ -20,9 +33,17 @@ class DataViewport;
 class ProcessorGraph;
 class MessageCenter;
 class ControlPanel;
-class Configuration;
 class AudioComponent;
 
+
+/**
+  
+  Allows subclasses to access important pointers within the application.
+
+  @see UIComponent
+
+*/
+
 class AccessClass : public ActionBroadcaster
 {
 public:
@@ -39,7 +60,6 @@ public:
 	ControlPanel* getControlPanel() {return cp;}
 	MessageCenter* getMessageCenter() {return mc;}
 	UIComponent* getUIComponent() {return ui;}
-	Configuration* getConfiguration() {return cf;}
 	AudioComponent* getAudioComponent() {return ac;}
 
 private:
@@ -51,7 +71,6 @@ private:
 	ProcessorGraph* pg;
 	ControlPanel* cp;
 	MessageCenter* mc;
-	Configuration* cf;
 	AudioComponent* ac;
 
 };
diff --git a/Source/Audio/AudioComponent.cpp b/Source/Audio/AudioComponent.cpp
index 93119a912623e550a9c05661d94aca078fa920c1..9942ff1476a20e2e480247cdf180fb32eea5118c 100644
--- a/Source/Audio/AudioComponent.cpp
+++ b/Source/Audio/AudioComponent.cpp
@@ -70,6 +70,9 @@ AudioComponent::AudioComponent() : isPlaying(false)
 
 	graphPlayer = new AudioProcessorPlayer();
 
+	stopDevice(); // reduces the amount of background processing when
+				  // device is not in use
+
 }
 
 AudioComponent::~AudioComponent() {
@@ -99,8 +102,22 @@ bool AudioComponent::callbacksAreActive() {
 	return isPlaying;
 }
 
+void AudioComponent::restartDevice()
+{
+	deviceManager.restartLastAudioDevice();
+
+}
+
+void AudioComponent::stopDevice()
+{
+
+	deviceManager.closeAudioDevice();
+}
+
 void AudioComponent::beginCallbacks() {
 	
+	restartDevice();
+
 	std::cout << std::endl << "Adding audio callback." << std::endl;
 	deviceManager.addAudioCallback(graphPlayer);
 	isPlaying = true;
@@ -113,5 +130,7 @@ void AudioComponent::endCallbacks() {
 	deviceManager.removeAudioCallback(graphPlayer);
 	isPlaying = false;
 
+	stopDevice();
+
 }
 
diff --git a/Source/Audio/AudioComponent.h b/Source/Audio/AudioComponent.h
index 45a804c4b88d84518d889a8a9b7c5a1a1f57acd6..e129564e6060014139eca8d14b446cd8705c5e1c 100644
--- a/Source/Audio/AudioComponent.h
+++ b/Source/Audio/AudioComponent.h
@@ -56,6 +56,9 @@ public:
 
 	bool callbacksAreActive();
 
+  void restartDevice();
+  void stopDevice();
+
   AudioDeviceManager deviceManager;
 
 private:
diff --git a/Source/Main.cpp b/Source/Main.cpp
index f70d622a995eaca5bbef5742a2a17e69a36bcf58..68b8d21ee9466d4ac51a8619724331a3bbe54e69 100644
--- a/Source/Main.cpp
+++ b/Source/Main.cpp
@@ -57,11 +57,7 @@ public:
         LookAndFeel::setDefaultLookAndFeel(customLookAndFeel);
     }
 
-    void shutdown()
-    {
-        mainWindow = 0;
-        customLookAndFeel = 0;
-    }
+    void shutdown() { }
 
     //==============================================================================
     void systemRequestedQuit()
diff --git a/Source/MainWindow.cpp b/Source/MainWindow.cpp
index d234bf00336fdf02d08944fc4ae42470daa3ba81..f741aa3d61105c921ff3859a65dbbe026d9f35a5 100644
--- a/Source/MainWindow.cpp
+++ b/Source/MainWindow.cpp
@@ -31,20 +31,22 @@ MainWindow::MainWindow()
                       Colour(Colours::black),
                       DocumentWindow::allButtons)
 {
-    //centreWithSize (500, 400);
+
     setResizable (true,     // isResizable
                   false);   // useBottomCornerRisizer -- doesn't work very well
-    
+   // centreWithSize(500,400);
+
     // Constraining the window's size doesn't seem to work:
     //setResizeLimits(500, 400, 10000, 10000);
 
     // Create ProcessorGraph and AudioComponent, and connect them.
     // Callbacks will be set by the play button in the control panel
-    processorGraph = new ProcessorGraph();
-    audioComponent = new AudioComponent();
-    audioComponent->connectToProcessorGraph(processorGraph);
 
-    setContentComponent (new UIComponent(this, processorGraph, audioComponent), true, true);
+     processorGraph = new ProcessorGraph();
+     audioComponent = new AudioComponent();
+     audioComponent->connectToProcessorGraph(processorGraph);
+
+     setContentComponent (new UIComponent(this, processorGraph, audioComponent), true, true);
 
     // commandManager.registerAllCommandsForTarget (getContentComponent());
     // commandManager.registerAllCommandsForTarget (JUCEApplication::getInstance());
@@ -61,16 +63,16 @@ MainWindow::MainWindow()
 MainWindow::~MainWindow()
 {
 
-  saveWindowBounds();
-  processorGraph->saveState();
+   saveWindowBounds();
+   processorGraph->saveState();
 
-  audioComponent->disconnectProcessorGraph();
+   audioComponent->disconnectProcessorGraph();
 
    deleteAndZero(processorGraph);
    deleteAndZero(audioComponent);
 
-  setContentComponent (0);
-  setMenuBar(0);
+   setContentComponent (0);
+  // setMenuBar(0);
 
 }
 
diff --git a/Source/Processors/AudioNode.cpp b/Source/Processors/AudioNode.cpp
index 0952a10817cb9e60dad869df627730ace251129b..5cede137287c4457cdf398f2c6c6f1918d6a58fb 100644
--- a/Source/Processors/AudioNode.cpp
+++ b/Source/Processors/AudioNode.cpp
@@ -25,29 +25,38 @@
 #include "AudioNode.h"
 
 AudioNode::AudioNode()
-	: GenericProcessor("Audio Node"), volume(5.0f)
+	: GenericProcessor("Audio Node"), volume(5.0f), audioEditor(0)
 {
 
+	settings.numInputs = 64;
+	settings.numOutputs = 2;
+
 	// 64 inputs, 2 outputs (left and right channel)
-	setPlayConfigDetails(64,2,44100.0,128);
+	setPlayConfigDetails(getNumInputs(),getNumOutputs(),44100.0,128);
 
 	leftChan.add(0);
 	rightChan.add(1);
+
+	currentChannel = 0;
+
+
 }
 
 
 AudioNode::~AudioNode() {
 
+
+
 }
 
 AudioProcessorEditor* AudioNode::createEditor()
 {
 	
-	AudioEditor* editor = new AudioEditor(this);
+	audioEditor = new AudioEditor(this);
 
-	setEditor(editor);
+	//setEditor(editor);
 	
-	return editor; 
+	return audioEditor; 
 
 }
 
@@ -65,6 +74,16 @@ void AudioNode::process(AudioSampleBuffer &buffer,
                             int& nSamples)
 {
 
+	// if (currentChannel == 0)
+	// {
+	// 	buffer.clear(1,0,buffer.getNumSamples());
+	// 	buffer.copyFrom();
+	// } else if (currentChannel == 1)
+	// {
+	// 	buffer.clear(0,0,buffer.getNumSamples());
+	// 	buffer.copyFrom();
+	// } else {
+
 	buffer.clear(0,0,buffer.getNumSamples());
 	buffer.clear(1,0,buffer.getNumSamples());
 
@@ -89,4 +108,5 @@ void AudioNode::process(AudioSampleBuffer &buffer,
 					   volume       // gain to apply
 					   );
 	}
+	//}
 }
diff --git a/Source/Processors/AudioNode.h b/Source/Processors/AudioNode.h
index ad8c07ef5a5b57d3e1bb69689cd41524302063da..9e19c2eb938e7312cfd442e625efe4dd2ce8d9cb 100644
--- a/Source/Processors/AudioNode.h
+++ b/Source/Processors/AudioNode.h
@@ -41,6 +41,8 @@
 
 */
 
+class AudioEditor;
+
 class AudioNode : public GenericProcessor
 {
 public:
@@ -53,6 +55,10 @@ public:
 	void setParameter (int parameterIndex, float newValue);
 
 	AudioProcessorEditor* createEditor();
+
+   // AudioEditor* getEditor() {return audioEditor;}
+
+    ScopedPointer<AudioEditor> audioEditor;
 	
 private:
 
diff --git a/Source/Processors/DataThreads/DataBuffer.h b/Source/Processors/DataThreads/DataBuffer.h
index 2695ab61d314e6ebe38189f3c9d550bcf34e4886..dc088a63000497d09f14bce680bf50c5db12b7f8 100644
--- a/Source/Processors/DataThreads/DataBuffer.h
+++ b/Source/Processors/DataThreads/DataBuffer.h
@@ -28,6 +28,9 @@ private:
 	AbstractFifo abstractFifo;
 	AudioSampleBuffer buffer;
 	int numChans;
+
+	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DataBuffer);
+
 };
 
 
diff --git a/Source/Processors/DataThreads/DataThread.cpp b/Source/Processors/DataThreads/DataThread.cpp
index a10c258dd7bd21d25339efbba1e28245187e2ee5..dd83b847c237fe7672fceedc8ffd7da0d43e3e2f 100644
--- a/Source/Processors/DataThreads/DataThread.cpp
+++ b/Source/Processors/DataThreads/DataThread.cpp
@@ -31,7 +31,10 @@ DataThread::DataThread(SourceNode* s) : Thread ("Data Thread"), dataBuffer(0)
 	setPriority(10);
 }
 
-DataThread::~DataThread() {}
+DataThread::~DataThread() 
+{
+    deleteAndZero(dataBuffer);
+}
 
 void DataThread::run() {
 
diff --git a/Source/Processors/DataThreads/DataThread.h b/Source/Processors/DataThreads/DataThread.h
index a86cfa4e266065ad5aea5de7bb57c21770e5ad0d..001bb8e5fabc36645a5ea8c49a8792ebdf8b9448 100644
--- a/Source/Processors/DataThreads/DataThread.h
+++ b/Source/Processors/DataThreads/DataThread.h
@@ -64,6 +64,11 @@ public:
 
 	SourceNode* sn;
 
+private:
+
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DataThread);
+
+
 };
 
 
diff --git a/Source/Processors/DataThreads/FileReaderThread.cpp b/Source/Processors/DataThreads/FileReaderThread.cpp
index ba6c1574082c28294d475db273136dcdc9de4c63..f7f1aa4ee0908735d105622ec797489e90b91f79 100644
--- a/Source/Processors/DataThreads/FileReaderThread.cpp
+++ b/Source/Processors/DataThreads/FileReaderThread.cpp
@@ -33,6 +33,8 @@ FileReaderThread::FileReaderThread(SourceNode* sn) : DataThread(sn),
 	File file = File("./data_stream_16ch");
 	input = file.createInputStream();
 
+   // lengthOfInputFile = file
+
 	dataBuffer = new DataBuffer(16, 4096);
 
 	std::cout << "File Reader Thread initialized." << std::endl;
@@ -65,12 +67,16 @@ bool FileReaderThread::updateBuffer()
 	while (dataBuffer->getNumSamples() < 4096)
 	{
 
+       // if (input->getTotalLength())
+
+        //input->read(thisSample, 4*)
+
     	for (int ch = 0; ch < numChannels; ch++) {
     		
     		if (input->isExhausted())
     			input->setPosition(0);   			
     	
-    		thisSample[ch%numChannels] = float(input->readShort());
+    		thisSample[ch%numChannels] = float(input->readShort())/80000.0f;
 
     	}
 
diff --git a/Source/Processors/DataThreads/FileReaderThread.h b/Source/Processors/DataThreads/FileReaderThread.h
index 4e625fe1bc1eb8d1946300d336fc7d9107ef0e90..d7ac4beb8c2a1e90c6ae9e4026ea358ef21372b4 100644
--- a/Source/Processors/DataThreads/FileReaderThread.h
+++ b/Source/Processors/DataThreads/FileReaderThread.h
@@ -62,9 +62,14 @@ private:
 	int numChannels;
 	int samplesPerBlock;
 
+    int lengthOfInputFile;
+
+    int playHead;
+
 	FileInputStream* input;
 
 	float thisSample[16];
+    float readBuffer[1600];
 
 	bool updateBuffer();
 
diff --git a/Source/Processors/Editors/AudioEditor.cpp b/Source/Processors/Editors/AudioEditor.cpp
index 50f6591776d0861cc8a077bfd4488e388958ddea..808226e56e2adf0d19b1697e25047fe4da7fa2d4 100644
--- a/Source/Processors/Editors/AudioEditor.cpp
+++ b/Source/Processors/Editors/AudioEditor.cpp
@@ -136,16 +136,23 @@ void AudioEditor::buttonClicked(Button* button)
 		{
 			if (acw == 0) {
 				
-				AudioComponent* ac = getAudioComponent();
-
-				if (ac != 0)
-					acw = new AudioConfigurationWindow(ac->deviceManager, (Button*) audioWindowButton);
+				// AudioComponent* audioComponent = getAudioComponent();
+				// audioComponent->restartDevice();
 
+				// if (audioComponent != 0) {
+					acw = new AudioConfigurationWindow(getAudioComponent()->deviceManager, (Button*) audioWindowButton);
+					acw->setUIComponent(getUIComponent());
+				//}
 			}
 
+			getAudioComponent()->restartDevice();
 			acw->setVisible(true);
+
 		} else {
+
 			acw->setVisible(false);
+			//deleteAndZero(acw);
+			getAudioComponent()->stopDevice();
 		}
 	}
 
@@ -205,6 +212,7 @@ AudioConfigurationWindow::~AudioConfigurationWindow()
 void AudioConfigurationWindow::closeButtonPressed()
 {
 	controlButton->setToggleState(false,false);
+	getAudioComponent()->stopDevice();
 	setVisible(false);
 }
 
diff --git a/Source/Processors/Editors/AudioEditor.h b/Source/Processors/Editors/AudioEditor.h
index fcdad65b524c20185352fc63cc4e283277b4a531..5389a25d8c2da7efd5237e47aabdb5d8b852532c 100644
--- a/Source/Processors/Editors/AudioEditor.h
+++ b/Source/Processors/Editors/AudioEditor.h
@@ -48,7 +48,8 @@ class AudioWindowButton : public Button
 		Font font;
 };
 
-class AudioConfigurationWindow : public DocumentWindow
+class AudioConfigurationWindow : public DocumentWindow,
+								 public AccessClass
 {
 public:
 	AudioConfigurationWindow(AudioDeviceManager& adm, Button* b);
diff --git a/Source/Processors/Editors/EventNodeEditor.cpp b/Source/Processors/Editors/EventNodeEditor.cpp
index 11d68a5b52ba4b85f197154d4692f48400f03533..36173b5e580869cb128511e388adfd21f23f7e84 100644
--- a/Source/Processors/Editors/EventNodeEditor.cpp
+++ b/Source/Processors/Editors/EventNodeEditor.cpp
@@ -39,15 +39,15 @@ EventNodeEditor::EventNodeEditor (GenericProcessor* parentNode)
 
 	createRadioButtons(35, 65, 160, hzValues, "Event frequency");
 
-	for (int n = 0; n < getNumChildComponents(); n++)
-	{
-		Button* c = (Button*) getChildComponent(n);
+	// for (int n = 0; n < getNumChildComponents(); n++)
+	// {
+	// 	Button* c = (Button*) getChildComponent(n);
 
-		if (c->isVisible())
-			c->addListener(this);
+	// 	if (c->isVisible())
+	// 		c->addListener(this);
 
-		c->setVisible(true);
-	}
+	// 	c->setVisible(true);
+	// }
 
 }
 
@@ -66,7 +66,7 @@ EventNodeEditor::~EventNodeEditor()
 
 // }
 
-void EventNodeEditor::buttonClicked (Button* button)
+void EventNodeEditor::buttonEvent (Button* button)
 {
 	//std::cout << button->getRadioGroupId() << " " << button->getName() << std::endl;
 	String value = button->getName();
diff --git a/Source/Processors/Editors/EventNodeEditor.h b/Source/Processors/Editors/EventNodeEditor.h
index a8eada7865534895b34b97c9990ff77c83480055..dc4bc09007c1e61ace467c64e22752b88b97d1f1 100644
--- a/Source/Processors/Editors/EventNodeEditor.h
+++ b/Source/Processors/Editors/EventNodeEditor.h
@@ -30,13 +30,12 @@
 
 class FilterViewport;
 
-class EventNodeEditor : public GenericEditor//,
-					// public Button::Listener
+class EventNodeEditor : public GenericEditor
 {
 public:
 	EventNodeEditor (GenericProcessor* parentNode);
 	virtual ~EventNodeEditor();
-	void buttonClicked(Button* button);
+	void buttonEvent(Button* button);
 
 private:	
 
diff --git a/Source/Processors/Editors/FilterEditor.cpp b/Source/Processors/Editors/FilterEditor.cpp
index e4c84b42fc338c34d87a2fa599a33f706977ba56..449d53126369705554d1c3830ac26358c907ea1e 100644
--- a/Source/Processors/Editors/FilterEditor.cpp
+++ b/Source/Processors/Editors/FilterEditor.cpp
@@ -75,11 +75,11 @@ FilterEditor::~FilterEditor()
 
 // }
 
-void FilterEditor::buttonClicked (Button* button)
+void FilterEditor::buttonEvent (Button* button)
 {
 	//std::cout << button->getRadioGroupId() << " " << button->getName() << std::endl;
 	
-	if (!checkDrawerButton(button) && !checkChannelSelectors(button)) {
+	//if (!checkDrawerButton(button) && !checkChannelSelectors(button)) {
 
 		String value = button->getName();
 		float val;
@@ -102,6 +102,6 @@ void FilterEditor::buttonClicked (Button* button)
 		}	
 
  	//std::cout << button->getRadioGroupId() << " " << val << std::endl;
- 	}
+ //	}
 
 }
\ No newline at end of file
diff --git a/Source/Processors/Editors/FilterEditor.h b/Source/Processors/Editors/FilterEditor.h
index ff4f336aeb4d3ddfe089e9a90382434b63302ab6..018e616f6d9d6bef6314d041a05746bf2337ef5f 100644
--- a/Source/Processors/Editors/FilterEditor.h
+++ b/Source/Processors/Editors/FilterEditor.h
@@ -31,18 +31,13 @@
 class FilterViewport;
 
 class FilterEditor : public GenericEditor
-				//	 public Button::Listener
 {
 public:
 	FilterEditor (GenericProcessor* parentNode);
 	virtual ~FilterEditor();
-	//void sliderValueChanged (Slider* slider);
-	void buttonClicked(Button* button);
+	void buttonEvent(Button* button);
 
 private:	
-	//Slider* lowSlider;
-	//Slider* highSlider;
-
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilterEditor);
 
diff --git a/Source/Processors/Editors/GenericEditor.cpp b/Source/Processors/Editors/GenericEditor.cpp
index 1bca25ccacd7216850e8389b87d5e4d760f778c3..b44d1a867730a11b928a94a7508b85522308e4ad 100644
--- a/Source/Processors/Editors/GenericEditor.cpp
+++ b/Source/Processors/Editors/GenericEditor.cpp
@@ -23,8 +23,11 @@
 
 #include "GenericEditor.h"
 
+#include "../ProcessorGraph.h"
+#include "../RecordNode.h"
+#include "../../UI/ProcessorList.h"
+
 #include "../../UI/EditorViewport.h"
-#include "../../UI/Configuration.h"
 
 #include <math.h>
 
@@ -70,24 +73,19 @@ GenericEditor::GenericEditor (GenericProcessor* owner)//, FilterViewport* vp)
     		paramsButton->setToggleState(true, true);
     	}
 
-    	
-
 	}
 
-	if (owner->isSource())
-		backgroundColor = Colour(255, 0, 0);//Colour(int(0.9*255.0f),int(0.019*255.0f),int(0.16*255.0f));
-	else if (owner->isSink())
-		backgroundColor = Colour(255, 149, 0);//Colour(int(0.06*255.0f),int(0.46*255.0f),int(0.9*255.0f));
-	else if (owner->isSplitter() || owner->isMerger())
-		backgroundColor = Colour(40, 40, 40);//Colour(int(0.7*255.0f),int(0.7*255.0f),int(0.7*255.0f));
-	else
-		backgroundColor = Colour(255, 89, 0);//Colour(int(1.0*255.0f),int(0.5*255.0f),int(0.0*255.0f));
-
-
 	paramsChannels.clear();
 	audioChannels.clear();
 	recordChannels.clear();
 
+	backgroundGradient = ColourGradient(Colour(190, 190, 190), 0.0f, 150.0f, 
+										 Colour(145, 145, 145), 0.0f, 0.0f, false);
+
+	//grad.addColour(0.5f, Colour(170, 170, 170));
+	//grad.addColour(0.5, Colours::lightgrey);
+	//grad.addColour(1.0f, Colours::grey);
+
 
 	fadeIn();
 }
@@ -99,6 +97,27 @@ GenericEditor::~GenericEditor()
 	//delete titleFont;
 }
 
+void GenericEditor::refreshColors()
+{
+
+	enum {
+		PROCESSOR_COLOR = 801,
+		FILTER_COLOR = 802,
+		SINK_COLOR = 803,
+		SOURCE_COLOR = 804,
+		UTILITY_COLOR = 805,
+	};
+
+	if (getProcessor()->isSource())
+		backgroundColor = getProcessorList()->findColour(SOURCE_COLOR);// Colour(255, 0, 0);//Colour(int(0.9*255.0f),int(0.019*255.0f),int(0.16*255.0f));
+	else if (getProcessor()->isSink())
+		backgroundColor = getProcessorList()->findColour(SINK_COLOR);//Colour(255, 149, 0);//Colour(int(0.06*255.0f),int(0.46*255.0f),int(0.9*255.0f));
+	else if (getProcessor()->isSplitter() || getProcessor()->isMerger())
+		backgroundColor =  getProcessorList()->findColour(UTILITY_COLOR);//Colour(40, 40, 40);//Colour(int(0.7*255.0f),int(0.7*255.0f),int(0.7*255.0f));
+	else
+		backgroundColor =  getProcessorList()->findColour(FILTER_COLOR);//Colour(255, 89, 0);//Colour(int(1.0*255.0f),int(0.5*255.0f),int(0.0*255.0f));
+
+}
 
 
 void GenericEditor::resized()
@@ -211,7 +230,10 @@ void GenericEditor::paint (Graphics& g)
 	g.fillRect(1,1,getWidth()-(2+offset),getHeight()-2);
 
 	// draw gray workspace
-	g.setColour(Colour(140, 140, 140));
+	//g.setColour(Colour(140, 140, 140));
+	
+
+	g.setGradientFill(backgroundGradient);
 	g.fillRect(1,22,getWidth()-2, getHeight()-29);
 
 	g.setFont(titleFont);
@@ -240,7 +262,7 @@ void GenericEditor::paint (Graphics& g)
 
 	if (isFading)
 	{
-		g.setColour(Colours::black.withAlpha((float) (15.0-accumulator)/15.0f));
+		g.setColour(Colours::black.withAlpha((float) (10.0-accumulator)/10.0f));
 		if (getWidth() > 0 && getHeight() > 0)
 			g.fillAll();
 	}
@@ -253,7 +275,7 @@ void GenericEditor::timerCallback()
 
 	repaint();
 
-	if (accumulator > 15.0)
+	if (accumulator > 10.0)
 	{
 		stopTimer();
 		isFading = false;
@@ -265,6 +287,9 @@ void GenericEditor::buttonClicked(Button* button)
 	
 	checkDrawerButton(button);
 	checkChannelSelectors(button);
+
+	buttonEvent(button); // needed to inform subclasses of 
+						 // button event
 }
 
 bool GenericEditor::checkDrawerButton(Button* button)
@@ -329,8 +354,18 @@ bool GenericEditor::checkChannelSelectors(Button* button)
 			}
 			else if (recordButton->getToggleState())
 			{
-				recordChannels.set(n,button->getToggleState());	
-				//type = "Record ";
+				recordChannels.set(n,button->getToggleState());
+				int id = getProcessor()->getNodeId();
+
+				RecordNode* rn = getProcessorGraph()->getRecordNode();
+
+				std::cout << "Button " << n << " was pressed." << std::endl;
+				rn->setChannel(id, n);
+
+				if (button->getToggleState())
+					rn->setParameter(2, 1.0f);
+				else
+					rn->setParameter(2, 0.0f);
 			}		
 			else if (paramsButton->getToggleState())
 			{
@@ -410,13 +445,32 @@ bool GenericEditor::checkChannelSelectors(Button* button)
 
 }
 
+void GenericEditor::selectChannels(Array<int> arr)
+{
+	for (int i = 0; i < channelSelectorButtons.size(); i++)
+	{
+		channelSelectorButtons[i]->setToggleState(false, false);
+	}
+
+	for (int i = 0; i < arr.size(); i++)
+	{
+		if (i > -1 && i < channelSelectorButtons.size())
+		{
+			channelSelectorButtons[i]->setToggleState(true,false);
+		}
+	}
+
+}
+
 void GenericEditor::update()
 {
 
-	std::cout << "Updating" << std::endl;
+	std::cout << "Editor for ";
 
 	GenericProcessor* p = (GenericProcessor*) getProcessor();
 
+	std::cout << p->getName() << " updating settings." << std::endl;
+
 	if (!p->isSink())
 	{
 
@@ -437,6 +491,18 @@ void GenericEditor::update()
 		numChannels = p->getNumInputs();
 	}
 
+	if (numChannels == 0)
+	{
+		if (drawerButton != 0)
+			drawerButton->setVisible(false);
+	} else {
+		if (drawerButton != 0)
+			drawerButton->setVisible(true);
+	}
+
+	updateVisualizer(); // does nothing unless this method
+						// has been implemented
+
 }
 
 Array<int> GenericEditor::getActiveChannels()
@@ -488,12 +554,10 @@ void GenericEditor::createRadioButtons(int x, int y, int w, StringArray values,
 int GenericEditor::createChannelSelectors()
 {
 
-	GenericProcessor* p = (GenericProcessor*) getProcessor();
-
+	GenericProcessor* p = getProcessor();
 
 	if (channelSelectorButtons.size() == 0) {
 
-
 		int width = 20;
 		int height = 14;
 		int numChannels;
@@ -503,7 +567,9 @@ int GenericEditor::createChannelSelectors()
 		else
 			numChannels = p->getNumInputs();
 
-		int nColumns = ceil(numChannels/4);
+		int nColumns = jmax((int) ceil(numChannels/4),1);
+		//std::cout << numChannels << " channels" << std::endl;
+		//std::cout << nColumns << " columns" << std::endl;
 
 		for (int n = 1; n < numChannels+1; n++)
 		{
@@ -725,3 +791,82 @@ void ChannelSelectorButton::paintButton(Graphics &g, bool isMouseOver, bool isBu
 
     g.drawText(getName(),0,0,getWidth(),getHeight(),Justification::centred,true);
 }
+
+//// BUTTONS ////
+
+void PlusButton::paintButton(Graphics& g, bool isMouseOver, bool isButtonDown)
+{
+    g.fillAll(Colours::orange);
+    g.setColour(Colours::black);
+    g.drawRect(0,0,getWidth(),getHeight(),1.0);
+
+    if (isMouseOver)
+    {
+        g.setColour(Colours::white);
+    } else {
+        g.setColour(Colours::black);
+    }
+
+    // if (isButtonDown)
+    // {
+    //     g.setColour(Colours::white);
+    // }
+
+    int thickness = 1;
+    int offset = 3;
+
+    g.fillRect(getWidth()/2-thickness,
+               offset, 
+               thickness*2,
+               getHeight()-offset*2);
+
+    g.fillRect(offset,
+               getHeight()/2-thickness,
+               getWidth()-offset*2,
+               thickness*2);
+}
+   
+
+void TriangleButton::paintButton(Graphics& g, bool isMouseOver, bool isButtonDown)
+{
+
+    //  g.fillAll(Colours::orange);
+    // g.setColour(Colours::black);
+    // g.drawRect(0,0,getWidth(),getHeight(),1.0);
+
+    if (isMouseOver)
+    {
+        g.setColour(Colours::grey);
+    } else {
+        g.setColour(Colours::black);
+    }
+
+    if (isButtonDown)
+    {
+        g.setColour(Colours::white);
+    }
+
+    int inset = 1;
+    int x1, y1, x2, y2, x3;
+
+    x1 = inset;
+    x2 = getWidth()/2;
+    x3 = getWidth()-inset;
+
+    if (direction == 1)
+    {
+        y1 = getHeight()-inset;
+        y2 = inset;
+
+    } else {
+        y1 = inset;
+        y2 = getHeight()-inset;
+    }
+
+    g.drawLine(x1, y1, x2, y2);
+    g.drawLine(x2, y2, x3, y1);
+    g.drawLine(x3, y1, x1, y1);
+
+
+}
+
diff --git a/Source/Processors/Editors/GenericEditor.h b/Source/Processors/Editors/GenericEditor.h
index 17f2bac8a09ea1370941add7d06c740244f4a6c1..5530b679b9c55df1e0f0368d63752d0c8179a309 100644
--- a/Source/Processors/Editors/GenericEditor.h
+++ b/Source/Processors/Editors/GenericEditor.h
@@ -33,7 +33,7 @@
   
   Base class for creating processor editors.
 
-  If a processor doesn't have an editor defined, a GenericEditor will be used.
+  If a processor doesn't havesign an editor defined, a GenericEditor will be used.
 
   Classes derived from this class must place their controls as child components.
   They shouldn't try to re-draw any aspects of their background.
@@ -46,19 +46,21 @@ class GenericProcessor;
 class DrawerButton;
 class EditorButton;
 class ChannelSelectorButton;
+class TriangleButton;
+class PlusButton;
 
 class GenericEditor : public AudioProcessorEditor,
                       public Timer,
                       public AccessClass,
-                      public Button::Listener
+                      public Button::Listener,
+                      public Slider::Listener
 
 {
 public:
-	GenericEditor (GenericProcessor* owner);//, FilterViewport* vp);
+	GenericEditor (GenericProcessor* owner);
 	virtual ~GenericEditor();
 
 	void paint (Graphics& g);
-	//void setViewport(FilterViewport*);
 
 	bool keyPressed (const KeyPress& key);
 
@@ -83,7 +85,7 @@ public:
 	virtual void switchSource(int) { }  // needed for MergerEditor
 	virtual void switchSource() { }; // needed for MergerEditor
 
-	AudioProcessor* getProcessor() const {return getAudioProcessor();}
+	GenericProcessor* getProcessor() const {return (GenericProcessor*) getAudioProcessor();}
 	
 	void createRadioButtons(int x, int y, int w, StringArray values, const String& name);
 		
@@ -96,13 +98,29 @@ public:
 	float accumulator;
 
 	virtual void buttonClicked(Button* button);
+	virtual void buttonEvent(Button* button) {}
+	virtual void sliderValueChanged(Slider* slider) {}
 
 	bool checkDrawerButton(Button* button);
 	bool checkChannelSelectors(Button* button);
 
+	void selectChannels(Array<int>);
+
+	void refreshColors();
+
 	virtual void update();
+	virtual void updateVisualizer() {}
 
 	Array<int> getActiveChannels();
+
+	Array<bool> audioChannels;
+	Array<bool> recordChannels;
+	Array<bool> paramsChannels;
+
+protected:
+	DrawerButton* drawerButton;
+	int drawerWidth;
+
 	
 private:
 
@@ -115,6 +133,7 @@ private:
 	virtual void destroyChannelSelectors();
 
 	Colour backgroundColor;
+	ColourGradient backgroundGradient;
 
 	bool isSelected;
 	bool isEnabled;
@@ -123,27 +142,27 @@ private:
 
 	int numChannels;
 
-	int drawerWidth;
 
-	DrawerButton* drawerButton;
 
 	EditorButton* audioButton;
 	EditorButton* recordButton;
 	EditorButton* paramsButton;
 
-	Array<bool> audioChannels;
-	Array<bool> recordChannels;
-	Array<bool> paramsChannels;
+	
 
 	Array<ChannelSelectorButton*> channelSelectorButtons;
 
 	ChannelSelectorButton* allButton;
 	ChannelSelectorButton* noneButton;
 
-	Font titleFont;
 
 	String name;
 
+protected:
+
+	Font titleFont;
+
+
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GenericEditor);
 
 };
@@ -198,5 +217,27 @@ private:
 	Font buttonFont;
 };
 
+class TriangleButton : public Button
+{
+public:
+    TriangleButton(int direction_) : Button("Arrow") 
+        {direction = direction_;}
+    ~TriangleButton() {}
+private:
+    void paintButton(Graphics& g, bool isMouseOver, bool isButtonDown);
+    
+    int direction;
+};
+
+class PlusButton : public Button
+{
+public:
+    PlusButton() : Button("Plus") {}
+    ~PlusButton() {}
+private:
+    void paintButton(Graphics& g, bool isMouseOver, bool isButtonDown);
+
+};
+
 
 #endif  // __GENERICEDITOR_H_DD406E71__
diff --git a/Source/Processors/Editors/LfpDisplayEditor.cpp b/Source/Processors/Editors/LfpDisplayEditor.cpp
index afb8b23bea77c4dbae0113c420aab757cfeb5cb5..da81819d1782a1134616553ba3a176034ed9c2b4 100644
--- a/Source/Processors/Editors/LfpDisplayEditor.cpp
+++ b/Source/Processors/Editors/LfpDisplayEditor.cpp
@@ -21,47 +21,16 @@
 
 */
 
-
 #include "LfpDisplayEditor.h"
-#include "../Visualization/LfpDisplayCanvas.h"
-
-SelectorButton::SelectorButton()
-	: DrawableButton (T("Selector"), DrawableButton::ImageFitted)
-{
-		DrawablePath normal, over, down;
-
-	    Path p;
-        p.addRectangle (0.0,0.0,20.0,20.0);
-        normal.setPath (p);
-        normal.setFill (Colours::lightgrey);
-        normal.setStrokeThickness (0.0f);
-
-        over.setPath (p);
-        over.setFill (Colours::black);
-        over.setStrokeFill (Colours::black);
-        over.setStrokeThickness (5.0f);
-
-        setImages (&normal, &over, &over);
-        setBackgroundColours(Colours::darkgrey, Colours::white);
-        setClickingTogglesState (true);
-        setTooltip ("Toggle a state.");
-
-}
-
-SelectorButton::~SelectorButton()
-{
-}
 
 
 LfpDisplayEditor::LfpDisplayEditor (GenericProcessor* parentNode) 
-	: GenericEditor(parentNode),
-	  tabIndex(-1), dataWindow(0),
-	  //streamBuffer(0), eventBuffer(0), canvas(0),
-	  isPlaying(false),
-	  canvas(0)
+	: VisualizerEditor(parentNode)
 
 {
 
+	tabText = "LFP";
+
 	desiredWidth = 250;
 
 	StringArray timeBaseValues;
@@ -80,104 +49,25 @@ LfpDisplayEditor::LfpDisplayEditor (GenericProcessor* parentNode)
 
 	createRadioButtons(35, 90, 160, displayGainValues, "Display Gain");
 
-	// 	for (int n = 0; n < getNumChildComponents(); n++)
-	// {
-	// 	Button* c = (Button*) getChildComponent(n);
-
-	// 	if (c->isVisible())
-	// 		c->addListener(this);
-
-	// 	if (c->getRadioGroupId() != 999)
-	// 		c->setVisible(true);
-	// }
-
-	// timebaseSlider = new Slider (T("Time Base Slider"));
-	// timebaseSlider->setBounds(60,20,200,40);
-	// timebaseSlider->setRange(500,10000,500);
-	// timebaseSlider->addListener(this);
-	// addAndMakeVisible(timebaseSlider);
-
-	// displayGainSlider = new Slider (T("Display Gain Slider"));
-	// displayGainSlider->setBounds(60,65,200,40);
-	// displayGainSlider->setRange(1,8,1);
-	// displayGainSlider->addListener(this);
-	// addAndMakeVisible(displayGainSlider);
-
-	// windowSelector = new SelectorButton();
-	// windowSelector->addListener(this);
-	// windowSelector->setBounds(25,25,20,20);
-	// windowSelector->setToggleState(false,false);
-	// addAndMakeVisible(windowSelector);
-
-	tabSelector = new SelectorButton();
-	tabSelector->addListener(this);
-	tabSelector->setBounds(205,30,10,10);
-	
-	addAndMakeVisible(tabSelector);
-	tabSelector->setToggleState(false,false);
-
-	//canvas = new LfpDisplayCanvas((LfpDisplayNode*) getProcessor());
-
 
 }
 
 LfpDisplayEditor::~LfpDisplayEditor()
 {
-
-	if (tabIndex > -1)
-	{
-		getDataViewport()->removeTab(tabIndex);
-	}
-
-	deleteAllChildren();
-
-}
-
-void LfpDisplayEditor::enable()
-{
-	std::cout << "   Enabling LfpDisplayEditor" << std::endl;
-	if (canvas != 0)
-		canvas->beginAnimation();
-	
-	isPlaying = true;
-}
-
-void LfpDisplayEditor::disable()
-{
-	if (canvas != 0)
-		canvas->endAnimation();
-
-	isPlaying = false;
 }
 
-void LfpDisplayEditor::updateNumInputs(int n)
-{
-	std::cout << "Setting num inputs on LfpDisplayEditor to " << n << std::endl;
-	if (canvas != 0)
-		canvas->updateNumInputs(n);
-}
 
-void LfpDisplayEditor::updateSampleRate(float r) 
+Visualizer* LfpDisplayEditor::createNewCanvas()
 {
-	if (canvas != 0)
-		canvas->updateSampleRate(r);
-}
 
-void LfpDisplayEditor::setBuffers(AudioSampleBuffer* asb, MidiBuffer* mb)
-{
-	std::cout << "LfpDisplayEditor buffers are set!" << std::endl;
-	//streamBuffer = asb;
-	//eventBuffer = mb;
+	LfpDisplayNode* processor = (LfpDisplayNode*) getProcessor();
+	return new LfpDisplayCanvas(processor);
 
-	//std::cout << streamBuffer << std::endl;
-	//std::cout << eventBuffer << std::endl;
 }
 
-void LfpDisplayEditor::buttonClicked(Button* button)
+void LfpDisplayEditor::buttonCallback(Button* button)
 {
 
-	if (!checkDrawerButton(button) && !checkChannelSelectors(button)) {
-
 	int gId = button->getRadioGroupId();
 
 	if (gId > 0) {
@@ -186,110 +76,6 @@ void LfpDisplayEditor::buttonClicked(Button* button)
 			canvas->setParameter(gId-1, button->getName().getFloatValue());
 		}
 
-	} else {
-
-	if (canvas == 0) {
-		
-		LfpDisplayNode* processor = (LfpDisplayNode*) getProcessor();
-		canvas = new LfpDisplayCanvas(processor);
-
-		if (isPlaying)
-			canvas->beginAnimation();
-	}
-
-	// if (button == windowSelector)
-	// {
-	// 	if (dataWindow == 0) {
-
-	// 		dataWindow = new DataWindow(windowSelector);
-
-	// 		//if (canvas == 0)
-	// 		//	canvas = new LfpDisplayCanvas((LfpDisplayNode*) getProcessor());
-
-	// 		//dataWindow->setContentComponent(new LfpDisplayCanvas(streamBuffer,eventBuffer,getConfiguration(), this));
-
-	// 		if (tabSelector->getToggleState())
-	// 		{
-	// 			tabSelector->setToggleState(false, false);
-	// 			dataViewport->removeTab(tabIndex);
-	// 			tabIndex = -1;
-	// 		}
-
-	// 		//LfpDisplayNode* p = (LfpDisplayNode*) getProcessor();
-
-	// 		dataWindow->setContentNonOwned(canvas, false);
-	// 		//p->isVisible = true;
-
-	// 		//getProcessor()->parentComponentChanged();
-	// 		dataWindow->setVisible(true);
-			
-	// 	} else {
+	} 
 
-	// 		if (tabSelector->getToggleState())
-	// 		{
-	// 			tabSelector->setToggleState(false, false);
-	// 			dataViewport->removeTab(tabIndex);
-	// 			tabIndex = -1;
-	// 		}
-
-	// 		dataWindow->setVisible(windowSelector->getToggleState());
-
-	// 		//LfpDisplayNode* p = (LfpDisplayNode*) getProcessor();
-	// 		//p->isVisible = windowSelector->getToggleState();
-	// 		//getProcessor()->parentComponentChanged();
-	// 	}
-
-	// } else
-		 if (button == tabSelector)
-		{
-			if (tabSelector->getToggleState() && tabIndex < 0)
-			{
-
-				//std::cout << "Editor data viewport: " << dataViewport << std::endl;
-				
-				// if (windowSelector->getToggleState())
-				// {
-				// 	windowSelector->setToggleState(false, false);
-				// 	dataWindow->setVisible(false);
-				// }
-
-				//tabIndex = dataViewport->addTabToDataViewport("LFP",new LfpDisplayCanvas(streamBuffer,eventBuffer,getConfiguration(), this));
-				//Component* p = (Component*) getProcessor();
-
-				//LfpDisplayNode* p = (LfpDisplayNode*) getProcessor();
-				tabIndex = getDataViewport()->addTabToDataViewport("LFP",canvas);
-				//if (isPlaying)
-				///{
-				//	canvas->beginAnimation();
-				//}
-
-				//p->isVisible = true;
-
-			} else if (!tabSelector->getToggleState() && tabIndex > -1)
-			{
-				getDataViewport()->removeTab(tabIndex);
-				tabIndex = -1;
-				//LfpDisplayNode* p = (LfpDisplayNode*) getProcessor();
-				//p->isVisible = false;
-			}
-		}
-	}
-	}
 }
-
-void LfpDisplayEditor::sliderValueChanged (Slider* slider)
-{
-
-	// if (canvas != 0)
-	// {
-	// 	if (slider == timebaseSlider)
-	// 		canvas->setParameter(0,slider->getValue());
-	// 	else
-	// 		canvas->setParameter(1,slider->getValue());
-	// }
-
-	
-	//else 
-	//	getAudioProcessor()->setParameter(1,slider->getValue());
-
-}
\ No newline at end of file
diff --git a/Source/Processors/Editors/LfpDisplayEditor.h b/Source/Processors/Editors/LfpDisplayEditor.h
index 255812705be1bb16997cc7e8ab31121cb89ca342..934cf40dc9f802ea9999335c620ca83a28501926 100644
--- a/Source/Processors/Editors/LfpDisplayEditor.h
+++ b/Source/Processors/Editors/LfpDisplayEditor.h
@@ -31,59 +31,22 @@
 #include "../Visualization/DataWindow.h"
 #include "../LfpDisplayNode.h"
 #include "../Visualization/LfpDisplayCanvas.h"
+#include "VisualizerEditor.h"
 
-//class FilterViewport;
-//class DataViewport;
-class DataWindow;
-class LfpDisplayCanvas;
+class Visualizer;
 
-class SelectorButton : public DrawableButton
-{
-	public:
-		SelectorButton();
-		~SelectorButton();	
-};
-
-class LfpDisplayEditor : public GenericEditor,//,
-				   	    // public Button::Listener,
-				   	     public Slider::Listener
+class LfpDisplayEditor : public VisualizerEditor
 {
 public:
 	LfpDisplayEditor (GenericProcessor*);
 	~LfpDisplayEditor();
 
-	void buttonClicked (Button* button);
-	void setBuffers (AudioSampleBuffer*, MidiBuffer*);
-	//void setUIComponent (UIComponent* ui) {UI = ui;}
-
-	void sliderValueChanged (Slider* slider);
-
-	void enable();
-	void disable();
+	void buttonCallback (Button* button);
 
-	void updateNumInputs(int);
-	void updateSampleRate(float);
+	Visualizer* createNewCanvas();
 
 private:	
 
-	bool isPlaying;
-	
-	ScopedPointer <DataWindow> dataWindow;
-
-	Slider* timebaseSlider;
-	Slider* displayGainSlider;
-
-	SelectorButton* windowSelector;
-	SelectorButton* tabSelector;
-
-	ScopedPointer <LfpDisplayCanvas> canvas;
-
-	//AudioSampleBuffer* streamBuffer;
-	//MidiBuffer* eventBuffer;
-	//UIComponent* UI;
-	//DataViewport* dataViewport;
-
-	int tabIndex;
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LfpDisplayEditor);
 
diff --git a/Source/Processors/Editors/MergerEditor.cpp b/Source/Processors/Editors/MergerEditor.cpp
index 1fa5234af7b1298f8920ab5ee46171c962eacc3a..5c21d4104142a73a9694c153847b98aaf55023ae 100644
--- a/Source/Processors/Editors/MergerEditor.cpp
+++ b/Source/Processors/Editors/MergerEditor.cpp
@@ -94,21 +94,21 @@ MergerEditor::~MergerEditor()
 	deleteAllChildren();
 }
 
-void MergerEditor::buttonClicked(Button* button)
+void MergerEditor::buttonEvent(Button* button)
 {
 	if (button == pipelineSelectorA)
 	{
 		pipelineSelectorA->setToggleState(true,false);
 		pipelineSelectorB->setToggleState(false,false);
 		Merger* processor = (Merger*) getProcessor();
-		processor->switchSource(0);
+		processor->switchIO(0);
 
 	} else if (button == pipelineSelectorB) 
 	{
 		pipelineSelectorB->setToggleState(true,false);
 		pipelineSelectorA->setToggleState(false,false);
 		Merger* processor = (Merger*) getProcessor();
-		processor->switchSource(1);
+		processor->switchIO(1);
 		
 	}
 }
@@ -120,14 +120,14 @@ void MergerEditor::switchSource(int source)
 		pipelineSelectorA->setToggleState(true,false);
 		pipelineSelectorB->setToggleState(false,false);
 		Merger* processor = (Merger*) getProcessor();
-		processor->switchSource(0);
+		processor->switchIO(0);
 
 	} else if (source == 1)
 	{
 		pipelineSelectorB->setToggleState(true,false);
 		pipelineSelectorA->setToggleState(false,false);
 		Merger* processor = (Merger*) getProcessor();
-		processor->switchSource(1);
+		processor->switchIO(1);
 		
 	}
 }
@@ -143,6 +143,6 @@ void MergerEditor::switchSource()
 	pipelineSelectorA->setToggleState(!isAOn,false);
 
 	Merger* processor = (Merger*) getProcessor();
-	processor->switchSource();
+	processor->switchIO();
 
 }
\ No newline at end of file
diff --git a/Source/Processors/Editors/MergerEditor.h b/Source/Processors/Editors/MergerEditor.h
index 51f9b2b1b78fced1c6275587f80c1ad6fe34598f..889e070f4989ad31488b6b5a085451566b342561 100644
--- a/Source/Processors/Editors/MergerEditor.h
+++ b/Source/Processors/Editors/MergerEditor.h
@@ -42,7 +42,7 @@ public:
 	MergerEditor (GenericProcessor* parentNode);
 	virtual ~MergerEditor();
 
-	virtual void buttonClicked (Button* button);
+	virtual void buttonEvent (Button* button);
 
     void switchSource(int);
     void switchSource ();
diff --git a/Source/Processors/Editors/SignalGeneratorEditor.cpp b/Source/Processors/Editors/SignalGeneratorEditor.cpp
index ccf5a351e49bbb4524d20167d34158552d025a28..faddc33b5b54a6c20793542cac897d0b5e4f9311 100644
--- a/Source/Processors/Editors/SignalGeneratorEditor.cpp
+++ b/Source/Processors/Editors/SignalGeneratorEditor.cpp
@@ -24,27 +24,68 @@
 
 #include "SignalGeneratorEditor.h"
 #include "../SignalGenerator.h"
+#include "../../UI/EditorViewport.h"
 #include <stdio.h>
 
 
 SignalGeneratorEditor::SignalGeneratorEditor (GenericProcessor* parentNode) 
-	: GenericEditor(parentNode), amplitudeSlider(0), frequencySlider(0)
+	: GenericEditor(parentNode), amplitudeSlider(0), frequencySlider(0), phaseSlider(0)
 
 {
-	desiredWidth = 250;
+	desiredWidth = 270;
+
+	int buttonWidth = 31;
+	int buttonHeight = 19;
+
+	for (int i = 0; i < 5; i++)
+	{
+		WaveformSelector* ws = new WaveformSelector(i);
+		ws->setBounds(15 + (buttonWidth)*i, 30, buttonWidth, buttonHeight);
+		ws->addListener(this);
+		waveformSelectors.add(ws);
+		addAndMakeVisible(ws);
+	}
 
-	amplitudeSlider = new Slider (T("Amplitude Slider"));
-	amplitudeSlider->setBounds(25,40,170,40);
-	amplitudeSlider->setRange(0.005,0.05,0.005);
+	amplitudeSlider = new Slider ("Amplitude Slider");
+	amplitudeSlider->setBounds(10,60,50,60);
+	amplitudeSlider->setRange(0,1000,10);
 	amplitudeSlider->addListener(this);
+	amplitudeSlider->setSliderStyle(Slider::Rotary);
+	amplitudeSlider->setTextBoxStyle(Slider::TextBoxBelow, false, 40, 20);
 	addAndMakeVisible(amplitudeSlider);
 
-	frequencySlider = new Slider (T("High-Cut Slider"));
-	frequencySlider->setBounds(25,70,170,40);
+	frequencySlider = new Slider ("Frequency Slider");
+	frequencySlider->setBounds(70,60,50,60);
 	frequencySlider->setRange(1,1000,1);
 	frequencySlider->addListener(this);
+	frequencySlider->setSliderStyle(Slider::Rotary);
+	frequencySlider->setTextBoxStyle(Slider::TextBoxBelow, false, 40, 20);
 	addAndMakeVisible(frequencySlider);
 
+	phaseSlider = new Slider ("Phase Slider");
+	phaseSlider->setBounds(130,60,50,60);
+	phaseSlider->setRange(0, 360, 1);
+	phaseSlider->addListener(this);
+	phaseSlider->setSliderStyle(Slider::Rotary);
+	phaseSlider->setTextBoxStyle(Slider::TextBoxBelow, false, 40, 20);
+	addAndMakeVisible(phaseSlider);
+
+	numChannelsLabel = new Label("Number of Channels","1");
+    numChannelsLabel->setEditable(true);
+    numChannelsLabel->addListener(this);
+    numChannelsLabel->setBounds(200,50,25,20);
+    addAndMakeVisible(numChannelsLabel);
+
+    upButton = new TriangleButton(1);
+    upButton->addListener(this);
+    upButton->setBounds(200,30,20,15);
+    addAndMakeVisible(upButton);
+
+    downButton = new TriangleButton(2);
+    downButton->addListener(this);
+    downButton->setBounds(200,75,20,15);
+    addAndMakeVisible(downButton);
+
 }
 
 SignalGeneratorEditor::~SignalGeneratorEditor()
@@ -67,10 +108,144 @@ void SignalGeneratorEditor::sliderValueChanged (Slider* slider)
 
 		if (slider == amplitudeSlider)
 			p->setParameter(0,slider->getValue());
-		else 
+		else if (slider == frequencySlider)
 			p->setParameter(1,slider->getValue());
+		else if (slider == phaseSlider)
+			p->setParameter(2,slider->getValue());
+
+	}
+
+
+}
+
+void SignalGeneratorEditor::buttonEvent (Button* button)
+{
+
+	for (int i = 0; i < waveformSelectors.size(); i++)
+	{
+		if (button == waveformSelectors[i])
+		{
+
+			Array<int> chans = getActiveChannels();
+	
+			GenericProcessor* p = getProcessor();
+
+			for (int n = 0; n < chans.size(); n++) {
+		
+				p->setCurrentChannel(chans[n]);
+				p->setParameter(3,(float) i);
+
+			}
+
 
+		}
 	}
 
+	int num = numChannelsLabel->getText().getIntValue();
 
+    if (button == upButton)
+    {
+        numChannelsLabel->setText(String(++num), true);
+
+    } else if (button == downButton)
+    {
+
+        if (num > 1)
+            numChannelsLabel->setText(String(--num), true);
+
+    }
+}
+
+
+void SignalGeneratorEditor::labelTextChanged (Label* label)
+{
+
+	SignalGenerator* sg = (SignalGenerator*) getProcessor();
+	sg->nOut = numChannelsLabel->getText().getIntValue();
+	getEditorViewport()->makeEditorVisible(this);
+}
+
+WaveformSelector::WaveformSelector(int type) : Button("Waveform")
+{
+
+	setRadioGroupId(299);
+	setClickingTogglesState(true);
+
+	if (type == 0) {
+	 	selected = ImageCache::getFromMemory (BinaryData::RadioButtons_selected01_png, 
+	 								    BinaryData::RadioButtons_selected01_pngSize);
+	 	selectedOver= ImageCache::getFromMemory (BinaryData::RadioButtons_selected_over01_png, 
+	 								    BinaryData::RadioButtons_selected_over01_pngSize);
+	 	neutral = ImageCache::getFromMemory (BinaryData::RadioButtons_neutral01_png, 
+	 								    BinaryData::RadioButtons_neutral01_pngSize);
+	 	neutralOver = ImageCache::getFromMemory (BinaryData::RadioButtons01_png, 
+	 								    BinaryData::RadioButtons01_pngSize);
+	 } 
+	else if (type == 1) {
+		selected = ImageCache::getFromMemory (BinaryData::RadioButtons_selected02_png, 
+	 								    BinaryData::RadioButtons_selected02_pngSize);
+	 	selectedOver= ImageCache::getFromMemory (BinaryData::RadioButtons_selected_over02_png, 
+	 								    BinaryData::RadioButtons_selected_over02_pngSize);
+	 	neutral = ImageCache::getFromMemory (BinaryData::RadioButtons_neutral02_png, 
+	 								    BinaryData::RadioButtons_neutral02_pngSize);
+	 	neutralOver = ImageCache::getFromMemory (BinaryData::RadioButtons02_png, 
+	 								    BinaryData::RadioButtons02_pngSize);
+	 }
+	else if (type == 2) {
+		selected = ImageCache::getFromMemory (BinaryData::RadioButtons_selected03_png, 
+	 								    BinaryData::RadioButtons_selected03_pngSize);
+	 	selectedOver= ImageCache::getFromMemory (BinaryData::RadioButtons_selected_over03_png, 
+	 								    BinaryData::RadioButtons_selected_over03_pngSize);
+	 	neutral = ImageCache::getFromMemory (BinaryData::RadioButtons_neutral03_png, 
+	 								    BinaryData::RadioButtons_neutral03_pngSize);
+	 	neutralOver = ImageCache::getFromMemory (BinaryData::RadioButtons03_png, 
+	 								    BinaryData::RadioButtons03_pngSize);
+	 }
+	else if (type == 3) {
+		selected = ImageCache::getFromMemory (BinaryData::RadioButtons_selected04_png, 
+	 								    BinaryData::RadioButtons_selected04_pngSize);
+	 	selectedOver= ImageCache::getFromMemory (BinaryData::RadioButtons_selected_over04_png, 
+	 								    BinaryData::RadioButtons_selected_over04_pngSize);
+	 	neutral = ImageCache::getFromMemory (BinaryData::RadioButtons_neutral04_png, 
+	 								    BinaryData::RadioButtons_neutral04_pngSize);
+	 	neutralOver = ImageCache::getFromMemory (BinaryData::RadioButtons04_png, 
+	 								    BinaryData::RadioButtons04_pngSize);
+	 }
+	else if (type == 4) {
+		selected = ImageCache::getFromMemory (BinaryData::RadioButtons_selected05_png, 
+	 								    BinaryData::RadioButtons_selected05_pngSize);
+	 	selectedOver= ImageCache::getFromMemory (BinaryData::RadioButtons_selected_over05_png, 
+	 								    BinaryData::RadioButtons_selected_over05_pngSize);
+	 	neutral = ImageCache::getFromMemory (BinaryData::RadioButtons_neutral05_png, 
+	 								    BinaryData::RadioButtons_neutral05_pngSize);
+	 	neutralOver = ImageCache::getFromMemory (BinaryData::RadioButtons05_png, 
+	 								    BinaryData::RadioButtons05_pngSize);
+	 }
+
+}
+
+void WaveformSelector::paintButton(Graphics& g, bool isMouseOver, bool isButtonDown)
+{
+ 
+
+     if (getToggleState())
+     {
+     	if (isMouseOver)
+        	g.drawImage(selectedOver, 0, 0, 31, 19, 0, 0, 31, 19);
+        else
+        	g.drawImage(selected, 0, 0, 31, 19, 0, 0, 31, 19);
+     } else {
+         if (isMouseOver)
+         	g.drawImage(neutralOver, 0, 0, 31, 19, 0, 0, 31, 19);
+        else
+        	g.drawImage(neutral, 0, 0, 31, 19, 0, 0, 31, 19);
+     }
+
+    // g.fillAll();
+
+    // g.setColour(Colours::black);
+    // g.drawRect(0, 0, getWidth(), getHeight());
+
+    // g.setImageResamplingQuality(Graphics::highResamplingQuality);
+     
 }
\ No newline at end of file
diff --git a/Source/Processors/Editors/SignalGeneratorEditor.h b/Source/Processors/Editors/SignalGeneratorEditor.h
index 00aae333669d0607b13662a6e24c8313ad7a42b9..ffe55aa6cc87fd4dace829a8d53f8c2f78b498e6 100644
--- a/Source/Processors/Editors/SignalGeneratorEditor.h
+++ b/Source/Processors/Editors/SignalGeneratorEditor.h
@@ -28,22 +28,55 @@
 #include "GenericEditor.h"
 
 class FilterViewport;
+class WaveformSelector;
 
 class SignalGeneratorEditor : public GenericEditor,
-					 		  public Slider::Listener
+                              public Label::Listener
 {
 public:
 	SignalGeneratorEditor (GenericProcessor* parentNode);
 	virtual ~SignalGeneratorEditor();
 	void sliderValueChanged (Slider* slider);
+    void buttonEvent(Button* button);
+    void labelTextChanged(Label* label);
 
 private:	
+
+    Label* numChannelsLabel;
+    TriangleButton* upButton;
+    TriangleButton* downButton;
+
 	Slider* amplitudeSlider;
 	Slider* frequencySlider;
+    Slider* phaseSlider;
+
+    Array<WaveformSelector*> waveformSelectors;
+
+    enum wvfrm
+    {
+        SINE, SQUARE, SAW, TRIANGLE, NOISE
+    };
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SignalGeneratorEditor);
 
 };
 
+class WaveformSelector : public Button
+{
+public:
+    WaveformSelector(int type_);
+    ~WaveformSelector() {}
+private:
+    void paintButton(Graphics& g, bool isMouseOver, bool isButtonDown);
+    
+    int type;
+
+    Image neutral;
+    Image neutralOver;
+    Image selected;
+    Image selectedOver;
+
+};
+
 
 #endif  // __SIGNALGENERATOREDITOR_H_841A7078__
diff --git a/Source/Processors/Editors/SpikeDetectorEditor.cpp b/Source/Processors/Editors/SpikeDetectorEditor.cpp
index bb395088e26e85ae98463b172625b0119266039d..c3e480bea000a976a70f01d7dea63ded216ca36d 100644
--- a/Source/Processors/Editors/SpikeDetectorEditor.cpp
+++ b/Source/Processors/Editors/SpikeDetectorEditor.cpp
@@ -27,30 +27,320 @@
 
 
 SpikeDetectorEditor::SpikeDetectorEditor (GenericProcessor* parentNode) 
-	: GenericEditor(parentNode), threshSlider(0)
+	: GenericEditor(parentNode), isPlural(true)
 
 {
-	desiredWidth = 200;
 
-	threshSlider = new Slider (T("Threshold Slider"));
-	threshSlider->setBounds(25,20,150,40);
-	threshSlider->setRange(1000,20000,1000);
-	threshSlider->addListener(this);
-	addAndMakeVisible(threshSlider);
+    MemoryInputStream mis(BinaryData::silkscreenserialized, BinaryData::silkscreenserializedSize, false);
+    Typeface::Ptr typeface = new CustomTypeface(mis);
+    font = Font(typeface);
+
+	desiredWidth = 370;
+
+    electrodeTypes = new ComboBox("Electrode Types");
+
+    SpikeDetector* processor = (SpikeDetector*) getProcessor();
+
+    for (int i = 0; i < processor->electrodeTypes.size(); i++)
+    {
+        String type = processor->electrodeTypes[i];
+        electrodeTypes->addItem (type += "s", i+1); 
+    }
+
+    electrodeTypes->setEditableText(false);
+    electrodeTypes->setJustificationType (Justification::centredLeft);
+    electrodeTypes->addListener(this);
+    electrodeTypes->setBounds(65,40,130,16);
+    electrodeTypes->setSelectedId(4);
+    addAndMakeVisible(electrodeTypes);
+
+    electrodeList = new ComboBox("Electrode List");
+    electrodeList->setEditableText(false);
+    electrodeList->setJustificationType (Justification::centredLeft);
+    electrodeList->addListener(this);
+    electrodeList->setBounds(20,80,115,20);
+    addAndMakeVisible(electrodeList);
+
+    numElectrodes = new Label("Number of Electrodes","4");
+    numElectrodes->setEditable(true);
+    numElectrodes->addListener(this);
+    numElectrodes->setBounds(30,40,25,20);
+    //labelTextChanged(numElectrodes);
+    addAndMakeVisible(numElectrodes);
+
+    upButton = new TriangleButton(1);
+    upButton->addListener(this);
+    upButton->setBounds(50,40,10,8);
+    addAndMakeVisible(upButton);
+
+    downButton = new TriangleButton(2);
+    downButton->addListener(this);
+    downButton->setBounds(50,50,10,8);
+    addAndMakeVisible(downButton);
+
+    plusButton = new PlusButton();
+    plusButton->addListener(this);
+    plusButton->setBounds(15,42,14,14);
+    addAndMakeVisible(plusButton);
+
+    ElectrodeEditorButton* e1 = new ElectrodeEditorButton("EDIT",font);
+    e1->addListener(this);
+    addAndMakeVisible(e1);
+    e1->setBounds(250,80,70,10);
+    electrodeEditorButtons.add(e1);
+
+    ElectrodeEditorButton* e2 = new ElectrodeEditorButton("MONITOR",font);
+    e2->addListener(this);
+    addAndMakeVisible(e2);
+    e2->setBounds(250,95,70,10);
+    electrodeEditorButtons.add(e2);
+
+    ElectrodeEditorButton* e3 = new ElectrodeEditorButton("DELETE",font);
+    e3->addListener(this);
+    addAndMakeVisible(e3);
+    e3->setBounds(250,110,70,10);
+    electrodeEditorButtons.add(e3);
+
 
 }
 
 SpikeDetectorEditor::~SpikeDetectorEditor()
 {
 
+    for (int i = 0; i < electrodeButtons.size(); i++)
+    {
+        removeChildComponent(electrodeButtons[i]);
+    }
+
 	deleteAllChildren();	
 
 }
 
-void SpikeDetectorEditor::sliderValueChanged (Slider* slider)
+void SpikeDetectorEditor::buttonEvent(Button* button)
+{
+
+    int num = numElectrodes->getText().getIntValue();
+
+    if (button == upButton)
+    {
+        numElectrodes->setText(String(++num), true);
+
+    } else if (button == downButton)
+    {
+
+        if (num > 1)
+            numElectrodes->setText(String(--num), true);
+
+    } else if (button == plusButton)
+    {
+       // std::cout << "Plus button pressed!" << std::endl;
+       
+        for (int n = 0; n < num; n++)
+        {
+            addElectrode(electrodeTypes->getSelectedId()); 
+        }
+
+        refreshElectrodeList();
+
+        electrodeList->setSelectedId(electrodeList->getNumItems(), true);
+        electrodeList->setText(electrodeList->getItemText(electrodeList->getNumItems()-1));
+        lastId = electrodeList->getNumItems();
+        electrodeList->setEditableText(true);
+
+        drawElectrodeButtons(electrodeList->getNumItems()-1);
+
+    } else if (button == electrodeEditorButtons[0]) // EDIT
+    {
+
+        for (int i = 0; i < electrodeButtons.size(); i++)
+        {
+            if (button->getToggleState())
+            {
+                electrodeButtons[i]->setToggleState(false, false);
+                electrodeButtons[i]->setRadioGroupId(299);
+            } else {
+                electrodeButtons[i]->setToggleState(true, false);
+                electrodeButtons[i]->setRadioGroupId(0);
+            }
+        }
+
+
+    } else if (button == electrodeEditorButtons[1]) // MONITOR
+    {
+
+    } else if (button == electrodeEditorButtons[2]) // DELETE
+    {
+
+        removeElectrode(electrodeList->getSelectedItemIndex());
+    }
+}
+
+void SpikeDetectorEditor::refreshElectrodeList()
 {
+    electrodeList->clear();
+
+    SpikeDetector* processor = (SpikeDetector*) getProcessor();
+
+    StringArray electrodeNames = processor->getElectrodeNames();
+
+    for (int i = 0; i < electrodeNames.size(); i++)
+    {
+        electrodeList->addItem (electrodeNames[i], electrodeList->getNumItems()+1);
+    }
+}
+
+void SpikeDetectorEditor::addElectrode(int nChans)
+{
+    SpikeDetector* processor = (SpikeDetector*) getProcessor();
+    processor->addElectrode(nChans);
+}
+
+
+void SpikeDetectorEditor::removeElectrode(int index)
+{
+    std::cout << "Deleting electrode number " << index << std::endl;
+    SpikeDetector* processor = (SpikeDetector*) getProcessor();
+    processor->removeElectrode(index);
+    refreshElectrodeList();
+
+    int newIndex = jmin(index, electrodeList->getNumItems()-1);
+    newIndex = jmax(newIndex, 0);
+
+    electrodeList->setSelectedId(newIndex, true);
+    electrodeList->setText(electrodeList->getItemText(newIndex));
+
+    if (electrodeList->getNumItems() == 0)
+    {
+        electrodeButtons.clear();
+        electrodeList->setEditableText(false);
+    }
+}
 
-	if (slider == threshSlider)
-		getAudioProcessor()->setParameter(0,slider->getValue());
+void SpikeDetectorEditor::labelTextChanged(Label* label)
+{
+    if (label->getText().equalsIgnoreCase("1") && isPlural)
+    {
+        for (int n = 1; n < 21; n++)
+        {
+            electrodeTypes->changeItemText(n,
+                    electrodeTypes->getItemText(n-1).trimCharactersAtEnd("s"));
+        }
+
+        isPlural = false;
+
+        String currentText = electrodeTypes->getText();
+        electrodeTypes->setText(currentText.trimCharactersAtEnd("s"));
+
+    } else if (!label->getText().equalsIgnoreCase("1") && !isPlural)
+    {
+        const String s = "s";
+        size_t one = 1;
+
+        for (int n = 1; n < 21; n++)
+        {
+            String currentString = electrodeTypes->getItemText(n-1);
+            currentString += "s";
+
+            electrodeTypes->changeItemText(n,currentString);
+        }
+        isPlural = true;
+
+        String currentText = electrodeTypes->getText();
+        electrodeTypes->setText(currentText += "s");
+    }
+
+}
+
+void SpikeDetectorEditor::comboBoxChanged(ComboBox* comboBox)
+{
+    
+    if (comboBox == electrodeList)
+    {
+        int ID = comboBox->getSelectedId();
+
+        if (ID == 0)
+        {
+            SpikeDetector* processor = (SpikeDetector*) getProcessor();
+
+            processor->setName(lastId, comboBox->getText());
+            refreshElectrodeList();
+
+        } else {
+
+            lastId = ID;
+
+            drawElectrodeButtons(ID-1);
+
+        }
+
+    }
+}
+
+void SpikeDetectorEditor::drawElectrodeButtons(int ID)
+{
+
+    SpikeDetector* processor = (SpikeDetector*) getProcessor();
+
+    electrodeButtons.clear();
+
+    int width = 20;
+    int height = 15;
+
+    int numChannels = processor->getNumChannels(ID);
+    int row = 0;
+    int column = 0;
+
+    for (int i = 0; i < numChannels; i++)
+    {
+        ElectrodeButton* button = new ElectrodeButton(processor->getChannel(ID,i));
+        electrodeButtons.add(button);
+        
+        button->setBounds(150+(column++)*width, 80+row*height, width, 15);
+        addAndMakeVisible(button);
+
+        if (column%5 == 0)
+        {
+            column = 0;
+            row++;
+        }
+
+    }
+
+}
+
+
+
+   
+void ElectrodeButton::paintButton(Graphics &g, bool isMouseOver, bool isButtonDown)
+{
+    if (getToggleState() == true)
+        g.setColour(Colours::orange);
+    else 
+        g.setColour(Colours::darkgrey);
+
+    if (isMouseOver)
+        g.setColour(Colours::white);
+
+    g.fillRect(0,0,getWidth(),getHeight());
+
+   // g.setFont(buttonFont);
+    g.setColour(Colours::black);
+
+    g.drawRect(0,0,getWidth(),getHeight(),1.0);
+
+    g.drawText(String(chan),0,0,getWidth(),getHeight(),Justification::centred,true);
+}
+
+   
+void ElectrodeEditorButton::paintButton(Graphics &g, bool isMouseOver, bool isButtonDown)
+{
+    if (getToggleState() == true)
+        g.setColour(Colours::darkgrey);
+    else 
+        g.setColour(Colours::lightgrey);
+
+    g.setFont(font);
+
+    g.drawText(name,0,0,getWidth(),getHeight(),Justification::left,true);
+}
 
-}
\ No newline at end of file
diff --git a/Source/Processors/Editors/SpikeDetectorEditor.h b/Source/Processors/Editors/SpikeDetectorEditor.h
index c181e801f17a1eea7461b078ab12b6baf4d3a5a6..0fc9544400ec4745a5c50fc5530670d17b1adea8 100644
--- a/Source/Processors/Editors/SpikeDetectorEditor.h
+++ b/Source/Processors/Editors/SpikeDetectorEditor.h
@@ -28,21 +28,83 @@
 #include "../../../JuceLibraryCode/JuceHeader.h"
 #include "GenericEditor.h"
 
-class FilterViewport;
+class TriangleButton;
+class PlusButton;
+
+class ElectrodeButton : public Button
+{
+public:
+    ElectrodeButton(int chan_) : Button("Electrode"), chan(chan_) 
+    {
+        setClickingTogglesState(true);
+        //setRadioGroupId(299);
+        setToggleState(true, false);
+    }
+    ~ElectrodeButton() {}
+private:
+    void paintButton(Graphics& g, bool isMouseOver, bool isButtonDown);
+
+    int chan;
+};
+
+class ElectrodeEditorButton : public Button
+{
+public:
+    ElectrodeEditorButton(const String& name_, Font font_) : Button("Electrode Editor"),
+        name(name_), font(font_)
+    {
+        if (name.equalsIgnoreCase("edit") || name.equalsIgnoreCase("monitor"))
+            setClickingTogglesState(true);
+    }
+    ~ElectrodeEditorButton() {}
+private:
+    void paintButton(Graphics& g, bool isMouseOver, bool isButtonDown);
+
+    const String name;
+
+    Font font;
+
+};
+
 
 class SpikeDetectorEditor : public GenericEditor,
-					 	    public Slider::Listener
+                            public Label::Listener,
+                            public ComboBox::Listener
+
 {
 public:
 	SpikeDetectorEditor (GenericProcessor* parentNode);
 	virtual ~SpikeDetectorEditor();
-	void sliderValueChanged (Slider* slider);
+    void buttonEvent(Button* button);
+    void labelTextChanged(Label* label);
+    void comboBoxChanged(ComboBox* comboBox);
 
 private:	
-	Slider* threshSlider;
-	DocumentWindow* docWindow;
 
-	//int tabIndex;
+    void drawElectrodeButtons(int);
+
+    void refreshElectrodeList();
+	
+    ComboBox* electrodeTypes;
+    ComboBox* electrodeList;
+    Label* numElectrodes;
+    TriangleButton* upButton;
+    TriangleButton* downButton;
+    PlusButton* plusButton;
+
+    OwnedArray<ElectrodeButton> electrodeButtons;
+    Array<ElectrodeEditorButton*> electrodeEditorButtons;
+
+    void addElectrode(int nChans);
+    void removeElectrode(int index);
+    void editElectrode(int index, int chan, int newChan);
+
+    int lastId;
+    bool isPlural;
+
+    Font font;
+
+    //ThresholdSlider* thresholdSlider;
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SpikeDetectorEditor);
 
diff --git a/Source/Processors/Editors/SpikeDisplayEditor.cpp b/Source/Processors/Editors/SpikeDisplayEditor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5118577e4fefbf43471d1458cf2682ab442c7f0e
--- /dev/null
+++ b/Source/Processors/Editors/SpikeDisplayEditor.cpp
@@ -0,0 +1,223 @@
+#include "SpikeDisplayEditor.h"
+#include <string>
+
+
+
+SpikeDisplayEditor::SpikeDisplayEditor (GenericProcessor* parentNode) 
+	: VisualizerEditor(parentNode,200)
+
+{
+	// Get the number of sub channels from the parentNode
+	// Assume all plots have the same number of subChannels
+	// Otherwise we'll have to track the number of subChannels
+	nSubChannels = 4;
+
+	for (int i=0; i<nSubChannels; i++)
+		subChanSelected[i] = true;
+
+	initializeButtons();
+
+	tabText = "Spikes";
+
+}
+
+SpikeDisplayEditor::~SpikeDisplayEditor()
+{
+	deleteAllChildren();
+}
+
+void SpikeDisplayEditor::initializeButtons(){
+	int w = 18;
+	int h = 18;
+	int xPad = 5;
+	int yPad = 6;
+
+	int xInitial = 10;
+	int yInitial = 25;
+	int x = xInitial;
+	int y = yInitial;
+
+	panLabel = new Label("PanLabel", "Pan:");	
+	panLabel->setBounds(x-xPad, y, w*2 + xPad, h);
+	panLabel->setJustificationType(Justification::centredLeft );
+	x+= 2*w+3*xPad;
+
+	zoomLabel = new Label("ZoomLabel", "Zoom:");
+	zoomLabel->setBounds(x-xPad,y,w*3+xPad, h);
+	zoomLabel->setJustificationType(Justification::centredLeft);
+	x = xInitial;
+	y += h + yPad/2;
+
+	panUpBtn = new ChannelSelectorButton("+", titleFont);
+	panUpBtn->setBounds(x, y, w, h); 
+	panUpBtn->setClickingTogglesState(false);
+	panUpBtn->addListener(this);
+	x+= w+xPad;
+
+	panDownBtn = new ChannelSelectorButton("-", titleFont);
+	panDownBtn->setBounds(x, y, w, h);
+	panDownBtn->setClickingTogglesState(false);
+	panDownBtn->addListener(this);
+	x+= w+xPad*2;
+
+	zoomInBtn = new ChannelSelectorButton("+", titleFont);
+	zoomInBtn->setBounds(x,y,w,h);
+	zoomInBtn->setClickingTogglesState(false);
+	zoomInBtn->addListener(this);
+	x += w + xPad;
+
+	zoomOutBtn = new ChannelSelectorButton("-", titleFont);
+	zoomOutBtn->setBounds(x,y,w,h);
+	zoomOutBtn->setClickingTogglesState(false);
+	zoomOutBtn->addListener(this);
+	x += w + xPad*3;
+
+
+	clearBtn = new ChannelSelectorButton("Clear", titleFont);
+	clearBtn->setBounds(x, y, w*2 + xPad, h);
+	clearBtn->setClickingTogglesState(false);
+	clearBtn->addListener(this);
+	x += (w + xPad) *2;
+	
+	
+	
+/*
+	x = xInitial;
+	y += h + yPad;
+
+	//panLabel->setFont(titleFont);
+
+	saveImgBtn = new ChannelSelectorButton("Save", titleFont);
+	saveImgBtn->setBounds(x,y,w*2 + xPad, h);
+	saveImgBtn->setClickingTogglesState(false);
+	saveImgBtn->addListener(this);
+	x += (w + xPad) * 2;
+
+	*/
+
+	
+
+	//zoomLabel->setFont(titleFont);
+	x = xInitial;
+	y += h + yPad;
+	// Button *zoomOutBtn = new EditorButton("-");
+
+	subChanLabel = new Label("SubChan", "Sub Channel:");
+	subChanLabel->setBounds(x - xPad,y,w*8, h);
+	subChanLabel->setJustificationType(Justification::centredLeft);
+	y += h + yPad/2;
+	//x += w/2;
+
+	allSubChansBtn = new ChannelSelectorButton("All", titleFont);
+	allSubChansBtn->setBounds(x,y,w*2+xPad,h);
+	allSubChansBtn->addListener(this);
+	allSubChansBtn->setToggleState(true, false);
+	x += (w+xPad) * 2;
+	
+	for (int i=0; i<nSubChannels; i++)
+	{
+		String s = "";
+		s += i;
+
+		subChanBtn[i] = new ChannelSelectorButton(s, titleFont);
+		subChanBtn[i]->setBounds(x,y,w,h);
+		subChanBtn[i]->addListener(this);
+		subChanBtn[i]->setToggleState(true, false);
+		x += w + xPad;
+	}
+
+
+
+	addAndMakeVisible(panUpBtn);
+	addAndMakeVisible(panDownBtn);
+	addAndMakeVisible(panLabel);
+
+
+	addAndMakeVisible(zoomInBtn);
+	addAndMakeVisible(zoomOutBtn);
+	addAndMakeVisible(zoomLabel);
+	addAndMakeVisible(clearBtn);
+	//addAndMakeVisible(saveImgBtn);
+
+	addAndMakeVisible(subChanLabel);
+	addAndMakeVisible(allSubChansBtn);
+	for (int i=0; i<nSubChannels; i++)
+		addAndMakeVisible(subChanBtn[i]);
+
+}
+
+Visualizer* SpikeDisplayEditor::createNewCanvas()
+{
+
+	SpikeDisplayNode* processor = (SpikeDisplayNode*) getProcessor();
+	return new SpikeDisplayCanvas(processor);
+
+}
+
+void SpikeDisplayEditor::buttonCallback(Button* button)
+{
+	//std::cout<<"Got event from component:"<<button<<std::endl;
+
+	int pIdx = 0;
+	if (button == panUpBtn){
+		for (int i=0; i<nSubChannels; i++)
+			if (subChanSelected[i])
+				canvas->setParameter(SPIKE_CMD_PAN_AXES, pIdx, i, 1);
+	}
+	else if (button == panDownBtn){
+		for (int i=0; i<nSubChannels; i++)
+			if (subChanSelected[i])
+				canvas->setParameter(SPIKE_CMD_PAN_AXES, pIdx, i, -1);
+	}
+	else if (button == zoomInBtn){
+		for (int i=0; i<nSubChannels; i++)
+			if (subChanSelected[i])
+				canvas->setParameter(SPIKE_CMD_ZOOM_AXES, pIdx, i, -1);
+	}
+	else if (button == zoomOutBtn)
+	{
+		for (int i=0; i<nSubChannels; i++)
+			if (subChanSelected[i])
+				canvas->setParameter(SPIKE_CMD_ZOOM_AXES, pIdx, i, 1);
+	}
+
+	else if (button == clearBtn){
+		std::cout<<"Clear!"<<std::endl;
+		canvas->setParameter(SPIKE_CMD_CLEAR_ALL, 0);
+	}
+	else if (button == saveImgBtn)
+		std::cout<<"Save!"<<std::endl;
+	
+	// toggle all sub channel buttons
+	else if (button == allSubChansBtn)
+	{
+		bool b = allSubChansBtn->getToggleState();
+		for (int i=0; i<nSubChannels; i++)
+			subChanBtn[i]->setToggleState(b, true);
+
+	}
+	// Check the sub Channel selection buttons one by one
+	else{ 
+		// If the user has clicked a sub channel button then the all channels button should be untoggled if toggled
+		allSubChansBtn->setToggleState(false, false);
+		for (int i=0; i<nSubChannels; i++)
+			if(button == subChanBtn[i])
+			{
+				std::cout<<"SubChannel:"<<i<< " set to:";
+				subChanSelected[i] = ((ChannelSelectorButton*) button)->getToggleState();
+				std::cout<< subChanSelected[i]<<std::endl;
+			}
+
+		// If the user has toggled all of the sub channels on, then set AllChans to on
+		bool allChansToggled = true;
+		for (int i=0; i<nSubChannels; i++)
+		{
+			if (subChanBtn[i]->getToggleState()!=allChansToggled){
+				allChansToggled = false;
+				break;
+			}
+		}
+		allSubChansBtn->setToggleState(allChansToggled, false);
+
+	}
+}
diff --git a/Source/Processors/Editors/SpikeDisplayEditor.h b/Source/Processors/Editors/SpikeDisplayEditor.h
new file mode 100644
index 0000000000000000000000000000000000000000..e5d4fd393d0176ed78a8408b5ff42f5bfd3fb765
--- /dev/null
+++ b/Source/Processors/Editors/SpikeDisplayEditor.h
@@ -0,0 +1,74 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef SPIKEDISPLAYEDITOR_H_
+#define SPIKEDISPLAYEDITOR_H_
+
+#include "../../../JuceLibraryCode/JuceHeader.h"
+#include "GenericEditor.h"
+#include "../../UI/UIComponent.h"
+#include "../../UI/DataViewport.h"
+#include "../Visualization/DataWindow.h"
+#include "../SpikeDisplayNode.h"
+#include "../Visualization/SpikeDisplayCanvas.h"
+#include "VisualizerEditor.h"
+
+#define MAX_N_SUB_CHAN 8
+class Visualizer;
+
+class SpikeDisplayEditor : public VisualizerEditor
+{
+public:
+	SpikeDisplayEditor (GenericProcessor*);
+	~SpikeDisplayEditor();
+
+	void buttonCallback (Button* button);
+
+	Visualizer* createNewCanvas();
+
+private:	
+
+    Button *panUpBtn;
+    Button *panDownBtn;
+    Button *zoomInBtn;
+    Button *zoomOutBtn;
+    Button *clearBtn;
+    Button *saveImgBtn;
+
+    Label *panLabel;
+    Label *zoomLabel;
+
+    Button *allSubChansBtn;
+
+    int nSubChannels;
+    Label *subChanLabel;
+    Button *subChanBtn[MAX_N_SUB_CHAN];
+    bool subChanSelected[MAX_N_SUB_CHAN];
+
+    void initializeButtons();
+
+	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SpikeDisplayEditor);
+
+};
+
+#endif  // SPIKEDISPLAYEDITOR_H_
diff --git a/Source/Processors/Editors/SplitterEditor.cpp b/Source/Processors/Editors/SplitterEditor.cpp
index 20de8670ce3d5c47f4b5683ed0171deff233e8db..e70a8340d8dacb3aa3bbbfe9d70fdd095fc0ab5e 100644
--- a/Source/Processors/Editors/SplitterEditor.cpp
+++ b/Source/Processors/Editors/SplitterEditor.cpp
@@ -94,21 +94,21 @@ SplitterEditor::~SplitterEditor()
 	deleteAllChildren();
 }
 
-void SplitterEditor::buttonClicked(Button* button)
+void SplitterEditor::buttonEvent(Button* button)
 {
 	if (button == pipelineSelectorA)
 	{
 		pipelineSelectorA->setToggleState(true,false);
 		pipelineSelectorB->setToggleState(false,false);
 		Splitter* processor = (Splitter*) getProcessor();
-		processor->switchDest(0);
+		processor->switchIO(0);
 
 	} else if (button == pipelineSelectorB) 
 	{
 		pipelineSelectorB->setToggleState(true,false);
 		pipelineSelectorA->setToggleState(false,false);
 		Splitter* processor = (Splitter*) getProcessor();
-		processor->switchDest(1);
+		processor->switchIO(1);
 		
 	}
 }
@@ -120,14 +120,14 @@ void SplitterEditor::switchDest(int dest)
 		pipelineSelectorA->setToggleState(true,false);
 		pipelineSelectorB->setToggleState(false,false);
 		Splitter* processor = (Splitter*) getProcessor();
-		processor->switchDest(0);
+		processor->switchIO(0);
 
 	} else if (dest == 1)
 	{
 		pipelineSelectorB->setToggleState(true,false);
 		pipelineSelectorA->setToggleState(false,false);
 		Splitter* processor = (Splitter*) getProcessor();
-		processor->switchDest(1);
+		processor->switchIO(1);
 		
 	}
 }
\ No newline at end of file
diff --git a/Source/Processors/Editors/SplitterEditor.h b/Source/Processors/Editors/SplitterEditor.h
index 6869c94ad584a99f683af4bba72d7f13d19c9f56..c3c4741ca909023abf2d83221ba0a2b37a2a3d44 100644
--- a/Source/Processors/Editors/SplitterEditor.h
+++ b/Source/Processors/Editors/SplitterEditor.h
@@ -35,14 +35,13 @@
 // 		~PipelineSelectorButton();	
 // };
 
-class SplitterEditor : public GenericEditor//,
-				//	   public Button::Listener
+class SplitterEditor : public GenericEditor
 {
 public:
 	SplitterEditor (GenericProcessor* parentNode);
 	virtual ~SplitterEditor();
 
-	void buttonClicked (Button* button);
+	void buttonEvent (Button* button);
 
     void switchDest(int);
 
diff --git a/Source/Processors/Editors/VisualizerEditor.cpp b/Source/Processors/Editors/VisualizerEditor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..db474bbb2ec6a06e9c78c50a58d9aeb06bbd95a1
--- /dev/null
+++ b/Source/Processors/Editors/VisualizerEditor.cpp
@@ -0,0 +1,235 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "VisualizerEditor.h"
+
+SelectorButton::SelectorButton(const String& name_)
+	: Button(name_)
+{
+	setClickingTogglesState (true);
+    setTooltip ("Toggle a state.");
+
+}
+
+SelectorButton::~SelectorButton()
+{
+}
+
+void SelectorButton::paintButton(Graphics &g, bool isMouseOver, bool isButtonDown)
+{
+    if (getToggleState() == true)
+        g.setColour(Colours::white);
+    else 
+        g.setColour(Colours::darkgrey);
+
+    if (isMouseOver)
+        g.setColour(Colours::yellow);
+
+
+   	if (getName().equalsIgnoreCase("window"))
+   	{
+   		// window icon
+   		g.drawRect(0,0,getWidth(),getHeight(),1.0);
+   		g.fillRect(0,0,getWidth(),3.0);
+   	} else {
+   		// tab icon
+   		g.drawVerticalLine(5,0,getHeight());
+   		g.fillRoundedRectangle(5,2,4,getHeight()-4,4.0f);
+   		g.fillRect(5,2,4,getHeight()-4);
+   	}
+  
+}
+
+
+VisualizerEditor::VisualizerEditor (GenericProcessor* parentNode, int width)
+: GenericEditor(parentNode),
+	  tabIndex(-1), dataWindow(0),
+	  isPlaying(false),
+	  canvas(0), tabText("Tab")
+
+{
+
+	desiredWidth = width;
+
+	initializeSelectors();
+
+}
+
+
+VisualizerEditor::VisualizerEditor (GenericProcessor* parentNode) 
+	: GenericEditor(parentNode),
+	  tabIndex(-1), dataWindow(0),
+	  isPlaying(false),
+	  canvas(0)
+
+{
+
+	desiredWidth = 250;
+	initializeSelectors();
+
+
+}
+void VisualizerEditor::initializeSelectors(){
+
+	windowSelector = new SelectorButton("window");
+	windowSelector->addListener(this);
+	windowSelector->setBounds(desiredWidth - 40,7,14,10);
+
+	windowSelector->setToggleState(false,false);
+	addAndMakeVisible(windowSelector);
+
+	tabSelector = new SelectorButton("tab");
+	tabSelector->addListener(this);
+	tabSelector->setBounds(desiredWidth - 20,7,15,10);
+	
+	addAndMakeVisible(tabSelector);
+	tabSelector->setToggleState(false,false);
+}
+
+VisualizerEditor::~VisualizerEditor()
+{
+
+	if (tabIndex > -1)
+	{
+		getDataViewport()->removeTab(tabIndex);
+	}
+
+	deleteAllChildren();
+
+}
+
+void VisualizerEditor::enable()
+{
+	std::cout << "   Enabling VisualizerEditor" << std::endl;
+	if (canvas != 0)
+		canvas->beginAnimation();
+	
+	isPlaying = true;
+}
+
+void VisualizerEditor::disable()
+{
+	if (canvas != 0)
+		canvas->endAnimation();
+
+	isPlaying = false;
+}
+
+void VisualizerEditor::updateVisualizer()
+{
+
+	if (canvas != 0)
+		canvas->update();
+
+}
+
+void VisualizerEditor::buttonEvent(Button* button)
+{
+
+	int gId = button->getRadioGroupId();
+
+	if (gId > 0) {
+		if (canvas != 0)
+		{
+			canvas->setParameter(gId-1, button->getName().getFloatValue());
+		}
+
+	} else {
+
+		if (canvas == 0) {
+			
+			canvas = createNewCanvas();
+
+			if (isPlaying)
+				canvas->beginAnimation();
+		}
+
+		if (button == windowSelector)
+		{
+
+			if (tabSelector->getToggleState() && windowSelector->getToggleState())
+		 	{
+		 		tabSelector->setToggleState(false, false);
+		 		getDataViewport()->destroyTab(tabIndex);
+		 		tabIndex = -1;
+		 	}
+
+		 	if (dataWindow == 0) {
+
+				dataWindow = new DataWindow(windowSelector);
+		 		dataWindow->setContentNonOwned(canvas, false);
+		 		dataWindow->setVisible(true);
+		 		canvas->refreshState();
+				
+		 	} else {
+
+		 		dataWindow->setVisible(windowSelector->getToggleState());
+		 		
+		 		if (windowSelector->getToggleState())
+		 		{
+		 			dataWindow->setContentNonOwned(canvas, false);
+		 			canvas->refreshState();
+		 		} else {
+		 			dataWindow->setContentNonOwned(0, false);
+		 		}
+		 		
+		 	}
+
+		} 
+		else if (button == tabSelector) 
+		{
+			if (tabSelector->getToggleState() && tabIndex < 0)
+			{
+
+				 if (windowSelector->getToggleState())
+				 {
+				 	dataWindow->setContentNonOwned(0, false);
+				 	windowSelector->setToggleState(false, false);
+				 	dataWindow->setVisible(false);
+				 }
+
+				tabIndex = getDataViewport()->addTabToDataViewport(tabText,canvas);
+
+
+			} else if (!tabSelector->getToggleState() && tabIndex > -1)
+			{
+				getDataViewport()->destroyTab(tabIndex);
+				tabIndex = -1;
+
+			}
+		}
+		
+	}
+
+	buttonCallback(button);
+
+	if (button == drawerButton)
+	{
+		std::cout<<"Drawer button clicked"<<std::endl;
+		windowSelector->setBounds(desiredWidth - 40,7,14,10);
+		tabSelector->setBounds(desiredWidth - 20,7,15,10);
+
+	}
+
+}
+
diff --git a/Source/Processors/Editors/VisualizerEditor.h b/Source/Processors/Editors/VisualizerEditor.h
new file mode 100644
index 0000000000000000000000000000000000000000..560fc51bfef910f294e515adcf36ca382ef48977
--- /dev/null
+++ b/Source/Processors/Editors/VisualizerEditor.h
@@ -0,0 +1,94 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef __VISUALIZEREDITOR_H_17E6D78C__
+#define __VISUALIZEREDITOR_H_17E6D78C__
+
+#include "../../../JuceLibraryCode/JuceHeader.h"
+#include "GenericEditor.h"
+#include "../../UI/UIComponent.h"
+#include "../../UI/DataViewport.h"
+#include "../Visualization/DataWindow.h"
+#include "../Visualization/Visualizer.h"
+
+/**
+  
+  Base class for creating editors with visualizers.
+
+  @see GenericEditor, Visualizer
+
+*/
+
+class DataWindow;
+class Visualizer;
+
+class SelectorButton : public Button
+{
+	public:
+		SelectorButton(const String& name);
+		~SelectorButton();	
+	private:
+		void paintButton(Graphics& g, bool isMouseOver, bool isButtonDown);
+};
+
+class VisualizerEditor : public GenericEditor
+{
+public:
+	VisualizerEditor (GenericProcessor*, int);
+	VisualizerEditor (GenericProcessor*);
+	~VisualizerEditor();
+
+	void buttonEvent (Button* button);
+	virtual void buttonCallback(Button* button) {}
+
+	virtual Visualizer* createNewCanvas() = 0;
+
+	virtual void enable();
+	virtual void disable();
+
+	void updateVisualizer();
+
+	ScopedPointer<DataWindow> dataWindow;
+	ScopedPointer<Visualizer> canvas;
+
+	String tabText;
+
+private:	
+
+	void initializeSelectors();
+	bool isPlaying;
+
+	SelectorButton* windowSelector;
+	SelectorButton* tabSelector;
+
+	int tabIndex;
+
+
+
+	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VisualizerEditor);
+
+};
+
+
+
+#endif  // __VISUALIZEREDITOR_H_17E6D78C__
diff --git a/Source/Processors/EventNode.cpp b/Source/Processors/EventNode.cpp
index 67d365b478703c534219e399d1779bc92b3a2965..b36be29e73a6aa93391520d8b17e46d6faee1e11 100644
--- a/Source/Processors/EventNode.cpp
+++ b/Source/Processors/EventNode.cpp
@@ -27,11 +27,6 @@
 EventNode::EventNode()
 	: GenericProcessor("Event Generator"), Hz(1), accumulator(0)
 {
-	setNumOutputs(0);
-	setNumInputs(0);
-//	setSampleRate(44100.0);
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
 
 }
 
@@ -42,30 +37,18 @@ EventNode::~EventNode()
 
 AudioProcessorEditor* EventNode::createEditor()
 {
-	EventNodeEditor* editor = new EventNodeEditor(this);
-	setEditor(editor);
-
-	std::cout << "Creating editor." << std::endl;
-	//editor->setUIComponent(getUIComponent());
-	//editor->setConfiguration(config);
-
-	//filterEditor = new FilterEditor(this);
+	editor = new EventNodeEditor(this);
 	return editor;
-
-	//return 0;
 }
 
-
-bool EventNode::canSendSignalTo(GenericProcessor* p)
+void EventNode::updateSettings()
 {
-	if (p->getName().equalsIgnoreCase("WiFi Output"))
-	{
-		return true;
-	} else {
-		return false;
-	}
+	// add event channels
+	settings.eventChannelIds.add(1);
+	settings.eventChannelNames.add("Trigger");
 }
 
+
 void EventNode::setParameter (int parameterIndex, float newValue)
 {
 	std::cout << "Setting frequency to " << newValue << " Hz." << std::endl;
@@ -86,11 +69,10 @@ void EventNode::process(AudioSampleBuffer &buffer,
 		if (accumulator > getSampleRate()/Hz)
 		{
 			//std::cout << "Adding message." << std::endl;
-			addMidiEvent(midiMessages, 10, i);
+			addEvent(midiMessages, TTL, i);
 			accumulator = 0;
 		}
 
 	}	
-	
 
 }
diff --git a/Source/Processors/EventNode.h b/Source/Processors/EventNode.h
index 6d1491a0c207c019b3645b77099911d3ebb1441a..f0664849d04018c8476024f7601ebce6e47d3cc0 100644
--- a/Source/Processors/EventNode.h
+++ b/Source/Processors/EventNode.h
@@ -36,8 +36,6 @@
 
 */
 
-class FilterViewport;
-
 class EventNode : public GenericProcessor
 
 {
@@ -50,11 +48,10 @@ public:
 	void setParameter (int parameterIndex, float newValue);
 
 	bool isSource() {return true;}
-	bool hasEditor() const {return true;}
 
-	float getSampleRate() {return 44100.0;}
+    int getDefaultNumOutputs() {return 0;}
 
-	bool canSendSignalTo(GenericProcessor*);
+    void updateSettings();
 
 	AudioProcessorEditor* createEditor();
 	
diff --git a/Source/Processors/FileReader.cpp b/Source/Processors/FileReader.cpp
deleted file mode 100644
index e0facd69406e3e149bc87def857cfc2df5d4bf6f..0000000000000000000000000000000000000000
--- a/Source/Processors/FileReader.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2012 Open Ephys
-
-    ------------------------------------------------------------------
-
-    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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "FileReader.h"
-
-
-FileReader::FileReader()
-	: GenericProcessor("File Reader"),
-	  sampleRate (40000.0),
-	  numChannels(16),
-	  samplesPerBlock(1024)
-{
-	setNumOutputs(numChannels);
-	setNumInputs(0);
-}
-
-FileReader::~FileReader()
-{
-}
-
-
-//AudioProcessorEditor* FileReader::createEditor( )
-//{
-	//filterEditor = new FilterEditor(this);
-	
-//	std::cout << "Creating editor." << std::endl;
-//	sourceEditor = new SourceNodeEditor(this);
-//	return sourceEditor;
-//}
-
-
-
-void FileReader::setParameter (int parameterIndex, float newValue)
-{
-	//std::cout << "Message received." << std::endl;
-}
-
-bool FileReader::enable () {
-
-	File file = File("./data_stream_16ch");
-	input = file.createInputStream();
-
-	
-	std::cout << "File Reader received enable signal." << std::endl;
-
-	return true;
-
-}
-
-bool FileReader::disable() {
-
-	deleteAndZero(input);
-	
-	std::cout << "File reader received disable signal." << std::endl;
-
-	return true;
-
-}
-
-void FileReader::process(AudioSampleBuffer &buffer, 
-                            MidiBuffer &midiMessages,
-                            int& nSamples)
-{
-
-	nSamples = samplesPerBlock;
-	//std::cout << buffer.getNumChannels() << std::endl;
-	
-    for (int i = 0; i < samplesPerBlock; ++i)
-    {
-
-    	for (int j = 0; j < numChannels; j++) {
-    		
-    		if (input->isExhausted())
-    			input->setPosition(0);   			
-    	
-    		const float sample = float(input->readShort());
-
-    		*buffer.getSampleData (j, i) = sample;
-    	}
-
-    }
-}
\ No newline at end of file
diff --git a/Source/Processors/FileReader.h b/Source/Processors/FileReader.h
deleted file mode 100644
index 30394bdd3bbef20564c6dfe04c05c685c4b5d6d0..0000000000000000000000000000000000000000
--- a/Source/Processors/FileReader.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2012 Open Ephys
-
-    ------------------------------------------------------------------
-
-    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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef __FILEREADER_H_605BF4A__
-#define __FILEREADER_H_605BF4A__
-
-
-#include "../../JuceLibraryCode/JuceHeader.h"
-#include "GenericProcessor.h"
-
-/**
-
-  --UNDER CONSTRUCTION--
-
-  Reads data from a file with a specific format.
-
-  @see GenericProcessor
-
-*/
-
-
-class FileReader : public GenericProcessor
-
-{
-public:
-	
-	// real member functions:
-	FileReader();
-	~FileReader();
-
-	void process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples);
-
-	void setParameter (int parameterIndex, float newValue);
-
-	//AudioProcessorEditor* createEditor();
-	bool hasEditor() const {return true;}
-
-	bool enable();
-	bool disable();
-
-	bool isSource() {return true;}
-
-private:
-
-	float sampleRate;
-	int numChannels;
-	int samplesPerBlock;
-
-	FileInputStream* input;
-
-	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileReader);
-
-};
-
-
-
-
-#endif  // __FILEREADER_H_605BF4A__
diff --git a/Source/Processors/FilterNode.cpp b/Source/Processors/FilterNode.cpp
index fd8fb9e55d9f4ead7ec1905a0316664c98a29d71..e381b58ea7f1e7b83da1d04ae20c465afab3d556 100644
--- a/Source/Processors/FilterNode.cpp
+++ b/Source/Processors/FilterNode.cpp
@@ -39,12 +39,12 @@ FilterNode::~FilterNode()
 
 AudioProcessorEditor* FilterNode::createEditor()
 {
-	FilterEditor* filterEditor = new FilterEditor(this);
-	setEditor(filterEditor);
+	editor = new FilterEditor(this);
+	//setEditor(filterEditor);
 	
 	std::cout << "Creating editor." << std::endl;
 
-	return filterEditor;
+	return editor;
 }
 
 
@@ -81,51 +81,34 @@ AudioProcessorEditor* FilterNode::createEditor()
 //  necessary to interoperate with the Filter virtual base class and its derived classes
 
 
-void FilterNode::setNumInputs(int inputs)
+void FilterNode::updateSettings()
 {		
 
-	numInputs = inputs;
-	setNumOutputs(inputs);
-
 	filters.clear();
 	lowCuts.clear();
 	highCuts.clear();
 
-	if (inputs < 100) {
-
-	for (int n = 0; n < getNumInputs(); n++)
-	{
-		std::cout << "Creating filter number " << n << std::endl;
-
-		filters.add(new Dsp::SmoothedFilterDesign 
-			<Dsp::Butterworth::Design::BandPass 	// design type
-			<4>,								 	// order
-			1,										// number of channels (must be const)
-			Dsp::DirectFormII>						// realization
-			(1024));	 
-
-		lowCuts.add(1.0f);
-		highCuts.add(1000.0f);
-		
-		setFilterParameters(1.0f, 1000.0f, n);
-	}
-
-	}
-				
-}
-
-void FilterNode::setSampleRate(float r)
-{
-	sampleRate = r;
-
-	if (numInputs < 100) {
+	if (getNumInputs() < 100) {
 
 		for (int n = 0; n < getNumInputs(); n++)
 		{
-			setFilterParameters(lowCuts[n], highCuts[n], n);
+			std::cout << "Creating filter number " << n << std::endl;
+
+			filters.add(new Dsp::SmoothedFilterDesign 
+				<Dsp::Butterworth::Design::BandPass 	// design type
+				<4>,								 	// order
+				1,										// number of channels (must be const)
+				Dsp::DirectFormII>						// realization
+				(1024));	 
+
+			lowCuts.add(1.0f);
+			highCuts.add(1000.0f);
+			
+			setFilterParameters(1.0f, 1000.0f, n);
 		}
+
 	}
-	
+				
 }
 
 void FilterNode::setFilterParameters(double lowCut, double highCut, int chan)
diff --git a/Source/Processors/FilterNode.h b/Source/Processors/FilterNode.h
index 2a6e616477d13d6b4eb18822254ee47d35a3caba..1dbe3fbd025385f56c26b3978c0a49a1f34dbf0c 100644
--- a/Source/Processors/FilterNode.h
+++ b/Source/Processors/FilterNode.h
@@ -52,9 +52,8 @@ public:
 	AudioProcessorEditor* createEditor();
 
 	bool hasEditor() const {return true;}
-	
-	void setNumInputs(int);
-	void setSampleRate(float);
+
+    void updateSettings();
 	
 private:
 
diff --git a/Source/Processors/GenericProcessor.cpp b/Source/Processors/GenericProcessor.cpp
index 385d8a8d85afa3111ea89d31552806bbca339a07..16f70eb2f9c7aa75b5aac1ee87e5cfbfe67e2b61 100644
--- a/Source/Processors/GenericProcessor.cpp
+++ b/Source/Processors/GenericProcessor.cpp
@@ -24,20 +24,18 @@
 #include "GenericProcessor.h"
 #include "../UI/UIComponent.h"
 
-GenericProcessor::GenericProcessor(const String& name_) : name(name_),
-	sourceNode(0), destNode(0), editor(0), isEnabled(true), saveOrder(-1), loadOrder(-1),
-	nextAvailableChannel(0), wasConnected(false), currentChannel(-1)
-	
+GenericProcessor::GenericProcessor(const String& name_) : 
+    name(name_),
+	sourceNode(0), destNode(0),
+	isEnabled(true), 
+	saveOrder(-1), loadOrder(-1),
+	nextAvailableChannel(0), currentChannel(-1),
+	wasConnected(false)
 {
-
 }
 
 GenericProcessor::~GenericProcessor()
 {
-	if (editor != 0)
-	{
-		deleteAndZero(editor);
-	}
 }
 
 AudioProcessorEditor* GenericProcessor::createEditor()
@@ -49,44 +47,26 @@ AudioProcessorEditor* GenericProcessor::createEditor()
 
 void GenericProcessor::setParameter (int parameterIndex, float newValue)
 {
-
+	if (currentChannel > 0)
+	{
+		//Parameter& p = parameters[parameterIndex];
+		//parameters[parameterIndex].setValue(newValue, currentChannel);
+	}
 
 }
 
-GenericProcessor* GenericProcessor::getOriginalSourceNode()
+const String GenericProcessor::getParameterName (int parameterIndex)
 {
-	if (isSource())
-	{
-		return this;
-	} else {
-		
-		GenericProcessor* source = getSourceNode();
-
-		if (source != 0)
-		{
-			while (!source->isSource() && source != 0)
-			{
-				source = source->getSourceNode();
-			}
-
-			return source;
-
-		} else {
-			return 0;
-		}
-	}
+	//Parameter& p = parameters[parameterIndex];
+	//return parameters[parameterIndex].getName();
 }
 
-int GenericProcessor::getDefaultNumOutputs()
+const String GenericProcessor::getParameterText (int parameterIndex)
 {
-	if (!isSink())
-	{
-		return 10;
-	} else {
-		return 0;
-	}
+	//Parameter& p = parameters[parameterIndex];
+	//return parameters[parameterIndex].getDescription();
 }
-
+	
 
 void GenericProcessor::prepareToPlay (double sampleRate_, int estimatedSamplesPerBlock)
 {
@@ -102,21 +82,12 @@ void GenericProcessor::releaseResources()
 	// disable() is only called by the ProcessorGraph at the end of acquisition
 }
 
-
-// void GenericProcessor::sendMessage(const String& msg)
-// {
-// 	std::cout << "Message: ";
-// 	std::cout << msg << "...." << std::endl;
-// 	UI->transmitMessage(msg);
-// }
-
-
 int GenericProcessor::getNextChannel(bool increment)
 {
 	int chan = nextAvailableChannel;
 
 	//std::cout << chan << std::endl;
-
+ 
 	if (increment)
 		nextAvailableChannel++;
 	
@@ -134,43 +105,42 @@ void GenericProcessor::resetConnections()
 	wasConnected = false;
 }
 
-void GenericProcessor::setNumSamples(MidiBuffer& midiMessages, int numberToAdd) {
+void GenericProcessor::setNumSamples(MidiBuffer& events, int sampleIndex) {
 
 	uint8 data[2];
 
-	data[0] = numberToAdd >> 8; 	// most-significant byte
-    data[1] = numberToAdd & 0xFF; 	// least-significant byte
-
-    midiMessages.addEvent(data, 		// spike data
-                          sizeof(data), // total bytes
-                          -1);           // sample index
+	data[0] = BUFFER_SIZE; 	// most-significant byte
+    data[1] = nodeId; 		// least-significant byte
 
+    events.addEvent(data, 		// spike data
+                    2, 			// total bytes
+                    sampleIndex); // sample index
 
 }
 
-int GenericProcessor::getNumSamples(MidiBuffer& midiMessages) {
+int GenericProcessor::getNumSamples(MidiBuffer& events) {
 
 	int numRead = 0;
 
-	if (midiMessages.getNumEvents() > 0) 
+	if (events.getNumEvents() > 0) 
 	{
 			
-		int m = midiMessages.getNumEvents();
+		int m = events.getNumEvents();
 
-		MidiBuffer::Iterator i (midiMessages);
+		MidiBuffer::Iterator i (events);
 		MidiMessage message(0xf4);
 
 		int samplePosition = -5;
 
 		while (i.getNextEvent (message, samplePosition)) {
 			
-				int numbytes = message.getRawDataSize();
-				uint8* dataptr = message.getRawData();
+			uint8* dataptr = message.getRawData();
 
-				if (message.getTimeStamp() < 0)
-					numRead = (*dataptr<<8) + *(dataptr+1);
+			if (*dataptr == BUFFER_SIZE)
+			{
+				numRead = message.getTimeStamp();
+			}
 		}
-
 	}
 
 	return numRead;
@@ -279,80 +249,86 @@ void GenericProcessor::setDestNode(GenericProcessor* dn)
 	}
 }
 
-void GenericProcessor::updateSettings()
+void GenericProcessor::clearSettings()
+{
+	settings.originalSource = 0;
+	settings.numInputs = 0;
+	settings.numOutputs = 0;
+	settings.inputChannelNames.clear();
+	settings.outputChannelNames.clear();
+	settings.bitVolts.clear();
+	settings.eventChannelIds.clear();
+	settings.eventChannelNames.clear();
+}
+
+void GenericProcessor::update()
 {
+
+	std::cout << getName() << " updating settings." << std::endl;
+
+	clearSettings();
 	
 	if (sourceNode != 0)
 	{
-		setSampleRate(sourceNode->getSampleRate());
-		setNumInputs(sourceNode->getNumOutputs());
+		// everything is inherited except numOutputs
+		settings = sourceNode->settings;
+		settings.numInputs = settings.numOutputs;
+		settings.numOutputs = settings.numInputs;
+
 	} else {
-		setSampleRate(getDefaultSampleRate());
-		setNumInputs(0);
-		setNumOutputs(getDefaultNumOutputs());
-	}
 
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
+		settings.sampleRate = getDefaultSampleRate();
+		settings.numOutputs = getDefaultNumOutputs();
 
-	updateParameters();
+		for (int i = 0; i < getNumOutputs(); i++)
+			settings.bitVolts.add(getDefaultBitVolts());
 
-	GenericEditor* editor = (GenericEditor*) getEditor();
+		generateDefaultChannelNames(settings.outputChannelNames);
 
-	editor->update();
+	}
 
-}
+	if (this->isSink())
+	{
+		settings.numOutputs = 0;
+		settings.outputChannelNames.clear();
+	}
 
-void GenericProcessor::updateParameters()
-{
-	
-}
+	updateSettings(); // custom settings code
 
+	// required for the ProcessorGraph to know the
+	// details of this processor:
+	setPlayConfigDetails(getNumInputs(),  // numIns
+		                 getNumOutputs(), // numOuts
+		                 44100.0,         // sampleRate
+		                 128);            // blockSize
+
+	editor->update(); // update editor settings
 
-int GenericProcessor::getNumInputs()
-{
-	return numInputs;
 }
 
-int GenericProcessor::getNumOutputs()
+bool GenericProcessor::recordStatus(int chan)
 {
-	return numOutputs;
-}
 
-void GenericProcessor::setNumInputs(int n) {
-	numInputs = n;
-	// if (destNode != 0)
-	// {
-	// 	destNode->setNumInputs();
-	// }
-	//setPlayConfigDetails(numInputs,numOutputs,44100.0,1024);
-}
+	return getEditor()->recordChannels[chan];
+
 
-void GenericProcessor::setNumInputs() {
-	
-	int n = getSourceNode()->getNumOutputs();
-	setNumInputs(n);
 }
 
-void GenericProcessor::setNumOutputs()
+void GenericProcessor::generateDefaultChannelNames(StringArray& names)
 {
-	setNumOutputs(getNumInputs());
-}
+	names.clear();
 
-void GenericProcessor::setNumOutputs(int n) {
-	numOutputs = n;
-	//setPlayConfigDetails(numInputs,numOutputs,44100.0,1024);
-}
+	for (int i = 0; i < settings.numOutputs; i++)
+	{
+		String channelName = "CH";
+		channelName += (i+1);
+		names.add(channelName);
+	}
 
-float GenericProcessor::getSampleRate()
-{
-	return sampleRate;
-}
-void GenericProcessor::setSampleRate(float sr)
-{
-	sampleRate = sr;
 }
 
-int GenericProcessor::checkForMidiEvents(MidiBuffer& midiMessages)
+
+int GenericProcessor::checkForEvents(MidiBuffer& midiMessages)
 {
 
 	if (midiMessages.getNumEvents() > 0) 
@@ -369,18 +345,10 @@ int GenericProcessor::checkForMidiEvents(MidiBuffer& midiMessages)
 
 		while (i.getNextEvent (message, samplePosition)) {
 			
-				int numbytes = message.getRawDataSize();
-				uint8* dataptr = message.getRawData();
+			uint8* dataptr = message.getRawData();
 
-				//std::cout << " Bytes received: " << numbytes << std::endl;
-				//std::cout << " Message timestamp = " << message.getTimeStamp() << std::endl;
+			handleEvent(*dataptr, message);
 
-				if (message.getTimeStamp() >= 0)
-				{
-					int value = (*dataptr<<8) + *(dataptr+1);
-					//std::cout << "   " << value << std::endl;
-					return value;
-				}
 		}
 
 	}
@@ -389,26 +357,35 @@ int GenericProcessor::checkForMidiEvents(MidiBuffer& midiMessages)
 
 }
 
-void GenericProcessor::addMidiEvent(MidiBuffer& midiMessages, int numberToAdd, int sampleNum)
+void GenericProcessor::addEvent(MidiBuffer& eventBuffer,
+							    uint8 type,
+							    int sampleNum,
+							    uint8 eventId,
+							    uint8 eventChannel,
+							    uint8 numBytes,
+							    uint8* eventData)
 {
-	uint8 data[2];
+	uint8 data[4+numBytes];
 
-	data[0] = numberToAdd >> 8; 	// most-significant byte
-    data[1] = numberToAdd & 0xFF; 	// least-significant byte
+	data[0] = type;    // event type
+    data[1] = nodeId;  // processor ID
+    data[2] = eventId; // event ID
+    data[3] = eventChannel; // event channel
+    memcpy(&data[4], eventData, numBytes);
 
-    midiMessages.addEvent(data, 		// spike data
+    eventBuffer.addEvent(data, 		// spike data
                           sizeof(data), // total bytes
                           sampleNum);     // sample index
 }
 
-void GenericProcessor::processBlock (AudioSampleBuffer &buffer, MidiBuffer &midiMessages)
+void GenericProcessor::processBlock (AudioSampleBuffer &buffer, MidiBuffer &eventBuffer)
 {
 	
-	int nSamples = getNumSamples(midiMessages); // removes first value from midimessages
+	int nSamples = getNumSamples(eventBuffer); // removes first value from midimessages
 
-	process(buffer, midiMessages, nSamples);
+	process(buffer, eventBuffer, nSamples);
 
-	setNumSamples(midiMessages, nSamples); // adds it back,
-										   // even if it's unchanged
+	setNumSamples(eventBuffer, nSamples); // adds it back,
+										  // even if it's unchanged
 
 }
diff --git a/Source/Processors/GenericProcessor.h b/Source/Processors/GenericProcessor.h
index 1612abe31703ec09ba94ce1a219f3672d5f59980..8e1a3e4e3763e716dbfc591e0f428d789c10abf9 100644
--- a/Source/Processors/GenericProcessor.h
+++ b/Source/Processors/GenericProcessor.h
@@ -27,8 +27,9 @@
 
 #include "../../JuceLibraryCode/JuceHeader.h"
 #include "Editors/GenericEditor.h"
-#include "../UI/Configuration.h"
+#include "Parameter.h"
 #include "../AccessClass.h"
+
 #include <time.h>
 #include <stdio.h>
 
@@ -49,9 +50,10 @@
 class EditorViewport;
 class DataViewport;
 class UIComponent;
+class GenericEditor;
+//class Parameter;
 
 class GenericProcessor : public AudioProcessor,
-						// public ActionBroadcaster,
 						 public AccessClass
 
 {
@@ -81,11 +83,11 @@ public:
 	void changeProgramName (int index, const String &newName) {}
 	void setCurrentProgram (int index) {}
 
-	const String getInputChannelName (int channelIndex) const {return T(" ");}
-	const String getOutputChannelName (int channelIndex) const {return T(" ");}
-	const String getParameterName (int parameterIndex) {return T(" ");}
-	const String getParameterText (int parameterIndex) {return T(" ");}
-	const String getProgramName (int index) {return T(" ");}
+	const String getInputChannelName (int channelIndex) const {return settings.inputChannelNames[channelIndex];}
+	const String getOutputChannelName (int channelIndex) const {return settings.outputChannelNames[channelIndex];}
+	const String getParameterName (int parameterIndex); //{return parameters[parameterIndex]->getName();}
+	const String getParameterText (int parameterIndex); //{return parameters[parameterIndex]->getDescription();}
+	const String getProgramName (int index) {return "";}
 	
 	bool isInputChannelStereoPair (int index) const {return true;}
 	bool isOutputChannelStereoPair (int index) const {return true;}
@@ -95,11 +97,12 @@ public:
 	bool isParameterAutomatable(int parameterIndex) {return false;}
 	bool isMetaParameter(int parameterIndex) {return false;}
 	
-	int getNumParameters() {return 0;}
+	int getNumParameters() {return parameters.size();}
 	int getNumPrograms() {return 0;}
 	int getCurrentProgram() {return 0;}
 	
 	float getParameter (int parameterIndex) {return 1.0;}
+	Parameter& getParameterByName(String parameterName);
 
 	//----------------------------------------------------------------------
 	// Custom methods:
@@ -109,37 +112,22 @@ public:
 						 MidiBuffer& /*buffer*/,
 						 int& /*nSamples*/) = 0;
 
-	
-
 	GenericProcessor* sourceNode;
 	GenericProcessor* destNode;
 
-	int numInputs;
-	int numOutputs;
-
-	float sampleRate;
-
-	//void sendMessage(const String& msg);
-
-	virtual float getSampleRate();
-	virtual void setSampleRate(float sr);
+	virtual float getSampleRate() {return settings.sampleRate;}
 	virtual float getDefaultSampleRate() {return 44100.0;}
 
-	virtual int getNumInputs();
-	virtual void setNumInputs(int);
-	virtual void setNumInputs();
-	
-	virtual int getNumOutputs();
-	virtual void setNumOutputs(int);
-	virtual void setNumOutputs();
-	virtual int getDefaultNumOutputs();
+	virtual int getNumInputs() {return settings.numInputs;}
+	virtual int getNumOutputs() {return settings.numOutputs;}
+	virtual int getDefaultNumOutputs() {return 2;}
+
+	//virtual float getBitVolts() {return settings.bitVolts;}
+	virtual float getDefaultBitVolts() {return 1.0;}
 
 	virtual int getNextChannel(bool);
 	virtual void resetConnections();
 	
-	virtual void updateSettings(); // updates sample rate and number of channels
-	virtual void updateParameters(); // called in updateSettings() to update params
-
 	virtual void setCurrentChannel(int chan) {currentChannel = chan;}
 
 	int getNodeId() {return nodeId;}
@@ -148,12 +136,9 @@ public:
 	// get/set source node functions
 	GenericProcessor* getSourceNode() {return sourceNode;}
 	GenericProcessor* getDestNode() {return destNode;}
-	GenericProcessor* getOriginalSourceNode();
 
-	virtual void switchSource(int) { };
-	virtual void switchSource() { };
-	virtual void switchDest() { };
-	virtual void switchDest(int) { };
+	virtual void switchIO(int) { };
+	virtual void switchIO() { };
 
 	virtual void setSourceNode(GenericProcessor* sn);
 	virtual void setDestNode(GenericProcessor* dn);
@@ -176,59 +161,84 @@ public:
 
 	virtual bool stillHasSource() {return true;}
 
+	bool isEnabled;
+	bool wasConnected;
+
 	virtual AudioSampleBuffer* getContinuousBuffer() {return 0;}
 	virtual MidiBuffer* getEventBuffer() {return 0;}
 
 	int nextAvailableChannel;
 
-	int checkForMidiEvents(MidiBuffer& mb);
-	void addMidiEvent(MidiBuffer& mb, int a, int b);
-
-	bool isEnabled;
-
-	bool wasConnected;
+	// event buffers
+	virtual int checkForEvents(MidiBuffer& mb);
+	virtual void addEvent(MidiBuffer& mb,
+	                      uint8 type,
+	                      int sampleNum,
+	                      uint8 eventID = 0,
+	                      uint8 eventChannel = 0,
+	                      uint8 numBytes = 0,
+	                      uint8* data = 0);
+
+	virtual void handleEvent(int eventType, MidiMessage& event) {}
+
+	enum eventTypes 
+ 	{
+ 		TIMESTAMP = 0,
+ 		BUFFER_SIZE = 1,
+ 		PARAMETER_CHANGE = 2,
+ 		TTL = 3,
+ 		SPIKE = 4,
+ 		EEG = 5,
+ 		CONTINUOUS = 6
+ 	};
 
 	int saveOrder;
 	int loadOrder;
 
 	int currentChannel;
 
+	virtual GenericEditor* getEditor() {return editor;}
+	ScopedPointer<GenericEditor> editor;
 
-	// Getting and setting:
+	struct ProcessorSettings {
 
-	AudioProcessorEditor* getEditor() {return editor;}
-	void setEditor(AudioProcessorEditor* e) {editor = e;}
+		GenericProcessor* originalSource;
 
-	// void setUIComponent(UIComponent* ui) {UI = ui;}
-	// UIComponent* getUIComponent() {return UI;}
+		int numInputs;
+		int numOutputs;
+		StringArray inputChannelNames;
+		StringArray outputChannelNames;
 
-	// virtual void setConfiguration(Configuration* cf) {config = cf;}
-	// Configuration* getConfiguration() {return config;}
+		float sampleRate;
+		Array<float> bitVolts;
 
-	// void setFilterViewport(FilterViewport* vp) {viewport = vp;}
-	// FilterViewport* getFilterViewport() {return viewport;}
+		Array<int> eventChannelIds;
+		StringArray eventChannelNames;
 
-	// void setDataViewport(DataViewport* dv) {dataViewport = dv;}
-	// DataViewport* getDataViewport() {return dataViewport;}
+	};
 
+	ProcessorSettings settings;
 
-	//FilterViewport* viewport;
-	//DataViewport* dataViewport;
-	//UIComponent* UI;
+	virtual bool recordStatus(int chan);
 
-	//Configuration* config;
+	virtual void clearSettings();
 
-	//int tabA, tabB; // needed for Merger
+	virtual void generateDefaultChannelNames(StringArray&);
 
-	AudioProcessorEditor* editor;
+	virtual void update(); // default node updating
+	virtual void updateSettings() {} // custom node updating
+
+	int nodeId;
+
+	// parameters:
+	Array<Parameter> parameters;
+	StringArray parameterNames;
 
 private:
 
 	void processBlock (AudioSampleBuffer &buffer, MidiBuffer &midiMessages);
 
 	const String name;
-
-	int nodeId;
 	
 	int getNumSamples(MidiBuffer&);
 	void setNumSamples(MidiBuffer&, int);
diff --git a/Source/Processors/LfpDisplayNode.cpp b/Source/Processors/LfpDisplayNode.cpp
index 09935130a9b80c809756fbed06674ddf2c47cfb1..c444d776a51e218e684a9581cf80c1bcde91c82d 100644
--- a/Source/Processors/LfpDisplayNode.cpp
+++ b/Source/Processors/LfpDisplayNode.cpp
@@ -30,64 +30,32 @@ LfpDisplayNode::LfpDisplayNode()
 	  displayBufferIndex(0), abstractFifo(100)
 
 {
-
-	numInputs = 2;
-	numOutputs = 0;
-	sampleRate = 44100.0;
-
-	setPlayConfigDetails(2,0,44100.0,128);
-
-	displayBuffer = new AudioSampleBuffer (8, 100);
+	displayBuffer = new AudioSampleBuffer(8, 100);
 	eventBuffer = new MidiBuffer();
 }
 
 LfpDisplayNode::~LfpDisplayNode()
 {
-
-	deleteAndZero(displayBuffer);
-	deleteAndZero(eventBuffer);
+	//deleteAndZero(displayBuffer);
+	//deleteAndZero(eventBuffer);
 }
 
 AudioProcessorEditor* LfpDisplayNode::createEditor()
 {
 
-	LfpDisplayEditor* editor = new LfpDisplayEditor(this);
-
-	//editor->setBuffers (displayBuffer, eventBuffer);
-	//editor->setUIComponent (getUIComponent());
-	//editor->setConfiguration (config);
-	//editor->updateNumInputs(getNumInputs());
-	//editor->updateSampleRate(sampleRate);
-
-	setEditor(editor);
-	
+	editor = new LfpDisplayEditor(this);	
 	return editor;
 
 }
 
-void LfpDisplayNode::setNumInputs(int inputs)
+void LfpDisplayNode::updateSettings()
 {
-	std::cout << "Setting num inputs on LfpDisplayNode to " << inputs << std::endl;
-	numInputs = inputs;	
-	setNumOutputs(0);
-
-	setPlayConfigDetails(getNumInputs(),0,44100.0,128);
-
-	LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor();
-	editor->updateNumInputs(inputs);
-}
-
-void LfpDisplayNode::setSampleRate(float r)
-{
-	sampleRate = r;
-
-	LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor();
-	editor->updateSampleRate(r);
+	std::cout << "Setting num inputs on LfpDisplayNode to " << getNumInputs() << std::endl;
 }
 
 bool LfpDisplayNode::resizeBuffer()
 {
-	int nSamples = (int) sampleRate*bufferLength;
+	int nSamples = (int) getSampleRate()*bufferLength;
 	int nInputs = getNumInputs();
 
 	std::cout << "Resizing buffer. Samples: " << nSamples << ", Inputs: " << nInputs << std::endl;
@@ -132,6 +100,7 @@ void LfpDisplayNode::setParameter (int parameterIndex, float newValue)
 void LfpDisplayNode::process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples)
 {
 	// 1. place any new samples into the displayBuffer
+
 	int samplesLeft = displayBuffer->getNumSamples() - displayBufferIndex;
 
 	if (nSamples < samplesLeft)
diff --git a/Source/Processors/LfpDisplayNode.h b/Source/Processors/LfpDisplayNode.h
index a0555542c33170cf6b61d61973309558e84c5a83..8fb4439cd9614e7ed5b8998cd00b6c7c3dcee0db 100644
--- a/Source/Processors/LfpDisplayNode.h
+++ b/Source/Processors/LfpDisplayNode.h
@@ -26,6 +26,7 @@
 
 #include "../../JuceLibraryCode/JuceHeader.h"
 #include "Editors/LfpDisplayEditor.h"
+#include "Editors/VisualizerEditor.h"
 #include "GenericProcessor.h"
 
 /**
@@ -56,8 +57,7 @@ public:
 
 	void setParameter(int, float);
 
-	void setNumInputs(int inputs);
-	void setSampleRate(float r);
+	void updateSettings();
 
 	bool enable();
 	bool disable();
@@ -67,10 +67,8 @@ public:
 
 private:
 
-	DataViewport* dataViewport;
-
-	AudioSampleBuffer* displayBuffer;
-	MidiBuffer* eventBuffer;
+	ScopedPointer<AudioSampleBuffer> displayBuffer;
+	ScopedPointer<MidiBuffer> eventBuffer;
 
 	int displayBufferIndex;
 
diff --git a/Source/Processors/Parameter.cpp b/Source/Processors/Parameter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d68d52698f9b01ed637dbd326888d2b04a0c9824
--- /dev/null
+++ b/Source/Processors/Parameter.cpp
@@ -0,0 +1,203 @@
+
+/*    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "Parameter.h"
+
+
+Parameter::Parameter(const String& name_, bool defaultVal) 
+		: name(name_), description("")
+{
+
+	defaultValue = defaultVal;
+
+	possibleValues.add(true);
+	possibleValues.add(false);
+
+	isBool = true;
+	isCont = false;
+	isDisc = false;
+
+}
+
+Parameter::Parameter(const String& name_, float low, float high, float defaultVal)
+	 : name(name_), description("")
+{
+	defaultValue = defaultVal;
+
+	possibleValues.add(low);
+	possibleValues.add(high);
+
+	isCont = true;
+	isBool = false;
+	isDisc = false;
+
+}
+
+Parameter::Parameter(const String& name_, Array<var> a, int defaultVal)
+	 : name(name_), description("")
+{
+	possibleValues = a;
+	defaultValue = possibleValues[defaultVal];
+
+	isCont = false;
+	isDisc = true;
+	isBool = false;
+
+}
+
+
+void Parameter::setValue(float val, int chan)
+{
+	if (isBoolean())
+	{
+		if (val > 0.0f)
+			values.set(chan, true);
+		else
+			values.set(chan, false);
+	} 
+	else if (isContinuous()) {
+
+		if (val < (float) possibleValues[0])
+		{
+			values.set(chan, possibleValues[0]);
+		} else if (val > (float) possibleValues[1]) {
+			values.set(chan, possibleValues[1]);
+		} else {
+			values.set(chan, val);
+		}
+
+	} else {
+		int index = (int) val;
+
+		if (index >= 0 && index < possibleValues.size())
+		{
+			values.set(chan, possibleValues[index]);
+		}
+
+	}
+
+}
+
+// void BooleanParameter::setValue(float val, int chan)
+// {
+
+// 	var b = true;
+// 	bool c = b;
+
+// 	if (val > 0)
+// 		values.set(chan, true);
+// 	else
+// 		values.set(chan, false);
+
+// }
+
+// void ContinuousParameter::setValue(float val, int chan)
+// {
+// 	if (val < low)
+// 	{
+// 		values.set(chan, low);
+// 	} else if (val > high) {
+// 		values.set(chan, high);
+// 	} else {
+// 		values.set(chan, val);
+// 	}
+// }
+
+// void DiscreteParameter::setValue(float val, int chan)
+// {
+// 	int index = (int) val;
+
+// 	if (index >= 0 && index < possibleValues.size())
+// 	{
+// 		values.set(chan, possibleValues[index]);
+// 	}
+
+// }
+
+// Array<var> BooleanParameter::getPossibleValues()
+// {
+// 	Array<var> a;
+// 	a.add(true);
+// 	a.add(false);
+
+// 	return a;
+
+// }
+
+// Array<var> ContinuousParameter::getPossibleValues()
+// {
+// 	Array<var> a;
+// 	a.add(low);
+// 	a.add(high);
+
+// 	return a;
+// }
+
+// Array<var> DiscreteParameter::getPossibleValues()
+// {
+// 	return possibleValues;
+
+// }
+
+
+// void* BooleanParameter::operator[](int chan)
+// {
+// 	return (void*) values[chan];
+// }
+
+// void* ContinuousParameter::operator[](int chan)
+// {
+// 	return (void*) values[chan];
+// }
+
+
+// void* DiscreteParameter::operator[](int chan)
+// {
+// 	return (void*) values[chan];
+// }
+
+// BooleanParameter::BooleanParameter(const String name_, bool defaultVal) : Parameter(name_)
+// {
+// 	defaultValue = defaultVal;
+// }
+
+// ContinuousParameter::ContinuousParameter(const String name_,
+// 										 float low_, float high_, float defaultVal)
+// 										 : Parameter(name_)
+// {
+// 	low = low_;
+// 	high = high_;
+
+// 	defaultValue = defaultVal;
+
+// }
+
+// DiscreteParameter::DiscreteParameter(const String name_,
+// 									 Array<var> a, int defaultVal)
+// 										 : Parameter(name_)
+// {
+// 	possibleValues = a;
+
+// 	defaultValue = possibleValues[defaultVal];
+// }
+
diff --git a/Source/Processors/Parameter.h b/Source/Processors/Parameter.h
new file mode 100644
index 0000000000000000000000000000000000000000..89a2c352e13cffa27934af2e0a3d1ff2f93f320c
--- /dev/null
+++ b/Source/Processors/Parameter.h
@@ -0,0 +1,161 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef __PARAMETER_H_62922AE5__
+#define __PARAMETER_H_62922AE5__
+
+#include "../../JuceLibraryCode/JuceHeader.h"
+// #include "Editors/GenericEditor.h"
+// #include "GenericProcessor.h"
+// #include "../AccessClass.h"
+
+#include <stdio.h>
+
+/**
+  
+  Class for holding user-definable processor parameters.
+
+  @see GenericProcessor, GenericEditor
+
+*/
+
+class Parameter
+{
+public:
+
+	Parameter(const String& name_, bool defaultVal);
+	Parameter(const String& name_, float low, float high, float defaultVal);
+	Parameter(const String& name_, Array<var> a, int defaultVal);
+
+	~Parameter() {}
+
+	const String& getName() {return name;}
+	const String& getDescription() {return description;}
+	void addDescription(const String& desc) {description = desc;}
+
+	Array<var> getPossibleValues() {return possibleValues;}
+	void setValue(float val, int chan);
+
+	var operator[](int chan) {return values[chan];}
+	Parameter& operator=(const Parameter& other);
+
+	bool isBoolean() {return isBool;}
+	bool isContinuous() {return isCont;}
+	bool isDiscrete() {return isDisc;}
+
+private:
+
+
+	const String name;
+	String description;
+
+	bool isBool, isCont, isDisc;
+
+	var defaultValue;
+	Array<var> values;
+	Array<var> possibleValues;
+
+};
+
+// class BooleanParameter : public Parameter
+// {
+// public:
+// 	BooleanParameter(const String name_, bool defaultVal);
+// 	~BooleanParameter() {}
+
+// 	Array<var> getPossibleValues();
+// 	void setValue(float val, int chan);
+// 	void* operator[](int chan);
+
+// 	bool isBoolean() {return true;}
+
+// 	bool defaultValue;
+
+// 	Array<bool> values;
+
+// };
+
+// class ContinuousParameter : public Parameter
+// {
+// public:
+// 	ContinuousParameter(const String name_, float low, float high, float defaultVal);
+// 	~ContinuousParameter() {}
+
+// 	Array<var> getPossibleValues();
+// 	void setValue(float val, int chan);
+// 	void* operator[](int chan);
+
+// 	bool isContinuous() {return true;}
+
+// 	float low, high, defaultValue;
+
+// 	Array<float> values;
+
+// };
+
+
+// class DiscreteParameter : public Parameter
+// {
+// public:
+// 	DiscreteParameter(const String name_, Array<var> a, int defaultVal);
+// 	~DiscreteParameter() {}
+
+// 	Array<var> getPossibleValues();
+// 	void setValue(float val, int chan);
+// 	void* operator[](int chan);
+
+// 	bool isDiscrete() {return true;}
+
+// 	Array<var> possibleValues;
+// 	Array<var> values;
+
+// 	int defaultValue;
+// };
+
+
+// template <class Type>
+
+// class Parameter
+// {
+// public:
+// 	Parameter(const String& name_,
+// 			  Type defaultVal,
+// 			  Array<var> possibleVals = Array<var>()) :
+// 			   name(name_), defaultValue(defaultVal), possibleValues(possibleVals)
+// 	{
+
+// 	}
+
+// 	Type operator[](int chan) {return values[chan];}
+
+// private:
+
+// 	const String name;
+// 	Type defaultValue;
+// 	Array<Type> values;
+// 	Array<var> possibleValues;
+
+// };
+
+
+#endif  // __PARAMETER_H_62922AE5__
diff --git a/Source/Processors/ProcessorGraph.cpp b/Source/Processors/ProcessorGraph.cpp
index ce3c7717aa5a2f21260ecda27de066548fd0313b..b690742cd4c8d816e04c9b313da5954c7f0a0de2 100644
--- a/Source/Processors/ProcessorGraph.cpp
+++ b/Source/Processors/ProcessorGraph.cpp
@@ -27,8 +27,8 @@
 
 #include "AudioNode.h"
 #include "LfpDisplayNode.h"
+#include "SpikeDisplayNode.h"
 #include "EventNode.h"
-#include "FileReader.h"
 #include "FilterNode.h"
 #include "GenericProcessor.h"
 #include "RecordNode.h"
@@ -40,21 +40,12 @@
 #include "Utilities/Splitter.h"
 #include "Utilities/Merger.h"
 #include "../UI/UIComponent.h"
-#include "../UI/Configuration.h"
 #include "../UI/EditorViewport.h"
 
-ProcessorGraph::ProcessorGraph() : 
-	currentNodeId(100),
-	RECORD_NODE_ID(199), 
-	AUDIO_NODE_ID(200), 
-	OUTPUT_NODE_ID(201), 
-	RESAMPLING_NODE_ID(202)
-	//totalAudioConnections(0),
-	//totalRecordConnections(0)
-	
+ProcessorGraph::ProcessorGraph() : currentNodeId(100)	
 	{
 
-	// ProcessorGraph will always have 0 inputs (all content is generated within graph)
+	// The ProcessorGraph will always have 0 inputs (all content is generated within graph)
 	// but it will have N outputs, where N is the number of channels for the audio monitor
 	setPlayConfigDetails(0, // number of inputs
 				         2, // number of outputs
@@ -78,12 +69,10 @@ void ProcessorGraph::createDefaultNodes()
 	// add record node -- sends output to disk
 	RecordNode* recn = new RecordNode();
 	recn->setNodeId(RECORD_NODE_ID);
-	//recn->setConfiguration(config);
 
 	// add audio node -- takes all inputs and selects those to be used for audio monitoring
 	AudioNode* an = new AudioNode();
 	recn->setNodeId(AUDIO_NODE_ID);
-	//an->setConfiguration(config);
 
 	// add resampling node -- resamples continuous signals to 44.1kHz
 	ResamplingNode* rn = new ResamplingNode(true);
@@ -94,7 +83,7 @@ void ProcessorGraph::createDefaultNodes()
 	addNode(an, AUDIO_NODE_ID);
 	addNode(rn, RESAMPLING_NODE_ID);
 
-	// connect audio network
+	// connect audio subnetwork
 	for (int n = 0; n < 2; n++) {
 		
 		addConnection(AUDIO_NODE_ID, n,
@@ -150,22 +139,22 @@ void ProcessorGraph::clearConnections()
 		 {
 		 	; // leave it   	
 		 } else {
-
-		 	Node* node = getNodeForId(connection->sourceNodeId);
-		 	GenericProcessor* p =(GenericProcessor*) node->getProcessor();
-		 	//if (p->getNextChannel(false) > 0)
-		 		p->resetConnections();
-
-		 	node = getNodeForId(connection->destNodeId);
-		 	p =(GenericProcessor*) node->getProcessor();
-		 	//if (p->getNextChannel(false) > 0)
-		 		p->resetConnections();
-
 		 	removeConnection(i);
 		 }
 	}
+
+	for (int i = 0; i < getNumNodes(); i++)
+	{
+		 Node* node = getNode(i);
+
+		 if (node->nodeId != OUTPUT_NODE_ID) {
+			 GenericProcessor* p =(GenericProcessor*) node->getProcessor();
+			 p->resetConnections();
+		}
+	}
 }
 
+
 void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSection> tabs)
 {
 	clearConnections(); // clear processor graph
@@ -208,8 +197,6 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
 			{
 
 				// add the connections to audio and record nodes if necessary
-
-
 				if (!(source->isSink() ||
 				      source->isSplitter() || source->isMerger()) && !(source->wasConnected))
 				{
@@ -217,18 +204,38 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
 
 					for (int chan = 0; chan < source->getNumOutputs(); chan++) {
 
-						addConnection(source->getNodeId(), // sourceNodeID
-						  	chan, // sourceNodeChannelIndex
-						   	AUDIO_NODE_ID, // destNodeID
+						//getAudioNode()->addInputChannel(source, chan);
+
+						addConnection(source->getNodeId(), 		   // sourceNodeID
+						  	chan, 						           // sourceNodeChannelIndex
+						   	AUDIO_NODE_ID, 					       // destNodeID
 						  	getAudioNode()->getNextChannel(true)); // destNodeChannelIndex
 
-						addConnection(source->getNodeId(), // sourceNodeID
-						  	chan, // sourceNodeChannelIndex
-						   	RECORD_NODE_ID, // destNodeID
+						
+						//std::cout << getAudioNode()->getNextChannel(false) << " ";
+
+						getRecordNode()->addInputChannel(source, chan);
+
+						addConnection(source->getNodeId(),          // sourceNodeID
+						  	chan,                                   // sourceNodeChannelIndex
+						   	RECORD_NODE_ID, 					    // destNodeID
 						  	getRecordNode()->getNextChannel(true)); // destNodeChannelIndex
+					
+						
 					}
+
+					// connect event channel
+					addConnection(source->getNodeId(), 				// sourceNodeID
+					  	midiChannelIndex, 							// sourceNodeChannelIndex
+					   	RECORD_NODE_ID, 							// destNodeID
+					  	midiChannelIndex);							// destNodeChannelIndex
+
+					getRecordNode()->addInputChannel(source, midiChannelIndex);
+
 				}
 
+				std::cout << std::endl;
+
 				if (dest != 0) {
 
 					if (dest->enabledState())
@@ -241,12 +248,7 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
 
 						std::cout << "     Connecting " << source->getName() << " channel ";
 
-						//int nextChan;
-						//int chan = 0;
-
 						for (int chan = 0; chan < source->getNumOutputs(); chan++) 
-						
-						//ile ((nextChan = dest->getNextChannel(true)) != -1)
 						{
 							std::cout << chan << " ";
 							           
@@ -258,14 +260,15 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
 
 						std::cout << " to " << dest->getName() << std::endl;
 							
-							std::cout << "     Connecting " << source->getName() <<
-							           " event channel to " <<
-							           dest->getName() << std::endl;
-							// connect event channel
-							addConnection(source->getNodeId(), // sourceNodeID
-							  	midiChannelIndex, // sourceNodeChannelIndex
-							   	dest->getNodeId(), // destNodeID
-							  	midiChannelIndex); // destNodeChannelIndex
+						std::cout << "     Connecting " << source->getName() <<
+						           " event channel to " <<
+						           dest->getName() << std::endl;
+
+						// connect event channel
+						addConnection(source->getNodeId(), // sourceNodeID
+						  	midiChannelIndex, // sourceNodeChannelIndex
+						   	dest->getNodeId(), // destNodeID
+						  	midiChannelIndex); // destNodeChannelIndex
 
 					}
 
@@ -279,7 +282,7 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
 			{
 				dest = splitters.getFirst(); // dest is now the splitter
 				splitters.remove(0); // take it out of the 
-				dest->switchDest(); // switch to the other destination
+				dest->switchIO(); // switch to the other destination
 				dest->wasConnected = true; // don't want to re-add splitter
 				source = dest->getSourceNode(); // splitter is now source
 			}
@@ -288,15 +291,6 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
 	} // end "tabs" for loop
 } // end method
 
-// int ProcessorGraph::getNextFreeAudioChannel()
-// {
-// 	return totalAudioConnections++;
-// }
-
-// int ProcessorGraph::getNextFreeRecordChannel()
-// {
-// 	return totalRecordConnections++;
-// }
 
 GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& description)
 {
@@ -310,7 +304,8 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
 
 	if (processorType.equalsIgnoreCase("Sources")) {
 
-		if (subProcessorType.equalsIgnoreCase("Intan Demo Board")) {
+		if (subProcessorType.equalsIgnoreCase("Intan Demo Board") || 
+			subProcessorType.equalsIgnoreCase("File Reader")) {
 			
 			// only one Intan Demo Board at a time, please
 			if (!processorWithSameNameExists(subProcessorType)) {
@@ -329,7 +324,7 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
 		}
 
 		
-		sendActionMessage("New source node created.");
+		//sendActionMessage("New source node created.");
 		
 
 	} else if (processorType.equalsIgnoreCase("Filters")) {
@@ -347,7 +342,7 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
 			processor = new SpikeDetector();
 		}
 
-		sendActionMessage("New filter node created.");
+		//sendActionMessage("New filter node created.");
 
 	} else if (processorType.equalsIgnoreCase("Utilities")) {
 
@@ -356,14 +351,14 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
 			std::cout << "Creating a new splitter." << std::endl;
 			processor = new Splitter();
 
-			sendActionMessage("New splitter created.");
+		//	sendActionMessage("New splitter created.");
 
 	 	} else if (subProcessorType.equalsIgnoreCase("Merger")) {
 	 		
 	 		std::cout << "Creating a new merger." << std::endl;
 			processor = new Merger();
 
-			sendActionMessage("New merger created.");
+		//	sendActionMessage("New merger created.");
 
 	 	}
 
@@ -376,12 +371,17 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
 		   // std::cout << "Graph data viewport: " << UI->getDataViewport() << std::endl;
 			// processor->setDataViewport(getDataViewport());
 			//processor->setUIComponent(UI);
-		} else if (subProcessorType.equalsIgnoreCase("WiFi Output")) {
+		} 
+		else if (subProcessorType.equalsIgnoreCase("Spike Viewer")) {
+			std::cout << "Creating an SpikeDisplayNode." << std::endl;
+			processor = new SpikeDisplayNode();	 
+		}
+		else if (subProcessorType.equalsIgnoreCase("WiFi Output")) {
 			std::cout << "Creating a WiFi node." << std::endl;
 			processor = new WiFiOutput();
 		}
 	
-		sendActionMessage("New sink created.");
+		//sendActionMessage("New sink created.");
 	}
 
 	return processor;
@@ -403,6 +403,7 @@ bool ProcessorGraph::processorWithSameNameExists(const String& name)
 
 }
 
+
 void ProcessorGraph::removeProcessor(GenericProcessor* processor) {
 	
 	std::cout << "Removing processor with ID " << processor->getNodeId() << std::endl;
@@ -411,27 +412,6 @@ void ProcessorGraph::removeProcessor(GenericProcessor* processor) {
 
 }
 
-// void ProcessorGraph::setUIComponent(UIComponent* ui)
-// {
-// 	UI = ui;
-// }
-
-// void ProcessorGraph::setFilterViewport(FilterViewport* fv)
-// {
-// 	filterViewport = fv;
-// }
-
-// void ProcessorGraph::setMessageCenter(MessageCenter* mc)
-// {
-// 	messageCenter = mc;
-// }
-
-// void ProcessorGraph::setConfiguration(Configuration* c)
-// {
-// 	config = c;
-// }
-
-
 bool ProcessorGraph::enableProcessors() {
 
 	updateConnections(getEditorViewport()->requestSignalChain());
@@ -458,7 +438,7 @@ bool ProcessorGraph::enableProcessors() {
 
 			if (!allClear) {
 				std::cout << p->getName() << " said it's not OK." << std::endl;
-				sendActionMessage("Could not initialize acquisition.");
+			//	sendActionMessage("Could not initialize acquisition.");
 				getUIComponent()->disableCallbacks();
 				return false;
 
@@ -480,7 +460,7 @@ bool ProcessorGraph::enableProcessors() {
 	
 	getEditorViewport()->signalChainCanBeEdited(false);
 
-	sendActionMessage("Acquisition started.");
+//	sendActionMessage("Acquisition started.");
 
 	return true;
 }
@@ -501,7 +481,7 @@ bool ProcessorGraph::disableProcessors() {
 			allClear = p->disable();
 
 			if (!allClear) {
-				sendActionMessage("Could not stop acquisition.");
+			//	sendActionMessage("Could not stop acquisition.");
 				return false;
 			}
 		}
@@ -509,7 +489,7 @@ bool ProcessorGraph::disableProcessors() {
 
 	getEditorViewport()->signalChainCanBeEdited(true);
 
-	sendActionMessage("Acquisition ended.");
+//	sendActionMessage("Acquisition ended.");
 
 	return true;
 }
diff --git a/Source/Processors/ProcessorGraph.h b/Source/Processors/ProcessorGraph.h
index 279ae740665397680f3415ed47fc706a67241577..914a574e884c637e0ad27a4757ae91ecc35bdc5f 100644
--- a/Source/Processors/ProcessorGraph.h
+++ b/Source/Processors/ProcessorGraph.h
@@ -45,13 +45,8 @@
 
 class GenericProcessor;
 class RecordNode;
-class SignalChainTabButton;
 class AudioNode;
-//class SourceNode;
-//class EditorViewport;
-//class UIComponent;
-//class Configuration;
-//class MessageCenter;
+class SignalChainTabButton;
 
 class ProcessorGraph : public AudioProcessorGraph,
 					   public AccessClass
@@ -71,11 +66,6 @@ public:
 	RecordNode* getRecordNode();
 	AudioNode* getAudioNode();
 
-	//void setUIComponent(UIComponent* ui);
-	//void setFilterViewport(FilterViewport *fv);
-	//void setMessageCenter(MessageCenter* mc);
-	//void setConfiguration(Configuration* config);
-
 	void updateConnections(Array<SignalChainTabButton*, CriticalSection>);
 
 	bool processorWithSameNameExists(const String& name);
@@ -83,31 +73,21 @@ public:
 	void saveState();
 	void loadState();
 
-	//int getNextFreeAudioChannel();
-	//int getNextFreeRecordChannel();
-
 private:	
 
 	int currentNodeId;
 
-	Array<int> source_node_IDs;
-
-	const int RECORD_NODE_ID;
-	const int AUDIO_NODE_ID;
-	const int OUTPUT_NODE_ID;
-	const int RESAMPLING_NODE_ID;
+	enum nodeIds
+	{
+		RECORD_NODE_ID = 900,
+		AUDIO_NODE_ID = 901,
+		OUTPUT_NODE_ID = 902,
+		RESAMPLING_NODE_ID = 903
+	};
 
 	void createDefaultNodes();
 	void clearConnections();
 
-	//UIComponent* UI;
-	//FilterViewport* filterViewport;
-	///Configuration* config;
-	//MessageCenter* messageCenter;
-
-	//int totalAudioConnections;
-	//int totalRecordConnections;
-
 };
 
 
diff --git a/Source/Processors/RecordNode.cpp b/Source/Processors/RecordNode.cpp
index 25d01f1ef9b124b2b3e250923e7885445b77041a..eb4d13d03ff4549f70fd5cfda9091cfb221bc607 100644
--- a/Source/Processors/RecordNode.cpp
+++ b/Source/Processors/RecordNode.cpp
@@ -22,17 +22,16 @@
 */
 
 #include "RecordNode.h"
+#include "ProcessorGraph.h"
 
 RecordNode::RecordNode()
-	: GenericProcessor("Record Node"), isRecording(false)
+	: GenericProcessor("Record Node"), isRecording(false), isProcessing(false)
 {
 
-	// need to update this:
-	setPlayConfigDetails(64,0,44100.0,128);
+	dataFolder = "./Data";
+
+	continuousDataBuffer = new int16[10000];
 
-	//utputFile = File("./data"); // create output file
-	//outputStream = 0;
-	
 }
 
 
@@ -40,20 +39,173 @@ RecordNode::~RecordNode() {
 
 }
 
+void RecordNode::setChannel(int id, int chan)
+{
+
+	std::cout << "Record node setting channel." << std::endl;
+
+	for (int i = 0; i < continuousChannels.size(); i++)
+	{
+
+		if (continuousChannels[i].nodeId == id &&
+			continuousChannels[i].chan == chan)
+		{
+			std::cout << "Found channel " << i << std::endl;
+			setCurrentChannel(i);
+			break;
+		}
+
+	}
+}
+
+void RecordNode::resetConnections()
+{
+	//std::cout << "Resetting connections" << std::endl;
+	nextAvailableChannel = 0;
+	wasConnected = false;
+
+	continuousChannels.clear();
+	eventChannels.clear();
+}
+
+
+void RecordNode::addInputChannel(GenericProcessor* sourceNode, int chan)
+{
+
+	if (chan != getProcessorGraph()->midiChannelIndex)
+	{
+		Channel newChannel;
+
+		std::cout << "Record node adding channel." << std::endl;
+
+		newChannel.nodeId = sourceNode->getNodeId();
+		newChannel.chan = chan;
+		newChannel.name = sourceNode->getOutputChannelName(chan);
+		newChannel.isRecording = sourceNode->recordStatus(chan);
+
+		String filename = dataFolder;
+		filename += "/";
+		filename += newChannel.nodeId;
+		filename += "_";
+		filename += newChannel.name;
+		filename += ".continuous";
+
+		newChannel.filename = filename;
+		newChannel.file = 0; 
+
+		if (newChannel.isRecording)
+			std::cout << "  This channel will be recorded." << std::endl;
+		else 
+			std::cout << "  This channel will NOT be recorded." << std::endl;
+	
+		std::cout << "adding channel " << getNextChannel(false) << std::endl;
+
+		std::pair<int, Channel> newPair (getNextChannel(false), newChannel);
+
+		continuousChannels.insert(newPair);
+
+		setPlayConfigDetails(getNextChannel(false)+1,0,44100.0,128);
+
+	} else {
+
+
+		std::map<int, Channel> eventChans;
+
+		int ID = sourceNode->getNodeId();
+
+		for (int n = 0; n < sourceNode->settings.eventChannelIds.size(); n++)
+		{
+
+			Channel newChannel;
+
+			newChannel.nodeId = ID;
+			newChannel.chan = sourceNode->settings.eventChannelIds[n];
+			newChannel.name = sourceNode->settings.eventChannelNames[n];
+			newChannel.isRecording = true;
+			newChannel.file = 0;
+
+			std::pair<int, Channel> newPair (newChannel.chan, newChannel);
+
+			eventChans.insert(newPair);
+
+		}
+
+		std::pair<int, std::map<int, Channel> > newPair (ID, eventChans);
+
+		eventChannels.insert(newPair);
+
+	}
+
+}
+
 
 void RecordNode::setParameter (int parameterIndex, float newValue)
 {
  	if (parameterIndex == 1) {
+
  		isRecording = true;
- 	} else {
+ 		std::cout << "START RECORDING." << std::endl;
+
+ 		// create / open necessary files
+ 		for (int i = 0; i < continuousChannels.size(); i++)
+ 		{
+ 			if (continuousChannels[i].isRecording)
+ 			{
+ 				std::cout << "OPENING FILE: " << continuousChannels[i].filename << std::endl;
+ 				continuousChannels[i].file = fopen(continuousChannels[i].filename.toUTF8(), "a");
+ 			}
+ 		}
+ 		
+
+ 	} else if (parameterIndex == 0) {
+
+
  		isRecording = false;
+ 		std::cout << "STOP RECORDING." << std::endl;
+
+ 		// close necessary files
+ 		for (int i = 0; i < continuousChannels.size(); i++)
+ 		{
+ 			if (continuousChannels[i].isRecording)
+ 			{
+ 				std::cout << "CLOSING FILE: " << continuousChannels[i].filename << std::endl;
+ 				fclose(continuousChannels[i].file);
+ 			}
+ 		}
+
+ 		// close necessary files
+ 	} else if (parameterIndex == 2) {
+
+ 		if (isProcessing) {
+
+ 			std::cout << "Toggling channel " << currentChannel << std::endl;
+
+	 		if (newValue == 0.0f) {
+	 			continuousChannels[currentChannel].isRecording = false;
+
+	 			if (isRecording) {
+	 				std::cout << "CLOSING FILE: " << continuousChannels[currentChannel].filename << std::endl;
+	 				fclose(continuousChannels[currentChannel].file);
+	 			}
+
+	 		}
+	 		else {
+	 			continuousChannels[currentChannel].isRecording = true;
+
+	 			if (isRecording) {
+	 				std::cout << "OPENING FILE: " << continuousChannels[currentChannel].filename << std::endl;
+	 				continuousChannels[currentChannel].file = 
+	 					fopen(continuousChannels[currentChannel].filename.toUTF8(), "a");
+	 			}
+	 		}
+ 		}
  	}
 }
 
 bool RecordNode::enable()
 {
-	//outputStream = outputFile.createOutputStream();
 
+	isProcessing = true;
 	return true;
 }
 
@@ -61,19 +213,52 @@ bool RecordNode::enable()
 bool RecordNode::disable() 
 {	
 	
-	// if (outputStream != 0) {
-	// 	outputStream->flush();
+	// close files if necessary
+	setParameter(0, 10.0f);
 
-	// 	delete(outputStream);
-	// 	outputStream = 0;
-	// }
+	isProcessing = false;
 
 	return true;
 }
 
 float RecordNode::getFreeSpace()
 {
-	return (1.0f-float(outputFile.getBytesFreeOnVolume())/float(outputFile.getVolumeTotalSize()));
+	// this needs to be updated:
+
+	return 0.5;
+	//return (1.0f-float(outputFile.getBytesFreeOnVolume())/float(outputFile.getVolumeTotalSize()));
+}
+
+void RecordNode::writeContinuousBuffer(float* data, int nSamples, int channel)
+{
+
+	// find file and write samples to disk
+
+	AudioDataConverters::convertFloatToInt16BE(data, continuousDataBuffer, nSamples);
+
+	//int16 samps = nSamples;
+
+	fwrite(&timestamp,							// ptr
+			   8,   							// size of each element
+			   1, 		  						// count 
+			   continuousChannels[channel].file);   // ptr to FILE object
+
+	fwrite(&nSamples,								// ptr
+			   sizeof(nSamples),   				// size of each element
+			   1, 		  						// count 
+			   continuousChannels[channel].file);   // ptr to FILE object
+
+	int n = fwrite(continuousDataBuffer,			// ptr
+			   2,			     					// size of each element
+			   nSamples, 		  					// count 
+			   continuousChannels[channel].file);   // ptr to FILE object
+	// n must equal "count", otherwise there was an error
+}
+ 
+void RecordNode::writeEventBuffer(MidiMessage& event, int node, int channel)
+{
+	// find file and write samples to disk
+
 }
 
 void RecordNode::process(AudioSampleBuffer &buffer, 
@@ -84,17 +269,32 @@ void RecordNode::process(AudioSampleBuffer &buffer,
 	//std::cout << "Record node processing block." << std::endl;
 	//std::cout << "Num channels: " << buffer.getNumChannels() << std::endl;
 
+	timestamp = timer.getHighResolutionTicks();
+
 	if (isRecording) {
 
-		//int nSamps = getNumSamples(midiMessages);
+		buffer.applyGain(0, nSamples, 0.1);
+
+		// cycle through events -- extract the samples per channel
+
+
+		// cycle through buffer channels
+		for (int i = 0; i < buffer.getNumChannels(); i++)
+		{
+
+			if (continuousChannels[i].isRecording)
+			{
+				// write buffer to disk!
+				writeContinuousBuffer(buffer.getSampleData(i),
+									  nSamples,
+									  i);
+				
+				//std::cout << "Record channel " << i << std::endl;
+			}
+				
 
-		for (int n = 0; n < nSamples; n++) {
-		
-			float* sample = buffer.getSampleData(1,n);
-			outputStream->writeFloat(*sample);
-			//AudioDataConverters::convertFloatToInt16BE(&sample)
-			//);
 		}
+
 	}
 
 }
diff --git a/Source/Processors/RecordNode.h b/Source/Processors/RecordNode.h
index f4c9b54b45f4b8c6d18134047c726790b2676eb5..c129f6eb6c5b6d502d0ee8810b35e3c98d877e61 100644
--- a/Source/Processors/RecordNode.h
+++ b/Source/Processors/RecordNode.h
@@ -27,6 +27,7 @@
 
 #include "../../JuceLibraryCode/JuceHeader.h"
 #include <stdio.h>
+#include <map>
 
 #include "GenericProcessor.h"
 
@@ -51,21 +52,51 @@ public:
 	RecordNode();
 	~RecordNode();
 	
-	void process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples);
+	void process(AudioSampleBuffer &buffer, MidiBuffer &eventBuffer, int& nSamples);
 
 	void setParameter (int parameterIndex, float newValue);
 
+  void addInputChannel(GenericProcessor* sourceNode, int chan);
+
 	bool enable();
 	bool disable();
 
 	float getFreeSpace();
+
+  void setChannel(int id, int chan);
+
+  void resetConnections();
 	
 private:
-
-	File outputFile;
+	
+  File headerFile;
 	FileOutputStream* outputStream;
 
-	bool isRecording;
+	bool isRecording, isProcessing;
+
+  String dataFolder;
+
+  int16* continuousDataBuffer;
+
+  int64 timestamp;
+
+  Time timer;
+
+  struct Channel
+  {
+    int nodeId;
+    int chan;
+    String name;
+    bool isRecording;
+    String filename;
+    FILE* file;
+  };
+
+  std::map<int, Channel> continuousChannels;
+  std::map<int, std::map<int,Channel> > eventChannels;
+
+  void writeContinuousBuffer(float* data, int nSamples, int channel);
+  void writeEventBuffer(MidiMessage& event, int node, int channel);
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RecordNode);
 
diff --git a/Source/Processors/ResamplingNode.cpp b/Source/Processors/ResamplingNode.cpp
index 1c17cdd5ce37359d78375eabd6e98efd1313c98c..9e66626244f52a6e67ebf88ee831c029dbc7eacc 100644
--- a/Source/Processors/ResamplingNode.cpp
+++ b/Source/Processors/ResamplingNode.cpp
@@ -33,11 +33,11 @@ ResamplingNode::ResamplingNode(bool destBufferType)
 	
 {
 
-	setNumInputs(2);
-	setNumOutputs(2);
+	settings.numInputs = 2;
+	settings.numOutputs = 2;
 
-		setPlayConfigDetails(2, // number of inputs
-				         2, // number of outputs
+	setPlayConfigDetails(getNumInputs(), // number of inputs
+				         getNumOutputs(), // number of outputs
 				         44100.0, // sampleRate
 				         128);    // blockSize
 
diff --git a/Source/Processors/SignalGenerator.cpp b/Source/Processors/SignalGenerator.cpp
index 08093b35b4b8e70368bfb8d027252c8b3069240e..35b192f4566c04c81f93b3a0800477ffaaf44c90 100644
--- a/Source/Processors/SignalGenerator.cpp
+++ b/Source/Processors/SignalGenerator.cpp
@@ -23,69 +23,56 @@
 
 
 #include "SignalGenerator.h"
-//#include "SourceNodeEditor.h"
 #include <stdio.h>
+#include <math.h>
 
 SignalGenerator::SignalGenerator()
 	: GenericProcessor("Signal Generator"),
 
 	  defaultFrequency(10.0),
-	  defaultAmplitude (0.02f)
+	  defaultAmplitude (0.02f),
+	  nOut(1)
 	
 {
 
-	setNumOutputs(10);
-	setNumInputs(0);
+	// const String n = "Test";
 
+	Parameter p = Parameter("Bill",true);
 
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
+	p.setValue(0.0f, 0);
+	bool a = p[0];
 
+	parameters.add(p);
 
-}
 
-SignalGenerator::~SignalGenerator()
-{
-	//config->removeDataSource(this);	
 }
 
 
-// void SignalGenerator::setConfiguration(Configuration* cf)
-// {
-// 	config = cf;
-
-//      DataSource* d = new DataSource(this, config);
+SignalGenerator::~SignalGenerator()
+{
 
-// 	 // add a new data source to this configuration
-//      config->addDataSource(d);
+}
 
-// }
 
 AudioProcessorEditor* SignalGenerator::createEditor( )
 {
-	SignalGeneratorEditor* ed = new SignalGeneratorEditor(this);
-	setEditor(ed);
-	
-	std::cout << "Creating editor." << std::endl;
-	//filterEditor = new FilterEditor(this);
-	return ed;
+	editor = new SignalGeneratorEditor(this);
+	return editor;
 }
 
-void SignalGenerator::updateParameters()
+void SignalGenerator::updateSettings()
 {
 
-	std::cout << "Signal generator updating parameters" << std::endl;
-
-	frequencies.clear();
-	amplitudes.clear();
-	currentPhase.clear();
-	phasePerSample.clear();
+	//std::cout << "Signal generator updating parameters" << std::endl;
 
-	for (int n = 0; n < getNumOutputs(); n++)
+	while (waveformType.size() < getNumOutputs())
 	{
-		frequencies.add(defaultFrequency*n);
-		amplitudes.add(defaultAmplitude);
+		waveformType.add(NOISE);
+		frequency.add(defaultFrequency);
+		amplitude.add(defaultAmplitude);
+		phase.add(0);
+		phasePerSample.add(double_Pi * 2.0 / (getSampleRate() / frequency.getLast()));
 		currentPhase.add(0);
-		phasePerSample.add(double_Pi * 2.0 / (getSampleRate() / frequencies[n]));
 	}
 
 }
@@ -96,11 +83,17 @@ void SignalGenerator::setParameter (int parameterIndex, float newValue)
 
 	if (currentChannel > -1) {
 		if (parameterIndex == 0) {
-			amplitudes.set(currentChannel,newValue);
-		} else {
-			frequencies.set(currentChannel,newValue);
-			phasePerSample.set(currentChannel, double_Pi * 2.0 / (sampleRate / frequencies[currentChannel]));
+			amplitude.set(currentChannel,newValue);
+		} else if (parameterIndex == 1) {
+			frequency.set(currentChannel,newValue);
+			phasePerSample.set(currentChannel, double_Pi * 2.0 / (getSampleRate() / frequency[currentChannel]));
+		} else if (parameterIndex == 2) {
+			phase.set(currentChannel, newValue/360.0f * (double_Pi * 2.0));
+		} else if (parameterIndex == 3) {
+			waveformType.set(currentChannel, (int) newValue);
 		}
+
+		//updateWaveform(currentChannel);
 	}
 
 }
@@ -109,9 +102,57 @@ void SignalGenerator::setParameter (int parameterIndex, float newValue)
 bool SignalGenerator::enable () {
 
 	std::cout << "Signal generator received enable signal." << std::endl;
+	
+	// for (int n = 0; n < waveformType.size(); n++)
+	// {
+	// 	updateWaveform(n);
+		
+	// }
+
 	return true;
 }
 
+// void SignalGenerator::updateWaveform(int n)
+// {
+
+	// Array<float> cycleData;
+
+	// int cycleLength = int(getSampleRate() / frequency[n]);
+	// float phasePerSample = double_Pi * 2.0 / (getSampleRate() / frequency[n]);
+
+	// cycleData.ensureStorageAllocated(cycleLength);
+
+	// for (int i = 0; i < cycleLength; i++)
+	// {
+	// 	switch (waveformType[n])
+	// 	{
+	// 		case SINE:
+	// 			cycleData.add(amplitude[n] * std::sin(i*phasePerSample + phase[n]));
+	// 			break;
+	// 		case SQUARE:
+	// 			cycleData.add(amplitude[n] * copysign(1,std::sin(i*phasePerSample + phase[n])));
+	// 			break;
+	// 		case TRIANGLE:
+	// 			cycleData.add(0);
+	// 			break;
+	// 		case SAW:
+	// 			cycleData.add(0);
+	// 			break;
+	// 		case NOISE:
+	// 			cycleData.add(0);
+	// 			break;
+	// 		default:
+	// 			cycleData.set(i, 0);
+	// 	}
+
+	// }
+
+	// waveforms.set(n, cycleData);
+
+	// currentSample.set(n,0);
+
+// }
+
 bool SignalGenerator::disable() {
 	
 	std::cout << "Signal generator received disable signal." << std::endl;
@@ -123,18 +164,111 @@ void SignalGenerator::process(AudioSampleBuffer &buffer,
                             int& nSamps)
 {
 
-	//std::cout << buffer.getNumChannels() << std::endl;
 	nSamps = buffer.getNumSamples();
-	
+
     for (int i = 0; i < nSamps; ++i)
     {
         for (int j = buffer.getNumChannels(); --j >= 0;) {
+
+        	float sample;
+
+        	switch (waveformType[j])
+        	{
+        		case SINE:
+        			sample = amplitude[j] * (float) std::sin (currentPhase[j] + phase[j]);
+   					break;
+				case SQUARE:
+					sample = amplitude[j] * copysign(1,std::sin(currentPhase[j] + phase[j]));
+					break;
+				case TRIANGLE:
+					sample = amplitude[j] * ((currentPhase[j] + phase[j]) / double_Pi - 1) *
+							copysign(2,std::sin(currentPhase[j] + phase[j]));
+					break;
+				case SAW:
+					sample = amplitude[j] * ((currentPhase[j] + phase[j]) / double_Pi - 1);
+					break;
+				case NOISE:
+					sample = amplitude[j] * (float(rand()) / float(RAND_MAX)-0.5f);
+					break;
+				default:
+					sample = 0;
+        	}
         	
-        	const float sample = amplitudes[j] * (float) std::sin (currentPhase[j]);
        		currentPhase.set(j,currentPhase[j] + phasePerSample[j]);
 
+       		if (currentPhase[j] > double_Pi*2)
+       			currentPhase.set(j,0);
+
        		// dereference pointer to one of the buffer's samples
             *buffer.getSampleData (j, i) = sample;
         }
     }
+
+
+ 	
+
+	// for (int chan = 0; chan < buffer.getNumChannels(); chan++)
+	// {
+		
+	// 	int dataSize = waveforms[chan].size();
+	// 	int destSample = -dataSize;
+	// 	int lastSample = dataSize;
+
+	// 	while (lastSample < nSamps)
+	// 	{
+
+	// 		destSample += dataSize;
+
+	// 		//std::cout << lastSample << " " << destSample << " " << currentSample[chan] << " " << dataSize << std::endl;
+
+	// 		// buffer.copyFrom(chan, 
+	// 		//  				destSample, 
+	// 		//  				waveforms[chan].getRawDataPointer() + currentSample[chan], 
+	// 		//  				dataSize - currentSample[chan]);
+
+	// 		lastSample += dataSize;
+
+	// 		currentSample.set(chan,0);
+
+	// 		//std::cout << "DONE" << std::endl;
+	// 	}
+
+	// 	//std::cout << lastSample << " " << destSample << " " << currentSample[chan] << " " << dataSize << std::endl;
+
+	// 	if (destSample < 0)
+	// 		destSample = 0;
+
+	// 	int samplesLeft = nSamps - destSample;
+
+	// 	if (samplesLeft < dataSize - currentSample[chan])
+	// 	{
+	// 	 	// buffer.copyFrom(chan,
+	// 	 	// 			destSample,
+	// 	 	// 			waveforms[chan].getRawDataPointer() + currentSample[chan],
+	// 	 	// 			samplesLeft);
+
+	// 	 	currentSample.set(chan, currentSample[chan] + samplesLeft);
+
+	// 	} else {
+
+	// 		int samps = dataSize - currentSample[chan];
+
+	// 		// buffer.copyFrom(chan,
+	// 	 // 				destSample,
+	// 	 // 				waveforms[chan].getRawDataPointer() + currentSample[chan],
+	// 	 // 				samps);
+
+	// 		destSample += samps;
+	// 		samplesLeft -= samps;
+
+	// 		// buffer.copyFrom(chan,
+	// 	 // 				destSample,
+	// 	 // 				waveforms[chan].getRawDataPointer(),
+	// 	 // 				samplesLeft);
+
+	// 		currentSample.set(chan, samplesLeft);
+	// 	}
+
+	// }
+
 }
diff --git a/Source/Processors/SignalGenerator.h b/Source/Processors/SignalGenerator.h
index abf1036edcff43ff4d3530e60b87b19c2d2d53ed..4ce5f106ad645b0201f7dad263ee8b5684348d9f 100644
--- a/Source/Processors/SignalGenerator.h
+++ b/Source/Processors/SignalGenerator.h
@@ -31,7 +31,7 @@
 
 /**
 
-  Outputs 16 channels of sine wave data.
+  Outputs synthesized data of one of 5 different waveform types.
 
   @see GenericProcessor, SignalGeneratorEditor
 
@@ -49,8 +49,6 @@ public:
 
 	void setParameter (int parameterIndex, float newValue);
 
-	void setConfiguration(Configuration* cf);
-
 	float getSampleRate() {return 44100.0;}
 
 	AudioProcessorEditor* createEditor();
@@ -61,18 +59,30 @@ public:
 
 	bool isSource() {return true;}
 
-	void updateParameters();
+	void updateSettings();
+
+	int getDefaultNumOutputs() {return nOut;}
+
+	int nOut;
 
 private:
 	
 	double defaultFrequency;
 	double defaultAmplitude;
 
-	Array<double> frequencies;
-	Array<double> amplitudes;
-	Array<double> currentPhase;
-	Array<double> phasePerSample;
+	//void updateWaveform(int chan);
+
+	enum wvfrm
+	{
+		TRIANGLE, SINE, SQUARE, SAW, NOISE
+	};
 
+	Array<int> waveformType;
+	Array<double> frequency;
+	Array<double> amplitude;
+	Array<double> phase;
+	Array<double> phasePerSample;
+	Array<double> currentPhase;
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SignalGenerator);
 
diff --git a/Source/Processors/SourceNode.cpp b/Source/Processors/SourceNode.cpp
index fdbd4e1340fd2f8a95e361fd86ddf25dca346beb..e22db7a14f7720cc7b432ce45ef06bcb51293873 100644
--- a/Source/Processors/SourceNode.cpp
+++ b/Source/Processors/SourceNode.cpp
@@ -27,8 +27,8 @@
 
 SourceNode::SourceNode(const String& name_)
 	: GenericProcessor(name_),
-	  dataThread(0),
-	  sourceCheckInterval(750), wasDisabled(true)
+	  dataThread(0), inputBuffer(0),
+	  sourceCheckInterval(2000), wasDisabled(true)
 {
 	if (getName().equalsIgnoreCase("Intan Demo Board")) {
 		dataThread = new IntanThread(this);
@@ -38,17 +38,6 @@ SourceNode::SourceNode(const String& name_)
 		dataThread = new FileReaderThread(this);
 	}
 
-	setNumInputs(0);
-
-	if (dataThread != 0) {
-		setNumOutputs(dataThread->getNumChannels());
-		inputBuffer = dataThread->getBufferAddress();
-	} else {
-		setNumOutputs(10);
-	}
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
-
 	if (dataThread != 0)
 	{
 		if (!dataThread->foundInputSource())
@@ -59,17 +48,22 @@ SourceNode::SourceNode(const String& name_)
 		enabledState(false);
 	}
 
-	// check for input source every two seconds
+	// check for input source every few seconds
 	startTimer(sourceCheckInterval); 
 
 }
 
 SourceNode::~SourceNode() 
 {
-	if (dataThread != 0)
-		deleteAndZero(dataThread);
+}
+
+void SourceNode::updateSettings()
+{
+	if (inputBuffer == 0 && dataThread != 0)
+	{
+		inputBuffer = dataThread->getBufferAddress();
+	}
 
-	//config->removeDataSource(this);	
 }
 
 float SourceNode::getSampleRate()
@@ -108,30 +102,6 @@ void SourceNode::enabledState(bool t)
 
 }
 
-// void SourceNode::setConfiguration(Configuration* cf)
-// {
-// 	config = cf;
-
-//      DataSource* d = new DataSource(this, config);
-
-//   //   // add tetrodes -- should really be doing this dynamically
-//      d->addTrode(4, "TT1");
-//      d->addTrode(4, "TT2");
-//      d->addTrode(4, "TT3");
-//      d->addTrode(4, "TT4");
-
-//      for (int n = 0; n < d->numTetrodes(); n++)
-//       {
-//            std::cout << d->getTetrode(n)->getName();
-//       }
-//       std::cout << std::endl;
-
-// 	 // // add a new data source to this configuration
-//      config->addDataSource(d);
-
-// }
-
-
 void SourceNode::setParameter (int parameterIndex, float newValue)
 {
 	//std::cout << "Got parameter change notification";
@@ -139,11 +109,8 @@ void SourceNode::setParameter (int parameterIndex, float newValue)
 
 AudioProcessorEditor* SourceNode::createEditor()
 {
-	SourceNodeEditor* ed = new SourceNodeEditor(this);
-	setEditor(ed);
-	
-	std::cout << "Creating editor." << std::endl;
-	return ed;
+	editor = new SourceNodeEditor(this);
+	return editor;
 }
 
 void SourceNode::timerCallback()
@@ -154,16 +121,14 @@ void SourceNode::timerCallback()
 			std::cout << "Input source found." << std::endl;
 			//stopTimer(); // check for input source every two seconds
 			enabledState(true);
-			GenericEditor* ed = (GenericEditor*) getEditor();
-			//ed->enable();
+			GenericEditor* ed = getEditor();
 			getEditorViewport()->makeEditorVisible(ed);
 		}
 	} else {
 		if (isEnabled) {
 			std::cout << "No input source found." << std::endl;
 			enabledState(false);
-			GenericEditor* ed = (GenericEditor*) getEditor();
-			//ed->disable();
+			GenericEditor* ed = getEditor();
 			getEditorViewport()->makeEditorVisible(ed);
 		}
 	}
@@ -194,29 +159,6 @@ bool SourceNode::enable() {
 
 	stopTimer();
 
-	
-
-	// bool return_code = true;
-
-	// if (getName().equalsIgnoreCase("Intan Demo Board")) {
-		
-	// 	dataThread = new IntanThread();
-	// 	inputBuffer = dataThread->getBufferAddress();
-	// 	return_code = dataThread->threadStarted();
-
-	// 	if (!return_code)
-	// 		deleteAndZero(dataThread);
-
-	// } else if (getName().equalsIgnoreCase("Custom FPGA")) {
-	// 	dataThread = new FPGAThread();
-	// 	inputBuffer = dataThread->getBufferAddress();
-	// } else if (getName().equalsIgnoreCase("File Reader")) {
-	// 	dataThread = new FileReaderThread();
-	// 	inputBuffer = dataThread->getBufferAddress();
-	// }
-
-	// return return_code;
-
 }
 
 bool SourceNode::disable() {
@@ -250,22 +192,14 @@ void SourceNode::acquisitionStopped()
 }
 
 
-void SourceNode::process(AudioSampleBuffer &outputBuffer, 
-                            MidiBuffer &midiMessages,
+void SourceNode::process(AudioSampleBuffer &buffer, 
+                            MidiBuffer &events,
                             int& nSamples)
 {
-
-	//std::cout << "Source node processing." << std::endl;
-	//std::cout << outputBuffer.getNumChannels() << " " << outputBuffer.getNumSamples() << std::endl;
-
 	
-	 outputBuffer.clear();
-	 nSamples = inputBuffer->readAllFromBuffer(outputBuffer,outputBuffer.getNumSamples());
-	// //setNumSamples(numRead); // write the total number of samples
-	// setNumSamples(midiMessages, numRead);
-	//std::cout << numRead << std::endl;
-
-	//addMidiEvent(midiMessages,10, 10);
+	 buffer.clear();
+	 nSamples = inputBuffer->readAllFromBuffer(buffer,buffer.getNumSamples());
+	
 }
 
 
diff --git a/Source/Processors/SourceNode.h b/Source/Processors/SourceNode.h
index fd6664411f6dadfe73b6289313d229a58fe4ae44..03a6ef5ab15b90b32e34480e105751463f1a3004 100644
--- a/Source/Processors/SourceNode.h
+++ b/Source/Processors/SourceNode.h
@@ -53,22 +53,15 @@ public:
 	~SourceNode();
 
 	void enabledState(bool t);
-
-	//void setName(const String name_);
 	
 	void process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples);
 
 	void setParameter (int parameterIndex, float newValue);
 
-	void setConfiguration(Configuration* cf);
-
 	float getSampleRate();
 	float getDefaultSampleRate();
 	int getDefaultNumOutputs();
 
-	// void setSourceNode(GenericProcessor* sn);
-	// void setDestNode(GenericProcessor* dn);
-
 	AudioProcessorEditor* createEditor();
 	bool hasEditor() const {return true;}
 
@@ -87,12 +80,13 @@ private:
 
 	bool wasDisabled;
 
-	//const String name;
 	void timerCallback();
 
-	DataThread* dataThread;
+	ScopedPointer<DataThread> dataThread;
 	DataBuffer* inputBuffer;
 
+	void updateSettings();
+
 	int* numSamplesInThisBuffer;
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SourceNode);
diff --git a/Source/Processors/SpikeDetector.cpp b/Source/Processors/SpikeDetector.cpp
index ee47256cdad0bfe40a3b4b19134814eeb0ed6303..ff8dcef3bc3f69db7bbc76cdf3108a688901e741 100644
--- a/Source/Processors/SpikeDetector.cpp
+++ b/Source/Processors/SpikeDetector.cpp
@@ -25,163 +25,393 @@
 #include "SpikeDetector.h"
 
 SpikeDetector::SpikeDetector()
-    : GenericProcessor("Spike Detector"), 
-	  sampleRate (40000.0), threshold(5000.0), prePeakMs(0.2), postPeakMs(0.6),
-	  accumulator(0)
+    : GenericProcessor("Spike Detector"), overflowBufferSize(100),
+      overflowBuffer(2,100), dataBuffer(overflowBuffer)
 	
 {
 
-	spikeBuffer = new MidiBuffer();
+    electrodeTypes.add("hentrode");
+    electrodeTypes.add("duotrode");
+    electrodeTypes.add("triode");
+    electrodeTypes.add("tetrode");
+    electrodeTypes.add("pentrode");
+    electrodeTypes.add("hextrode");
+    electrodeTypes.add("heptrode");
+    electrodeTypes.add("octrode");
+    electrodeTypes.add("enneatrode");
+    electrodeTypes.add("decatrode");
+    electrodeTypes.add("hendecatrode");
+    electrodeTypes.add("dodecatrode");
+    electrodeTypes.add("triskaidecatrode");
+    electrodeTypes.add("tetrakaidecatrode");
+    electrodeTypes.add("pentakaidecatrode");
+    electrodeTypes.add("hexadecatrode");
+    electrodeTypes.add("heptakaidecatrode");
+    electrodeTypes.add("octakaidecatrode");
+    electrodeTypes.add("enneakaidecatrode");
+    electrodeTypes.add("icosatrode");
+
+    for (int i = 0; i < 21; i++)
+    {
+        electrodeCounter.add(0);
+    }
 
 }
 
 SpikeDetector::~SpikeDetector()
 {
-	deleteAndZero(spikeBuffer);
+
 }
 
 
 AudioProcessorEditor* SpikeDetector::createEditor()
 {
-
-	SpikeDetectorEditor* editor = new SpikeDetectorEditor(this);
-	
-	std::cout << "Creating editor." << std::endl;
-
-    setEditor(editor);
-
+	editor = new SpikeDetectorEditor(this);
 	return editor;
 }
 
-void SpikeDetector::setParameter (int parameterIndex, float newValue)
+void SpikeDetector::updateSettings()
 {
-	//std::cout << "Message received." << std::endl;
-	if (parameterIndex == 0) {
-		for (int n = 0; n < getNumOutputs(); n++)
-        {
-            thresh.set(n,newValue);
-        }
-	}
 
-}
+    overflowBuffer.setSize(getNumInputs(),overflowBufferSize);
 
+}
 
-bool SpikeDetector::enable()
+bool SpikeDetector::addElectrode(int nChans)
 {
-	//std::cout << "SpikeDetector node preparing." << std::endl;
-	prePeakSamples = int((prePeakMs / 1000.0f) / (1/getSampleRate()));
-	postPeakSamples = int((postPeakMs / 1000.0f) / (1/getSampleRate()));
+    int firstChan;
+
+    int currentVal = electrodeCounter[nChans];
+    electrodeCounter.set(nChans,++currentVal);
 
-    thresh.ensureStorageAllocated(getNumOutputs());
-    channels.ensureStorageAllocated(getNumOutputs());
-    nChans.ensureStorageAllocated(getNumOutputs());
-    isActive.ensureStorageAllocated(getNumOutputs());
-    lastSpike.ensureStorageAllocated(getNumOutputs());
+    String electrodeName = electrodeTypes[nChans-1];
+    String newName = electrodeName.substring(0,1);
+    newName = newName.toUpperCase();
+    electrodeName = electrodeName.substring(1,electrodeName.length());
+    newName += electrodeName;
+    newName += " ";
+    newName += electrodeCounter[nChans];
 
-    for (int n = 0; n < getNumOutputs(); n++)
+    if (electrodes.size() == 0)
     {
-        isActive.set(n,false);
-        lastSpike.set(n,-40);
+        firstChan = 0;
+    } else {
+        Electrode* e = electrodes.getLast();
+        firstChan = *(e->channels+(e->numChannels-1))+1;
     }
 
-    // check configuration
-    for (int ds = 0; ds < getConfiguration()->numDataSources(); ds++)
+    Electrode* newElectrode = new Electrode();
+
+    newElectrode->name = newName;
+    newElectrode->numChannels = nChans;
+    newElectrode->prePeakSamples = 8;
+    newElectrode->postPeakSamples = 32;
+    newElectrode->thresholds = new double[nChans];
+    newElectrode->isActive = new bool[nChans];
+    newElectrode->channels = new int[nChans];
+
+    for (int i = 0; i < nChans; i++)
     {
-        for (int tt = 0; tt < getConfiguration()->getSource(ds)->numTetrodes(); tt++)
-        {
+        *(newElectrode->channels+i) = firstChan+i;
+        *(newElectrode->thresholds+i) = getDefaultThreshold();
+        *(newElectrode->isActive+i) = true;
+    }
 
-            Trode* t = getConfiguration()->getSource(ds)->getTetrode(tt);
+    resetElectrode(newElectrode);
 
-            for (int ch = 0; ch < t->numChannels(); ch++)
-            {
-                thresh.set(t->getChannel(ch),t->getThreshold(ch));
-                channels.set(t->getChannel(ch),t->getRawDataPointer());
-                nChans.set(t->getChannel(ch),t->numChannels());
-                isActive.set(t->getChannel(ch),t->getState(ch));
-            }
-        }
+    electrodes.add(newElectrode);
+
+}
+
+float SpikeDetector::getDefaultThreshold()
+{
+    return 0.14;
+}
+
+StringArray SpikeDetector::getElectrodeNames()
+{
+    StringArray names;
+
+    for (int i = 0; i < electrodes.size(); i++)
+    {
+        names.add(electrodes[i]->name);
     }
 
+    return names;
+}
+
+void SpikeDetector::resetElectrode(Electrode* e)
+{
+    e->lastBufferIndex = 0;
+}
+
+bool SpikeDetector::removeElectrode(int index) 
+{
+
+   // std::cout << "Spike detector removing electrode" << std::endl;
+
+    if (index > electrodes.size() || index < 0)
+        return false;
+
+    electrodes.remove(index);
     return true;
+}
+
+bool SpikeDetector::setName(int index, String newName)
+{
+    electrodes[index-1]->name = newName;
+}
+
+bool SpikeDetector::setChannel(int electrodeIndex, int channelNum, int newChannel) 
+{
+    *(electrodes[electrodeIndex]->channels+channelNum) = newChannel;
+}
 
+int SpikeDetector::getNumChannels(int index)
+{
+    return electrodes[index]->numChannels;
+}
+
+int SpikeDetector::getChannel(int index, int i)
+{
+    return *(electrodes[index]->channels+i);
+}
+
+void SpikeDetector::setParameter (int parameterIndex, float newValue)
+{
+	//std::cout << "Message received." << std::endl;
+	// if (parameterIndex == 0) 
+ //    {
+ //        thresh.set(currentChannel,newValue);
+	// }
+
+}
+
+
+bool SpikeDetector::enable()
+{
+
+    useOverflowBuffer = false;
+    return true;
 }
 
 bool SpikeDetector::disable() 
 {	
-    thresh.clear();
-    channels.clear();
-    nChans.clear();
-    isActive.clear();
-    lastSpike.clear();
+
+    for (int n = 0; n < electrodes.size(); n++)
+    {
+        resetElectrode(electrodes[n]);
+    }
 
     return true;
 }
 
+void SpikeDetector::createSpikeEvent(int& peakIndex,
+                                     int& electrodeNumber, int& currentChannel,
+                                     MidiBuffer& eventBuffer)
+{
+
+    int spikeLength = electrodes[electrodeNumber]->prePeakSamples +
+                        + electrodes[electrodeNumber]->postPeakSamples;
+
+    uint8 dataSize = spikeLength*2;
+
+    uint8 data[dataSize];
+    uint8* dataptr = data;
+
+    // cycle through buffer
+    for (int sample = 0; sample < spikeLength; sample++)
+    {
+         uint16 sampleValue = uint16(getNextSample(currentChannel) + 32768);
+
+         *dataptr++ = uint8(sampleValue >> 8);
+         *dataptr++ = uint8(sampleValue & 255);
+
+         sampleIndex++;
+
+    }
+
+    addEvent(eventBuffer,
+             SPIKE,
+             peakIndex,
+             uint8(electrodeNumber),
+             uint8(currentChannel),
+             dataSize,
+             data);
+
+    sampleIndex -= spikeLength; // reset sample index
+
+}
+
 void SpikeDetector::process(AudioSampleBuffer &buffer, 
-                            MidiBuffer &midiMessages,
+                            MidiBuffer &events,
                             int& nSamples)
 {
 
-	int maxSamples = nSamples;//getNumSamples(midiMessages);
-	int spikeSize = 2 + prePeakSamples*2 + postPeakSamples*2; 
+    // cycle through electrodes
+    Electrode* electrode;
+    dataBuffer = buffer;
 
-    spikeBuffer->clear();
+    //std::cout << dataBuffer.getMagnitude(0,nSamples) << std::endl;
 
-    for (int sample = prePeakSamples + 1; sample < maxSamples - postPeakSamples - 1; sample++)
+    for (int i = 0; i < electrodes.size(); i++)
     {
-        for (int chan = 0; chan < getNumOutputs(); chan++) 
+
+        //std::cout << "ELECTRODE " << i << std::endl;
+
+        electrode = electrodes[i];
+
+        // refresh buffer index for this electrode
+        sampleIndex = electrode->lastBufferIndex - 1; // subtract 1 to account for
+                                                      // increment at start of getNextSample()
+
+        // cycle through samples
+        while (samplesAvailable(nSamples))
         {
-            if (isActive[chan] && lastSpike[chan]+spikeSize < sample) // channel is active
+
+            sampleIndex++;
+
+
+            // cycle through channels
+            for (int chan = 0; chan < electrode->numChannels; chan++)
             {
-                if (*buffer.getSampleData(chan,sample) > thresh[chan])
+
+             //   std::cout << "  channel " << chan << std::endl;
+
+                if (*(electrode->isActive+chan))
                 {
-                    // if thresh cross is detected on one channel
-                    // save a waveform on all of them
-                   // std::cout << "Thresh cross on channel " << chan << ": " << thresh[chan] << std::endl;
-                   // std::cout << "  Capturing spikes on " << nChans[chan] << " channels." << std::endl;
 
-                    for (int wire = 0; wire < nChans[chan]; wire++)
+                    int currentChannel = *(electrode->channels+chan);
+
+                    if (getNextSample(currentChannel) > *(electrode->thresholds+chan)) // trigger spike
                     {
-                        int* firstChan = channels[chan];
-                        int channelNum = *(firstChan+wire);
 
-                        //std::cout << "     Found spike on channel " << channelNum << std::endl;
+                        //std::cout << "Spike detected on electrode " << i << std::endl;
+                        // find the peak
+                        int peakIndex = sampleIndex;
 
-                        uint8 data[spikeSize];
-                        data[0] = channelNum >> 8; // channel most-significant byte
-                        data[1] = channelNum & 0xFF; // channel least-significant byte
+                        while (getCurrentSample(currentChannel) <
+                               getNextSample(currentChannel) &&
+                               sampleIndex < peakIndex + electrode->postPeakSamples) 
+                        {
+                            sampleIndex++;
+                        }
 
-                        // not currently looking for peak, just centering on thresh cross
-                        uint8* dataptr = data+2;
+                        peakIndex = sampleIndex;
+                        sampleIndex -= (electrode->prePeakSamples+1);
 
-                        for (int s = -prePeakSamples; s < postPeakSamples; s++) {
-                
-                            uint16 sampleValue = uint16(*buffer.getSampleData(channelNum, sample+s) + 32768);
+                        // package spikes;
+                        for (int currentChannel = 0; currentChannel < electrode->numChannels; currentChannel++)
+                        {
 
-                            *dataptr++ = uint8(sampleValue >> 8);
-                            *dataptr++ = uint8(sampleValue & 255);
+                            if (*(electrode->isActive+currentChannel))
+                            {
 
+                                createSpikeEvent(peakIndex,       // peak index
+                                                 i,               // electrodeNumber
+                                                 currentChannel,  // channel number
+                                                 events);         // event buffer
+
+
+                            } // end if channel is active
                         }
 
-                        // broadcast spike
-                        spikeBuffer->addEvent(data, // spike data
-                              sizeof(data), // total bytes
-                              sample);           // sample index
-                        
-                        // keep track of last spike
-                        lastSpike.set(channelNum, sample-prePeakSamples);
-
-                    }
-                }                
-            }
-        }
-    }
+                        // advance the sample index
+                        sampleIndex = peakIndex + electrode->postPeakSamples;
 
-    // reset lastSpike at the end of each buffer
-    for (int n = 0; n < getNumOutputs(); n++)
+                        break; // quit "for" loop
+                   } // end spike trigger
+
+               } // end if chanel is active
+            } // end cycle through channels
+           
+        } // end cycle through samples
+
+        electrode->lastBufferIndex = sampleIndex - nSamples; // should be negative
+
+        jassert(electrode->lastBufferIndex < 0);
+
+    } // end cycle through electrodes
+
+    // copy end of this buffer into the overflow buffer
+
+    //std::cout << "Copying buffer" << std::endl;
+   // std::cout << "nSamples: " << nSamples;
+    //std::cout << "overflowBufferSize:" << overflowBufferSize;
+
+    //if (nSamples > overflowBufferSize) {
+
+    for (int i = 0; i < overflowBuffer.getNumChannels(); i++)
     {
-        lastSpike.set(n,-40);
+        overflowBuffer.copyFrom(i, 0, 
+                                buffer, i, 
+                                nSamples-overflowBufferSize, 
+                                overflowBufferSize);
     }
+        useOverflowBuffer = true;
+    //} else {
+   //     useOverflowBuffer = false;
+   // }
+    
+}
+
+float SpikeDetector::getNextSample(int& chan)
+{
+
+    
+
+    //if (useOverflowBuffer)
+    //{
+        if (sampleIndex < 0)
+        {
+          // std::cout << "  sample index " << sampleIndex << "from overflowBuffer" << std::endl;
+            return *overflowBuffer.getSampleData(chan, overflowBufferSize + sampleIndex);
+        } else {
+          //  useOverflowBuffer = false;
+          // std::cout << "  sample index " << sampleIndex << "from regular buffer" << std::endl;
+            return *dataBuffer.getSampleData(chan, sampleIndex);
+        }   
+    //} else {
+    //    std::cout << "  sample index " << sampleIndex << "from regular buffer" << std::endl;
+   //     return *dataBuffer.getSampleData(chan, sampleIndex);
+    //}
+
+}
+
+float SpikeDetector::getCurrentSample(int& chan)
+{
+
+    // if (useOverflowBuffer)
+    // {
+    //     return *overflowBuffer.getSampleData(chan, overflowBufferSize + sampleIndex - 1);
+    // } else {
+    //     return *dataBuffer.getSampleData(chan, sampleIndex - 1);
+    // }
 
+    if (sampleIndex < 1)
+        {
+            //std::cout << "  sample index " << sampleIndex << "from overflowBuffer" << std::endl;
+            return *overflowBuffer.getSampleData(chan, overflowBufferSize + sampleIndex - 1);
+        } else {
+          //  useOverflowBuffer = false;
+           // std::cout << "  sample index " << sampleIndex << "from regular buffer" << std::endl;
+            return *dataBuffer.getSampleData(chan, sampleIndex - 1);
+        }   
+    //} else {
 
 }
+
+
+bool SpikeDetector::samplesAvailable(int& nSamples)
+{
+
+    if (sampleIndex > nSamples - overflowBufferSize/2)
+    {
+        return false;
+    } else {
+        return true;
+    }
+
+}
+
+
diff --git a/Source/Processors/SpikeDetector.h b/Source/Processors/SpikeDetector.h
index 8d0a1059e24a74ec24d3edd90b56b5a5c7d42073..065dbca51454d6d01cb06f7e048e462a3c41a68b 100644
--- a/Source/Processors/SpikeDetector.h
+++ b/Source/Processors/SpikeDetector.h
@@ -25,13 +25,13 @@
 #define __SPIKEDETECTOR_H_3F920F95__
 
 #include "../../JuceLibraryCode/JuceHeader.h"
+
 #include "GenericProcessor.h"
 #include "Editors/SpikeDetectorEditor.h"
-#include "../UI/Configuration.h"
 
 /**
 
-  --UNDER CONSTRUCTION--
+  == UNDER CONSTRUCTION ==
 
   Detects spikes in a continuous signal and outputs events containing the spike data.
 
@@ -40,7 +40,6 @@
 */
 
 class SpikeDetectorEditor;
-class FilterViewport;
 
 class SpikeDetector : public GenericProcessor
 
@@ -50,33 +49,70 @@ public:
 	SpikeDetector();
 	~SpikeDetector();
 	
-	void process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples);
+	void process(AudioSampleBuffer &buffer, MidiBuffer &events, int& nSamples);
 	void setParameter (int parameterIndex, float newValue);
 
+	void updateSettings();
+
 	bool enable();
 	bool disable();
 
-	MidiBuffer* getEventBuffer() {return spikeBuffer;}
-
 	AudioProcessorEditor* createEditor();
 
-	bool hasEditor() const {return true;}
-	
+	AudioSampleBuffer overflowBuffer;
+	AudioSampleBuffer& dataBuffer;
+
+	bool addElectrode(int nChans);
+	bool removeElectrode(int index);
+	bool setChannel(int electrodeIndex, int channelNum, int newChannel);
+	bool setName(int index, String newName);
+
+	int getNumChannels(int index);
+	int getChannel(int index, int chan);
+
+	StringArray electrodeTypes;
+
+	StringArray getElectrodeNames();
+
 private:
-	double sampleRate, threshold;
-	double prePeakMs, postPeakMs;
-	int prePeakSamples, postPeakSamples;
-	int accumulator;
 
-	Array<float> thresh;
-	Array<int*> channels;
-	Array<int> nChans;
-	Array<bool> isActive;
-	Array<int> lastSpike;
+	float getDefaultThreshold();
+
+	int overflowBufferSize;
+
+	int sampleIndex;
+	//int lastBufferIndex;
+
+	Array<int> electrodeCounter;
+
+	float getNextSample(int& chan);
+	float getCurrentSample(int& chan);
+	bool samplesAvailable(int& nSamples);
+
+	bool useOverflowBuffer;
+
+	struct Electrode {
+
+		String name;
+
+		int numChannels;
+		int prePeakSamples, postPeakSamples;
+		int lastBufferIndex;
+
+		int* channels;
+		double* thresholds;
+		bool* isActive;
+
+	};
+
+	Array<Electrode*> electrodes;
 
-	MidiBuffer* spikeBuffer;
+	void createSpikeEvent(int& peakIndex,
+						  int& electrodeNumber,
+						  int& currentChannel,
+						  MidiBuffer& eventBuffer);
 
-	//AudioData::ConverterInstance<AudioData::Float32, AudioData::Int16> converter;
+	void resetElectrode(Electrode*);
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SpikeDetector);
 
diff --git a/Source/Processors/SpikeDisplayNode.cpp b/Source/Processors/SpikeDisplayNode.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..471a8267f2936acec06e724a30f3979e181be3ab
--- /dev/null
+++ b/Source/Processors/SpikeDisplayNode.cpp
@@ -0,0 +1,119 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "SpikeDisplayNode.h"
+#include <stdio.h>
+
+
+
+SpikeDisplayNode::SpikeDisplayNode()
+	: GenericProcessor("Spike Viewer"),
+	  bufferSize(0), abstractFifo(100)
+
+{
+//	displayBuffer = new AudioSampleBuffer(8, 100);
+	eventBuffer = new MidiBuffer();
+}
+
+SpikeDisplayNode::~SpikeDisplayNode()
+{
+	//deleteAndZero(displayBuffer);
+	//deleteAndZero(eventBuffer);
+}
+
+AudioProcessorEditor* SpikeDisplayNode::createEditor()
+{
+	std::cout<<"SpikeDisplayNode Created!"<<std::endl;
+
+	editor = new SpikeDisplayEditor(this);	
+	return editor;
+
+}
+
+void SpikeDisplayNode::updateSettings()
+{
+	std::cout << "Setting num inputs on SpikeDisplayNode to " << getNumInputs() << std::endl;
+}
+
+
+bool SpikeDisplayNode::enable()
+{
+	std::cout<<"SpikeDisplayNode::enable()"<<std::endl;
+	SpikeDisplayEditor* editor = (SpikeDisplayEditor*) getEditor();
+	editor->enable();
+	return true;
+		
+}
+
+bool SpikeDisplayNode::disable()
+{
+	std::cout<<"SpikeDisplayNode disabled!"<<std::endl;
+	SpikeDisplayEditor* editor = (SpikeDisplayEditor*) getEditor();
+	editor->disable();
+	return true;
+}
+
+int SpikeDisplayNode::getNumberOfChannelsForInput(int i){
+	std::cout<<"SpikeDisplayNode::getNumberOfChannelsForInput()"<<std::endl;
+	return 1;
+}
+
+
+void SpikeDisplayNode::setParameter (int param, float val)
+{
+	std::cout<<"Got Param:"<< param<< " with value:"<<val<<std::endl;
+}
+
+
+
+void SpikeDisplayNode::process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples)
+{
+	//std::cout<<"SpikeDisplayNode::process"<<std::endl;
+	/*
+	uint64_t ts =  00000; 
+	int noise = 10;
+	SpikeObject newSpike;
+
+	generateSimulatedSpike(&newSpike, ts, noise);
+	
+	spikebuffer.push(newSpike);
+	bufferSize++;
+	*/
+}
+
+bool SpikeDisplayNode::getNextSpike(SpikeObject *spike){
+	std::cout<<"SpikeDisplayNode::getNextSpike()"<<std::endl;
+	/*
+	if (bufferSize<1 || spikebuffer.empty())
+		return false;
+	else{
+		SpikeObject s = spikebuffer.front();
+		spikebuffer.pop();
+		bufferSize--;
+		*spike = s;
+		return true;
+	}
+	*/
+	return false;
+
+}
\ No newline at end of file
diff --git a/Source/Processors/SpikeDisplayNode.h b/Source/Processors/SpikeDisplayNode.h
new file mode 100644
index 0000000000000000000000000000000000000000..02092c5a032da33f8d7fa7bc4018464b71fa62ca
--- /dev/null
+++ b/Source/Processors/SpikeDisplayNode.h
@@ -0,0 +1,95 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef SPIKEDISPLAYNODE_H_
+#define SPIKEDISPLAYNODE_H_
+
+#include "../../JuceLibraryCode/JuceHeader.h"
+#include "Editors/SpikeDisplayEditor.h"
+#include "Editors/VisualizerEditor.h"
+#include "GenericProcessor.h"
+#include "Visualization/SpikeObject.h"
+
+
+
+#define SPIKE_CMD_CLEAR_ALL 	10000
+#define SPIKE_CMD_CLEAR_SEL 	10001
+#define SPIKE_CMD_PAN_AXES	 	10002    
+#define SPIKE_CMD_ZOOM_AXES		10003
+
+    
+/**
+  
+ Takes in MidiEvents and extracts SpikeObjects from the MidiEvent buffers. Those Events are then held in a queue until they are pulled by the spikeviewer
+
+  @see GenericProcessor, SpikeDisplayEditor, SpikeDisplayCanvas
+
+*/
+
+
+
+class DataViewport;
+
+class SpikeDisplayNode :  public GenericProcessor
+{
+public:
+
+	SpikeDisplayNode();
+	~SpikeDisplayNode();
+
+	AudioProcessorEditor* createEditor();
+
+	bool isSink() {return true;}
+
+	void process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples);
+
+	void setParameter(int, float);
+
+	void updateSettings();
+
+	bool enable();
+	bool disable();
+
+	int getNumberOfChannelsForInput(int i);
+
+	bool getNextSpike(SpikeObject *spike);
+	
+private:
+
+	int numberOfSources;
+	AbstractFifo abstractFifo;
+
+	ScopedPointer<AudioSampleBuffer> displayBuffer;
+	ScopedPointer<MidiBuffer> eventBuffer;
+
+	//std::queue<SpikeObject> spikebuffer;
+
+	int bufferSize;
+	//bool resizeBuffer();
+
+	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SpikeDisplayNode);
+
+};
+
+
+#endif  // SPIKEDISPLAYNODE_H_
diff --git a/Source/Processors/Utilities/Merger.cpp b/Source/Processors/Utilities/Merger.cpp
index 2ac4ae8121e3bd6fc81f90d49e52db2caa24d265..fd6f69cc7f8b66f8c332005d0c20e71d15f1d490 100644
--- a/Source/Processors/Utilities/Merger.cpp
+++ b/Source/Processors/Utilities/Merger.cpp
@@ -30,10 +30,7 @@ Merger::Merger()
 	: GenericProcessor("Merger"), 
 		sourceNodeA(0), sourceNodeB(0), activePath(0)//, tabA(-1), tabB(-1)
 {
-	setNumOutputs(0);
-	setNumInputs(0);
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
+	
 }
 
 Merger::~Merger()
@@ -43,10 +40,10 @@ Merger::~Merger()
 
 AudioProcessorEditor* Merger::createEditor()
 {
-	MergerEditor* editor = new MergerEditor(this);
-	setEditor(editor);
+	editor = new MergerEditor(this);
+	//tEditor(editor);
 	
-	std::cout << "Creating editor." << std::endl;
+	//std::cout << "Creating editor." << std::endl;
 	return editor;
 }
 
@@ -64,7 +61,7 @@ void Merger::setMergerSourceNode(GenericProcessor* sn)
 	}
 }
 
-void Merger::switchSource(int sourceNum) {
+void Merger::switchIO(int sourceNum) {
 
 	//std::cout << "Switching to source number " << sourceNum << std::endl;
 	
@@ -95,8 +92,11 @@ bool Merger::stillHasSource()
 
 }
 
-void Merger::switchSource()
+void Merger::switchIO()
 {
+
+	std::cout << "Merger switching source." << std::endl;
+
 	if (activePath == 0) {
 		activePath = 1;
 		sourceNode = sourceNodeB;
@@ -108,25 +108,55 @@ void Merger::switchSource()
 
 }
 
-void Merger::setNumInputs(int n)
+void Merger::addSettingsFromSourceNode(GenericProcessor* sn)
+{
+
+	settings.numInputs += sn->getNumOutputs();
+	settings.inputChannelNames.addArray(sn->settings.inputChannelNames);
+	settings.eventChannelIds.addArray(sn->settings.eventChannelIds);
+	settings.eventChannelNames.addArray(sn->settings.eventChannelNames);
+	settings.bitVolts.addArray(sn->settings.bitVolts);
+
+	settings.originalSource = sn->settings.originalSource;
+	settings.sampleRate = sn->settings.sampleRate;
+
+	settings.numOutputs = settings.numInputs;
+	settings.outputChannelNames = settings.inputChannelNames;
+
+}
+
+void Merger::updateSettings()
 {
-	numInputs = 0;
+
+	// default is to get everything from sourceNodeA,
+	// but this might not be ideal
+	clearSettings();
 
 	if (sourceNodeA != 0)
 	{
 		std::cout << "   Merger source A found." << std::endl;
-		numInputs += sourceNodeA->getNumOutputs();
+		addSettingsFromSourceNode(sourceNodeA);
 	}
+
 	if (sourceNodeB != 0)
 	{
 		std::cout << "   Merger source B found." << std::endl;
-		numInputs += sourceNodeB->getNumOutputs();
+		addSettingsFromSourceNode(sourceNodeB);
+	}	
+
+	if (sourceNodeA == 0 && sourceNodeB == 0) {
+
+		settings.sampleRate = getDefaultSampleRate();
+		settings.numOutputs = getDefaultNumOutputs();
+
+		for (int i = 0; i < getNumOutputs(); i++)
+			settings.bitVolts.add(getDefaultBitVolts());
+
+		generateDefaultChannelNames(settings.outputChannelNames);
 	}
 
 	std::cout << "Number of merger outputs: " << getNumInputs() << std::endl;
 
-	setNumOutputs(getNumInputs());
-
 }
 
 // void Merger::setNumOutputs(int /*outputs*/)
diff --git a/Source/Processors/Utilities/Merger.h b/Source/Processors/Utilities/Merger.h
index 66d4459bc188844581cabd3cb6175e1f724d5bea..7b416027915a4b5b5c0417520c013d737b6df8d9 100644
--- a/Source/Processors/Utilities/Merger.h
+++ b/Source/Processors/Utilities/Merger.h
@@ -51,11 +51,12 @@ public:
 
 	bool isMerger() {return true;}
 
-	void switchSource(int);
-	void switchSource();
+	void switchIO(int);
+	void switchIO();
 	void setMergerSourceNode(GenericProcessor* sn);
 
-	void setNumInputs(int);
+    void updateSettings();
+    void addSettingsFromSourceNode(GenericProcessor* sn);
 
 	bool stillHasSource();
 
diff --git a/Source/Processors/Utilities/Splitter.cpp b/Source/Processors/Utilities/Splitter.cpp
index f259291f9e2a06bdbfb93a2128c95d806df1d577..fed00295d36a987e2b649c7f14b13063dec279e8 100644
--- a/Source/Processors/Utilities/Splitter.cpp
+++ b/Source/Processors/Utilities/Splitter.cpp
@@ -31,10 +31,6 @@ Splitter::Splitter()
 		destNodeA(0), destNodeB(0), activePath(0)
 {
 
-	setNumOutputs(0);
-	setNumInputs(0);
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
 }
 
 Splitter::~Splitter()
@@ -44,10 +40,10 @@ Splitter::~Splitter()
 
 AudioProcessorEditor* Splitter::createEditor()
 {
-	SplitterEditor* editor = new SplitterEditor(this);
-	setEditor(editor);
+	editor = new SplitterEditor(this);
+	//tEditor(editor);
 	
-	std::cout << "Creating editor." << std::endl;
+	//std::cout << "Creating editor." << std::endl;
 	return editor;
 }
 
@@ -65,7 +61,7 @@ void Splitter::setSplitterDestNode(GenericProcessor* dn)
 	}
 }
 
-void Splitter::switchDest(int destNum) {
+void Splitter::switchIO(int destNum) {
 	
 	std::cout << "Switching to dest number " << destNum << std::endl;
 	
@@ -81,12 +77,15 @@ void Splitter::switchDest(int destNum) {
 		std::cout << "Dest node: " << getDestNode() << std::endl;
 	}
 
-	getEditorViewport()->makeEditorVisible((GenericEditor*) getEditor());
+	getEditorViewport()->makeEditorVisible(getEditor());
 
 }
 
-void Splitter::switchDest()
+void Splitter::switchIO()
 {
+
+	std::cout << "Splitter switching source." << std::endl;
+
 	if (activePath == 0) {
 		activePath = 1;
 		destNode = destNodeB;
@@ -97,9 +96,3 @@ void Splitter::switchDest()
 	}
 
 }
-
-void Splitter::setNumInputs(int n)
-{
-	numInputs = n;
-	setNumOutputs(getNumInputs());
-}
\ No newline at end of file
diff --git a/Source/Processors/Utilities/Splitter.h b/Source/Processors/Utilities/Splitter.h
index 69581ba625c6fc5ee72ba6793032cce4dee4a8d9..ed775bdcf4ebe83ab5ed07ec52a80218f1479609 100644
--- a/Source/Processors/Utilities/Splitter.h
+++ b/Source/Processors/Utilities/Splitter.h
@@ -53,11 +53,10 @@ public:
 
 	bool isSplitter() {return true;}
 
-	void switchDest(int);
-    void switchDest();
+	void switchIO(int);
+    void switchIO();
 	void setSplitterDestNode(GenericProcessor* dn);
 
-    void setNumInputs(int);
 
 private:
 
diff --git a/Source/Processors/Visualization/LfpDisplayCanvas.cpp b/Source/Processors/Visualization/LfpDisplayCanvas.cpp
index 809dbcc15317f1db104d7fa7f711653ed39dc75e..7e7a9251e8b33883698a0887ba87a4fd18a4e315 100644
--- a/Source/Processors/Visualization/LfpDisplayCanvas.cpp
+++ b/Source/Processors/Visualization/LfpDisplayCanvas.cpp
@@ -29,21 +29,21 @@ LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* n) : processor(n),
 	    timebase(1.0f), displayGain(5.0f), displayBufferIndex(0)
 {
 
-	//GenericProcessor* gp = (GenericProcessor*) editor->getProcessor();
-
-
 	nChans = processor->getNumInputs();
 	sampleRate = processor->getSampleRate();
 	std::cout << "Setting num inputs on LfpDisplayCanvas to " << nChans << std::endl;
 
 	displayBuffer = processor->getDisplayBufferAddress();
 	displayBufferSize = displayBuffer->getNumSamples();
-		std::cout << "Setting displayBufferSize on LfpDisplayCanvas to " << displayBufferSize << std::endl;
+	std::cout << "Setting displayBufferSize on LfpDisplayCanvas to " << displayBufferSize << std::endl;
 
 
 	totalHeight = (plotHeight+yBuffer)*nChans + yBuffer;
 
-	screenBuffer = new AudioSampleBuffer(nChans, 10000);
+	if (nChans > 0)
+		screenBuffer = new AudioSampleBuffer(nChans, 10000);
+	else
+		screenBuffer = new AudioSampleBuffer(1, 10000);
 	
 }
 
@@ -86,22 +86,24 @@ void LfpDisplayCanvas::endAnimation()
 	stopCallbacks();
 }
 
-void LfpDisplayCanvas::updateNumInputs(int n)
+void LfpDisplayCanvas::update()
 {
-	std::cout << "Setting num inputs on LfpDisplayCanvas to " << n << std::endl;
-	nChans = n;
-	if (n < 200 && n > 0)
+	nChans = processor->getNumInputs();
+	sampleRate = processor->getSampleRate();
+
+	std::cout << "Setting num inputs on LfpDisplayCanvas to " << nChans << std::endl;
+	if (nChans < 200 && nChans > 0)
 		screenBuffer->setSize(nChans, 10000);
 	//sampleRate = processor->getSampleRate();
-}
 
-void LfpDisplayCanvas::updateSampleRate(float r)
-{
-	sampleRate = r;
-	//displayBufferSize = displayBuffer->getNumSamples();
-	std::cout << "Display canvas updating sample rate to " << r << std::endl;
+	screenBuffer->clear();
+
+	repaint();
+
+	totalHeight = (plotHeight+yBuffer)*nChans + yBuffer;
 }
 
+
 void LfpDisplayCanvas::setParameter(int param, float val)
 {
 	if (param == 0)
@@ -117,6 +119,8 @@ void LfpDisplayCanvas::refreshState()
 	displayBufferIndex = processor->getDisplayBufferIndex();
 	screenBufferIndex = 0;
 
+	//resized();
+
 }
 
 void LfpDisplayCanvas::updateScreenBuffer()
@@ -202,6 +206,10 @@ void LfpDisplayCanvas::updateScreenBuffer()
 	}
 }
 
+void LfpDisplayCanvas::canvasWasResized()
+{
+	//std::cout << "Resized!" << std::endl;	
+}
 
 void LfpDisplayCanvas::renderOpenGL()
 {
@@ -343,7 +351,7 @@ int LfpDisplayCanvas::getTotalHeight()
 }
 
 
-void LfpDisplayCanvas::mouseDown(const MouseEvent& e) 
+void LfpDisplayCanvas::mouseDownInCanvas(const MouseEvent& e) 
 {
 
 	Point<int> pos = e.getPosition();
@@ -358,7 +366,6 @@ void LfpDisplayCanvas::mouseDown(const MouseEvent& e)
 		repaint();
 	}
 
-	mouseDownInCanvas(e);
 }
 
 // void LfpDisplayCanvas::mouseDrag(const MouseEvent& e) {mouseDragInCanvas(e);}
diff --git a/Source/Processors/Visualization/LfpDisplayCanvas.h b/Source/Processors/Visualization/LfpDisplayCanvas.h
index e124911962481dc5cf347c995fb14440fabc24b3..a274076cc8ca571f31790f464faf74d649e8944f 100644
--- a/Source/Processors/Visualization/LfpDisplayCanvas.h
+++ b/Source/Processors/Visualization/LfpDisplayCanvas.h
@@ -23,15 +23,13 @@
 #ifndef __LFPDISPLAYCANVAS_H_B711873A__
 #define __LFPDISPLAYCANVAS_H_B711873A__
 
-
 #include "../../../JuceLibraryCode/JuceHeader.h"
-#include "OpenGLCanvas.h"
-#include "../../UI/Configuration.h"
 #include "../LfpDisplayNode.h"
+#include "Visualizer.h"
 
 class LfpDisplayNode;
 
-class LfpDisplayCanvas : public OpenGLCanvas
+class LfpDisplayCanvas : public Visualizer
 
 {
 public: 
@@ -45,10 +43,11 @@ public:
 
 	void refreshState();
 
-	void updateNumInputs(int);
-	void updateSampleRate(float);
+	void update();
 
 	void setParameter(int, float);
+	void setParameter(int, int, int, float){}
+
 
 private:
 
@@ -57,7 +56,6 @@ private:
 	float sampleRate;
 	float timebase;
 	float displayGain;
-	//float ratio;
 
 	LfpDisplayNode* processor;
 	AudioSampleBuffer* displayBuffer;
@@ -73,8 +71,6 @@ private:
 
 	bool checkBounds(int chan);
 
-
-
 	void updateScreenBuffer();
 	int screenBufferIndex;
 	int displayBufferIndex;
@@ -85,8 +81,8 @@ private:
 
 	int getTotalHeight();
 
-	// void resized();
-	 void mouseDown(const MouseEvent& e);
+	 void canvasWasResized();
+	 void mouseDownInCanvas(const MouseEvent& e);
 	// void mouseDrag(const MouseEvent& e);
 	// void mouseMove(const MouseEvent& e);
 	// void mouseUp(const MouseEvent& e);
diff --git a/Source/Processors/Visualization/OpenGLCanvas.cpp b/Source/Processors/Visualization/OpenGLCanvas.cpp
index 4353220dc26d1c308db8c2df49c325aed032b9b9..a51104ccbb736f2ef4a92ee75e8dd2c2753b4880 100644
--- a/Source/Processors/Visualization/OpenGLCanvas.cpp
+++ b/Source/Processors/Visualization/OpenGLCanvas.cpp
@@ -28,7 +28,7 @@
 OpenGLCanvas::OpenGLCanvas() : //OpenGLComponent(OpenGLComponent::OpenGLType::openGLDefault, true),
 	scrollPix(0), scrollTime(0), scrollDiff(0), originalScrollPix(0), 
 	scrollBarWidth(15), PI(3.1415926), showScrollTrack(true),
-	animationIsActive(false), refreshMs(100)
+	animationIsActive(false), refreshMs(50)
 {
 
 	loadFonts();
@@ -45,16 +45,29 @@ OpenGLCanvas::~OpenGLCanvas()
 void OpenGLCanvas::setUp2DCanvas()
 {
 	glMatrixMode (GL_PROJECTION);
+	glLoadIdentity();
 
+	glMatrixMode (GL_MODELVIEW);
 	glLoadIdentity();
+
 	glOrtho (0, 1, 1, 0, 0, 1);
-	glMatrixMode (GL_MODELVIEW);
 	
 	glEnable(GL_TEXTURE_2D);
 }
 
 void OpenGLCanvas::activateAntiAliasing()
 {
+
+	// disable everything we don't need
+	glDisable(GL_FOG);
+	glDisable(GL_LIGHTING);
+	glDisable(GL_DITHER);
+	glDisable(GL_CULL_FACE);
+	glDisable(GL_ALPHA_TEST);
+	glDisable(GL_DEPTH_TEST);
+	glDisable(GL_SCISSOR_TEST);
+	glDisable(GL_STENCIL_TEST);
+
 	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
 	glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
 	glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
@@ -65,6 +78,8 @@ void OpenGLCanvas::activateAntiAliasing()
 
 	glEnable(GL_BLEND);
 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+	glShadeModel(GL_FLAT);
 }
 
 
@@ -195,6 +210,7 @@ void OpenGLCanvas::stopCallbacks()
 
 void OpenGLCanvas::drawScrollBars()
 {
+	
 	float scrollBarY = float(getHeight())/float(getTotalHeight());
 	float timeSinceScroll = timer->getMillisecondCounter()-scrollTime;
 	
@@ -223,6 +239,7 @@ void OpenGLCanvas::drawScrollBars()
 		}
 		showScrollTrack = false;
 	}
+
 }
 
 void OpenGLCanvas::drawScrollBar(float y1, float y2, float alpha)
@@ -334,7 +351,7 @@ void OpenGLCanvas::drawRoundedRect(float x,
 
 }
 
-void OpenGLCanvas::mouseMoveInCanvas(const MouseEvent& e)
+void OpenGLCanvas::mouseMove(const MouseEvent& e)
 {
 	if (getTotalHeight() > getHeight()) {
 	Point<int> pos = e.getPosition();
@@ -344,9 +361,11 @@ void OpenGLCanvas::mouseMoveInCanvas(const MouseEvent& e)
 		showScrollTrack = true; showScrollBars();
 	}
 	}
+
+	mouseMoveInCanvas(e);
 }
 
-void OpenGLCanvas::mouseDownInCanvas(const MouseEvent& e)
+void OpenGLCanvas::mouseDown(const MouseEvent& e)
 {
 
 	if (getTotalHeight() > getHeight()) {
@@ -376,9 +395,11 @@ void OpenGLCanvas::mouseDownInCanvas(const MouseEvent& e)
 		showScrollBars();
 	}
 	}
+
+	mouseDownInCanvas(e);
 }
 
-void OpenGLCanvas::mouseDragInCanvas(const MouseEvent& e)
+void OpenGLCanvas::mouseDrag(const MouseEvent& e)
 {
 
 	if (getTotalHeight() > getHeight()) {
@@ -415,54 +436,48 @@ void OpenGLCanvas::mouseDragInCanvas(const MouseEvent& e)
 		} 
 	}
 	}
+
+	mouseDragInCanvas(e);
 }
 
-void OpenGLCanvas::mouseUpInCanvas(const MouseEvent& e)
+void OpenGLCanvas::mouseUp(const MouseEvent& e)
 {
 	scrollDiff = 0;
+
+	mouseUpInCanvas(e);
 }
 
-void OpenGLCanvas::mouseWheelMoveInCanvas(const MouseEvent&e,
+void OpenGLCanvas::mouseWheelMove(const MouseEvent&e,
                                       float wheelIncrementX, float wheelIncrementY)
 
 {
 	if (getTotalHeight() > getHeight()) {
-	if (wheelIncrementY > 0)
-	{
-		if (scrollPix + getHeight() < getTotalHeight())
+
+		if (wheelIncrementY > 0)
 		{
-			scrollPix += int(100.0f*wheelIncrementY);
-			if (scrollPix + getHeight() > getTotalHeight())
-				scrollPix = getTotalHeight() - getHeight();
-		}
-	} else if (wheelIncrementY < 0)
-	{
-		if (scrollPix > 0)
+			if (scrollPix + getHeight() < getTotalHeight())
+			{
+				scrollPix += int(100.0f*wheelIncrementY);
+				if (scrollPix + getHeight() > getTotalHeight())
+					scrollPix = getTotalHeight() - getHeight();
+			}
+		} else if (wheelIncrementY < 0)
 		{
-			scrollPix += int(100.0f*wheelIncrementY);
-			if (scrollPix < 0)
-				scrollPix = 0;
+			if (scrollPix > 0)
+			{
+				scrollPix += int(100.0f*wheelIncrementY);
+				if (scrollPix < 0)
+					scrollPix = 0;
+			}
 		}
-	}
 
-	repaint();
+		repaint();
 
-	showScrollBars();
+		showScrollBars();
 
 	}
 
-}
-
-void OpenGLCanvas::canvasWasResized()
-{
-	//glClear(GL_COLOR_BUFFER_BIT);
-
-	if (scrollPix + getHeight() > getTotalHeight() && getTotalHeight() > getHeight())
-		scrollPix = getTotalHeight() - getHeight();
-	else
-		scrollPix = 0;
-
-	showScrollBars();
+	mouseWheelMoveInCanvas(e, wheelIncrementX, wheelIncrementY);
 
 }
 
@@ -472,18 +487,15 @@ void OpenGLCanvas::timerCallback()
 }
 
 
-
-void OpenGLCanvas::mouseDown(const MouseEvent& e) 
+void OpenGLCanvas::resized()
 {
-	mouseDownInCanvas(e);
-}
 
-void OpenGLCanvas::mouseDrag(const MouseEvent& e) {mouseDragInCanvas(e);}
-void OpenGLCanvas::mouseMove(const MouseEvent& e) {mouseMoveInCanvas(e);}
-void OpenGLCanvas::mouseUp(const MouseEvent& e) 	{mouseUpInCanvas(e);}
-void OpenGLCanvas::mouseWheelMove(const MouseEvent& e, float a, float b) {mouseWheelMoveInCanvas(e,a,b);}
+	if (scrollPix + getHeight() > getTotalHeight() && getTotalHeight() > getHeight())
+		scrollPix = getTotalHeight() - getHeight();
+	else
+		scrollPix = 0;
+
+	showScrollBars();
 
-void OpenGLCanvas::resized()
-{
 	canvasWasResized();
 }
\ No newline at end of file
diff --git a/Source/Processors/Visualization/OpenGLCanvas.h b/Source/Processors/Visualization/OpenGLCanvas.h
index 3712b51d8bf2a1ca71d93d580d13ea256f7b56c9..a80f539fb7af2a6f27ec6381ea74ed5234159d22 100644
--- a/Source/Processors/Visualization/OpenGLCanvas.h
+++ b/Source/Processors/Visualization/OpenGLCanvas.h
@@ -40,24 +40,28 @@ public:
 
 	virtual void refreshState() {};
 
-	void mouseDownInCanvas(const MouseEvent& e);
-	void mouseDragInCanvas(const MouseEvent& e);
-	void mouseMoveInCanvas(const MouseEvent& e);
-	void mouseUpInCanvas(const MouseEvent& e);
-	void mouseWheelMoveInCanvas(const MouseEvent&, float, float);
-
-	virtual void resized();
-	virtual void mouseDown(const MouseEvent& e);
-	virtual void mouseDrag(const MouseEvent& e);
-	virtual void mouseMove(const MouseEvent& e);
-	virtual void mouseUp(const MouseEvent& e);
-	virtual void mouseWheelMove(const MouseEvent&, float, float);
+
+
+	void resized();
+	virtual void canvasWasResized() { }
+
+	void mouseDown(const MouseEvent& e);
+	void mouseDrag(const MouseEvent& e);
+	void mouseMove(const MouseEvent& e);
+	void mouseUp(const MouseEvent& e);
+	void mouseWheelMove(const MouseEvent&, float, float);
+
+	virtual void mouseDownInCanvas(const MouseEvent& e) {}
+	virtual void mouseDragInCanvas(const MouseEvent& e) {}
+	virtual void mouseMoveInCanvas(const MouseEvent& e) {}
+	virtual void mouseUpInCanvas(const MouseEvent& e) {}
+	virtual void mouseWheelMoveInCanvas(const MouseEvent&,
+									    float,
+									    float) {}
 
 	void startCallbacks();
 	void stopCallbacks();
 
-	void canvasWasResized();
-
 	int getScrollAmount() {return scrollPix;};
 	int getScrollBarWidth() {return scrollBarWidth;}
 	void drawScrollBars();
@@ -69,6 +73,8 @@ public:
 protected:
 
 	virtual int getTotalHeight() = 0;
+	int scrollPix;
+	void showScrollBars();
 
 private:
 
@@ -80,9 +86,8 @@ private:
 
 	void drawScrollBar(float y1, float y2, float alpha);
 	
-	void showScrollBars();
 
-	int scrollBarWidth, scrollPix, scrollDiff, originalScrollPix;
+	int scrollBarWidth, scrollDiff, originalScrollPix;
 	int scrollTime;
 	bool showScrollTrack;
 
diff --git a/Source/Processors/Visualization/SpikeDisplayCanvas.cpp b/Source/Processors/Visualization/SpikeDisplayCanvas.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..33315e9aa1a1d1a5ed93554870a9f96c0db22b12
--- /dev/null
+++ b/Source/Processors/Visualization/SpikeDisplayCanvas.cpp
@@ -0,0 +1,389 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "SpikeDisplayCanvas.h"
+
+SpikeDisplayCanvas::SpikeDisplayCanvas(SpikeDisplayNode* n) : processor(n),
+	 	xBuffer(25), yBuffer(25),  newSpike(false), plotsInitialized(false),
+	 	totalScrollPix(0)
+{
+
+	
+
+	nSources = 0; //processor->getNumInputs();
+	std::cout<<"SpikeDisplayNode has :"<<nSources<<" outputs!"<<std::endl;
+	
+	for (int i=0; i<nSources; i++)
+		nChannels[i] = processor->getNumberOfChannelsForInput(i);
+
+	std::cout << "Setting num inputs on SpikeDisplayCanvas to " << nSources << std::endl;
+	
+	
+	
+}
+
+SpikeDisplayCanvas::~SpikeDisplayCanvas()
+{
+	
+}
+
+void SpikeDisplayCanvas::initializeSpikePlots(){
+	std::cout<<"Initializing Plots"<<std::endl;
+
+
+	int nPlots = 6;
+	int nCols = 2;
+
+	int totalWidth = getWidth(); 
+	
+	int plotWidth =  (totalWidth - yBuffer * ( nCols+1)) / nCols + .99;
+	int plotHeight = plotWidth / 2 + .5;
+	int rowCount = 0;
+	int i;
+
+	for (i=0; i<nPlots; i++)
+	{
+
+		StereotrodePlot p = StereotrodePlot( 
+									xBuffer + i%nCols * (plotWidth + xBuffer) , 
+									yBuffer + rowCount * (plotHeight + yBuffer), 
+									plotWidth, 
+									plotHeight); // deprecated conversion from string constant to char
+		SpikeObject tmpSpike;
+		generateEmptySpike(&tmpSpike, 4);
+		p.processSpikeObject(tmpSpike);
+		
+		plots.push_back(p);
+
+		if (i%nCols == nCols-1)
+			rowCount++;
+
+	}
+	totalHeight = yBuffer + rowCount * (plotHeight + yBuffer) + yBuffer;
+
+	// Set the total height of the Canvas to the top of the top most plot
+	plotsInitialized = true;
+	repositionSpikePlots();
+}
+
+void SpikeDisplayCanvas::repositionSpikePlots(){
+	
+	int nPlots = plots.size();
+	int nCols = 2;
+
+	int totalWidth = getWidth(); 
+	
+	int plotWidth =  (totalWidth - yBuffer * ( nCols+1)) / nCols + .99;
+	int plotHeight = plotWidth / 2 + .5;
+	int rowCount = 0;
+
+	for (int i=0; i<plots.size(); i++)
+	{
+
+		plots[i].setPosition(	xBuffer + i%nCols * (plotWidth + xBuffer) , 
+								yBuffer + rowCount * (plotHeight + yBuffer), 
+								plotWidth, 
+								plotHeight); // deprecated conversion from string constant to char
+
+		if (i%nCols == nCols-1)
+			rowCount++;	
+	 }
+
+	// Set the total height of the Canvas to the top of the top most plot
+	totalHeight = yBuffer + rowCount * (plotHeight + yBuffer) + yBuffer;
+}
+
+void SpikeDisplayCanvas::newOpenGLContextCreated()
+{
+
+	std::cout<<"SpikeDisplayCanvas::newOpenGLContextCreated()"<<std::endl;
+	setUp2DCanvas();
+	activateAntiAliasing();
+
+	glClearColor (0.667, 0.698, 0.718, 1.0);
+	resized();
+	endAnimation();
+	//startTimer(50);
+
+}
+
+void SpikeDisplayCanvas::beginAnimation()
+{
+	std::cout << "Beginning animation." << std::endl;
+
+	// displayBufferSize = displayBuffer->getNumSamples();
+
+	// screenBuffer->clear();
+
+	//displayBufferIndex = 0;
+//	screenBufferIndex = 0;
+	
+	startCallbacks();
+}
+
+void SpikeDisplayCanvas::endAnimation()
+{
+	std::cout << "Ending animation." << std::endl;
+	stopCallbacks();
+}
+
+void SpikeDisplayCanvas::update()
+{
+	// nChans = processor->getNumInputs();
+	// sampleRate = processor->getSampleRate();
+
+	// std::cout << "Setting num inputs on SpikeDisplayCanvas to " << nChans << std::endl;
+	// if (nChans < 200 && nChans > 0)
+	// 	screenBuffer->setSize(nChans, 10000);
+	// //sampleRate = processor->getSampleRate();
+
+    // screenBuffer->clear();
+
+	repaint();
+
+	// totalHeight = (plotHeight+yBuffer)*nChans + yBuffer;
+}
+
+
+// Used for Plot specific commands, this commands target a specific PLOT and have
+// no additional information, IE PARAM-> CLEAR  val->plot6  
+// for more complex messages use the other version of setParameter
+void SpikeDisplayCanvas::setParameter(int param, float val)
+{
+	std::cout<<"Got Param:"<< param<< " with value:"<<val<<std::endl;
+	switch (param)
+	{
+		case SPIKE_CMD_CLEAR_ALL :
+			for (int i=0; i<plots.size(); i++)
+				plots[i].clear();
+			break;
+	
+		case SPIKE_CMD_CLEAR_SEL:
+		//clear plot number val
+			break;
+		default:
+			std::cout<<"Unkown Commad specified! "<<param<<std::endl;
+	}
+}
+
+void SpikeDisplayCanvas::setParameter(int param, int p2, int p3, float value){
+	std::cout<<"Got Parameter:"<<param<<" p2:"<<p2<<" p3:"<<p3<<" value:"<<value<<std::endl;
+	switch (param){
+		case SPIKE_CMD_PAN_AXES:
+			panPlot(p2, p3, value<=0);
+			break;
+		case SPIKE_CMD_ZOOM_AXES:
+			zoomPlot(p2, p3, value<=0);
+			break;
+	}
+}
+
+
+void SpikeDisplayCanvas::refreshState()
+{
+	// called when the component's tab becomes visible again
+	// displayBufferIndex = processor->getDisplayBufferIndex();
+	// screenBufferIndex = 0;
+
+	//resized();
+	totalScrollPix = 0;
+}
+
+void SpikeDisplayCanvas::canvasWasResized()
+{
+	repositionSpikePlots();
+}
+
+void SpikeDisplayCanvas::renderOpenGL()
+{
+	if(!plotsInitialized)
+			initializeSpikePlots();
+	glClearColor (0.667, 0.698, 0.718, 1.0);
+	glClear(GL_COLOR_BUFFER_BIT); // clear buffers to preset values
+//	std::cout<<"SpikeDisplayCanvas::renderOpenGL"<<std::endl;
+	// Get Spikes from the processor
+	// Iterate through each spike, passing them individually to the appropriate plots and calling redraw before moving on to the next spike
+	
+	//while(processor->getNextSpike(&spike))
+	//{
+		
+	// Identify which plot the spike should go to
+	
+	// Distribute those spike to the appropriate plot object
+	
+	
+	SpikeObject tmpSpike;
+	 for (int i=0; i<plots.size(); i++){
+		generateSimulatedSpike(&tmpSpike, 0, 150);
+		plots[i].processSpikeObject(tmpSpike);
+ 		plots[i].redraw();
+ 		drawPlotTitle( i );
+	 }
+	
+	//}
+	//std::cout << getHeight()<<" "<< getTotalHeight()<<" "<<std::endl;
+ 	drawScrollBars();
+}
+
+void SpikeDisplayCanvas::drawPlotTitle(int chan){
+
+	glViewport(0,0,getWidth(), getHeight());
+	setViewportRange(0, 0, getWidth(), getHeight());
+
+	int x, y;
+	double w,h;
+ 	plots[chan].getPosition(&x,&y,&w,&h);
+
+	float alpha = 0.50f;
+
+	glColor4f(0.0f,0.0f,0.0f,alpha);
+	glRasterPos2f(x, y+h+2);
+	
+	String s = "Source:";//String("Channel ");
+	s += (chan+1);
+
+	getFont(String("cpmono-bold"))->FaceSize(25);
+	getFont(String("cpmono-bold"))->Render(s);
+}
+
+int SpikeDisplayCanvas::getTotalHeight() 
+{
+	return totalHeight;
+}
+
+
+void SpikeDisplayCanvas::mouseDownInCanvas(const MouseEvent& e) 
+{
+
+	/*
+	Point<int> pos = e.getPosition();
+	int xcoord = pos.getX();
+
+	if (xcoord < getWidth()-getScrollBarWidth())
+	{
+		int chan = (e.getMouseDownY() + getScrollAmount())/(yBuffer+plotHeight);
+
+			selectedChan = chan;
+
+		repaint();
+	}*/
+
+}
+
+// void SpikeDisplayCanvas::mouseDrag(const MouseEvent& e) {mouseDragInCanvas(e);}
+// void SpikeDisplayCanvas::mouseMove(const MouseEvent& e) {mouseMoveInCanvas(e);}
+void SpikeDisplayCanvas::mouseUp(const MouseEvent& e) 	{
+	// std::cout<<"Mouse Event!"<<std::endl;
+
+	// bool inout = false;
+
+	// if (e.getMouseDownX() < getWidth()/2)
+	// 	inout = false;
+	// else
+	// 	inout = true;
+
+	// if (e.getMouseDownY() < getHeight()/2)
+	// 	zoomPlot(0,0, inout);
+	// else
+	// 	panPlot(0,0,inout);
+}
+void SpikeDisplayCanvas::mouseWheelMove(const MouseEvent& e, float wheelIncrementX, float wheelIncrementY) {
+
+	// std::cout<<"Mouse Wheel Move:"<< wheelIncrementX<<","<<wheelIncrementY;
+	// std::cout<<" Scroll Pix:"<<scrollPix<<std::endl;
+
+	int scrollAmount = 0;
+	// std::cout<<getTotalHeight()<<" "<<getHeight()<<std::endl;
+
+	if (getTotalHeight() > getHeight()) {
+		//if (wheelIncrementY > 0 )
+			scrollAmount += int(100.0f*wheelIncrementY);	
+		//else if (wheelIncrementY < 0)
+			
+		totalScrollPix += scrollAmount;
+		
+		// don't let the user scroll too far down
+		int minScrollDown = (-1 * totalHeight) + getHeight();
+		int maxScrollUp = 0; // never scroll plots up, there is nothing below the bottom plot
+
+		// std::cout<<"TotalScrollPix:"<<totalScrollPix<<" min:"<<minScrollDown<<" max:"<<maxScrollUp<<std::endl;
+		
+		if (totalScrollPix < minScrollDown){
+			totalScrollPix= minScrollDown;
+			scrollAmount = 0;
+		}
+		
+		else if (totalScrollPix > maxScrollUp)
+		{
+			totalScrollPix = maxScrollUp;
+			scrollAmount = 0;
+		}
+
+		for (int i=0; i<plots.size(); i++){
+			int x,y;
+			double w,h;
+			plots[i].getPosition(&x, &y, &w, &h);
+			plots[i].setPosition(x,y+scrollAmount, w, h);
+		}
+
+		scrollPix = 0;//totalScrollPix;
+
+		repaint();
+
+		showScrollBars();
+
+	}
+
+	mouseWheelMoveInCanvas(e, wheelIncrementX, wheelIncrementY);
+}
+
+void SpikeDisplayCanvas::panPlot(int p, int c, bool up){
+	std::cout<<"SpikeDisplayCanvas::panPlot()"<<std::endl;
+	if (p<0 || p>plots.size())
+		return;
+	plots[p].pan(c, up);
+
+}
+void SpikeDisplayCanvas::zoomPlot(int p, int c, bool in){
+	std::cout<<"SpikeDisplayCanvas::panPlot()"<<std::endl;
+	if (p<0 || p>plots.size())
+		return;
+	plots[p].zoom(c, in);
+}
+
+// void SpikeDisplayCanvas::resized()
+// {
+// 	//screenBuffer = new AudioSampleBuffer(nChans, getWidth());
+
+// 	// glClear(GL_COLOR_BUFFER_BIT);
+
+// 	// //int h = getParentComponent()->getHeight();
+
+// 	// if (scrollPix + getHeight() > getTotalHeight() && getTotalHeight() > getHeight())
+// 	// 	scrollPix = getTotalHeight() - getHeight();
+// 	// else
+// 	// 	scrollPix = 0;
+
+// 	// showScrollBars();
+// 	canvasWasResized();
+// }
\ No newline at end of file
diff --git a/Source/Processors/Visualization/SpikeDisplayCanvas.h b/Source/Processors/Visualization/SpikeDisplayCanvas.h
new file mode 100644
index 0000000000000000000000000000000000000000..c142b3566c7c3aa9a71e6dbcce56e0df5803aa90
--- /dev/null
+++ b/Source/Processors/Visualization/SpikeDisplayCanvas.h
@@ -0,0 +1,127 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef SPIKEDISPLAYCANVAS_H_
+#define SPIKEDISPLAYCANVAS_H_
+
+#include "../../../JuceLibraryCode/JuceHeader.h"
+
+#include "../SpikeDisplayNode.h"
+#include "SpikePlotting/ElectrodePlot.h"
+#include "SpikePlotting/StereotrodePlot.h"
+#include "SpikePlotting/TetrodePlot.h"
+#include "SpikeObject.h"
+
+#include "Visualizer.h"
+#include <vector>
+
+ /**
+  
+  Displays spike waveforms and projections.
+
+  @see SpikeDisplayNode, SpikeDisplayEditor, Visualizer
+
+*/
+
+#define MAX_NUMBER_OF_SPIKE_SOURCES = 128;
+
+class SpikeDisplayNode;
+
+class SpikeDisplayCanvas : public Visualizer
+
+{
+public: 
+	SpikeDisplayCanvas(SpikeDisplayNode* n);
+	~SpikeDisplayCanvas();
+	void newOpenGLContextCreated();
+	void renderOpenGL();
+
+	void beginAnimation();
+	void endAnimation();
+
+	void refreshState();
+
+	void update();
+
+	void setParameter(int, float);
+	void setParameter(int, int, int, float);
+
+	void panPlot(int, int, bool);
+	void zoomPlot(int, int, bool);
+
+private:
+
+	int xBuffer, yBuffer;
+
+	bool plotsInitialized;
+
+	bool newSpike;
+	SpikeObject spike;
+	SpikeDisplayNode* processor;
+	std::vector<StereotrodePlot> plots;
+
+	int totalScrollPix;
+	// AudioSampleBuffer* displayBuffer;
+	// ScopedPointer<AudioSampleBuffer> screenBuffer;
+	// MidiBuffer* eventBuffer;
+
+	// void setViewport(int chan);
+	// void drawBorder(bool isSelected);
+	// void drawChannelInfo(int chan, bool isSelected);
+	// void drawWaveform(int chan, bool isSelected);
+
+	void drawPlotTitle(int chan);
+	//void drawTicks();
+
+	// bool checkBounds(int chan);
+
+	// void updateScreenBuffer();
+	// int screenBufferIndex;
+	// int displayBufferIndex;
+	// int displayBufferSize;
+
+	int totalHeight;
+	// int selectedChan;
+
+	int getTotalHeight();
+
+	int nSources;
+	int nChannels[MAX_NUMBER_OF_SPIKE_CHANNELS];
+
+	void initializeSpikePlots();
+	void repositionSpikePlots();
+
+	void canvasWasResized();
+	void mouseDownInCanvas(const MouseEvent& e);
+	// void mouseDrag(const MouseEvent& e);
+	// void mouseMove(const MouseEvent& e);
+	void mouseUp(const MouseEvent& e);
+	void mouseWheelMove(const MouseEvent&, float, float);
+
+	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SpikeDisplayCanvas);
+	
+};
+
+
+
+#endif  // SPIKEDISPLAYCANVAS_H_
diff --git a/Source/Processors/Visualization/SpikeObject.cpp b/Source/Processors/Visualization/SpikeObject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a13c839a66631c6e17b40dcf4df35d29c964a3ba
--- /dev/null
+++ b/Source/Processors/Visualization/SpikeObject.cpp
@@ -0,0 +1,220 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "SpikeObject.h"
+#include <iostream>
+#include "memory.h"
+#include <stdlib.h>
+#include "time.h"
+      
+// Simple method for serializing a SpikeObject into a string of bytes
+bool packSpike(SpikeObject *s, char* buffer, int bufferSize){
+
+	int idx = 0;
+	memcpy(buffer+idx, &(s->timestamp), 4);
+	idx += 4;
+
+	memcpy(buffer+idx, &(s->source), 2);
+	idx +=2;
+
+	memcpy(buffer+idx, &(s->nChannels), 2);
+	idx +=2;
+
+	memcpy(buffer+idx, &(s->nSamples), 2);
+	idx +=2;
+
+	memcpy(buffer+idx, &(s->data), s->nChannels * s->nSamples * 2);
+	idx += s->nChannels * s->nSamples * 2;
+
+	memcpy(buffer+idx, &(s->gain), s->nChannels);
+	idx += s->nChannels;
+
+	memcpy(buffer+idx, &(s->threshold), s->nChannels);
+	idx += s->nChannels;
+
+if (idx>=bufferSize)
+		std::cout<<"Buffer Overrun! More data packaged than space provided!"<<std::endl;
+	// makeBufferValid(buffer, bufferSize);
+
+}
+
+// Simple method for deserializing a string of bytes into a Spike object
+bool unpackSpike(SpikeObject *s, char* buffer, int bufferSize){
+	// if !(isBufferValid(buffer, bufferSize));
+	// 	return false;
+
+	int idx = 0;
+	
+	memcpy( &(s->timestamp), buffer+idx, 4);
+	idx += 4;
+
+	memcpy( &(s->source), buffer+idx, 2);
+	idx += 2;
+
+	memcpy( &(s->nChannels), buffer+idx, 2);
+	idx +=2;
+
+	memcpy( &(s->nSamples), buffer+idx, 2);
+	idx +=2;
+
+	memcpy( &(s->data), buffer+idx, s->nChannels * s->nSamples * 2);
+	idx += s->nChannels * s->nSamples * 2;
+
+	memcpy( &(s->gain), buffer+idx, s->nChannels * 2);
+	idx += s->nChannels * 2;
+
+	memcpy( &(s->threshold), buffer+idx, s->nChannels *2);
+	idx += s->nChannels * 2;
+
+	if (idx>=bufferSize)
+		std::cout<<"Buffer Overrun! More data extracted than was given!"<<std::endl;
+	
+}
+
+// Checks the validity of the buffer, this should be run before unpacking and after packing the buffer
+bool isBufferValid(char *buffer, int bufferSize){
+
+	if (! CHECK_BUFFER_VALIDITY )
+		return true;
+
+	uint16_t runningSum = 0;
+	uint16_t value = 0;
+	
+	int idx = 0;
+
+	for (idx; idx<bufferSize-2; idx+=2){
+		memcpy(buffer + idx, &value, 2);
+		runningSum += value;
+	}
+
+	uint16_t integrityCheck = 0;
+	memcpy(buffer + idx, &integrityCheck, 2);
+
+	std::cout<<integrityCheck<<" == "<< runningSum <<std::endl;
+	return (integrityCheck == runningSum);
+}
+
+void makeBufferValid(char *buffer, int bufferSize){
+	if (! CHECK_BUFFER_VALIDITY )
+		return;
+
+	uint16_t runningSum = 0;
+	uint16_t value = 0;
+	
+	int idx = 0;
+
+	for (idx; idx<bufferSize-2; idx+=2){
+		memcpy(buffer + idx, &value, 2);
+		runningSum += value;
+	}
+
+	memcpy(&runningSum, buffer + idx, 2);
+
+}
+
+void generateSimulatedSpike(SpikeObject *s, uint64_t timestamp, int noise)
+{
+	//std::cout<<"generateSimulatedSpike()"<<std::endl;
+
+	uint16_t trace[][32] =
+	{
+	{ 	880,	900,	940,	1040,	1290,	1790,	2475,	2995, 	3110, 	2890,
+		2505,	2090,	1720,	1410, 	1155,  	945,	775,	635,	520, 	420,
+		340,	265,	205,	155,	115,	80,		50,		34,		10, 	34,  	50,		80},
+	{	1040,   1090,   1190,	1350,	1600,	1960,   2380,   2790,   3080,	3140,
+		2910,	2430,	1810,	1180,	680,	380,	270,	320,	460, 	630,
+		770,	870,	940,	970,	990,	1000,	1000,	1000,	1000,	1000,  1000,	1000},
+	{ 	1000,	1000,	1000,	1000,	1000,	1040,	1140,	1440,	2040,	2240,
+		2400,	2340,	2280,	1880,	1640,	920,	520,	300,	140,	040,
+		20,		20,		40,		100,	260,	500,	740,	900,	960,	1000,	1000,	1000}
+    };
+
+
+    // We don't want to shift the waveform but scale it, and we don't want to scale
+    // the baseline, just the peak of the waveform
+    float scale[32] = 
+    {	1.0, 1.0, 1.0, 1.0, 1.1, 1.2, 1.3, 1.5, 1.7, 2.0, 2.1, 2.2, 2.1, 2.0, 1.7, 1.5,
+    	1.3, 1.2, 1.1, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
+
+    uint16_t gain = 2000;
+
+    s->timestamp = timestamp;
+    s->source = 0;
+    s->nChannels = 4;
+    s->nSamples = 32;
+    int idx=0;
+    
+    int waveType = rand()%2; // Pick one of the three predefined waveshapes to generate
+    int shift = 1000;
+
+    for (int i=0; i<4; i++)
+    {
+        s->gain[i] = gain;
+        s->threshold[i] = 4000;
+        double scaleExponent =  (double)(rand()%26+2) / 10.0f; // Scale the wave between 50% and 150%
+        
+		for (int j=0; j<32; j++){
+			
+			int n = 0;
+			if (noise>0){
+				n = rand() % noise - noise/2;
+			}
+
+            s->data[idx] = (trace[waveType][j] + n)  * pow(scale[j],scaleExponent) + shift;
+            idx = idx+1;
+        }
+    }
+    
+}
+void generateEmptySpike(SpikeObject *s, int nChannels){
+
+	s->timestamp = 0;
+    s->source = 0;
+    s->nChannels = 4;
+    s->nSamples = 32;
+    
+    int idx = 0;
+    for (int i=0; i<4; i++)
+    {
+        s->gain[i] = 0;
+        s->threshold[i] = 0;
+        for (int j=0; j<32; j++){
+            s->data[idx] = 0;
+            idx = idx+1;
+        }
+    }
+}
+
+
+// std::ostream& operator<<(std::ostream &strm, const SpikeObject s){
+
+// 	strm << " SpikeObject:\n";
+// 	strm << "\tTimestamp:" << s.timestamp;
+// 	strm << "\tSource:" << s.source;
+// 	strm << "\tnChannels:" <<s.nChannels;
+// 	strm <<"\tnSamples" << s.nSamples;
+// 	strm <<"\n\t 8 Data Samples:";
+// 	for (int i=0; i<8; i++)
+// 		strm << s.data[i]<<" ";
+// 	return strm;
+// }
diff --git a/Source/Processors/Visualization/SpikeObject.h b/Source/Processors/Visualization/SpikeObject.h
new file mode 100644
index 0000000000000000000000000000000000000000..f2b517ae02125e3efdd3180994866ec2eb76d49b
--- /dev/null
+++ b/Source/Processors/Visualization/SpikeObject.h
@@ -0,0 +1,85 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef SPIKEOBJECT_H_
+#define SPIKEOBJECT_H_
+
+#include <stdint.h>
+#include <math.h>
+
+#define MAX_NUMBER_OF_SPIKE_CHANNELS 4
+#define MAX_NUMBER_OF_SPIKE_CHANNEL_SAMPLES 256
+#define CHECK_BUFFER_VALIDITY true
+
+struct SpikeObject{
+
+  uint64_t    timestamp;                                           
+  uint16_t    source;                                        
+  uint16_t    nChannels;                                      
+  uint16_t    nSamples;
+  uint16_t    data[MAX_NUMBER_OF_SPIKE_CHANNELS * MAX_NUMBER_OF_SPIKE_CHANNEL_SAMPLES]; 
+  uint16_t    gain[MAX_NUMBER_OF_SPIKE_CHANNELS];           
+  uint16_t    threshold[MAX_NUMBER_OF_SPIKE_CHANNELS];    
+
+};
+
+/*
+  For transmission between processors SpikeObjects must be packaged up into buffers that can fit into MidiEvents
+  The following two methods can be used to package the above spike object into a buffer and  unpackage a buffer
+  into a SpikeObject.  
+
+  The buffer is LittleEndian (thank Intel) and the byte order is the same as the SpikeObject definition. 
+  IE. the first 2 bytes are the timestamp, the next two bytes are the source identifier, etc... with the last
+  set of bytes corresponding to the thresholds of the different channels.
+
+  Finally the buffer will have an additional byte on the end that is used to check the integerity of the entire package.
+  The way this works is the buffer is divivded up into a series of 16 bit unsigned integers. The sum of all these integers
+  (except the last 16 bit integer) is taken and the sum should equal that 16 bit integer. If not then the data is corrupted 
+  and should be dropped or delt with another way.
+*/
+
+// Simple method for serializing a SpikeObject into a string of bytes, returns true is the packaged spike buffer is valid
+bool packSpike(SpikeObject *s, char* buffer, int bufferLength);
+
+// Simple method for deserializing a string of bytes into a Spike object, returns true is the provided spike buffer is valid
+bool unpackSpike(SpikeObject *s, char* buffer, int bufferLength);
+
+// Checks the validity of the buffer, this should be run before unpacking the buffer
+bool isBufferValid(char *buffer, int bufferLength);
+
+// Computes the validity value for the buffer, this should be called after packing the buffer
+void makeBufferValid(char *buffer, int bufferLength);
+
+// Help function for generating fake spikes in the absence of a real spike source. 
+// Can be used to generate a sign wave with a fixed Frequency of 1000 hz or a basic spike waveform
+// Additionally noise can be added to the waveform for help in diagnosing projection plots
+void generateSimulatedSpike(SpikeObject *s, uint64_t timestamp, int noise);
+
+// Define the << operator for the SpikeObject
+// std::ostream& operator<<(std::ostream &strm, const SpikeObject s);
+
+// Helper function for zeroing out a spike object with a specified number of channels
+void generateEmptySpike(SpikeObject *s, int nChannels);
+
+
+#endif //SPIKEOBJECT_H_
\ No newline at end of file
diff --git a/Source/Processors/Visualization/SpikePlotting/BaseUIElement.cpp b/Source/Processors/Visualization/SpikePlotting/BaseUIElement.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..99995ba290bd97b2a8f213a8fba7ad0e5d3b4c28
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/BaseUIElement.cpp
@@ -0,0 +1,90 @@
+#include "BaseUIElement.h"
+
+BaseUIElement::BaseUIElement():
+	xpos(0),  ypos(0), yOffset(0), 
+	width(100), height(100), enabled(true), padding(0)
+{	
+}
+
+BaseUIElement::BaseUIElement(int x, int y, double w, double h):
+	yOffset(0), enabled(true), padding(0)
+{
+	xpos = x+padding;
+	ypos = y+padding;
+	width = w-padding*2;
+	height = h-padding*2;
+}
+BaseUIElement::BaseUIElement(int x, int y, double w, double h, int p):
+	enabled(true), padding(0)
+{
+	xpos = x+padding;
+	ypos = y+padding;	
+	width = w-padding*2;
+	height = h-padding*2;
+}
+
+void BaseUIElement::redraw(){
+//	std::cout<<"BaseUIElement::redraw(), Position:"<<xpos<<","<<ypos<<" : "<<width<<","<<height<<std::endl;
+	setGlViewport();
+	
+	// if (clearNextDraw || !clearNextDraw){
+	// 	clearNextDraw = false;
+	glColor3f(0.0, 0.0, 0.0);
+	glRecti(-1,-1,1,1);
+		
+		
+	// }
+}
+void BaseUIElement::drawElementEdges(){
+	// std::cout<<"BaseUIElement::drawBaseUIElementEdges(), Position:"<<xpos<<","<<ypos<<" : "<<width<<","<<height<<std::endl;
+	glColor3f(1.0, 1.0, 1.0);
+	setGlViewport();
+	glLineWidth(2);
+	drawViewportEdge();
+}
+void BaseUIElement::setEnabled(bool e){
+	enabled = e;	
+}
+bool BaseUIElement::getEnabled(){
+	return enabled;
+}
+void BaseUIElement::setGlViewport(){
+	
+	glLoadIdentity();
+	glViewport(xpos, ypos, width, height);
+	
+	// std::cout<<xpos<<"x"<<ypos<<"-"<<width<<"x"<<height<<"\t"<<BaseUIElementName<<std::endl;
+}
+void BaseUIElement::setPosition(int x, int y, double w, double h){
+	xpos = x+padding;
+	ypos = y+padding;
+	width = w - padding*2;
+	height = h - padding*2;
+}
+
+void BaseUIElement::getPosition(int *x, int *y, double *w, double *h){
+	*x = xpos;
+	*y = ypos;
+	*w = width;
+	*h = height;
+}
+// void BaseUIElement::clearOnNextDraw(bool c){
+// 	clearNextDraw = c;
+// }
+
+bool BaseUIElement::hitTest(int x, int y){
+    return (x>xpos && x<xpos+width) && (y>ypos && y<ypos+height);
+}
+
+double BaseUIElement::getHeight(){
+    return height;
+}
+double BaseUIElement::getWidth(){
+    return width;
+}
+int BaseUIElement::getX(){
+    return xpos;
+}
+int BaseUIElement::getY(){
+    return ypos;
+}
diff --git a/Source/Processors/Visualization/SpikePlotting/BaseUIElement.h b/Source/Processors/Visualization/SpikePlotting/BaseUIElement.h
new file mode 100644
index 0000000000000000000000000000000000000000..b69a491dda3b0128d928c3191f876fd125317c8c
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/BaseUIElement.h
@@ -0,0 +1,40 @@
+#ifndef BASEUIELEMENT_H_
+#define BASEUIELEMENT_H_
+
+#include "PlotUtils.h"
+
+
+class BaseUIElement{
+
+protected:	
+	int xpos, ypos, yOffset;
+	double height, width;
+	bool enabled;
+	double padding;
+	
+	void setGlViewport();
+		
+public:
+	BaseUIElement();
+	BaseUIElement(int x, int y, double w, double h);
+	BaseUIElement(int x, int y, double w, double h, int p);
+	void redraw();
+	void drawElementEdges();
+	void setEnabled(bool e);
+	bool getEnabled();
+	void setPosition(int x, int y, double w, double h);
+	void getPosition(int*, int*, double*, double*);
+    double getHeight();
+    double getWidth();
+    int getX();
+    int getY();
+	
+	// void clearOnNextDraw(bool);
+	// bool clearNextDraw;
+    bool hitTest(int x, int y);
+	
+};
+
+
+
+#endif // BaseUIElement_H_
diff --git a/Source/Processors/Visualization/SpikePlotting/ElectrodePlot.cpp b/Source/Processors/Visualization/SpikePlotting/ElectrodePlot.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e12df2daf39ed012f8e6fcc94c292842ace57ba8
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/ElectrodePlot.cpp
@@ -0,0 +1,257 @@
+#include "ElectrodePlot.h"
+#include "../SpikeObject.h"
+#include "PlotUtils.h"
+
+ElectrodePlot::ElectrodePlot():
+	BaseUIElement(), limitsChanged(true)
+{
+}
+
+ElectrodePlot::ElectrodePlot(int x, int y, int w, int h):
+	BaseUIElement(x,y,w,h,1),  limitsChanged(true)
+{
+
+	initAxes();
+}
+
+ElectrodePlot::~ElectrodePlot(){
+}
+
+// Each plot needs to update its children axes when its redraw gets called.
+//  it also needs to call the parent plot  when children axes get added it
+//  should place them in the correct location because it KNOWS where WAVE1 and PROJ1x3
+//  should go by default. This isn't as general as it should be but its a good push in
+//  the right direction
+
+void ElectrodePlot::redraw(){
+	 //std::cout<<"ElectrodePlot() starting drawing"<<std::endl;\
+	BaseUIElement::clearNextDraw = true;
+	BaseUIElement::redraw();
+
+	axes.redraw();
+}
+
+// This would normally happen for collection of axes but an electrode plot doesn't have a collection instead its a single axes
+void ElectrodePlot::processSpikeObject(SpikeObject s){
+	//std::cout<<"ElectrdePlot::processSpikeObject()"<<std::endl;
+	axes.updateSpikeData(s);
+}
+
+void ElectrodePlot::setEnabled(bool e){
+	BaseUIElement::enabled = e;
+
+	axes.setEnabled(e);
+}
+
+bool ElectrodePlot::getEnabled(){
+	return BaseUIElement::enabled;
+}
+
+
+void ElectrodePlot::initAxes(){
+	initLimits();
+    
+    int minX = BaseUIElement::xpos;
+	int minY = BaseUIElement::ypos;
+	
+	double axesWidth = BaseUIElement::width;
+	double axesHeight = BaseUIElement::height;
+	
+	
+	axes = WaveAxes(minX, minY, axesWidth, axesHeight, WAVE1);
+	
+    //axes.setEnabled(false);
+	axes.setYLims(-1*pow(2,11), pow(2,14)*1.6);
+	axes.setWaveformColor(1.0, 1.0, 1.0);
+
+}
+
+void ElectrodePlot::setPosition(int x, int y, double w, double h){
+	BaseUIElement::setPosition(x,y,w,h);
+	int minX = BaseUIElement::xpos;
+	int minY = BaseUIElement::ypos;
+	
+	double axesWidth = BaseUIElement::width;
+	double axesHeight = BaseUIElement::height;
+	
+	axes.setPosition(minX, minY, axesWidth, axesHeight);
+	
+}
+
+int ElectrodePlot::getNumberOfAxes(){
+	return 1;;
+}
+
+
+void ElectrodePlot::initLimits(){
+    for (int i=0; i<4; i++)
+    {
+        limits[i][0] = -1*pow(2,11);
+        limits[i][1] = pow(2,14);
+    }
+
+}
+
+void ElectrodePlot::getPreferredDimensions(double *w, double *h){
+    *w = 75;
+    *h = 75;
+}
+// void ElectrodePlot::mouseDown(int x, int y){
+
+// //     selectedAxesN = -1;
+// //     std::list<GenericAxes>::iterator i;
+// //     int idx=-1;
+// //     bool hit = false;
+
+// //     selectedAxes = NULL;
+// //     for (i=axesList.begin(); i!=axesList.end(); ++i)
+// //     {
+// //         if (i->hitTest(x,y))
+// //         {
+// //             selectedAxes = addressof(*i);
+// //             selectedAxesN = i->getType();
+// //             hit = true;
+// // //            break;
+// //         }
+// //         idx++;
+// //     }
+// //     if (!hit)
+// //         selectedAxes = NULL;
+// //     if (selectedAxes != NULL)
+// //         std::cout<<"ElectrodePlot::mouseDown() hit:"<<selectedAxes<<" AxesType:"<<selectedaxes.getType()<<std::endl;
+// //     else
+// //         std::cout<<"ElectrodePlot::mouseDown() NO HIT!"<<std::endl;
+    
+// }
+// void ElectrodePlot::mouseDragX(int dx, bool shift, bool ctrl){
+
+// //     if (selectedAxes == NULL || dx==0)
+// //         return;
+// // //    zoomAxes(selectedaxes.getType(), true, dx>0);
+// //     if (shift)
+// //         zoomAxes(selectedAxesN, true, dx);
+// //     if (ctrl)
+// //         panAxes(selectedAxesN, true, dx);
+
+// }
+// void ElectrodePlot::mouseDragY(int dy, bool shift, bool ctrl){
+//     if (selectedAxes == NULL || dy==0)
+//         return;
+//     if(shift)
+//         zoomAxes(selectedAxesN, false, dy);
+//     if(ctrl)
+//         panAxes(selectedAxesN, false, dy);
+// }
+
+// void ElectrodePlot::zoomAxes(int n, bool xdim, int zoom){
+// //    std::cout<<"ElectrodePlot::zoomAxes() n:"<< n<<" xdim"<< xdim<<" in:"<<zoomin<<std::endl;
+//     // If trying to zoom an invalid axes type
+//     if (n<WAVE1 || n>PROJ3x4)
+//         return;
+//     if (n<=WAVE4)
+//         zoomWaveform(n, xdim, zoom);
+//     else
+//         zoomProjection(n, xdim, zoom);
+// }
+
+// void ElectrodePlot::zoomWaveform(int n, bool xdim, int zoom){
+
+//     // waveform plots don't have a xlimits
+//     if (xdim)
+//         return;
+// //    std::cout<<"Zooming Waveform:"<<n<<" zoomin:"<<zoomin<<" ";
+//     double min, max;
+    
+//     if(xdim)
+//         return;
+
+//     min = limits[n][0];
+//     max = limits[n][1];
+    
+//     double mean = (max + min)/2.0f;
+//     double delta = max - mean;
+//     delta = delta / pow(.99, -1*zoom);
+
+//     min = mean - delta;
+//     max = mean + delta;
+
+//     limits[n][0] = min;
+//     limits[n][1] = max;
+    
+//     limitsChanged = true;
+// }
+
+// void ElectrodePlot::panAxes(int n, bool xdim, int panval){
+//     //    std::cout<<"ElectrodePlot::zoomAxes() n:"<< n<<" xdim"<< xdim<<" in:"<<zoomin<<std::endl;
+//     // If trying to zoom an invalid axes type
+//     if (n<WAVE1 || n>PROJ3x4)
+//         return;
+//     if (n<=WAVE4)
+//         panWaveform(n, xdim, panval);
+//     else
+//         panProjection(n, xdim, panval);
+// }
+
+// void ElectrodePlot::panWaveform(int n, bool xdim, int pan){
+    
+//     // waveform plots don't have a xlimits
+//     if (xdim)
+//         return;
+//     //    std::cout<<"Panning Waveform:"<<n<<" pan:"<<pan<<" "<<std::endl;
+//     double min, max;
+    
+//     if(xdim)
+//         return;
+    
+//     min = limits[n][0];
+//     max = limits[n][1];
+    
+//     double dy = max-min;
+    
+//     // Need to grab something if pan event is driven by the keyboard, which means that all the plots are getting panned so this should be okay
+//     if (selectedAxes == NULL)
+//         selectedAxes = &axesList.front();
+    
+//     double yPixels = (BaseUIElement::height - titleHeight)/2.0;
+    
+//     double pixelWidth = -1 * dy/yPixels;
+    
+//     double delta = pan * pixelWidth;
+//     min = min + delta;
+//     max = max + delta;
+    
+//     limits[n][0] = min;
+//     limits[n][1] = max;
+    
+//     limitsChanged = true;
+// }
+
+
+
+bool ElectrodePlot::processKeyEvent(SimpleKeyEvent k){
+    // std::cout<<"Key:"<<(char)k.key<<std::endl;
+    // switch(k.key)
+    // {
+    //     case '=':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             zoomWaveform(i, false, 3);
+    //         break;        
+    //     case '+':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             panWaveform(i, false, 3);
+    //         break;
+    //     case '-':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             zoomWaveform(i, false, -3);
+    //         break;    
+    //     case '_':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             panWaveform(i, false, -3);
+    //         break;
+    //     case 'C':
+    //         clearOnNextDraw(true);
+    //         break;
+    // }
+}
+
+
diff --git a/Source/Processors/Visualization/SpikePlotting/ElectrodePlot.h b/Source/Processors/Visualization/SpikePlotting/ElectrodePlot.h
new file mode 100644
index 0000000000000000000000000000000000000000..6377aa42c15b538396966600feebcca7d6043a2e
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/ElectrodePlot.h
@@ -0,0 +1,66 @@
+#ifndef ELECTRODE_PLOT_H
+#define ELECTRODE_PLOT_H
+
+#if defined(__linux__)
+	#include <GL/glut.h>
+#else
+	#include <GLUT/glut.h>
+#endif
+#include <list>
+#include <math.h>
+
+#include "WaveAxes.h"
+#include "BaseUIElement.h"
+#include "PlotUtils.h"
+#include "SimpleKeyEvent.h"
+
+
+class ElectrodePlot : public BaseUIElement{
+	
+	bool enabled;
+    
+    bool limitsChanged;
+    double limits[1][2];
+    
+    WaveAxes axes;
+    
+    
+    
+    // void zoomAxes(int n, bool xdim, int zoomval);
+    // void zoomProjection (int n, bool xdim, int zoomval);
+    // void zoomWaveform (int n, bool xdim, int zoomval);
+    
+    // void panAxes(int n, bool xdim, int panval);
+    // void panProjection (int n, bool xdim, int panval);
+    // void panWaveform(int n, bool xdim, int panval);
+    
+    void initLimits();
+	
+public:
+	ElectrodePlot();
+	ElectrodePlot(int x, int y,int w,int h);
+	~ElectrodePlot();
+
+	void initAxes();
+	void redraw();
+	void setEnabled(bool enabled);
+	bool getEnabled();
+	void setPosition(int,int,double,double);
+
+	void getPreferredDimensions(double*, double*);
+
+	int getNumberOfAxes();
+    
+    void mouseDown(int x, int y);
+    
+    void mouseDragX(int dx, bool shift, bool ctr);
+    void mouseDragY(int dy, bool shift, bool ctr);
+
+    bool processKeyEvent(SimpleKeyEvent k);
+
+    void processSpikeObject(SpikeObject s);
+};
+
+
+
+#endif
diff --git a/Source/Processors/Visualization/SpikePlotting/GenericAxes.cpp b/Source/Processors/Visualization/SpikePlotting/GenericAxes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dfb7a815e63cabf7a5cdc8671783af56e786b0f2
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/GenericAxes.cpp
@@ -0,0 +1,68 @@
+#include "GenericAxes.h"
+
+GenericAxes::GenericAxes():
+					BaseUIElement(),
+					type(0),
+					gotFirstSpike(false)
+{	
+	ylims[0] = 0;
+	ylims[1] = 1;
+	loadFont();
+}
+
+GenericAxes::GenericAxes(int x, int y, double w, double h, int t):
+					BaseUIElement(x,y,w,h),
+					gotFirstSpike(false)
+{
+	type = t;
+	loadFont();
+}
+GenericAxes::~GenericAxes(){
+	//delete font;
+}
+void GenericAxes::updateSpikeData(SpikeObject newSpike){
+	if (!gotFirstSpike){
+		gotFirstSpike = true;	
+	}
+
+	s = newSpike;
+}
+
+void GenericAxes::loadFont(){
+	const unsigned char* buffer = reinterpret_cast<const unsigned char*>(BinaryData::cpmono_plain_otf);
+	size_t bufferSize = BinaryData::misoregular_ttfSize;
+	font = new FTPixmapFont(buffer, bufferSize);
+}
+
+void GenericAxes::setYLims(double ymin, double ymax){
+	ylims[0] = ymin;
+	ylims[1] = ymax;
+}
+void GenericAxes::getYLims(double *min, double *max){
+	*min = ylims[0];
+	*max = ylims[1];
+}
+void GenericAxes::setXLims(double xmin, double xmax){
+	xlims[0] = xmin;
+	xlims[1] = xmax;
+}
+void GenericAxes::getXLims(double *min, double *max){
+	*min = xlims[0];
+	*max = xlims[1];
+}
+
+void GenericAxes::setType(int t){
+	 if (t<WAVE1 || t>PROJ3x4){
+		std::cout<<"Invalid Axes type specified";
+		return;
+	}	
+	type = t;
+}
+
+int GenericAxes::getType(){
+    return type;
+}
+
+void GenericAxes::setPosition(int x, int y, double w, double h){
+	BaseUIElement::setPosition(x,y,w,h);	
+}
diff --git a/Source/Processors/Visualization/SpikePlotting/GenericAxes.h b/Source/Processors/Visualization/SpikePlotting/GenericAxes.h
new file mode 100644
index 0000000000000000000000000000000000000000..3ef432ed9ab4a6da1d751631da966987f6638b13
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/GenericAxes.h
@@ -0,0 +1,60 @@
+#ifndef GENERIC_AXES_H_
+#define GENERIC_AXES_H_
+
+
+#if defined(__linux__)
+	#include <GL/glut.h>
+#else
+	#include <GLUT/glut.h>
+#endif
+#include <stdlib.h>
+#include <FTGL/ftgl.h>
+#include "../../../../JuceLibraryCode/JuceHeader.h"
+
+#include "../SpikeObject.h"
+
+#include "BaseUIElement.h"
+#include "PlotUtils.h"
+
+ 	
+class GenericAxes: public BaseUIElement{
+
+protected:
+	double xlims[2];
+	double ylims[2];
+	SpikeObject s;
+
+	bool gotFirstSpike;
+	
+	int type;
+	virtual void plot(){}
+
+	FTPixmapFont* font;
+	void loadFont();
+
+	
+public:
+	GenericAxes();
+	GenericAxes(int x, int y, double w, double h, int t);
+	~GenericAxes();
+
+	void updateSpikeData(SpikeObject s);
+
+	virtual void redraw(){}
+	
+	void setXLims(double xmin, double xmax);
+	void getXLims(double *xmin, double *xmax);
+	void setYLims(double ymin, double ymax);
+	void getYLims(double *ymin, double *ymax);
+
+	void setType(int type);
+	int getType();
+    
+	
+	void setPosition(int,int,double,double);
+   	
+};
+
+
+
+#endif
diff --git a/Source/Processors/Visualization/SpikePlotting/PlotUtils.cpp b/Source/Processors/Visualization/SpikePlotting/PlotUtils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8da171314791dfc157b19606d578972e45af703e
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/PlotUtils.cpp
@@ -0,0 +1,227 @@
+#include "PlotUtils.h"
+
+void checkGlError(){
+	GLenum errCode;
+	const GLubyte *errString;
+	if ((errCode = glGetError()) != GL_NO_ERROR) {
+	    errString = gluErrorString(errCode);
+	   	fprintf (stderr, "OpenGL Error: %s\n", errString);
+		exit(1);
+	}
+	else
+		std::cout<<"OpenGL Okay!"<<std::endl;
+}
+
+void drawString(float x, float y, void *f, const char *string){
+	glRasterPos2f(x, y);
+	int len = strlen(string);
+	// glColor3f(1.0, 1.0, 1.0);
+	for (int i = 0; i < len; i++) {
+ 		//glutBitmapCharacter(f, string[i]);
+	}
+}
+
+void drawString(float x, float y, int size, String s, FTPixmapFont* f){
+	
+	glRasterPos2f(x, y);
+
+	f->FaceSize(size);
+	f->Render(s);
+}
+
+void drawViewportEdge(){
+	glPushMatrix();
+	glLoadIdentity();
+	
+	glBegin(GL_LINE_LOOP);
+		glVertex2f(-.995, -.995);
+		glVertex2f( .995, -.995);
+		glVertex2f( .995, .995);
+		glVertex2f(-.995, .995);
+	glEnd();
+	
+	glPopMatrix();
+}
+
+void drawViewportCross(){
+	glColor3f(0.0,1.0,1.0);
+	
+	glPushMatrix();
+	glLoadIdentity();
+	
+	glBegin(GL_LINE_LOOP);
+		glVertex2f(-.995, -.995);
+		glVertex2f( .995, .995);
+		glVertex2f( .995, -.995);
+		glVertex2f(-.995, .995);
+	glEnd();
+	
+	glPopMatrix();
+}
+
+void setViewportRange(int xMin,int yMin,int xMax,int yMax){
+	
+	float dx = xMax-xMin;
+	float dy = yMax-yMin;
+	
+//	printf("Setting viewport to:%d,%d %d,%d with dims%d,%d %d,%d\n", x,y,w,h, xMin, xMin, xMax,yMax);
+//	printf("Dx:%f Dy:%f, Scaling viewport by:%f,%f \n", dx,dy,2.0/dx, 2.0/dy);
+	glLoadIdentity();
+	glTranslatef(-1.0,-1.0,0.0); 
+	glScalef(2.0f/dx, 2.0f/dy, 1.0);
+	glTranslatef(0-xMin, 0-yMin, 0);
+	
+}
+int roundUp(int numToRound, int multiple) 
+{ 
+	if(multiple == 0) 
+ 	{ 
+  		return numToRound; 
+ 	} 
+
+ 	int remainder = numToRound % multiple;
+ 	if (remainder == 0)
+  		return numToRound;
+ 	return numToRound + multiple - remainder;
+}
+
+double ad16ToUv(int x, int gain){	
+	int result =  (double)(x * 20e6) / (double)(gain * pow(2,16));
+	return result;
+}
+
+void makeLabel(int val, int gain, bool convert, char * s){
+	if (convert){
+		double volt = ad16ToUv(val, gain)/1000.;
+		if (abs(val)>1e6){
+			val = val/(1e6);
+			sprintf(s, "%.2fV", volt);
+		}
+		else if(abs(val)>1e3){
+			val = val/(1e3);
+			sprintf(s, "%.2fmV", volt);
+		}
+		else
+			sprintf(s, "%.2fuV", volt);
+	}
+	else
+		sprintf(s,"%d", (int)val);		
+}
+
+void n2ProjIdx(int proj, int *p1, int *p2){
+    int d1, d2;
+	if (proj==PROJ1x2){
+		d1 = 0;
+		d2 = 1;
+	}
+	else if(proj==PROJ1x3){
+		d1 = 0;
+		d2 = 2;
+	}
+	else if(proj==PROJ1x4){
+		d1 = 0;
+		d2 = 3;
+	}
+	else if(proj==PROJ2x3){
+		d1 = 1;
+		d2 = 2;
+	}
+	else if(proj==PROJ2x4){
+		d1 = 1;
+		d2 = 3;
+	}
+	else if (proj==PROJ3x4){
+		d1 = 2;
+		d2 = 3;
+	}
+	else{
+		std::cout<<"Invalid projection:"<<proj<<"! Cannot determine d1 and d2"<<std::endl;
+        *p1 = -1;
+        *p2 = -1;
+		return;
+	}
+    *p1 = d1;
+    *p2 = d2;
+}
+
+
+bool isFrameBufferExtensionSupported(){
+
+    std::cout<<"Checking to see if the OpenGL Frame Buffer Extension is Supported"<<std::endl;
+    
+    char* str = 0;
+    char* tok = 0;
+
+    std::string fboExt = "GL_EXT_framebuffer_object";
+
+    str = (char*)glGetString(GL_EXTENSIONS);
+           
+    if(str)
+    {
+        std::vector <std::string> extensions;
+        tok = strtok((char*)str, " ");
+        while(tok)
+        {          
+
+            std::string ext = tok;
+
+            if (ext == fboExt)
+                return true;
+
+            tok = strtok(0, " ");         
+        }
+        return false;
+    }
+    else
+        return false;
+}
+
+bool checkFramebufferStatus()
+{
+    // check FBO status
+    GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+    return status == GL_FRAMEBUFFER_COMPLETE_EXT;
+
+    switch(status)
+    {
+    case GL_FRAMEBUFFER_COMPLETE_EXT:
+        std::cout << "Framebuffer complete." << std::endl;
+        return true;
+
+    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+        std::cout << "[ERROR] Framebuffer incomplete: Attachment is NOT complete." << std::endl;
+        return false;
+
+    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
+        std::cout << "[ERROR] Framebuffer incomplete: No image is attached to FBO." << std::endl;
+        return false;
+
+    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
+        std::cout << "[ERROR] Framebuffer incomplete: Attached images have different dimensions." << std::endl;
+        return false;
+
+    case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
+        std::cout << "[ERROR] Framebuffer incomplete: Color attached images have different internal formats." << std::endl;
+        return false;
+
+    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+        std::cout << "[ERROR] Framebuffer incomplete: Draw buffer." << std::endl;
+        return false;
+
+    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+        std::cout << "[ERROR] Framebuffer incomplete: Read buffer." << std::endl;
+        return false;
+
+    case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+        std::cout << "[ERROR] Unsupported by FBO implementation." << std::endl;
+        return false;
+
+    default:
+        std::cout << "[ERROR] Unknow error." << std::endl;
+        return false;
+    }
+}
+
+// std::addressof was introduced in C++11, an equivalent function is defined below
+// definition from http://en.cppreference.com/w/cpp/memory/addressof
+
diff --git a/Source/Processors/Visualization/SpikePlotting/PlotUtils.h b/Source/Processors/Visualization/SpikePlotting/PlotUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..bffdd3c45fe4b63702286a927c6f17843c57b24d
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/PlotUtils.h
@@ -0,0 +1,59 @@
+#ifndef PLOT_UTILS_H_
+#define PLOT_UTILS_H_
+
+#define GL_GLEXT_PROTOTYPES
+
+#if defined(__linux__)
+	#include <GL/glut.h>
+#else // assume OS X
+	#include <GLUT/glut.h>
+	#include <OpenGL/glu.h>
+	#include <OpenGL/glext.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <cstring>
+#include <iostream>
+#include <vector>
+#include <FTGL/ftgl.h>
+
+#include "../../../../JuceLibraryCode/JuceHeader.h"
+
+#define WAVE1 0
+#define WAVE2 1
+#define WAVE3 2
+#define WAVE4 3
+#define PROJ1x2 4
+#define PROJ1x3 5
+#define PROJ1x4 6
+#define PROJ2x3 7
+#define PROJ2x4 8
+#define PROJ3x4 9
+
+void checkGlError();
+void setViewportRange(int xMin,int xMax,int yMin,int yMax);
+
+void drawString(float x, float y, void *f, const char *string);
+void drawString(float x, float y, int size, String s, FTPixmapFont* f);
+
+void drawViewportEdge();
+
+void drawViewportCross();
+
+int roundUp(int, int);
+
+double ad16ToUv(int ad, int gain);
+
+void makeLabel(int val, int gain, bool convert, char * s);
+
+void n2ProjIdx(int i, int *p1, int *p2);
+
+template< class T >
+T* addressof(T& arg) {
+    return (T*)&(char&)arg;
+}
+
+bool isFrameBufferExtensionSupported();
+bool checkFramebufferStatus();
+#endif
\ No newline at end of file
diff --git a/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.cpp b/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..204f579643386a60053d50bceedc6df80c8afb93
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.cpp
@@ -0,0 +1,329 @@
+#include "ProjectionAxes.h"
+
+ProjectionAxes::ProjectionAxes():
+					GenericAxes(),
+					drawGrid(false),
+					overlay(false),
+					convertLabelUnits(true),
+					buffIdx(-1),
+					totalSpikes(0),
+					newSpike(false),
+					isTextureValid(false), 
+					allSpikesNextRender(false)
+{	
+	GenericAxes::type = PROJ1x2;
+	GenericAxes::gotFirstSpike = false;
+	
+	ylims[0] = 0;
+	ylims[1] = 1;
+	setPointColor(1.0,1.0,1.0);
+	n2ProjIdx(type, &ampDim1, &ampDim2);
+
+	clearOnNextDraw = false;
+}
+
+ProjectionAxes::ProjectionAxes(int x, int y, double w, double h, int t):
+					GenericAxes(x,y,w,h,t),
+					drawGrid(true),
+					overlay(false),
+					convertLabelUnits(true),
+					buffIdx(-1),
+					totalSpikes(0),
+					newSpike(false),
+					isTextureValid(false),
+					allSpikesNextRender(false)
+{	
+	GenericAxes::gotFirstSpike = false;
+
+	setPointColor(1.0,1.0,1.0);
+
+	n2ProjIdx(type, &ampDim1, &ampDim2);
+
+	clearOnNextDraw = false;
+}
+
+void ProjectionAxes::updateSpikeData(SpikeObject s){
+	//std::cout<<"ProjectionAxes::updateSpikeData()"<<std::endl;
+	GenericAxes::updateSpikeData(s);
+
+	buffIdx++;
+	if (buffIdx >= AMP_BUFF_MAX_SIZE)
+		buffIdx %= AMP_BUFF_MAX_SIZE;
+
+	int idx1, idx2;
+	calcWaveformPeakIdx(ampDim1,ampDim2,&idx1, &idx2);
+
+	ampBuffer[0][buffIdx] = s.data[idx1];
+	ampBuffer[1][buffIdx] = s.data[idx2];
+	newSpike = true;
+}
+
+void ProjectionAxes::redraw(){
+	
+	BaseUIElement::redraw();
+	
+	plot();
+	
+	BaseUIElement::drawElementEdges();
+}
+
+
+void ProjectionAxes::plot(){
+	//setViewportRange(xlims[0], ylims[0], xlims[1], ylims[1]);
+
+	GLenum errCode;
+	const GLubyte *errString;
+
+	// Should we plot all spikes to the texture or just the newest one
+	bool allSpikes = false;
+
+	if (!isTextureValid){
+		std::cout<<"ProjectionAxes::plot() --> Texture is invalid regenerating it!"<<std::endl;
+        createTexture();
+		allSpikes = true;
+    }
+
+	if (clearOnNextDraw){
+		clearTexture();
+		clearOnNextDraw = false;
+	}
+	
+	drawSpikesToTexture(allSpikes);
+	drawTexturedQuad();
+	plotNewestSpike();
+
+	// if there has been an openGL error we need to rerender the texture and replot everything
+	// errors occur when the openGL context has been destroyed and recreated. I'm not sure how to 
+	// explicitly catch that event so instead we check for a drawing error.
+	if ((errCode = glGetError()) != GL_NO_ERROR) {
+	   errString = gluErrorString(errCode);
+	   std::cout<<"OpenGL Error:"<< errString << "! Invalidating and rerendering the texture!" << std::endl;
+	   
+	   invalidateTexture();
+	   plot();
+	   return;
+	}
+}
+
+void ProjectionAxes::plotOldSpikes(bool allSpikes){
+	//std::cout<<"ProjectionAxes::plotOldSpikes() allSpikes:"<<allSpikes<<std::endl;
+	
+	//set the viewport to the size of the texture
+	glViewport(0,0,texWidth, texHeight);
+	
+	//set the plotting range for the viewport to the limits of the plot
+	setViewportRange(xlims[0], ylims[0], xlims[1], ylims[1]);
+	
+	// if allSpikes plot start with 1 else start with buffIdx
+	int startIdx = (allSpikes) ? 1 : buffIdx;
+	// either plot to totalSpikes or the end of the buffer if total spikes has wrapped
+	int stopIdx = (totalSpikes > AMP_BUFF_MAX_SIZE) ? AMP_BUFF_MAX_SIZE : buffIdx;
+
+	// if (allSpikes)
+	// 	std::cout<<"\tUpdating texture with all spikes: "<< stopIdx - startIdx + 1 <<std::endl;
+
+	glColor3f(1.0, 1.0, 1.0);
+	glPointSize(1);
+	glBegin(GL_POINTS);
+		for (int i=startIdx; i<=stopIdx; i++)		
+			glVertex2i(ampBuffer[0][i], ampBuffer[1][i]);
+	glEnd();
+
+}
+
+
+void ProjectionAxes::plotNewestSpike(){
+	
+	BaseUIElement::setGlViewport();
+	setViewportRange(xlims[0], ylims[0], xlims[1], ylims[1]);
+
+	// draw the newest spike as a big red point so it stands out against the old spikes
+	glColor3f(1.0, 0.0, 0.0);
+	glPointSize(4);
+
+	glBegin(GL_POINTS);
+        glVertex2i(ampBuffer[0][buffIdx], ampBuffer[1][buffIdx]);
+	glEnd();
+
+	newSpike = false;
+}
+
+ void ProjectionAxes::calcWaveformPeakIdx(int d1, int d2, int *idx1, int *idx2){
+
+	int max1 = -1*pow(2,15);
+	int max2 = max1;
+	
+	for (int i=0; i<s.nSamples ; i++){
+		if (s.data[d1*s.nSamples + i] > max1)
+		{	
+			*idx1 = d1*s.nSamples+i;
+			max1 = s.data[*idx1];
+		}
+		if (s.data[d2*s.nSamples+i] > max2)
+		{	
+			*idx2 = d2*s.nSamples+i;
+			max2 = s.data[*idx2];
+		}
+	}
+}
+
+void ProjectionAxes::setPosition(int x, int y, int w, int h){
+	// std::cout<<"ProjectionAxes::setPosition()"<<std::endl;
+	
+	// only invalidate the texture if its size has actually changed
+	if (w!=GenericAxes::width || h!=GenericAxes::height)
+		invalidateTexture();
+
+	GenericAxes::setPosition(x,y,w,h);
+}
+
+void ProjectionAxes::setPointColor(GLfloat r, GLfloat g, GLfloat b){
+	pointColor[0] = r;
+	pointColor[1] = g;
+	pointColor[2] = b;
+}
+void ProjectionAxes::setGridColor(GLfloat r, GLfloat g, GLfloat b){
+	gridColor[0] = r;
+	gridColor[1] = g;
+	gridColor[2] = b;
+}
+
+
+void ProjectionAxes::createTexture(){
+		
+	texWidth = BaseUIElement::width;
+	texHeight = BaseUIElement::height;
+
+  	std::cout<<"Creating a new texture of size:"<<texWidth<<"x"<<texHeight<<std::endl;
+  	// Delete the old texture
+    glDeleteTextures(1, &textureId);
+    // Generate a new texture 
+    glGenTextures(1, &textureId);
+    // Bind the texture, and set the appropriate parameters
+    glBindTexture(GL_TEXTURE_2D, textureId);
+    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); 
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+    // generate a new FrameBufferObject
+    createFBO();
+
+    // the texture should now be valid, set the flag appropriately
+    isTextureValid = true;
+
+}
+
+void ProjectionAxes::createFBO(){
+	std::cout<<"Creating a new frame buffer object"<<std::endl;
+
+	// if (!isTextureValid)
+	// 	createTexture();
+	// Delete the old frame buffer, render buffer
+	glDeleteFramebuffers(1, &fboId);
+	glDeleteRenderbuffers(1, &rboId);
+
+	// Generate and Bind the frame buffer
+	glGenFramebuffersEXT(1, &fboId);
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
+
+	// Generate and bind the new Render Buffer
+	glGenRenderbuffersEXT(1, &rboId);
+	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId);
+	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, texWidth, texHeight);
+	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+
+	// Attach the texture to the framebuffer
+	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0);
+	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId);
+
+	// If the FrameBuffer wasn't created then we have a bigger problem. Abort the program.
+	if(!checkFramebufferStatus()){
+	    std::cout<<"FrameBufferObject not created! Are you running the newest version of OpenGL?"<<std::endl;
+	    std::cout<<"FrameBufferObjects are REQUIRED! Quitting!"<<std::endl;
+	    exit(1);
+	}
+
+	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+}
+
+void ProjectionAxes::drawSpikesToTexture(bool allSpikes){
+	
+	//std::cout<<"ProjectionAxes::drawSpikesToTexture() plotting all spikes:"<<allSpikes<<std::endl;
+	
+
+	// For some reason if we want to plot ALL the spikes to a texture we must plot two draw cycles
+	// in a row, perhaps this has to do with double buffering, i'm not sure why... investigae this!
+	
+	// if the allSpikes flag is set we set the allSpikesNextRender as true so we plot next
+	// all spikes next render cycle too, if only the allSpikesNextRender is true we set all spikes
+	// to true and allSpikes next render to false.  
+
+	//Basically this logic ensures that if allSpikes is ever set to true it will be set to true
+	//on the next call to drawSpikesToTexture() regardless of what value it is actually set to
+	if (allSpikes)
+		allSpikesNextRender = true;
+	else if (!allSpikes && allSpikesNextRender)
+	{
+		allSpikes = true;
+		allSpikesNextRender = false;
+	}
+	// set the rendering destination to FBO
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);    
+	
+    // plot to the texture
+    plotOldSpikes(allSpikes);
+
+    // bind the original FrameBuffer
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 
+}
+
+void ProjectionAxes::invalidateTexture(){
+	isTextureValid = false;
+}
+
+
+void ProjectionAxes::drawTexturedQuad(){
+	BaseUIElement::setGlViewport();
+	// We need to scale the viewport in this case because we want to fill it with a quad. 
+	// if we load identity then we can use a quad bound by (-1, 1);
+    glLoadIdentity();
+
+    // Bind the texture to render
+    glBindTexture(GL_TEXTURE_2D, textureId);
+
+    // Build the quad
+    int size = 1;
+    int texS = 1;
+    glBegin(GL_QUADS);
+        glColor4f(1, 1, 1, 1);
+        glTexCoord2f(texS,  texS);  glVertex3f(size,        size,0);
+        glTexCoord2f(0,     texS);  glVertex3f(-1 * size ,  size,0);
+        glTexCoord2f(0,     0);     glVertex3f(-1 * size,   -1 * size,0);
+        glTexCoord2f(texS,  0);     glVertex3f(size,        -1 * size,0);
+    glEnd();
+    
+    // Unbind the texture
+    glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void ProjectionAxes::clear(){
+	
+	//reset buffIDx and totalSpikes
+	buffIdx = 0;
+	totalSpikes = 0;
+	
+	// set flag to clear on next draw
+	clearOnNextDraw = true;	
+}
+
+void ProjectionAxes::clearTexture(){
+	std::cout<<"ProjectinAxes::clearTexture() --> Clearing the Texture!"<<std::endl;
+
+	glViewport(0,0,texWidth, texHeight);
+	setViewportRange(xlims[0], ylims[0], xlims[1], ylims[1]);
+
+	// set the rendering destination to FBO
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);    
+    // Clear the framebufferObject
+  	glClearColor (0, 0, 0, 1);
+	glClear(GL_COLOR_BUFFER_BIT);
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 
+}
\ No newline at end of file
diff --git a/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.h b/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3fdfd0c1b65fc75e6bb76c82ae518449fc86c67
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/ProjectionAxes.h
@@ -0,0 +1,94 @@
+#ifndef PROJECTION_AXES_H_
+#define PROJECTION_AXES_H_
+
+#define GL_GLEXT_PROTOTYPES
+
+#if defined(__linux__)
+	#include <GL/glut.h>
+#else
+	#include <GLUT/glut.h>
+#endif
+#include <stdlib.h>
+#include "BaseUIElement.h"
+#include "../SpikeObject.h"
+#include "PlotUtils.h"
+#include "GenericAxes.h"
+#include <stdint.h>
+
+#define AMP_BUFF_MAX_SIZE 50000
+ 	
+class ProjectionAxes: public GenericAxes{
+	
+	GLfloat pointColor[3];
+	GLfloat gridColor[3];
+
+	int ampBuffer[2][AMP_BUFF_MAX_SIZE];
+	uint16_t buffIdx; // points to the most recent spike
+	uint64_t totalSpikes;
+
+
+	int ampDim1, ampDim2;
+		
+	
+  	void drawProjectionGrid(int thold, int gain);
+  	void calcWaveformPeakIdx(int, int, int*, int*);
+
+  	void createTexture();
+  	void createFBO();
+
+  	void drawSpikesToTexture(bool allSpikes);
+  	// void updateTexture();
+  	void drawTexturedQuad();
+  	void plotOldSpikes(bool allSpikes);
+  	void plotNewestSpike();
+
+  	bool newSpike;
+
+  	
+  	GLuint fboId; // Frame Buffer Object 
+  	GLuint textureId; // Texture 
+  	GLuint rboId; // Render Buffer 
+
+  	int texWidth;
+  	int texHeight;
+
+  	bool clearOnNextDraw;
+ 	bool isTextureValid;
+  	void clearTexture();
+
+  	void validateTexture();
+
+  	bool allSpikesNextRender;
+
+protected:
+	void plot();
+
+
+public:
+	ProjectionAxes();
+	ProjectionAxes(int x, int y, double w, double h, int t);
+    
+   	void setPosition(int, int, int, int);
+   	void updateSpikeData(SpikeObject s);
+
+	void setPointColor(GLfloat r, GLfloat g, GLfloat b);
+	void setGridColor(GLfloat, GLfloat, GLfloat);
+	
+	void clear();
+	void invalidateTexture();
+
+	void redraw();	
+	
+	bool overlay;
+	bool drawGrid;
+	bool convertLabelUnits;
+
+	
+};
+
+#endif  // PROJECTION_AXES_H_
+
+
+
+
+// #endif
diff --git a/Source/Processors/Visualization/SpikePlotting/SimpleKeyEvent.h b/Source/Processors/Visualization/SpikePlotting/SimpleKeyEvent.h
new file mode 100644
index 0000000000000000000000000000000000000000..1ce4277790e72b9f3d90dca14e4f187011adf23e
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/SimpleKeyEvent.h
@@ -0,0 +1,25 @@
+#ifndef SIMPLE_KEY_EVENT_H
+#define SIMPLE_KEY_EVENT_H
+
+struct SimpleKeyEvent{
+    
+    int key;
+    bool shift;
+    bool ctrl;
+    bool alt;
+//    
+//    ArteKeyEvent(){
+//        key = 0;
+//        shift = false;
+//        ctrl = false;
+//        alt = false;
+//    }
+//    ArteKeyEvent(int k){
+//        key = k;
+//        shift = false;
+//        `ctrl = false;
+//        alt = false;
+//    }
+};
+
+#endif
\ No newline at end of file
diff --git a/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.cpp b/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c8fe109639256817d29504eda70c9a8e403df23d
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.cpp
@@ -0,0 +1,193 @@
+#include "StereotrodePlot.h"
+#include "../SpikeObject.h"
+#include "PlotUtils.h"
+
+StereotrodePlot::StereotrodePlot():
+	BaseUIElement(),  limitsChanged(true)
+{
+
+}
+
+StereotrodePlot::StereotrodePlot(int x, int y, int w, int h):
+	BaseUIElement(x,y,w,h,0), limitsChanged(true)
+{
+
+	initAxes();
+}
+
+StereotrodePlot::~StereotrodePlot(){
+}
+
+// Each plot needs to update its children axes when its redraw gets called.
+//  it also needs to call the parent plot  when children axes get added it
+//  should place them in the correct location because it KNOWS where WAVE1 and PROJ1x3
+//  should go by default. This isn't as general as it should be but its a good push in
+//  the right direction
+
+void StereotrodePlot::redraw(){
+	//std::cout<<"StereotrodePlot() starting drawing"<<std::endl;\
+	//BaseUIElement::clearNextDraw = true;
+	//BaseUIElement::redraw();
+
+	wAxes[0].redraw();
+    wAxes[1].redraw();
+    pAxes.redraw();
+}
+
+// This would normally happen for collection of axes but an electrode plot doesn't have a collection instead its a single axes
+void StereotrodePlot::processSpikeObject(SpikeObject s){
+	//std::cout<<"ElectrdePlot::processSpikeObject()"<<std::endl;
+	wAxes[0].updateSpikeData(s);
+    wAxes[1].updateSpikeData(s);
+    pAxes.updateSpikeData(s);
+}
+
+void StereotrodePlot::setEnabled(bool e){
+	BaseUIElement::enabled = e;
+
+	wAxes[0].setEnabled(e);
+    wAxes[1].setEnabled(e);
+    pAxes.setEnabled(e);
+}
+
+bool StereotrodePlot::getEnabled(){
+	return BaseUIElement::enabled;
+}
+
+
+void StereotrodePlot::initAxes(){
+	initLimits();
+    
+    int minX = BaseUIElement::xpos;
+	int minY = BaseUIElement::ypos;
+	
+	double axesWidth = BaseUIElement::width/2;
+	double axesHeight = BaseUIElement::height;
+	
+	
+	wAxes[0] = WaveAxes(minX, minY, axesWidth/2, axesHeight, WAVE1);
+    wAxes[1] = WaveAxes(minX + axesWidth/2, minY, axesWidth/2, axesHeight, WAVE2);
+    pAxes = ProjectionAxes(minX + axesWidth, minY, axesWidth, axesHeight, PROJ1x2);
+
+    wAxes[0].setWaveformColor(1.0, 1.0, 1.0);
+    wAxes[1].setWaveformColor(1.0, 1.0, 1.0);
+    pAxes.setPointColor(1.0, 1.0, 1.0);
+
+    setLimitsOnAxes();
+}
+
+void StereotrodePlot::setLimitsOnAxes(){
+    std::cout<<"StereotrodePlot::setLimitsOnAxes()"<<std::endl;
+    
+    wAxes[0].setYLims(limits[0][0], limits[0][1]);
+    wAxes[1].setYLims(limits[1][0], limits[1][1]);
+    pAxes.setYLims(limits[0][0], limits[0][1]);
+    pAxes.setXLims(limits[1][0], limits[1][1]);
+    
+
+}
+void StereotrodePlot::setPosition(int x, int y, double w, double h){
+    
+//    std::cout<<"StereotrodePlot::setPosition()"<<std::endl;
+	BaseUIElement::setPosition(x,y,w,h);
+	int minX = BaseUIElement::xpos;
+	int minY = BaseUIElement::ypos;
+	
+	double axesWidth = BaseUIElement::width/2;
+	double axesHeight = BaseUIElement::height;
+	
+    wAxes[0].setPosition(minX, minY, axesWidth/2, axesHeight);
+    wAxes[1].setPosition(minX + axesWidth/2, minY, axesWidth/2, axesHeight);	
+    pAxes.setPosition(minX + axesWidth, minY, axesWidth, axesHeight);
+}
+
+int StereotrodePlot::getNumberOfAxes(){
+	return 2;
+}
+
+void StereotrodePlot::initLimits(){
+    for (int i=0; i<2; i++)
+    {
+        limits[i][0] = -1*pow(2,11);
+        limits[i][1] = pow(2,14)*1.6;
+    }
+
+}
+
+void StereotrodePlot::getPreferredDimensions(double *w, double *h){
+    *w = 75;
+    *h = 75;
+}
+
+void StereotrodePlot::clear(){
+    std::cout<<"StereotrodePlot::clear()"<<std::endl;
+    pAxes.clear();
+}
+
+
+bool StereotrodePlot::processKeyEvent(SimpleKeyEvent k){
+    // std::cout<<"Key:"<<(char)k.key<<std::endl;
+    // switch(k.key)
+    // {
+    //     case '=':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             zoomWaveform(i, false, 3);
+    //         break;        
+    //     case '+':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             panWaveform(i, false, 3);
+    //         break;
+    //     case '-':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             zoomWaveform(i, false, -3);
+    //         break;    
+    //     case '_':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             panWaveform(i, false, -3);
+    //         break;
+    //     case 'C':
+    //         clearOnNextDraw(true);
+    //         break;
+    // }
+}
+
+void StereotrodePlot::pan(int dim, bool up){
+
+    std::cout<<"StereotrodePlot::pan() dim:"<<dim<<std::endl;
+    if (dim>1 || dim<0)
+        return;
+    
+    int mean = (limits[dim][0] + limits[dim][1])/2;
+    int dLim = limits[dim][1] - mean;
+    
+    if (up)
+        mean = mean + dLim/20;
+    else
+        mean = mean - dLim/20;
+
+    limits[dim][0] = mean-dLim;
+    limits[dim][1] = mean+dLim;
+
+    setLimitsOnAxes();
+}
+void StereotrodePlot::zoom(int dim, bool in){
+    std::cout<<"StereotrodePlot::zoom()"<<std::endl;
+
+    if (dim>1 || dim<0)
+        return;
+    
+    int mean = (limits[dim][0] + limits[dim][1])/2;
+    int dLim = limits[dim][1] - mean;
+    
+    if (in)
+        dLim = dLim * .90;
+    else
+        dLim = dLim / .90;
+
+    limits[dim][0] = mean-dLim;
+    limits[dim][1] = mean+dLim;
+
+    setLimitsOnAxes();
+}
+
+
diff --git a/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.h b/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.h
new file mode 100644
index 0000000000000000000000000000000000000000..73ce14f5b1287098ac9121062243d95e0c3f059b
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/StereotrodePlot.h
@@ -0,0 +1,75 @@
+#ifndef STEROETRODE_PLOT_H_
+#define STEROETRODE_PLOT_H_
+
+#if defined(__linux__)
+	#include <GL/glut.h>
+#else
+	#include <GLUT/glut.h>
+#endif
+#include <list>
+#include <math.h>
+
+#include "WaveAxes.h"
+#include "ProjectionAxes.h"
+#include "BaseUIElement.h"
+#include "PlotUtils.h"
+#include "SimpleKeyEvent.h"
+
+
+class StereotrodePlot : public BaseUIElement{
+	
+	bool enabled;	
+    
+    bool limitsChanged;
+    double limits[2][2];
+    
+    WaveAxes wAxes[2];
+    ProjectionAxes pAxes;
+    
+    
+    
+    // void zoomAxes(int n, bool xdim, int zoomval);
+    // void zoomProjection (int n, bool xdim, int zoomval);
+    // void zoomWaveform (int n, bool xdim, int zoomval);
+    
+    // void panAxes(int n, bool xdim, int panval);
+    // void panProjection (int n, bool xdim, int panval);
+    // void panWaveform(int n, bool xdim, int panval);
+    
+    void initLimits();
+    void setLimitsOnAxes();
+
+	
+public:
+	StereotrodePlot();
+	StereotrodePlot(int x, int y,int w,int h);
+	~StereotrodePlot();
+
+	void initAxes();
+	void redraw();
+
+	void setEnabled(bool enabled);
+	bool getEnabled();
+	void setPosition(int,int,double,double);
+
+	void getPreferredDimensions(double*, double*);
+
+	int getNumberOfAxes();
+    
+    void mouseDown(int x, int y);
+    
+    void mouseDragX(int dx, bool shift, bool ctr);
+    void mouseDragY(int dy, bool shift, bool ctr);
+
+    bool processKeyEvent(SimpleKeyEvent k);
+
+    void processSpikeObject(SpikeObject s);
+
+    void clear();
+    void zoom(int, bool);
+    void pan(int, bool);
+};
+
+
+
+#endif
diff --git a/Source/Processors/Visualization/SpikePlotting/TetrodePlot.cpp b/Source/Processors/Visualization/SpikePlotting/TetrodePlot.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5d4c86611874fe4cc17669fc4e6224af8826e529
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/TetrodePlot.cpp
@@ -0,0 +1,320 @@
+#include "TetrodePlot.h"
+#include "../SpikeObject.h"
+#include "PlotUtils.h"
+
+TetrodePlot::TetrodePlot():
+    BaseUIElement(), limitsChanged(true)
+{
+}
+
+TetrodePlot::TetrodePlot(int x, int y, int w, int h):
+    BaseUIElement(x,y,w,h,0), limitsChanged(true)
+{
+
+    initAxes();
+}
+
+TetrodePlot::~TetrodePlot(){
+}
+
+// Each plot needs to update its children axes when its redraw gets called.
+//  it also needs to call the parent plot  when children axes get added it
+//  should place them in the correct location because it KNOWS where WAVE1 and PROJ1x3
+//  should go by default. This isn't as general as it should be but its a good push in
+//  the right direction
+
+void TetrodePlot::redraw(){
+     //std::cout<<"TetrodePlot() starting drawing"<<std::endl;\
+    BaseUIElement::clearNextDraw = true;
+   
+    BaseUIElement::redraw();
+   
+    for (int i=0; i<4; i++)
+        wAxes[i].redraw();
+
+    for (int i=0; i<6; i++)
+        pAxes[i].redraw();
+}
+
+// This would normally happen for collection of axes but an electrode plot doesn't have a collection instead its a single axes
+void TetrodePlot::processSpikeObject(SpikeObject s){
+    //std::cout<<"ElectrdePlot::processSpikeObject()"<<std::endl;
+    for (int i=0; i<4; i++)
+        wAxes[i].updateSpikeData(s);
+    for (int i=0; i<6; i++)
+        pAxes[i].updateSpikeData(s);
+}
+
+void TetrodePlot::setEnabled(bool e){
+    BaseUIElement::enabled = e;
+    for (int i=0; i<4; i++)
+        wAxes[i].setEnabled(e);
+    for (int i=0; i<6; i++)
+        pAxes[i].setEnabled(e);
+}
+
+bool TetrodePlot::getEnabled(){
+    return BaseUIElement::enabled;
+}
+
+
+void TetrodePlot::initAxes(){
+    initLimits();
+    
+    int minX = BaseUIElement::xpos;
+    int minY = BaseUIElement::ypos;
+   
+    int axesWidth = BaseUIElement::width/4; 
+    int axesHeight = BaseUIElement::height/2;
+    
+    
+    wAxes[0] = WaveAxes(minX, minY, axesWidth/2, axesHeight, WAVE1);
+    wAxes[1] = WaveAxes(minX + axesWidth/2, minY, axesWidth/2, axesHeight, WAVE2);
+    wAxes[2] = WaveAxes(minX, minY + axesHeight, axesWidth/2, axesHeight, WAVE3);
+    wAxes[3] = WaveAxes(minX + axesWidth/2, minY + axesHeight, axesWidth/2, axesHeight, WAVE4);
+
+    // for (int i=0; i<6; i++)
+    // {
+    //     pAxes[i] = ProjectionAxes(
+    //                     minX + axesWidth * ((i%3)+1),
+    //                     minY + (i/3) * axesHeight, 
+    //                     axesWidth , 
+    //                     axesHeight,
+    //                     i);
+    //}
+    // 
+
+    // because the width of the plot doesn't always divide evenly into 4 we are going to pad the width 
+    // of the 3rd and 6th projection plot to cover up the space cleared by the TetrodePlotElement
+
+    int xPad = 1;
+    pAxes[0] = ProjectionAxes(minX + axesWidth*1, minY,     axesWidth, axesHeight, PROJ1x2);
+    pAxes[1] = ProjectionAxes(minX + axesWidth*2, minY,     axesWidth, axesHeight, PROJ1x3);
+    pAxes[2] = ProjectionAxes(minX + axesWidth*3, minY,     axesWidth+xPad, axesHeight, PROJ1x4);
+    pAxes[3] = ProjectionAxes(minX + axesWidth*1, minY + axesHeight,    axesWidth, axesHeight, PROJ2x3);
+    pAxes[4] = ProjectionAxes(minX + axesWidth*2, minY + axesHeight,    axesWidth, axesHeight, PROJ2x4);
+    pAxes[5] = ProjectionAxes(minX + axesWidth*3, minY + axesHeight,    axesWidth+xPad, axesHeight, PROJ3x4);
+
+    
+    //axes.setEnabled(false);
+    for (int i=0; i<4; i++){
+        wAxes[i].setYLims(-1*pow(2,11), pow(2,14)*1.6);
+        wAxes[i].setWaveformColor(1.0, 1.0, 1.0);
+    }
+    for (int i=0; i<6; i++)
+    {
+        pAxes[i].setXLims(-1*pow(2,11), pow(2,14)*1.6);
+        pAxes[i].setYLims(-1*pow(2,11), pow(2,14)*1.6);
+        pAxes[i].setPointColor(1.0, 1.0, 1.0);
+    }
+
+}
+
+void TetrodePlot::setPosition(int x, int y, double w, double h){
+    BaseUIElement::setPosition(x,y,w,h);
+    int minX = BaseUIElement::xpos;
+    int minY = BaseUIElement::ypos;
+    
+    int axesWidth = BaseUIElement::width/4;
+    int axesHeight = BaseUIElement::height/2;
+    
+    wAxes[0].setPosition(minX, minY, axesWidth/2, axesHeight);
+    wAxes[1].setPosition(minX + axesWidth/2, minY, axesWidth/2, axesHeight);
+    wAxes[2].setPosition(minX, minY + axesHeight, axesWidth/2, axesHeight);
+    wAxes[3].setPosition(minX + axesWidth/2, minY + axesHeight, axesWidth/2, axesHeight);
+
+    // pAxes[0].setPosition(minX + axesWidth*1, minY, axesWidth, axesHeight);
+    // pAxes[1].setPosition(minX + axesWidth*2, minY, axesWidth, axesHeight);
+    // pAxes[2].setPosition(minX + axesWidth*3, minY, axesWidth, axesHeight);
+    // pAxes[3].setPosition(minX + axesWidth*1, minY + axesHeight, axesWidth, axesHeight);
+    // pAxes[4].setPosition(minX + axesWidth*2, minY + axesHeight, axesWidth, axesHeight);
+    // pAxes[5].setPosition(minX + axesWidth*3, minY + axesHeight, axesWidth, axesHeight);
+
+    //titleBox.setPosition(x, y+h-titleHeight-3, w, titleHeight+3);
+}
+
+void TetrodePlot::setPosition(int x, int y){
+    setPosition(x,y, BaseUIElement::width, BaseUIElement::height );
+}
+
+void TetrodePlot::setDimensions(double w, double h){
+    setPosition(BaseUIElement::xpos, BaseUIElement::ypos, w, h);
+}
+
+int TetrodePlot::getNumberOfAxes(){
+    return 1;;
+}
+
+
+void TetrodePlot::initLimits(){
+    for (int i=0; i<4; i++)
+    {
+        limits[i][0] = -1*pow(2,11);
+        limits[i][1] = pow(2,14);
+    }
+
+}
+
+void TetrodePlot::getPreferredDimensions(double *w, double *h){
+    *w = 75;
+    *h = 75;
+}
+// void TetrodePlot::mouseDown(int x, int y){
+
+// //     selectedAxesN = -1;
+// //     std::list<GenericAxes>::iterator i;
+// //     int idx=-1;
+// //     bool hit = false;
+
+// //     selectedAxes = NULL;
+// //     for (i=axesList.begin(); i!=axesList.end(); ++i)
+// //     {
+// //         if (i->hitTest(x,y))
+// //         {
+// //             selectedAxes = addressof(*i);
+// //             selectedAxesN = i->getType();
+// //             hit = true;
+// // //            break;
+// //         }
+// //         idx++;
+// //     }
+// //     if (!hit)
+// //         selectedAxes = NULL;
+// //     if (selectedAxes != NULL)
+// //         std::cout<<"TetrodePlot::mouseDown() hit:"<<selectedAxes<<" AxesType:"<<selectedaxes.getType()<<std::endl;
+// //     else
+// //         std::cout<<"TetrodePlot::mouseDown() NO HIT!"<<std::endl;
+    
+// }
+// void TetrodePlot::mouseDragX(int dx, bool shift, bool ctrl){
+
+// //     if (selectedAxes == NULL || dx==0)
+// //         return;
+// // //    zoomAxes(selectedaxes.getType(), true, dx>0);
+// //     if (shift)
+// //         zoomAxes(selectedAxesN, true, dx);
+// //     if (ctrl)
+// //         panAxes(selectedAxesN, true, dx);
+
+// }
+// void TetrodePlot::mouseDragY(int dy, bool shift, bool ctrl){
+//     if (selectedAxes == NULL || dy==0)
+//         return;
+//     if(shift)
+//         zoomAxes(selectedAxesN, false, dy);
+//     if(ctrl)
+//         panAxes(selectedAxesN, false, dy);
+// }
+
+// void TetrodePlot::zoomAxes(int n, bool xdim, int zoom){
+// //    std::cout<<"TetrodePlot::zoomAxes() n:"<< n<<" xdim"<< xdim<<" in:"<<zoomin<<std::endl;
+//     // If trying to zoom an invalid axes type
+//     if (n<WAVE1 || n>PROJ3x4)
+//         return;
+//     if (n<=WAVE4)
+//         zoomWaveform(n, xdim, zoom);
+//     else
+//         zoomProjection(n, xdim, zoom);
+// }
+
+// void TetrodePlot::zoomWaveform(int n, bool xdim, int zoom){
+
+//     // waveform plots don't have a xlimits
+//     if (xdim)
+//         return;
+// //    std::cout<<"Zooming Waveform:"<<n<<" zoomin:"<<zoomin<<" ";
+//     double min, max;
+    
+//     if(xdim)
+//         return;
+
+//     min = limits[n][0];
+//     max = limits[n][1];
+    
+//     double mean = (max + min)/2.0f;
+//     double delta = max - mean;
+//     delta = delta / pow(.99, -1*zoom);
+
+//     min = mean - delta;
+//     max = mean + delta;
+
+//     limits[n][0] = min;
+//     limits[n][1] = max;
+    
+//     limitsChanged = true;
+// }
+
+// void TetrodePlot::panAxes(int n, bool xdim, int panval){
+//     //    std::cout<<"TetrodePlot::zoomAxes() n:"<< n<<" xdim"<< xdim<<" in:"<<zoomin<<std::endl;
+//     // If trying to zoom an invalid axes type
+//     if (n<WAVE1 || n>PROJ3x4)
+//         return;
+//     if (n<=WAVE4)
+//         panWaveform(n, xdim, panval);
+//     else
+//         panProjection(n, xdim, panval);
+// }
+
+// void TetrodePlot::panWaveform(int n, bool xdim, int pan){
+    
+//     // waveform plots don't have a xlimits
+//     if (xdim)
+//         return;
+//     //    std::cout<<"Panning Waveform:"<<n<<" pan:"<<pan<<" "<<std::endl;
+//     double min, max;
+    
+//     if(xdim)
+//         return;
+    
+//     min = limits[n][0];
+//     max = limits[n][1];
+    
+//     double dy = max-min;
+    
+//     // Need to grab something if pan event is driven by the keyboard, which means that all the plots are getting panned so this should be okay
+//     if (selectedAxes == NULL)
+//         selectedAxes = &axesList.front();
+    
+//     double yPixels = (BaseUIElement::height - titleHeight)/2.0;
+    
+//     double pixelWidth = -1 * dy/yPixels;
+    
+//     double delta = pan * pixelWidth;
+//     min = min + delta;
+//     max = max + delta;
+    
+//     limits[n][0] = min;
+//     limits[n][1] = max;
+    
+//     limitsChanged = true;
+// }
+
+
+
+bool TetrodePlot::processKeyEvent(SimpleKeyEvent k){
+    // std::cout<<"Key:"<<(char)k.key<<std::endl;
+    // switch(k.key)
+    // {
+    //     case '=':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             zoomWaveform(i, false, 3);
+    //         break;        
+    //     case '+':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             panWaveform(i, false, 3);
+    //         break;
+    //     case '-':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             zoomWaveform(i, false, -3);
+    //         break;    
+    //     case '_':
+    //         for (int i=0; i<=WAVE4; i++)
+    //             panWaveform(i, false, -3);
+    //         break;
+    //     case 'C':
+    //         clearOnNextDraw(true);
+    //         break;
+    // }
+}
+
+
diff --git a/Source/Processors/Visualization/SpikePlotting/TetrodePlot.h b/Source/Processors/Visualization/SpikePlotting/TetrodePlot.h
new file mode 100644
index 0000000000000000000000000000000000000000..5eaac34babc43fe918010ed8736628286cb2e58d
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/TetrodePlot.h
@@ -0,0 +1,71 @@
+#ifndef TETRODE_PLOT_H_
+#define TETRODE_PLOT_H_
+
+#if defined(__linux__)
+	#include <GL/glut.h>
+#else
+	#include <GLUT/glut.h>
+#endif
+#include <list>
+#include <math.h>
+
+#include "WaveAxes.h"
+#include "ProjectionAxes.h"
+#include "BaseUIElement.h"
+#include "PlotUtils.h"
+#include "SimpleKeyEvent.h"
+
+
+class TetrodePlot : public BaseUIElement{
+	
+
+	bool enabled;
+
+	    
+    bool limitsChanged;
+    double limits[1][2];
+    
+    WaveAxes wAxes[4];
+    ProjectionAxes pAxes[6];
+       
+    // void zoomAxes(int n, bool xdim, int zoomval);
+    // void zoomProjection (int n, bool xdim, int zoomval);
+    // void zoomWaveform (int n, bool xdim, int zoomval);
+    
+    // void panAxes(int n, bool xdim, int panval);
+    // void panProjection (int n, bool xdim, int panval);
+    // void panWaveform(int n, bool xdim, int panval);
+    
+    void initLimits();
+	
+public:
+	TetrodePlot();
+	TetrodePlot(int x, int y,int w,int h);
+	~TetrodePlot();
+
+	void initAxes();
+	void redraw();
+	void setEnabled(bool enabled);
+	bool getEnabled();
+	
+	void setPosition(int,int,double,double);
+	void setPosition(int, int);
+	void setDimensions(double,double);
+
+	void getPreferredDimensions(double*, double*);
+
+	int getNumberOfAxes();
+    
+    void mouseDown(int x, int y);
+    
+    void mouseDragX(int dx, bool shift, bool ctr);
+    void mouseDragY(int dy, bool shift, bool ctr);
+
+    bool processKeyEvent(SimpleKeyEvent k);
+
+    void processSpikeObject(SpikeObject s);
+};
+
+
+
+#endif
diff --git a/Source/Processors/Visualization/SpikePlotting/WaveAxes.cpp b/Source/Processors/Visualization/SpikePlotting/WaveAxes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..18feacbed932645bcdf1d36a0a63ea031f7f7347
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/WaveAxes.cpp
@@ -0,0 +1,208 @@
+#include "WaveAxes.h"
+
+WaveAxes::WaveAxes():
+					GenericAxes(),
+					drawWaveformLine(true),
+					drawWaveformPoints(false),
+					drawGrid(true),
+					overlay(false),
+					convertLabelUnits(true)
+{	
+	GenericAxes::gotFirstSpike = false;
+
+	ylims[0] = 0;
+	ylims[1] = 1;
+	setWaveformColor(1.0,1.0,0.6);
+	setThresholdColor(1.0, 0.1, 0.1);
+	setGridColor(0.4, 0.2, 0.2);
+	
+}
+
+WaveAxes::WaveAxes(int x, int y, double w, double h, int t):
+					GenericAxes(x,y,w,h,t),
+					drawWaveformLine(true),
+					drawWaveformPoints(false),
+					drawGrid(true),
+					overlay(false),
+					convertLabelUnits(true)
+{	
+	GenericAxes::gotFirstSpike = false;
+
+	setWaveformColor(1.0,1.0,0.6);
+	setThresholdColor(1.0, 0.1, 0.1);
+	setGridColor(0.2, 0.2, 0.2);
+
+}
+
+void WaveAxes::updateSpikeData(SpikeObject newSpike){
+	//std::cout<<"WaveAxes::updateSpikeData()"<<std::endl;
+	GenericAxes::updateSpikeData(newSpike);
+
+}
+
+void WaveAxes::redraw(){
+	
+	BaseUIElement::redraw();
+	
+	plot();
+	
+	BaseUIElement::drawElementEdges();
+}
+
+
+void WaveAxes::plot(){
+
+	int chan = 0;
+	
+	// If no spikes have been received then don't plot anything
+	if (!gotFirstSpike)
+	{
+		std::cout<<"\tWaiting for the first spike"<<std::endl;
+		return;
+	}
+	
+	// Set the plotting range for the current axes the xlims member is ignored as the xdims are 0->number of samples per waveform minus one
+    // so the line goes all the way to the edges ydims are specified by the ylims vector		
+	setViewportRange(0, ylims[0], s.nSamples-1, ylims[1]);
+	
+	// draw the grid lines for the waveforms?
+	 if(drawGrid)
+	 	drawWaveformGrid(s.threshold[chan], s.gain[chan]);
+	
+	//compute the spatial width for each wawveform sample	
+	float dx = 1;
+	float x = 0;
+
+	// type corresponds to channel so we need to calculate the starting
+	// sample based upon which channel is getting plotted
+	// type values are defined in PlotUtils.h 
+	int	sampIdx = s.nSamples * type; //  
+	//std::cout<<"Starting with idx:"<<sampIdx<<std::endl;
+
+
+	//Draw the individual waveform points connected with a line
+	glColor3fv(waveColor);
+	glLineWidth(1);
+	glBegin( GL_LINE_STRIP );
+	
+	int dSamples = 1;
+	for (int i=0; i<s.nSamples; i++)
+	{
+		//std::cout<<"\t"<<s.data[sampIdx];
+		glVertex2f(x, s.data[sampIdx]);
+		sampIdx += dSamples;
+		x +=dx; 
+	}
+	
+	glEnd();
+	
+
+	//Draw the threshold line and label
+	glColor3fv(thresholdColor);
+	glLineWidth(1); 
+	glLineStipple(4, 0xAAAA); // make a dashed line
+	glEnable(GL_LINE_STIPPLE);
+
+	glBegin( GL_LINE_STRIP );
+		glVertex2f(0, s.threshold[chan]);
+		glVertex2f(s.nSamples, s.threshold[chan]);
+	glEnd();		
+
+	glDisable(GL_LINE_STIPPLE);
+
+	char cstr[100] = {0};
+	
+	makeLabel(s.threshold[chan], s.gain[chan], convertLabelUnits, cstr);
+	String str = String(cstr);
+	
+	float yOffset = (ylims[1] - ylims[0])/BaseUIElement::height * 2;
+	drawString(1 ,s.threshold[chan] + yOffset, 15, str, font);
+}
+
+void WaveAxes::drawWaveformGrid(int thold, int gain){
+
+	double voltRange = ylims[1] - ylims[0];
+	double pixelRange = BaseUIElement::height;
+	//This is a totally arbitrary value that seemed to lok the best for me
+	int minPixelsPerTick = 25;
+	int MAX_N_TICKS = 10;
+
+	int nTicks = pixelRange / minPixelsPerTick;
+	while(nTicks>MAX_N_TICKS){
+		minPixelsPerTick += 5;
+		nTicks = pixelRange / minPixelsPerTick;
+	}
+
+	int voltPerTick = (voltRange / nTicks);
+
+	double meanRange = voltRange/2;
+	glColor3fv(gridColor);
+
+	glLineWidth(1);
+	char cstr[200] = {0}; 
+	String str;
+	
+	double tickVoltage = thold;
+
+	// If the limits are bad we don't want to hang the program trying to draw too many ticks
+	// so count the number of ticks drawn and kill the routine after 100 draws
+	int tickCount=0;
+	while(tickVoltage < ylims[1] - voltPerTick*1.5) // Draw the ticks above the thold line
+	{
+		tickVoltage = roundUp(tickVoltage + voltPerTick, 100);
+		
+		glBegin(GL_LINE_STRIP);
+		glVertex2i(0, tickVoltage);
+		glVertex2i(s.nSamples, tickVoltage);
+		glEnd();
+		
+		makeLabel(tickVoltage, gain, convertLabelUnits, cstr);
+		str = String(cstr);
+		drawString(1, tickVoltage+voltPerTick/10, 15, str, font);
+		
+		if (tickCount++>100)
+			return;
+	}
+	
+	tickVoltage = thold;
+	tickCount = 0;
+	while(tickVoltage > ylims[0] + voltPerTick) // draw the ticks below the thold line
+	{
+		tickVoltage = roundUp(tickVoltage - voltPerTick, 100);
+
+		glBegin(GL_LINE_STRIP);
+		glVertex2i(0, tickVoltage);
+		glVertex2i(s.nSamples, tickVoltage);
+		glEnd();
+			
+		makeLabel(tickVoltage, gain, convertLabelUnits, cstr);
+		str = String(cstr);
+		drawString(1, tickVoltage+voltPerTick/10, 15, str, font);
+
+		if (tickCount++>100)
+			return;
+	}
+	
+	
+}
+
+void WaveAxes::setWaveformColor(GLfloat r, GLfloat g, GLfloat b){
+	waveColor[0] = r;
+	waveColor[1] = g;
+	waveColor[2] = b;
+}
+void WaveAxes::setThresholdColor(GLfloat r, GLfloat g, GLfloat b){
+	thresholdColor[0] = r;
+	thresholdColor[1] = g;
+	thresholdColor[2] = b;
+}
+// void WaveAxes::setPointColor(GLfloat r, GLfloat g, GLfloat b){
+// 	pointColor[0] = r;
+// 	pointColor[1] = g;
+// 	pointColor[2] = b;
+// }
+void WaveAxes::setGridColor(GLfloat r, GLfloat g, GLfloat b){
+	gridColor[0] = r;
+	gridColor[1] = g;
+	gridColor[2] = b;
+}
\ No newline at end of file
diff --git a/Source/Processors/Visualization/SpikePlotting/WaveAxes.h b/Source/Processors/Visualization/SpikePlotting/WaveAxes.h
new file mode 100644
index 0000000000000000000000000000000000000000..56add88d8301374fe07b5dd0aa74388a117dd8cb
--- /dev/null
+++ b/Source/Processors/Visualization/SpikePlotting/WaveAxes.h
@@ -0,0 +1,51 @@
+#ifndef WAVE_AXES_H
+#define WAVE_AXES_H
+
+#if defined(__linux__)
+	#include <GL/glut.h>
+#else
+	#include <GLUT/glut.h>
+#endif
+#include <stdlib.h>
+#include "BaseUIElement.h"
+#include "../SpikeObject.h"
+#include "PlotUtils.h"
+#include "GenericAxes.h"
+
+ 	
+class WaveAxes: public GenericAxes{
+	
+	GLfloat waveColor[3];
+	GLfloat thresholdColor[3];
+	GLfloat gridColor[3];
+		
+	
+  	void drawWaveformGrid(int thold, int gain);
+
+protected:
+	void plot();
+
+
+public:
+	WaveAxes();
+	WaveAxes(int x, int y, double w, double h, int t);
+    
+   	void updateSpikeData(SpikeObject s);
+
+	void setWaveformColor(GLfloat r, GLfloat g, GLfloat b);
+	void setThresholdColor(GLfloat r, GLfloat g, GLfloat b);
+	void setGridColor(GLfloat, GLfloat, GLfloat);
+	 
+	void redraw();
+	
+	bool drawWaveformLine;
+	bool drawWaveformPoints;
+	bool overlay;
+	bool drawGrid;
+	bool convertLabelUnits;
+	
+};
+
+
+
+#endif
diff --git a/Source/Processors/Visualization/SpikeViewer.cpp b/Source/Processors/Visualization/SpikeViewer.cpp
deleted file mode 100644
index 3a06ca5fbad429b493c3a2473f4e0c6b0e864677..0000000000000000000000000000000000000000
--- a/Source/Processors/Visualization/SpikeViewer.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2012 Open Ephys
-
-    ------------------------------------------------------------------
-
-    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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "SpikeViewer.h"
-
-
-SpikeViewer::SpikeViewer(AudioSampleBuffer* sBuffer, MidiBuffer* eBuffer, UIComponent* ui)
-	: Renderer(sBuffer, eBuffer, ui)
-{
-
-}
-
-
-
-SpikeViewer::~SpikeViewer() {}
-
-void SpikeViewer::resized() 
-{
-	
-	xBox = getWidth()/4;
-	yBox = getHeight()/2;
-	yPadding = 5;
-	xPadding = 5;
-
-	glClear(GL_COLOR_BUFFER_BIT);
-
-	clearWaveforms();
-	clearProjections();
-
-}
-
-void SpikeViewer::newOpenGLContextCreated()
-{
-
-	glClearDepth (1.0);
-
-	glMatrixMode (GL_PROJECTION);
-	glLoadIdentity ();
-	glOrtho(0, 1, 1, 0, 0, 1);
-	glMatrixMode (GL_MODELVIEW);
-	
-	glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
-
-	resized();
-
-	glFlush();
-
-}
-
-void SpikeViewer::clearWaveforms()
-{
-	
-	for (int n = 0; n < 4; n++)
-	{
-		setViewportForWaveN(n);
-		drawBorder();
-	}
-
-}
-
-void SpikeViewer::clearProjections()
-{
-	for (int n = 0; n < 6; n++)
-	{
-		setViewportForProjectionN(n);
-		drawBorder();
-	}
-
-}
-
-void SpikeViewer::renderOpenGL()
-{
-		
-	 if (eventBuffer->getNumEvents() > 0) {
-
-	   	glRasterPos2f(0.1,0.1);
-
-	   	//const char* str = "i";
-	  // 	void* font = GLUT_BITMAP_8_BY_13;
-
-	  // 	glutBitmapCharacter(font,54);
-	   //	drawBorder();
-
-		//std::cout << "Events received by Spike Viewer." << std::endl;
-
-		MidiBuffer::Iterator i (*eventBuffer);
-		MidiMessage message(0xf4);
-
-		int samplePosition;
-		i.setNextSamplePosition(samplePosition);
-
-		//Array<int> peaks;
-
-
-		clearWaveforms();
-
-		while (i.getNextEvent (message, samplePosition)) {
-
-			int numbytes = message.getRawDataSize();
-			int numSamples = (numbytes-2)/2;
-			uint8* dataptr = message.getRawData();
-
-			int chan = (*dataptr<<8) + *(dataptr+1);
-			int electrode = config->getSource(0)->getElectrodeNumberForChannel(chan);
-
-			//std::cout << chan << "::" << electrode << std::endl;
-
- 			dataptr += 2;
-
-			//glViewport(0,0,getWidth()/2,getHeight());
-
-			if (electrode == 0)
-			{
-			//for (int n = 0; n < 4; n++) {
-				setViewportForWaveN(chan);
-				float peak = drawWaveform(dataptr, numSamples);
-
-				peaks.set(chan,peak*1.25);
-				//peaks.set(chan,peak);
-				
-			}
-
-			if (peaks.size() == 4)
-			{
-				drawProjections();
-				peaks.clear();
-			}
-
-			//std::cout << " Bytes received: " << numbytes << std::endl;
-			//std::cout << " Message timestamp = " << message.getTimeStamp() << std::endl;
-			//std::cout << " Message channel: " << chan << std::endl;
-
- 			//std::cout << "   ";
-			
- 			//AudioDataConverters::convertInt16BEToFloat ( dataptr, // source
-    		//			spikeData, // dest
-    		//			numSamples, // numSamples
-    		//			2 ); // destBytesPerSample = 2
-
-			//for (int n = 0; n < numSamples; n++) {
-			//	std::cout << String(spikeData[n]) << " ";
-			//}
-					
-			//std::cout << std::endl << std::endl;
-		}
-
-		// for (int ch = 0; ch < 4; ch++)
-		// {
-			
-		// }
-
-		//eventBuffer->clear();
-
-	}
-
-	//glOrtho(0, 0.5, 0.5, 0, 0, 1);
-	glFlush();
-
-}
-
-void SpikeViewer::drawProjections() 
-{
-	
-	for (int i = 0; i < 6; i++)
-	{
-		setViewportForProjectionN(i);
-
-		int d1,d2;
-		
-		if (i == 0){
-			d1 = 0;
-			d2 = 1;	
-		} else if (i == 1) {
-			d1 = 0;
-			d2 = 2;
-		} else if (i == 2) {
-			d1 = 0;
-			d2 = 3;
-		} else if (i == 3) {
-			d1 = 1;
-			d2 = 2;
-		} else if (i == 4) {
-			d1 = 1;
-			d2 = 3;
-		} else if (i == 5) {
-			d1 = 2;
-			d2 = 3;
-		}
-
-		glColor3f(0.0, 0.0, 0.0);
-		glBegin(GL_POINTS);
-			glVertex2f(1-peaks[d1],peaks[d2]);
-		glEnd();
-
-	}
-
-}
-
-float SpikeViewer::drawWaveform(uint8* dataptr, int numSamples)
-{
-
-	glColor3f(0,0.0,0);
-	
-	glBegin(GL_LINE_STRIP);
-
-	float maxVal = 0;
-
- 	for (int n = 0; n < numSamples; n++)
- 	{
- 		uint16 sampleValue = (*dataptr << 8) + *(dataptr+1);
-
- 		float sampleVal = -float(sampleValue - 32768)/32768 + 0.6;
-
- 		(sampleVal > maxVal) ? maxVal = sampleVal : maxVal = maxVal;
-
- 		glVertex2f(float(n)/numSamples + 0.01, 
- 					sampleVal);
- 		dataptr += 2;
-
- 	}
-
-	glEnd();
-
-	return maxVal;
-
-}
-
-void SpikeViewer::drawBorder()
-{
-
-	 glColor3f(0.9,0.7,0.2);
-
-	 glRectf(0.01f,0.01f,0.99f,0.99f);
-
-    // glBegin(GL_LINE_STRIP);
- 	//  glVertex2f(0.01f, 0.01f);
- 	//  glVertex2f(0.99f, 0.01f);
- 	//  glVertex2f(0.99f, 0.99f);
- 	//  glVertex2f(0.01f, 0.99f);
- 	//  glVertex2f(0.01f, 0.01f);
- 	//  glEnd();
-}
-
-void SpikeViewer::setViewportForProjectionN(int n)
-{
-	//	std::cout<<"Setting viewport on projection:"<<n<<std::endl;
-    float viewDX = xBox;
-    float viewDY = yBox;
-    float viewX,viewY;
-
-    switch (n){
-    case 0:
-        viewX=xBox;
-        viewY=yBox;
-        break;
-    case 1:
-        viewX = xBox*2;
-        viewY = yBox;
-        break;
-    case 2:
-        viewX=xBox*3;
-        viewY=yBox;
-        break;
-    case 3:
-        viewX = xBox;
-        viewY = 0;
-        break;
-    case 4:
-        viewX = xBox*2;
-        viewY = 0;
-        break;
-    case 5:
-        viewX = xBox*3;
-        viewY = 0;
-        break;
-    default:
-        std::cout<<"drawing of more than 4 channels is not supported, returning! Requested:"<<n<<std::endl;
-        return;
-    }
-	viewX = viewX + xPadding;
-	viewY = viewY + yPadding;
-	viewDX = viewDX - 2*xPadding;
-	viewDY = viewDY - 2*yPadding;
-
-	glViewport(viewX, viewY, viewDX, viewDY);
-
-}
-
-
-void SpikeViewer::setViewportForWaveN(int n){
-	float viewDX = xBox/2;
-	float viewDY = yBox;
-	float viewX,viewY;
-	switch (n){
-	case 0:
-		viewX=0;
-		viewY=yBox;
-		break;
-	case 1:
-		viewX = xBox/2;
-		viewY = yBox;
-		break;
-	case 2:
-		viewX=0;
-		viewY=0;
-		break;
-	case 3:
-		viewX = xBox/2;
-		viewY = 0;
-		break;
-	default:
-		std::cout<<"drawing of more than 4 channels is not supported, returning! Requested:"<<n<<std::endl;
-		return;
-	}
-	viewX = viewX + xPadding;
-	viewY = viewY + yPadding;
-	viewDX = viewDX - 2*xPadding;
-	viewDY = viewDY - 2*yPadding;
-	glViewport(viewX,viewY,viewDX,viewDY);
-}
\ No newline at end of file
diff --git a/Source/Processors/Visualization/SpikeViewer.h b/Source/Processors/Visualization/SpikeViewer.h
deleted file mode 100644
index 0ab44684ebe17560d4fdd25ed7d3edfff4c4705c..0000000000000000000000000000000000000000
--- a/Source/Processors/Visualization/SpikeViewer.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2012 Open Ephys
-
-    ------------------------------------------------------------------
-
-    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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef __SPIKEVIEWER_H_AF442416__
-#define __SPIKEVIEWER_H_AF442416__
-
-#include "../../../JuceLibraryCode/JuceHeader.h"
-#include "../Editors/Visualizer.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-#if JUCE_WINDOWS
-#include <gl/gl.h>
-#include <gl/glu.h>
-#elif JUCE_LINUX
-#include <GL/gl.h>
-#include <GL/glut.h>
-#undef KeyPress
-#elif JUCE_IPHONE
-#include <OpenGLES/ES1/gl.h>
-#include <OpenGLES/ES1/glext.h>
-#elif JUCE_MAC
-#include <GLUT/glut.h>
-#endif
-
-#ifndef GL_BGRA_EXT
-#define GL_BGRA_EXT 0x80e1
-#endif
-
-/**
-  
-  --THIS FILE IS OBSOLETE, BUT REMAINS FOR REFERENCE PURPOSES--
-
-*/
-
-
-class SpikeViewer : public Renderer
-{
-public:
-	SpikeViewer(AudioSampleBuffer* streamBuffer, MidiBuffer* eventBuffer, UIComponent* ui);
-	~SpikeViewer();
-	void renderOpenGL();	
-	void newOpenGLContextCreated();
-
-	//void setViewportForProjection
-private:
-	int nTrodes;
-
-	Array<float> peaks;
-
-	float xBox, yBox, xPadding, yPadding;
-
-	void drawBorder();
-
-	void clearWaveforms();
-	void clearProjections();
-
-	void drawProjections();
-	float drawWaveform(uint8* dataptr, int numSamples);
-
-	void setViewportForWaveN(int n);
-	void setViewportForProjectionN(int n);
-
-	void resized();
-
-};
-
-
-#endif  // __SPIKEVIEWER_H_AF442416__
diff --git a/Source/UI/Configuration.cpp b/Source/Processors/Visualization/Visualizer.h
similarity index 53%
rename from Source/UI/Configuration.cpp
rename to Source/Processors/Visualization/Visualizer.h
index 33bfd6ab625f3ee89ba880b9fe8cc0ab644d65d1..e2832cac0bcffe38cb7cde3f6eed544c16b112f4 100644
--- a/Source/UI/Configuration.cpp
+++ b/Source/Processors/Visualization/Visualizer.h
@@ -21,45 +21,34 @@
 
 */
 
-#include "Configuration.h"
+#ifndef __VISUALIZER_H_C5943EC1__
+#define __VISUALIZER_H_C5943EC1__
 
+#include "../../../JuceLibraryCode/JuceHeader.h"
+#include "OpenGLCanvas.h"
 
-DataSource::DataSource(GenericProcessor* p, Configuration* c)
-{
-
-	processor = p;
-
-	name = p->getName();
-	id = p->getNodeId();
-
-	firstChan = 0;
+class Visualizer : public OpenGLCanvas
 
-	for (int n = 0; n < c->numDataSources(); n++)
-	{
-       firstChan += c->getSource(n)->getNumChans();
-	}
-
-	numChans = p->getNumOutputs();
+{
+public: 
+	Visualizer() {}
+	~Visualizer() {}
 
-	nextAvailableChan = firstChan;
+	virtual void newOpenGLContextCreated() = 0;
+	virtual void renderOpenGL() = 0;
 
-	channelMapping.ensureStorageAllocated(numChans);
+	virtual void refreshState() = 0;
 
-	totalElectrodes = 0;
+	virtual void update() = 0;
+	virtual int getTotalHeight() = 0;
 
-}
+	virtual void beginAnimation() = 0;
+	virtual void endAnimation() = 0;
 
+	virtual void setParameter(int, float) = 0;
+    virtual void setParameter(int, int, int, float) = 0;
 
-void Configuration::removeDataSource(GenericProcessor* p)
-{
-	std::cout << "Removing data source from configuration!" << std::endl;
+};
 
-	for (int n = 0; n < numDataSources(); n++) 
-	{
-		GenericProcessor* gp = (GenericProcessor*) getSource(n)->getProcessor();
-		
-		if (gp == p)
-			dataSources.remove(n);
-	}
 
-}
\ No newline at end of file
+#endif  // __VISUALIZER_H_C5943EC1__
diff --git a/Source/Processors/WiFiOutput.cpp b/Source/Processors/WiFiOutput.cpp
index d9fa1ba3f49100e35f0e92a7be6aec5532e13847..ccf3deea3131813cc3459ec867f4fd0de3191024 100644
--- a/Source/Processors/WiFiOutput.cpp
+++ b/Source/Processors/WiFiOutput.cpp
@@ -27,11 +27,6 @@
 WiFiOutput::WiFiOutput()
 	: GenericProcessor("WiFi Output")
 {
-	setNumOutputs(0);
-	setNumInputs(0);
-
-	setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
-
 }
 
 WiFiOutput::~WiFiOutput()
@@ -41,13 +36,8 @@ WiFiOutput::~WiFiOutput()
 
 AudioProcessorEditor* WiFiOutput::createEditor()
 {
-	WiFiOutputEditor* wifiEditor = new WiFiOutputEditor(this);
-	
-	setEditor(wifiEditor);
-	//wifiEditor->setConfiguration(config);
-
-	std::cout << "Creating editor." << std::endl;
-	return wifiEditor;
+	editor = new WiFiOutputEditor(this);
+	return editor;
 }
 
 
@@ -57,12 +47,12 @@ void WiFiOutput::setParameter (int parameterIndex, float newValue)
 }
 
 void WiFiOutput::process(AudioSampleBuffer &buffer, 
-                            MidiBuffer &midiMessages,
+                            MidiBuffer &events,
                             int& nSamples)
 {
 	
 
-	int sampleNum = checkForMidiEvents(midiMessages);
+	int sampleNum = checkForEvents(events);
 
 	if (sampleNum >= 0)
 	{
diff --git a/Source/UI/Configuration.h b/Source/UI/Configuration.h
deleted file mode 100644
index 9a24edea1585112bb739a278488fe6852d3ebefd..0000000000000000000000000000000000000000
--- a/Source/UI/Configuration.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
-    ------------------------------------------------------------------
-
-    This file is part of the Open Ephys GUI
-    Copyright (C) 2012 Open Ephys
-
-    ------------------------------------------------------------------
-
-    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 3 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, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef __CONFIGURATION_H_9DEA9372__
-#define __CONFIGURATION_H_9DEA9372__
-
-#include "../../JuceLibraryCode/JuceHeader.h"
-#include "../Processors/GenericProcessor.h"
-
-/**
-  
-  Holds configuration information for the signal chain.
-
-  The Configuration can be accessed by all processors in order to
-     update channel names, electrode groupings, and acquisition parameters.
-
-  @see UIComponent, GenericProcessor
-
-*/
-
-class GenericProcessor;
-class Configuration;
-
-class Trode
-{
-public:
-	Trode(int nchans, int startChan, String name_)
-	{
-		name = name_;
-
-		for (int n = 0; n < nchans; n++)
-		{
-			channelMapping.add(startChan++);
-			inputRange.add(10000.0);
-			threshold.add(5000.0);
-			isActive.add(true);
-		}
-	}
-
-	~Trode() {}
-
-	int numChannels() {return channelMapping.size();}
-
-	void setChannel(int wire, int chan)
-	{
-		if (checkWire(wire))
-			channelMapping.set(wire,chan);		
-	}
-
-	void setThreshold(int wire, float thresh)
-	{
-		if (checkWire(wire))
-			threshold.set(wire,thresh); 		
-	}
-
-	void setInputRange(int wire, float inRange)
-	{
-		if (checkWire(wire))
-			inputRange.set(wire,inRange); 		
-	}
-
-	void setState(int wire, bool state)
-	{
-		if (checkWire(wire))
-			isActive.set(wire,state);		
-	}
-
-	int getChannel(int wire)
-	{
-		if (checkWire(wire))
-			return channelMapping[wire];
-		else 
-			return -1;
-	}
-
-	float getThreshold(int wire)
-	{
-		if (checkWire(wire))
-			return threshold[wire];
-		else 
-			return -1;
-	}
-
-	float getInputRange(int wire)
-	{
-		if (checkWire(wire))
-			return inputRange[wire];
-		else 
-			return -1;
-	}
-
-	bool getState(int wire)
-	{
-		if (checkWire(wire))
-			return isActive[wire];
-		else 
-			return false;
-	}
-
-	int* getRawDataPointer()
-	{
-		return channelMapping.getRawDataPointer();
-	}
-
-	String getName() {return name;}
-
-private:
-	Array<int, CriticalSection> channelMapping;
-	Array<float, CriticalSection> threshold;
-	Array<float, CriticalSection> inputRange;
-	Array<bool, CriticalSection> isActive;
-
-	String name;
-
-	bool checkWire(int wire) 
-	{
-		if (wire < channelMapping.size() && wire > -1)
-			return true;
-		else
-			return false;	
-	}
-
-};
-
-class DataSource
-{
-public:
-	DataSource(GenericProcessor* p, Configuration* c);
-
-	~DataSource() {}
-
-	GenericProcessor* getProcessor() {return processor;}
-
-	int numTetrodes() {return tetrodes.size();}
-	int numStereotrodes() {return stereotrodes.size();}
-	int numSingleWires() {return singleWires.size();}
-	int getElectrodeNumberForChannel(int chan)
-	{
-		return channelMapping[chan];
-	}
-
-	Trode* getTetrode(int n) {return tetrodes[n];}
-	Trode* getStereotrode(int n) {return stereotrodes[n];}
-	Trode* getSingleWire(int n) {return singleWires[n];}
-
-	void addTrode(int numChannels, String name_)
-	{
-		Trode* t = new Trode(numChannels, nextAvailableChan, name_);
-
-		for (int n = 0; n < numChannels; n++)
-		{
-			channelMapping.set(nextAvailableChan++, totalElectrodes);
-		}
-
-		totalElectrodes++;
-
-		if (t->numChannels() == 1)
-			singleWires.add(t);
-		else if (t->numChannels() == 2)
-			stereotrodes.add(t);
-		else if (t->numChannels() == 4)
-			tetrodes.add(t); 
-	}
-
-	String getName() {return name;}
-
-	int getNumChans() {return numChans;}
-	int getFirstChan() {return firstChan;}
-
-	int id;
-
-private:
-
-	String name;
-	
-	OwnedArray<Trode, CriticalSection> tetrodes;
-	OwnedArray<Trode, CriticalSection> stereotrodes;
-	OwnedArray<Trode, CriticalSection> singleWires;
-	Array<int, CriticalSection> channelMapping;
-
-	int totalElectrodes;
-	int firstChan;
-	int numChans;
-	int nextAvailableChan;
-
-	GenericProcessor* processor;
-
-};
-
-class Configuration
-{
-public:
-	Configuration() {};
-	~Configuration() {};
-
-	void removeDataSource(GenericProcessor*);
-
-	int numDataSources() {return dataSources.size();}
-	DataSource* getSource(int sourceNum) {return dataSources[sourceNum];}
-
-	void addDataSource(DataSource* d)
-	{
-		std::cout << "New data source added." << std::endl;
-		dataSources.add(d);
-	}
-
-private:
-
-	OwnedArray<DataSource, CriticalSection> dataSources;
-};
-
-
-
-
-#endif  // __CONFIGURATION_H_9DEA9372__
diff --git a/Source/UI/ControlPanel.cpp b/Source/UI/ControlPanel.cpp
index c7cea6acea139220acebc920e162d4d67807c326..c233e8635676f3f711c4fddfb078b66ff9931649 100644
--- a/Source/UI/ControlPanel.cpp
+++ b/Source/UI/ControlPanel.cpp
@@ -400,6 +400,9 @@ void ControlPanel::buttonClicked(Button* button)
 			
 			if (graph->enableProcessors()) 
 			{
+				if (recordButton->getToggleState())
+					graph->getRecordNode()->setParameter(1,10.0f);
+				
 				audio->beginCallbacks();
 				masterClock->start();
 			}
diff --git a/Source/UI/ControlPanel.h b/Source/UI/ControlPanel.h
index e532a258c99082f704ff3149d807ddc1968bb239..72988db998dcd514274a9c77d8e2d3f3af067b61 100644
--- a/Source/UI/ControlPanel.h
+++ b/Source/UI/ControlPanel.h
@@ -33,8 +33,6 @@
 
 #include "../OpenGL.h"
 
-//------------------------------------------------------------------------
-
 /**
   
   Displays information and provides buttons to control acquistion and recording.
diff --git a/Source/UI/CustomLookAndFeel.cpp b/Source/UI/CustomLookAndFeel.cpp
index f6968b9f27af9247e34152ecb8f25d33ff5bb0c3..abc3ec4edf21801634be866a54c999a3db403872 100644
--- a/Source/UI/CustomLookAndFeel.cpp
+++ b/Source/UI/CustomLookAndFeel.cpp
@@ -27,6 +27,21 @@ CustomLookAndFeel::CustomLookAndFeel()
 {
   MemoryInputStream mis(BinaryData::misoserialized, BinaryData::misoserializedSize, false);
   Miso = new CustomTypeface(mis);
+
+  enum {
+    PROCESSOR_COLOR = 0x801,
+    FILTER_COLOR = 0x802,
+    SINK_COLOR = 0x803,
+    SOURCE_COLOR = 0x804,
+    UTILITY_COLOR = 0x805,
+  };
+
+  setColour(PROCESSOR_COLOR, Colour(59, 59, 59));
+  setColour(FILTER_COLOR, Colour(255, 89, 0));
+  setColour(SINK_COLOR, Colour(255, 149, 0));
+  setColour(SOURCE_COLOR, Colour(255, 0, 0));
+  setColour(UTILITY_COLOR, Colour(90, 80, 80));
+
 }
 
 CustomLookAndFeel::~CustomLookAndFeel() {}
@@ -538,4 +553,61 @@ void CustomLookAndFeel::drawGlassPointer (Graphics& g,
 
     g.setColour (Colours::black.withAlpha (0.5f * colour.getFloatAlpha()));
     g.strokePath (p, PathStrokeType (outlineThickness));
+}
+
+/// ------ combo box ---------------///
+
+
+void CustomLookAndFeel::drawComboBox (Graphics& g, int width, int height,
+                                const bool isButtonDown,
+                                int buttonX, int buttonY,
+                                int buttonW, int buttonH,
+                                ComboBox& box)
+{
+
+    g.fillAll (box.findColour (ComboBox::backgroundColourId));
+
+    if (box.isEnabled() && box.hasKeyboardFocus (false))
+    {
+        g.setColour (box.findColour (TextButton::buttonColourId));
+        g.drawRect (0, 0, width, height, 2);
+    }
+    else
+    {
+        g.setColour (box.findColour (ComboBox::outlineColourId));
+        g.drawRect (0, 0, width, height);
+    }
+
+    const float outlineThickness = box.isEnabled() ? (isButtonDown ? 1.2f : 0.5f) : 0.3f;
+
+    const Colour baseColour (Colours::orange);/*LookAndFeelHelpers::createBaseColour (box.findColour (ComboBox::buttonColourId),
+                                                                   box.hasKeyboardFocus (true),
+                                                                   false, isButtonDown)
+                                .withMultipliedAlpha (box.isEnabled() ? 1.0f : 0.5f));*/
+
+    drawGlassLozenge (g,
+                      buttonX + outlineThickness, buttonY + outlineThickness,
+                      buttonW - outlineThickness * 2.0f, buttonH - outlineThickness * 2.0f,
+                      baseColour, outlineThickness, -1.0f,
+                      true, true, true, true);
+
+    if (box.isEnabled())
+    {
+        const float arrowX = 0.3f;
+        const float arrowH = 0.2f;
+
+        Path p;
+        p.addTriangle (buttonX + buttonW * 0.5f,            buttonY + buttonH * (0.45f - arrowH),
+                       buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.45f,
+                       buttonX + buttonW * arrowX,          buttonY + buttonH * 0.45f);
+
+        p.addTriangle (buttonX + buttonW * 0.5f,            buttonY + buttonH * (0.55f + arrowH),
+                       buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.55f,
+                       buttonX + buttonW * arrowX,          buttonY + buttonH * 0.55f);
+
+        g.setColour (box.findColour (ComboBox::arrowColourId));
+        g.fillPath (p);
+    }
+
+
 }
\ No newline at end of file
diff --git a/Source/UI/CustomLookAndFeel.h b/Source/UI/CustomLookAndFeel.h
index 2bd37b8b52a2844abea5d669aedaedfad22fcc91..c654933729e1cdf0a5831eaec449f538dc34cbf1 100644
--- a/Source/UI/CustomLookAndFeel.h
+++ b/Source/UI/CustomLookAndFeel.h
@@ -142,6 +142,13 @@ public:
 
     const Typeface::Ptr getTypefaceForFont (const Font& font);
 
+    // ======== custom combo box methods: =============================
+
+    void drawComboBox (Graphics& g, int width, int height,
+                                const bool isButtonDown,
+                                int buttonX, int buttonY,
+                                int buttonW, int buttonH,
+                                ComboBox& box);
 
 private:	
 
diff --git a/Source/UI/DataViewport.cpp b/Source/UI/DataViewport.cpp
index c4c0a1bae57a092dbbafd4f3570a09a75939ebbc..f580e271cf8764cbc2895169757f5aad1caadc21 100644
--- a/Source/UI/DataViewport.cpp
+++ b/Source/UI/DataViewport.cpp
@@ -63,14 +63,20 @@ DataViewport::~DataViewport()
 
  }
 
- void DataViewport::removeTab(int index) {
+ void DataViewport::destroyTab(int index) {
         
-     int newIndex = tabArray->indexOf(index);
-     tabArray->remove(newIndex);
+    int newIndex = tabArray->indexOf(index);
 
-     getTabbedButtonBar().removeTab(newIndex);
+    Component* canvas = getTabContentComponent(newIndex);
+    Component* parent = canvas->getParentComponent();
+    parent->removeChildComponent(canvas);
 
-     if (tabArray->size() == 0)
+    tabArray->remove(newIndex);
+
+    removeTab(newIndex);
+    //getTabbedButtonBar().removeTab(newIndex);
+
+    if (tabArray->size() == 0)
      	setVisible(false);
 
  }
@@ -79,8 +85,9 @@ DataViewport::~DataViewport()
  {
      OpenGLCanvas* canvas = (OpenGLCanvas*) getTabContentComponent(newIndex);
 
-     if (canvas != 0)
+     if (canvas != 0) {
          canvas->refreshState();
+     }
  }
 
 void DataViewport::paint(Graphics& g)
diff --git a/Source/UI/DataViewport.h b/Source/UI/DataViewport.h
index 3b590ea32439f0b5689cba1de7b788caef387525..03361495ce820fdc0b8cfd0016bc6c25790f5244 100644
--- a/Source/UI/DataViewport.h
+++ b/Source/UI/DataViewport.h
@@ -49,7 +49,7 @@ public:
     int addTabToDataViewport(String tabName, Component* componentToAdd);
 
     /** Removes a tab with a specified index.*/
-    void removeTab(int);
+    void destroyTab(int);
 
     /** Informs the component of the current tab that it's now active.*/
     void currentTabChanged(int newIndex, const String& newTabName);
diff --git a/Source/UI/EditorViewport.cpp b/Source/UI/EditorViewport.cpp
index 8bdb0b2d3e4ab2246d7151806ba080875f6e7db3..0652adc754df3dc3651e1dc7222f0178d22dcbce 100644
--- a/Source/UI/EditorViewport.cpp
+++ b/Source/UI/EditorViewport.cpp
@@ -28,17 +28,17 @@
 
 EditorViewport::EditorViewport()
     : message ("Drag-and-drop some rows from the top-left box onto this component!"),
-      somethingIsBeingDraggedOver (false), shiftDown(false), leftmostEditor(0),
+      somethingIsBeingDraggedOver(false), shiftDown(false), leftmostEditor(0),
        insertionPoint(0), componentWantsToMove(false), indexOfMovingComponent(-1), 
-       borderSize(6), tabSize(30), tabButtonSize(15), canEdit(true), currentTab(-1)//, signalChainNeedsSource(true)
+       borderSize(6), tabSize(30), tabButtonSize(15), canEdit(true), currentTab(-1)
 {
 
-  addMouseListener(this, true);
+    addMouseListener(this, true);
 
-  MemoryInputStream mis(BinaryData::silkscreenserialized, BinaryData::silkscreenserializedSize, false);
-  Typeface::Ptr typeface = new CustomTypeface(mis);
-  font = Font(typeface);
-  font.setHeight(10);
+    MemoryInputStream mis(BinaryData::silkscreenserialized, BinaryData::silkscreenserializedSize, false);
+    Typeface::Ptr typeface = new CustomTypeface(mis);
+    font = Font(typeface);
+    font.setHeight(10);
 
     sourceDropImage = ImageCache::getFromMemory (BinaryData::SourceDrop_png, 
                                       BinaryData::SourceDrop_pngSize);
@@ -64,13 +64,11 @@ EditorViewport::EditorViewport()
     addAndMakeVisible(rightButton);
     addAndMakeVisible(leftButton);
 
-
-
 }
 
 EditorViewport::~EditorViewport()
 {
-    deleteAndZero(signalChainManager);
+   // deleteAndZero(signalChainManager);
     deleteAllChildren();
 }
 
@@ -218,9 +216,10 @@ void EditorViewport::itemDropped (const String& sourceDescription, Component* /*
 
         if (activeEditor != 0)
         {
-            addChildComponent(activeEditor);
             activeEditor->setUIComponent(getUIComponent());
-
+            activeEditor->refreshColors();
+            addChildComponent(activeEditor);
+            
             lastEditor = activeEditor;
 
             signalChainManager->updateVisibleEditors(activeEditor, indexOfMovingComponent, insertionPoint, ADD);
@@ -480,8 +479,6 @@ void EditorViewport::mouseDown(const MouseEvent &e) {
         }
     } 
 
-   // selectEditor((GenericEditor*) e.eventComponent);
-
 }
 
 void EditorViewport::mouseDrag(const MouseEvent &e) {
@@ -572,7 +569,7 @@ void EditorViewport::mouseExit(const MouseEvent &e) {
 void EditorViewport::checkScrollButtons(int topTab)
 {
     
-    if (editorArray.size() - topTab > 4)
+    if (signalChainArray.size() - topTab > 4)
     {
         downButton->setActive(true);
     } else {
@@ -638,74 +635,115 @@ void EditorViewport::buttonClicked (Button* button)
 
 SignalChainTabButton::SignalChainTabButton() : Button("Name"),
         configurationChanged(true)
-    {
-        setRadioGroupId(99);
-        //setToggleState(false,true);
-        setClickingTogglesState(true);
+{
+    setRadioGroupId(99);
+    setClickingTogglesState(true);
 
-        MemoryInputStream mis(BinaryData::silkscreenserialized, BinaryData::silkscreenserializedSize, false);
-        Typeface::Ptr typeface = new CustomTypeface(mis);
-        buttonFont = Font(typeface);
-        buttonFont.setHeight(14);
+    MemoryInputStream mis(BinaryData::silkscreenserialized, BinaryData::silkscreenserializedSize, false);
+    Typeface::Ptr typeface = new CustomTypeface(mis);
+    buttonFont = Font(typeface);
+    buttonFont.setHeight(14);
 
-        offset = 0;
-    }
+    offset = 0;
+}
 
 
 void SignalChainTabButton::clicked() 
 {
     
-        //std::cout << "Button clicked: " << firstEditor->getName() << std::endl;
-        EditorViewport* ev = (EditorViewport*) getParentComponent();
-    
-        scm->updateVisibleEditors(firstEditor, 0, 0, ACTIVATE); 
-        ev->leftmostEditor = offset;
-        ev->refreshEditors();   
+    //std::cout << "Button clicked: " << firstEditor->getName() << std::endl;
+    EditorViewport* ev = (EditorViewport*) getParentComponent();
+
+    scm->updateVisibleEditors(firstEditor, 0, 0, ACTIVATE); 
+    ev->leftmostEditor = offset;
+    ev->refreshEditors();   
 
     
 }
 
 void SignalChainTabButton::paintButton(Graphics &g, bool isMouseOver, bool isButtonDown)
 {
-        if (getToggleState() == true)
-            g.setColour(Colours::orange);
-        else 
-            g.setColour(Colours::darkgrey);
-
-        if (isMouseOver)
-            g.setColour(Colours::white);
-
-        g.fillEllipse(0,0,getWidth(),getHeight());
-
-        g.setFont(buttonFont);
-        g.setColour(Colours::black);
-
-        String n;
-
-        if (num == 0)
-            n = "A";
-        else if (num == 1)
-            n = "B";
-        else if (num == 2)
-            n = "C";
-        else if (num == 3)
-            n = "D";
-        else if (num == 4)
-            n = "E";
-        else if (num == 5)
-            n = "F";
-        else if (num == 6)
-            n = "G";
-        else if (num == 7)
-            n = "H";
-        else if (num == 8)
-            n = "I";
-        else
-            n = "-";
-
-        g.drawText(n,0,0,getWidth(),getHeight(),Justification::centred,true);
+
+    ColourGradient grad1, grad2;
+
+    if (getToggleState() == true) {
+
+        grad1 = ColourGradient(Colour(255, 136, 34), 0.0f, 0.0f, 
+                               Colour(230, 193, 32), 0.0f, 20.0f,
+                               false);
+
+        grad2 = ColourGradient(Colour(255, 136, 34), 0.0f, 20.0f, 
+                               Colour(230, 193, 32), 0.0f, 0.0f,
+                               false);
+    }
+    else { 
+         grad2 = ColourGradient(Colour(80, 80, 80), 0.0f, 20.0f, 
+                               Colour(120, 120, 120), 0.0f, 0.0f,
+                               false);
+
+        grad1 =  ColourGradient(Colour(80, 80, 80), 0.0f, 0.0f, 
+                               Colour(120, 120, 120), 0.0f, 20.0f,
+                               false);
+    }
+
+    if (isMouseOver) {
+        
+        grad1.multiplyOpacity(0.7f);
+        grad2.multiplyOpacity(0.7f);
+        //  grad1 = ColourGradient(Colour(255, 255, 255), 0.0f, 20.0f, 
+        //                         Colour(180, 180, 180), 0.0f, 0.0f,
+        //                        false);
+
+        // grad2 = ColourGradient(Colour(255, 255, 255), 0.0f, 0.0f, 
+        //                         Colour(180, 180, 180), 0.0f, 20.0f,
+        //                        false);
+    }
+
+    if (isButtonDown) {
+
+        // ColourGradient grad3 = grad1;
+        // grad1 = grad2;
+        // grad2 = grad3;
+        // grad1.multiplyOpacity(0.7f);
+        // grad2.multiplyOpacity(0.7f);
+
     }
 
+    g.setGradientFill(grad2);
+    g.fillEllipse(0,0,getWidth(),getHeight());
+
+    g.setGradientFill(grad1);
+    g.fillEllipse(2,2,getWidth()-4,getHeight()-4);
+
+    g.setFont(buttonFont);
+    g.setColour(Colours::black);
+
+    String n;
+
+    if (num == 0)
+        n = "A";
+    else if (num == 1)
+        n = "B";
+    else if (num == 2)
+        n = "C";
+    else if (num == 3)
+        n = "D";
+    else if (num == 4)
+        n = "E";
+    else if (num == 5)
+        n = "F";
+    else if (num == 6)
+        n = "G";
+    else if (num == 7)
+        n = "H";
+    else if (num == 8)
+        n = "I";
+    else
+        n = "-";
+
+    g.drawText(n,0,0,getWidth(),getHeight(),Justification::centred,true);
+}
+
 
 
 // how about some loading and saving?
@@ -811,10 +849,7 @@ const String EditorViewport::saveState(const File& file)
                 {
                     splitPoints.add(nextProcessor);
 
-                    if (nextProcessor->isSplitter())
-                        nextProcessor->switchDest(0);
-                    else
-                        nextProcessor->switchSource(0);
+                    nextProcessor->switchIO(0);
                 }
 
             } else {
@@ -826,22 +861,19 @@ const String EditorViewport::saveState(const File& file)
                     nextProcessor = splitPoints.getFirst();
                     splitPoints.remove(0);
 
+                    nextProcessor->switchIO(1);
+                    signalChain->addChildElement(switchNodeXml(nextProcessor));
+                    
                     if (nextProcessor->isMerger())
                     {
-                        std::cout << "    Switching merger source." << std::endl;
-                        nextProcessor->switchSource(1);
-                        signalChain->addChildElement(switchNodeXml(nextProcessor));
                         insertionPt = 0;
                         moveForward = false;
-                    } else {
-                        std::cout << "    Switching splitter dest." << std::endl;
-                        nextProcessor->switchDest(1);
-                        signalChain->addChildElement(switchNodeXml(nextProcessor));
+                    } else { 
                         insertionPt = 1;
                         moveForward = true;
                     }
 
-                    editor = (GenericEditor*) nextProcessor->getEditor();
+                    editor = nextProcessor->getEditor();
 
                 } else {
 
@@ -882,7 +914,6 @@ const String EditorViewport::loadState(const File& file)
     {
         std::cout << "File not found." << std::endl;
         delete xml;
-        // don't do anything
         return "Not a valid file.";
     }
 
@@ -948,8 +979,5 @@ const String EditorViewport::loadState(const File& file)
 
     delete xml;
     return "Everything went ok.";
-
-   // refreshEditors();
-
 }
 
diff --git a/Source/UI/EditorViewport.h b/Source/UI/EditorViewport.h
index 0d547454ad591b2e9eb5b942be7ea689b91c1d79..ce01d43a358378870ac2acea1d6c8125cf65e582 100644
--- a/Source/UI/EditorViewport.h
+++ b/Source/UI/EditorViewport.h
@@ -64,14 +64,11 @@ public:
 
     // Creating and deleting editors:
     void deleteNode(GenericEditor* editor);
-   // void updateVisibleEditors(GenericEditor* activeEditor, int action);
     void selectEditor(GenericEditor* e);
 
     void makeEditorVisible(GenericEditor* e);
     void refreshEditors();
 
-   // void setActiveEditor(GenericEditor* e) {activeEditor = e; updateVisibleEditors();}
-
     void signalChainCanBeEdited(bool t);
 
     // DragAndDropTarget methods:
@@ -104,7 +101,7 @@ public:
 
     void checkScrollButtons(int topTab);
 
-      int leftmostEditor;
+    int leftmostEditor;
     
 private:
 
@@ -115,23 +112,16 @@ private:
     bool canEdit;
     GenericEditor* lastEditor;
 
-    //ProcessorGraph* graph;
-    //DataViewport* tabComponent;
-
     Array<GenericEditor*, CriticalSection> editorArray;
     Array<SignalChainTabButton*, CriticalSection> signalChainArray;
 
-    SignalChainManager* signalChainManager;
+    ScopedPointer<SignalChainManager> signalChainManager;
 
     Font font;
     Image sourceDropImage;
-   // int activeTab;
 
-  
-    
     void createNewTab(GenericEditor* editor);
     void removeTab(int tabIndex);
-    //void drawTabs();
 
     int borderSize, tabSize, tabButtonSize;
 
@@ -152,8 +142,6 @@ private:
 
     void resized();
 
-    //bool signalChainNeedsSource;
-
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EditorViewport);  
 
 };
@@ -161,7 +149,7 @@ private:
 class SignalChainTabButton : public Button
 {
 public:
-    SignalChainTabButton();// : Button("Name") {configurationChanged = true;}
+    SignalChainTabButton();
     ~SignalChainTabButton() {}
 
     void setEditor(GenericEditor* p) {firstEditor = p;}
@@ -175,8 +163,6 @@ public:
 
     int offset;
 
-
-
 private:
 
     GenericEditor* firstEditor;
@@ -187,7 +173,6 @@ private:
 
     void clicked();
     
-
     enum actions {ADD, MOVE, REMOVE, ACTIVATE};
     
     int num;
@@ -195,7 +180,6 @@ private:
 
     Font buttonFont;
 
-
 };
 
 #endif  // __EDITORVIEWPORT_H_80260F3F__
diff --git a/Source/UI/InfoLabel.cpp b/Source/UI/InfoLabel.cpp
index 9aa437b50d5b946b8485361ef465008a5ffe91f9..2da53f2776bcb38a4e13b50c8a6f42ddedee2a0b 100644
--- a/Source/UI/InfoLabel.cpp
+++ b/Source/UI/InfoLabel.cpp
@@ -105,13 +105,11 @@ void InfoLabel::drawLabel()
 
 }
 
-void InfoLabel::resized() 
+void InfoLabel::canvasWasResized() 
 {
 
 	layout.SetLineLength(getWidth()-45);
 
-	canvasWasResized();
-
 }
 
 int InfoLabel::getTotalHeight() 
diff --git a/Source/UI/InfoLabel.h b/Source/UI/InfoLabel.h
index f3fd77740cfb20b11627566d38883f1f8ba3027e..4967de8fc93dfd61b871a02afeeeaecda79adb6b 100644
--- a/Source/UI/InfoLabel.h
+++ b/Source/UI/InfoLabel.h
@@ -54,7 +54,7 @@ private:
 
 	int getTotalHeight();
 
-	void resized();
+	void canvasWasResized();
 
 	FTSimpleLayout layout;	
 	String infoString;
diff --git a/Source/UI/ProcessorList.cpp b/Source/UI/ProcessorList.cpp
index 6c2af6c893fdb80ce881f95fc0a546f8a995b9b7..405b0eed98c0ebd65f23e7a7b850d08214f5479f 100644
--- a/Source/UI/ProcessorList.cpp
+++ b/Source/UI/ProcessorList.cpp
@@ -36,21 +36,35 @@ ProcessorList::ProcessorList() : isDragging(false),
                            yBuffer(1)
 {
 
+	enum {
+		PROCESSOR_COLOR = 801,
+		FILTER_COLOR = 802,
+		SINK_COLOR = 803,
+		SOURCE_COLOR = 804,
+		UTILITY_COLOR = 805,
+	};
+
+	setColour(PROCESSOR_COLOR, Colour(59, 59, 59));
+	setColour(FILTER_COLOR, Colour(27, 86, 224));//Colour(255, 89, 0));
+	setColour(SINK_COLOR, Colour(41, 76, 158));//Colour(255, 149, 0));
+	setColour(SOURCE_COLOR, Colour(48, 67, 112)); //Colour(255, 0, 0));
+	setColour(UTILITY_COLOR, Colour(90, 80, 80));
+
 	ProcessorListItem* sources = new ProcessorListItem("Sources");
 	sources->addSubItem(new ProcessorListItem("Intan Demo Board"));
 	sources->addSubItem(new ProcessorListItem("Signal Generator"));
 	//sources->addSubItem(new ProcessorListItem("Custom FPGA"));
-	//sources->addSubItem(new ProcessorListItem("File Reader"));
+	sources->addSubItem(new ProcessorListItem("File Reader"));
 	sources->addSubItem(new ProcessorListItem("Event Generator"));
 
 	ProcessorListItem* filters = new ProcessorListItem("Filters");
 	filters->addSubItem(new ProcessorListItem("Bandpass Filter"));
 	//filters->addSubItem(new ProcessorListItem("Resampler"));
-	//filters->addSubItem(new ProcessorListItem("Spike Detector"));
+	filters->addSubItem(new ProcessorListItem("Spike Detector"));
 
 	ProcessorListItem* sinks = new ProcessorListItem("Sinks");
 	sinks->addSubItem(new ProcessorListItem("LFP Viewer"));
-	//sinks->addSubItem(new ProcessorListItem("Spike Display"));
+	sinks->addSubItem(new ProcessorListItem("Spike Viewer"));
 	sinks->addSubItem(new ProcessorListItem("WiFi Output"));
 
 	ProcessorListItem* utilities = new ProcessorListItem("Utilities");
@@ -153,10 +167,12 @@ void ProcessorList::drawItems()
 
 void ProcessorList::drawItem(ProcessorListItem* item)
 {
-	
-	glColor4f(item->color.getFloatRed(),
-		      item->color.getFloatGreen(),
-		      item->color.getFloatBlue(),
+
+	Colour c = findColour(item->colorId);
+
+	glColor4f(c.getFloatRed(),
+		      c.getFloatGreen(),
+		      c.getFloatBlue(),
 		      1.0f);
 
 	glBegin(GL_POLYGON);
@@ -322,9 +338,7 @@ int ProcessorList::getTotalHeight()
  	return totalHeight;
 }
 
-void ProcessorList::resized() {canvasWasResized();}
-
-void ProcessorList::mouseDown(const MouseEvent& e) 
+void ProcessorList::mouseDownInCanvas(const MouseEvent& e) 
 {
 
 	isDragging = false;
@@ -370,12 +384,10 @@ void ProcessorList::mouseDown(const MouseEvent& e)
 		}
 	}
 
-	mouseDownInCanvas(e);
-
 	repaint();
 }
 
-void ProcessorList::mouseDrag(const MouseEvent& e) 
+void ProcessorList::mouseDragInCanvas(const MouseEvent& e) 
 {
 
 	if (e.getMouseDownX() < getWidth()-getScrollBarWidth() && !(isDragging))
@@ -410,7 +422,7 @@ void ProcessorList::mouseDrag(const MouseEvent& e)
 						Image dragImage (Image::ARGB, 100, 15, true);
 
 						Graphics g(dragImage);
-						g.setColour (fli->color);
+						g.setColour (findColour(fli->colorId));
 						g.fillAll();
 						g.setColour(Colours::white);
 						g.setFont(14);
@@ -427,14 +439,8 @@ void ProcessorList::mouseDrag(const MouseEvent& e)
 		}
 	}
 
-	mouseDragInCanvas(e);
 }
 
-void ProcessorList::mouseMove(const MouseEvent& e) {mouseMoveInCanvas(e);}
-void ProcessorList::mouseUp(const MouseEvent& e) 	{mouseUpInCanvas(e);}
-void ProcessorList::mouseWheelMove(const MouseEvent& e, float a, float b) {mouseWheelMoveInCanvas(e,a,b);}
-
-
 ProcessorListItem::ProcessorListItem(const String& name_) : name(name_), open(true), selected(false)
 {
 }
@@ -502,22 +508,35 @@ void ProcessorListItem::setParentName(const String& name)
 {
 	parentName = name;
 
+	enum {
+		PROCESSOR_COLOR = 801,
+		FILTER_COLOR = 802,
+		SINK_COLOR = 803,
+		SOURCE_COLOR = 804,
+		UTILITY_COLOR = 805,
+	};
+
 	if (parentName.equalsIgnoreCase("Processors"))
 	{
-		color = Colour(59, 59, 59);
+		colorId = PROCESSOR_COLOR;
+		//color = Colour(59, 59, 59);
 
 	} else if (parentName.equalsIgnoreCase("Filters"))
 	{
-		color = Colour(255, 89, 0);
+		colorId = FILTER_COLOR;
+		//color = Colour(255, 89, 0);
 	} else if (parentName.equalsIgnoreCase("Sinks"))
 	{
-		color = Colour(255, 149, 0);
+		colorId = SINK_COLOR;
+		//color = Colour(255, 149, 0);
 	} else if (parentName.equalsIgnoreCase("Sources"))
 	{
-		color = Colour(255, 0, 0);
+		colorId = SOURCE_COLOR;
+		//color = Colour(255, 0, 0);
 
 	} else {
-		color = Colour(90, 80, 80);
+		colorId = UTILITY_COLOR;
+		//color = Colour(90, 80, 80);
 	}
 }
 
diff --git a/Source/UI/ProcessorList.h b/Source/UI/ProcessorList.h
index 57150369ab85c239f40e2c9aff797bbb61db8f13..faf6b6558d3abfae1e6082185908b2b1f2c53550 100644
--- a/Source/UI/ProcessorList.h
+++ b/Source/UI/ProcessorList.h
@@ -78,16 +78,10 @@ private:
 	int totalHeight, itemHeight, subItemHeight;
 	int xBuffer, yBuffer;
 
-	//UIComponent* UI;
-
 	String category;
 	
-	void resized();
-	void mouseDown(const MouseEvent& e);
-	void mouseDrag(const MouseEvent& e);
-	void mouseMove(const MouseEvent& e);
-	void mouseUp(const MouseEvent& e);
-	void mouseWheelMove(const MouseEvent&, float, float);
+	void mouseDownInCanvas(const MouseEvent& e);
+	void mouseDragInCanvas(const MouseEvent& e);
 
 	ProcessorListItem* baseItem;
 
@@ -95,7 +89,7 @@ private:
 
 };
 
-class ProcessorListItem
+class ProcessorListItem //: public Component
 {
 public:
 	ProcessorListItem(const String& name);
@@ -120,7 +114,8 @@ public:
 	const String& getParentName();
 	void setParentName(const String& name);
 
-	Colour color;
+	//Colour color;
+	int colorId;
 
 private:
 
diff --git a/Source/UI/SignalChainManager.cpp b/Source/UI/SignalChainManager.cpp
index 29f77b0406c8837d15c45acbdb823209bb76b291..3312bd856da6622aa1b96357a30c7f7162029831 100644
--- a/Source/UI/SignalChainManager.cpp
+++ b/Source/UI/SignalChainManager.cpp
@@ -175,7 +175,7 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
         // need to inform the other source that its merger has disappeared
         if (p->isMerger())
         {
-        	p->switchSource();
+        	p->switchIO();
         	if (p->getSourceNode() != 0)
         		p->getSourceNode()->setDestNode(0);
         }
@@ -244,12 +244,7 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
         GenericProcessor* source = 0;
         GenericProcessor* dest = (GenericProcessor*) editorArray[0]->getProcessor();
 
-        if (!dest->isMerger())
-        	dest->setSourceNode(source); // set first source as 0
-        else
-        	dest->setMergerSourceNode(source);
-
-      //  std::cout << "        " << dest->getName() << "::";
+        dest->setSourceNode(source); 
 
         for (int n = 1; n < editorArray.size(); n++)
         {
@@ -257,23 +252,12 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
             dest = (GenericProcessor*) editorArray[n]->getProcessor();
             source = (GenericProcessor*) editorArray[n-1]->getProcessor();
 
-            //if (!dest->isMerger())
-        		dest->setSourceNode(source);
-        	//else
-        	//	dest->setMergerSourceNode(source);
-
-           //std::cout << dest->getName() << "::";
+        	dest->setSourceNode(source);
         }
 
-        if (!dest->isSplitter())
-        	dest->setDestNode(0); // set first source as 0
-        else
-        	dest->setSplitterDestNode(0);
-      //  dest->setDestNode(0); // set last dest as 0
-
-      // std::cout << std::endl;
-    }//
+        dest->setDestNode(0);
 
+    }
 
     // Step 3: check for new tabs
    if (action != ACTIVATE) {
@@ -284,8 +268,6 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
         {
             GenericProcessor* p = (GenericProcessor*) editorArray[n]->getProcessor();
 
-      //      std::cout << editorArray[n]->tabNumber() << std::endl;
-
             if (p->getSourceNode() == 0)// && editorArray[n]->tabNumber() == -1)
             {
                
@@ -316,26 +298,12 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
         }
     }
 
-
-
-    
     // Step 4: Refresh editors in editor array, based on active editor
     for (int n = 0; n < editorArray.size(); n++)
     {
         editorArray[n]->setVisible(false);
     }
 
- //    int activeChain;
-
-	// for (int n = 0; n < signalChainArray.size(); n++)
-	// {
-	// 	if (signalChainArray[n]->getToggleState())
-	// 	{
-	// 		activeChain = n;
-	// 		break;
-	// 	}
-	// }
-
     editorArray.clear();
     std::cout << "Cleared editor array." << std::endl;
 
@@ -361,18 +329,6 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
             editorToAdd = 0;
            
         }
-
-        // if (currentProcessor->isMerger())
-        // {
-         //   	std::cout << "It's a merger!" << std::endl;
-
-		    	//if (currentProcessor->getSource() == activeChain)
-		    	// 	editorToAdd->switchSource(0);
-		    	// else
-		    	// 	editorToAdd->switchSource(1);
-            
-        // }
-
     }
 
     editorToAdd = activeEditor;
@@ -397,8 +353,6 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
 
 				 if (dest->getSourceNode() != currentProcessor)
 				 	editorToAdd->switchSource();
-				// else
-				// 	editorToAdd->switchSource(1);
             
          	}
 
@@ -410,8 +364,6 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
 
     }
 
-    //std::cout << "OK1." << std::endl;
-
     // Step 5: check the validity of the signal chain
     if (true) {
         bool enable = true;
@@ -426,8 +378,6 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
 
         } else {
 
-            //bool sourceIsInChain = true;
-
             for (int n = 0; n < editorArray.size()-1; n++)
             {
                 GenericProcessor* source = (GenericProcessor*) editorArray[n]->getProcessor();
@@ -464,37 +414,42 @@ void SignalChainManager::updateVisibleEditors(GenericEditor* activeEditor,
     }
 
     // Step 7: update all settings
-    if (action != ACTIVATE) {
+    if (true) {//action != ACTIVATE) {
 
         std::cout << "Updating settings." << std::endl;
 
+        Array<GenericProcessor*> splitters;
+
         for (int n = 0; n < signalChainArray.size(); n++)
-        {
+        { // iterate through signal chains
             
-            GenericEditor* source = (GenericEditor*) signalChainArray[n]->getEditor();
-            GenericProcessor* p = (GenericProcessor*) source->getProcessor();
+            GenericEditor* source = signalChainArray[n]->getEditor();
+            GenericProcessor* p = source->getProcessor();
 
-            p->updateSettings();
+            p->update();
+
+            if (p->isSplitter())
+            {
+                splitters.add(p);
+            }
 
             GenericProcessor* dest = p->getDestNode();
 
             while (dest != 0)
-            {
-                dest->updateSettings();
+            { // iterate through processors
+                dest->update();
                 dest = dest->getDestNode();
+
+                if (dest == 0 && splitters.size() > 0)
+                {
+                    splitters.getFirst()->switchIO();
+                    dest = splitters[0]->getDestNode();
+                    splitters.remove(0);
+                }
             }
         }
     }
 
-   // std::cout << "OK2." << std::endl;
-
-    // Step 8: make sure all editors are visible, and refresh
-   // for (int n = 0; n < editorArray.size(); n++)
-  //  {
-       // std::cout << "Editor " << n << ": " << editorArray[n]->getName() << std::endl;
-    //    editorArray[n]->setVisible(true);
-   // }
-
 
    std::cout << "Finished adding new editor." << std::endl << std::endl << std::endl;
     
diff --git a/Source/UI/UIComponent.cpp b/Source/UI/UIComponent.cpp
index 44d282ca6bb6d27de4204ea31b5fcabff57ce273..48d126c1e4cd4bee80cbe2693df2560f1d768f93 100644
--- a/Source/UI/UIComponent.cpp
+++ b/Source/UI/UIComponent.cpp
@@ -39,9 +39,8 @@ UIComponent::UIComponent (MainWindow* mainWindow_, ProcessorGraph* pgraph, Audio
 
 	std::cout << "Created data viewport." << std::endl;
 
-	editorViewport = new EditorViewport();//(processorGraph, dataViewport);
-	//processorGraph->setEditorViewport(editorViewport);
-	
+	editorViewport = new EditorViewport();
+
 	addAndMakeVisible(editorViewport);
 
 	std::cout << "Created filter viewport." << std::endl;
@@ -55,23 +54,16 @@ UIComponent::UIComponent (MainWindow* mainWindow_, ProcessorGraph* pgraph, Audio
 	std::cout << "Created control panel." << std::endl;
 
 	processorList = new ProcessorList();
-	//filterList->setUIComponent(this);
 	addAndMakeVisible(processorList);
 
 	std::cout << "Created filter list." << std::endl;
 
 	messageCenter = new MessageCenter();
-	//processorGraph->addActionListener(messageCenter);
 	addActionListener(messageCenter);
 	addAndMakeVisible(messageCenter);
 
 	std::cout << "Created message center." << std::endl;
 
-	config = new Configuration();
-	//processorGraph->setConfiguration(config);
-
-	std::cout << "Created configuration object." << std::endl;
-
 	setBounds(0,0,500,400);
 
 	std::cout << "Component width = " << getWidth() << std::endl;
@@ -79,10 +71,8 @@ UIComponent::UIComponent (MainWindow* mainWindow_, ProcessorGraph* pgraph, Audio
 
 	std::cout << "UI component data viewport: " << dataViewport << std::endl;
 
-
 	std::cout << "Finished UI stuff." << std::endl << std::endl << std::endl;
 
-
 	processorGraph->setUIComponent(this);
 	processorList->setUIComponent(this);
 	editorViewport->setUIComponent(this);
@@ -96,7 +86,6 @@ UIComponent::~UIComponent()
 {
 	deleteAllChildren();
 
-	deleteAndZero(config);
 	deleteAndZero(infoLabel);
 
 	processorGraph = 0;
@@ -150,6 +139,17 @@ void UIComponent::resized()
 	if (messageCenter != 0)
 		messageCenter->setBounds(6,h-35,w-241,30);
 
+	// for debugging purposes:
+	if (false) {
+		dataViewport->setVisible(false);
+		editorViewport->setVisible(false);
+		processorList->setVisible(false);
+		messageCenter->setVisible(false);
+		controlPanel->setVisible(false);
+		editorViewportButton->setVisible(false);
+	}
+
+
 }
 
 void UIComponent::disableCallbacks()
@@ -262,8 +262,6 @@ void EditorViewportButton::drawName()
 	font->FaceSize(23);
 	font->Render("SIGNAL CHAIN");
 	
-
-	
 }
 
 void EditorViewportButton::drawButton()
diff --git a/Source/UI/UIComponent.h b/Source/UI/UIComponent.h
index 2c374b53f66e4d4573a4d0c92f7a50e51239a34e..68e0cc9e5df35448ddb826f9f11b5f8b0f8b1055 100644
--- a/Source/UI/UIComponent.h
+++ b/Source/UI/UIComponent.h
@@ -31,7 +31,6 @@
 #include "EditorViewport.h"
 #include "DataViewport.h"
 #include "MessageCenter.h"
-#include "Configuration.h"
 #include "../Processors/ProcessorGraph.h"
 #include "../Audio/AudioComponent.h"
 #include "../MainWindow.h"
@@ -71,7 +70,6 @@ public:
 	EditorViewport* getEditorViewport() {return editorViewport;}
 	ProcessorList* getProcessorList() {return processorList;}
 	DataViewport* getDataViewport() {return dataViewport;}
-	Configuration* getConfiguration() {return config;}
 	ProcessorGraph* getProcessorGraph() {return processorGraph;}
 	ControlPanel* getControlPanel() {return controlPanel;}
 	MessageCenter* getMessageCenter() {return messageCenter;}
@@ -95,7 +93,6 @@ private:
 	ProcessorList* processorList;
 	ControlPanel* controlPanel;
 	MessageCenter* messageCenter;
-	Configuration* config;
 	InfoLabel* infoLabel;
 
 	MainWindow* mainWindow;
diff --git a/open-ephys.jucer b/open-ephys.jucer
index 2768d9df5014df67ecc942d65400bef9ec6de543..5eb088f9745b0109761d33258566279cdbe6740d 100644
--- a/open-ephys.jucer
+++ b/open-ephys.jucer
@@ -10,15 +10,16 @@
               pluginRTASCategory="" bundleIdentifier="" jucerVersion="3.0.0">
   <EXPORTFORMATS>
     <XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="~/SDKs/vstsdk2.4" rtasFolder="~/SDKs/PT_80_SDK"
-               juceFolder="JuceLibraryCode" extraLinkerFlags="-lftdi -lftgl"/>
+               juceFolder="JuceLibraryCode" extraLinkerFlags="-lftdi -lftgl"
+               objCExtraSuffix="fea2mT"/>
     <LINUX_MAKE targetFolder="Builds/Linux" vstFolder="~/SDKs/vstsdk2.4" juceFolder="JuceLibraryCode"
-                extraLinkerFlags="-lftdi -lftgl" extraCompilerFlags="-export-dynamic"/>
+                extraLinkerFlags="-lftdi -lftgl" extraCompilerFlags="-export-dynamic -pg"/>
   </EXPORTFORMATS>
   <CONFIGURATIONS>
     <CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="open-ephys"
-                   osxSDK="default" osxCompatibility="default"/>
+                   osxSDK="default" osxCompatibility="default" osxArchitecture="default"/>
     <CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="open-ephys"
-                   osxSDK="default" osxCompatibility="default"/>
+                   osxSDK="default" osxCompatibility="default" osxArchitecture="default"/>
   </CONFIGURATIONS>
   <MAINGROUP id="h3HbSTV" name="open-ephys">
     <GROUP id="0wpTCpt" name="Resources">
@@ -47,6 +48,52 @@
       </GROUP>
       <GROUP id="W2L6BdA" name="Images">
         <GROUP id="Gu1BsKu" name="Icons">
+          <FILE id="AQfzTI0" name="RadioButtons-01.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons-01.png"/>
+          <FILE id="zaiYTpn" name="RadioButtons-02.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons-02.png"/>
+          <FILE id="tMMIgNQ" name="RadioButtons-03.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons-03.png"/>
+          <FILE id="izT7ken" name="RadioButtons-04.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons-04.png"/>
+          <FILE id="wUnR602" name="RadioButtons-05.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons-05.png"/>
+          <FILE id="imnUJ17" name="RadioButtons_neutral-01.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons_neutral-01.png"/>
+          <FILE id="lSUFFn" name="RadioButtons_neutral-02.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons_neutral-02.png"/>
+          <FILE id="RLptoX" name="RadioButtons_neutral-03.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons_neutral-03.png"/>
+          <FILE id="cTSMIj9" name="RadioButtons_neutral-04.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons_neutral-04.png"/>
+          <FILE id="e2xa4yY" name="RadioButtons_neutral-05.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons_neutral-05.png"/>
+          <FILE id="uRp98Z6" name="RadioButtons_selected-01.png" compile="0"
+                resource="1" file="Resources/Images/Icons/RadioButtons_selected-01.png"/>
+          <FILE id="TSUeLsT" name="RadioButtons_selected-02.png" compile="0"
+                resource="1" file="Resources/Images/Icons/RadioButtons_selected-02.png"/>
+          <FILE id="3iZ1q0" name="RadioButtons_selected-03.png" compile="0" resource="1"
+                file="Resources/Images/Icons/RadioButtons_selected-03.png"/>
+          <FILE id="eBBTz15" name="RadioButtons_selected-04.png" compile="0"
+                resource="1" file="Resources/Images/Icons/RadioButtons_selected-04.png"/>
+          <FILE id="3UcfCgS" name="RadioButtons_selected-05.png" compile="0"
+                resource="1" file="Resources/Images/Icons/RadioButtons_selected-05.png"/>
+          <FILE id="dwuGoW2" name="RadioButtons_selected_over-01.png" compile="0"
+                resource="1" file="Resources/Images/Icons/RadioButtons_selected_over-01.png"/>
+          <FILE id="sNKpDX4" name="RadioButtons_selected_over-02.png" compile="0"
+                resource="1" file="Resources/Images/Icons/RadioButtons_selected_over-02.png"/>
+          <FILE id="3hxkdcI" name="RadioButtons_selected_over-03.png" compile="0"
+                resource="1" file="Resources/Images/Icons/RadioButtons_selected_over-03.png"/>
+          <FILE id="NJA55tz" name="RadioButtons_selected_over-04.png" compile="0"
+                resource="1" file="Resources/Images/Icons/RadioButtons_selected_over-04.png"/>
+          <FILE id="SDmWsOz" name="RadioButtons_selected_over-05.png" compile="0"
+                resource="1" file="Resources/Images/Icons/RadioButtons_selected_over-05.png"/>
+          <FILE id="rdA7uYL" name="noise_wave.png" compile="0" resource="1" file="Resources/Images/Icons/noise_wave.png"/>
+          <FILE id="s0uKcoP" name="saw_wave.png" compile="0" resource="1" file="Resources/Images/Icons/saw_wave.png"/>
+          <FILE id="4jA1Wxu" name="sine_wave.png" compile="0" resource="1" file="Resources/Images/Icons/sine_wave.png"/>
+          <FILE id="goY3ZC" name="square_wave.png" compile="0" resource="1" file="Resources/Images/Icons/square_wave.png"/>
+          <FILE id="gkPmriI" name="triangle_wave.png" compile="0" resource="1"
+                file="Resources/Images/Icons/triangle_wave.png"/>
           <FILE id="wI03PLF" name="wifi.png" compile="0" resource="1" file="Resources/Images/Icons/wifi.png"/>
           <FILE id="p1qlCZ5" name="SourceDrop.png" compile="0" resource="1" file="Resources/Images/Icons/SourceDrop.png"/>
           <FILE id="nWbYpu" name="DefaultDataSource.png" compile="0" resource="1"
@@ -137,6 +184,12 @@
               file="Source/Audio/AudioComponent.h"/>
       </GROUP>
       <GROUP id="yQmqZWk" name="Processors">
+        <FILE id="pQaYQiE" name="Parameter.cpp" compile="1" resource="0" file="Source/Processors/Parameter.cpp"/>
+        <FILE id="0jxvc4H" name="Parameter.h" compile="0" resource="0" file="Source/Processors/Parameter.h"/>
+        <FILE id="arRy5R" name="SpikeDisplayNode.cpp" compile="1" resource="0"
+              file="Source/Processors/SpikeDisplayNode.cpp"/>
+        <FILE id="VwDxj" name="SpikeDisplayNode.h" compile="0" resource="0"
+              file="Source/Processors/SpikeDisplayNode.h"/>
         <FILE id="Poqus0b" name="WiFiOutput.cpp" compile="1" resource="0" file="Source/Processors/WiFiOutput.cpp"/>
         <FILE id="IklsJpw" name="WiFiOutput.h" compile="0" resource="0" file="Source/Processors/WiFiOutput.h"/>
         <FILE id="ZuMpSio" name="LfpDisplayNode.cpp" compile="1" resource="0"
@@ -150,6 +203,39 @@
           <FILE id="DXYynnz" name="Splitter.h" compile="0" resource="0" file="Source/Processors/Utilities/Splitter.h"/>
         </GROUP>
         <GROUP id="W4eqkOy" name="Visualization">
+          <GROUP id="g8GOfh" name="SpikePlotting">
+            <FILE id="PzmX0I" name="StereotrodePlot.cpp" compile="1" resource="0"
+                  file="Source/Processors/Visualization/SpikePlotting/StereotrodePlot.cpp"/>
+            <FILE id="LPK6G1" name="StereotrodePlot.h" compile="0" resource="0"
+                  file="Source/Processors/Visualization/SpikePlotting/StereotrodePlot.h"/>
+            <FILE id="EgoljI" name="ElectrodePlot.cpp" compile="1" resource="0"
+                  file="Source/Processors/Visualization/SpikePlotting/ElectrodePlot.cpp"/>
+            <FILE id="oFUMq0" name="ElectrodePlot.h" compile="0" resource="0" file="Source/Processors/Visualization/SpikePlotting/ElectrodePlot.h"/>
+            <FILE id="Qq75l" name="BaseUIElement.cpp" compile="1" resource="0"
+                  file="Source/Processors/Visualization/SpikePlotting/BaseUIElement.cpp"/>
+            <FILE id="PZdkKU" name="BaseUIElement.h" compile="0" resource="0" file="Source/Processors/Visualization/SpikePlotting/BaseUIElement.h"/>
+            <FILE id="lFRVqc" name="GenericAxes.cpp" compile="1" resource="0" file="Source/Processors/Visualization/SpikePlotting/GenericAxes.cpp"/>
+            <FILE id="BP8BOa" name="GenericAxes.h" compile="0" resource="0" file="Source/Processors/Visualization/SpikePlotting/GenericAxes.h"/>
+            <FILE id="f7vOFh" name="PlotUtils.cpp" compile="1" resource="0" file="Source/Processors/Visualization/SpikePlotting/PlotUtils.cpp"/>
+            <FILE id="TQfHuh" name="PlotUtils.h" compile="0" resource="0" file="Source/Processors/Visualization/SpikePlotting/PlotUtils.h"/>
+            <FILE id="d3ducO" name="ProjectionAxes.cpp" compile="1" resource="0"
+                  file="Source/Processors/Visualization/SpikePlotting/ProjectionAxes.cpp"/>
+            <FILE id="BdHvyv" name="ProjectionAxes.h" compile="0" resource="0"
+                  file="Source/Processors/Visualization/SpikePlotting/ProjectionAxes.h"/>
+            <FILE id="RnnkTt" name="SimpleKeyEvent.h" compile="0" resource="0"
+                  file="Source/Processors/Visualization/SpikePlotting/SimpleKeyEvent.h"/>
+            <FILE id="dP2Ikw" name="TetrodePlot.cpp" compile="1" resource="0" file="Source/Processors/Visualization/SpikePlotting/TetrodePlot.cpp"/>
+            <FILE id="SH9Un2" name="TetrodePlot.h" compile="0" resource="0" file="Source/Processors/Visualization/SpikePlotting/TetrodePlot.h"/>
+            <FILE id="yg1Xuq" name="WaveAxes.cpp" compile="1" resource="0" file="Source/Processors/Visualization/SpikePlotting/WaveAxes.cpp"/>
+            <FILE id="cZX4SM" name="WaveAxes.h" compile="0" resource="0" file="Source/Processors/Visualization/SpikePlotting/WaveAxes.h"/>
+          </GROUP>
+          <FILE id="ajAJi" name="SpikeObject.cpp" compile="1" resource="0" file="Source/Processors/Visualization/SpikeObject.cpp"/>
+          <FILE id="xqF5zL" name="SpikeObject.h" compile="0" resource="0" file="Source/Processors/Visualization/SpikeObject.h"/>
+          <FILE id="jGEqDp" name="SpikeDisplayCanvas.cpp" compile="1" resource="0"
+                file="Source/Processors/Visualization/SpikeDisplayCanvas.cpp"/>
+          <FILE id="LVHMu2" name="SpikeDisplayCanvas.h" compile="0" resource="0"
+                file="Source/Processors/Visualization/SpikeDisplayCanvas.h"/>
+          <FILE id="yDPZGpt" name="Visualizer.h" compile="0" resource="0" file="Source/Processors/Visualization/Visualizer.h"/>
           <FILE id="BX1Vj3V" name="DataWindow.cpp" compile="1" resource="0" file="Source/Processors/Visualization/DataWindow.cpp"/>
           <FILE id="l2VKLuP" name="DataWindow.h" compile="0" resource="0" file="Source/Processors/Visualization/DataWindow.h"/>
           <FILE id="2rXPco7" name="LfpDisplayCanvas.cpp" compile="1" resource="0"
@@ -164,13 +250,19 @@
               file="Source/Processors/SpikeDetector.cpp"/>
         <FILE id="jIX00WN" name="SpikeDetector.h" compile="0" resource="0"
               file="Source/Processors/SpikeDetector.h"/>
-        <FILE id="sKJ2lid" name="FileReader.cpp" compile="1" resource="0" file="Source/Processors/FileReader.cpp"/>
-        <FILE id="9o71Tr2" name="FileReader.h" compile="0" resource="0" file="Source/Processors/FileReader.h"/>
         <FILE id="gZRZq2O" name="AudioNode.cpp" compile="1" resource="0" file="Source/Processors/AudioNode.cpp"/>
         <FILE id="ZPSmLKn" name="AudioNode.h" compile="0" resource="0" file="Source/Processors/AudioNode.h"/>
         <FILE id="hGnGAjh" name="EventNode.cpp" compile="1" resource="0" file="Source/Processors/EventNode.cpp"/>
         <FILE id="dUtRN6" name="EventNode.h" compile="0" resource="0" file="Source/Processors/EventNode.h"/>
         <GROUP id="AqvwO6w" name="Editors">
+          <FILE id="s5YUmi" name="SpikeDisplayEditor.cpp" compile="1" resource="0"
+                file="Source/Processors/Editors/SpikeDisplayEditor.cpp"/>
+          <FILE id="EE43GV" name="SpikeDisplayEditor.h" compile="0" resource="0"
+                file="Source/Processors/Editors/SpikeDisplayEditor.h"/>
+          <FILE id="2XqqPOS" name="VisualizerEditor.cpp" compile="1" resource="0"
+                file="Source/Processors/Editors/VisualizerEditor.cpp"/>
+          <FILE id="CUHGPJF" name="VisualizerEditor.h" compile="0" resource="0"
+                file="Source/Processors/Editors/VisualizerEditor.h"/>
           <FILE id="bsIZbuu" name="MergerEditor.cpp" compile="1" resource="0"
                 file="Source/Processors/Editors/MergerEditor.cpp"/>
           <FILE id="vfmEY5L" name="MergerEditor.h" compile="0" resource="0" file="Source/Processors/Editors/MergerEditor.h"/>
@@ -287,10 +379,6 @@
         <FILE id="bWElQSS" name="DataViewport.cpp" compile="1" resource="0"
               file="Source/UI/DataViewport.cpp"/>
         <FILE id="mMoQ3ls" name="DataViewport.h" compile="0" resource="0" file="Source/UI/DataViewport.h"/>
-        <FILE id="iFsLzAy" name="Configuration.cpp" compile="1" resource="0"
-              file="Source/UI/Configuration.cpp"/>
-        <FILE id="vNTFgW9" name="Configuration.h" compile="0" resource="0"
-              file="Source/UI/Configuration.h"/>
         <FILE id="rRa3X6v" name="MessageCenter.cpp" compile="1" resource="0"
               file="Source/UI/MessageCenter.cpp"/>
         <FILE id="Gwnvgdy" name="MessageCenter.h" compile="0" resource="0"