diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile index 4f28f6488b337237c46573d7fe85e329e85a3a96..b00bec1330aed6503cd834f272de0ad03f5d17e4 100644 --- a/Builds/Linux/Makefile +++ b/Builds/Linux/Makefile @@ -57,6 +57,7 @@ OBJECTS := \ $(OBJDIR)/AudioComponent_521bd9c9.o \ $(OBJDIR)/PlaceholderProcessorEditor_7b4cbcf7.o \ $(OBJDIR)/PlaceholderProcessor_167f09aa.o \ + $(OBJDIR)/LinearSmoothedValueAtomic_df1e5b97.o \ $(OBJDIR)/Bessel_7e54cb27.o \ $(OBJDIR)/Biquad_622c856b.o \ $(OBJDIR)/Butterworth_6aca939b.o \ @@ -105,6 +106,8 @@ OBJECTS := \ $(OBJDIR)/ParameterEditor_112258eb.o \ $(OBJDIR)/Parameter_b3e5ac9e.o \ $(OBJDIR)/ProcessorGraph_8c3a250a.o \ + $(OBJDIR)/DataQueue_d6cc297a.o \ + $(OBJDIR)/RecordThread_fb797372.o \ $(OBJDIR)/EngineConfigWindow_4fd44ceb.o \ $(OBJDIR)/OriginalRecording_d6dc3293.o \ $(OBJDIR)/RecordEngine_97ef83aa.o \ @@ -117,13 +120,18 @@ OBJECTS := \ $(OBJDIR)/DataWindow_83ce6754.o \ $(OBJDIR)/SpikeObject_24e8c655.o \ $(OBJDIR)/MatlabLikePlot_fb09c37f.o \ + $(OBJDIR)/TiledButtonGroupManager_e05788a6.o \ + $(OBJDIR)/LinearButtonGroupManager_ea5cb5bf.o \ + $(OBJDIR)/ButtonGroupManager_75d0fbfa.o \ + $(OBJDIR)/MaterialButtonLookAndFeel_d7d19ba2.o \ + $(OBJDIR)/MaterialSliderLookAndFeel_c97dd613.o \ + $(OBJDIR)/CustomLookAndFeel_fcb2406a.o \ $(OBJDIR)/CustomArrowButton_206e4278.o \ $(OBJDIR)/GraphViewer_e43fd2ce.o \ $(OBJDIR)/EditorViewportButtons_29af2a5c.o \ $(OBJDIR)/SignalChainManager_d2b643f0.o \ $(OBJDIR)/EditorViewport_1d991caf.o \ $(OBJDIR)/ProcessorList_1ad3f3de.o \ - $(OBJDIR)/CustomLookAndFeel_53a8fcdb.o \ $(OBJDIR)/InfoLabel_a2051bf4.o \ $(OBJDIR)/DataViewport_2cf95d2c.o \ $(OBJDIR)/ControlPanel_a895ede3.o \ @@ -193,6 +201,11 @@ $(OBJDIR)/PlaceholderProcessor_167f09aa.o: ../../Source/Processors/PlaceholderPr @echo "Compiling PlaceholderProcessor.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/LinearSmoothedValueAtomic_df1e5b97.o: ../../Source/Processors/Dsp/LinearSmoothedValueAtomic.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling LinearSmoothedValueAtomic.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/Bessel_7e54cb27.o: ../../Source/Processors/Dsp/Bessel.cpp -@mkdir -p $(OBJDIR) @echo "Compiling Bessel.cpp" @@ -433,6 +446,16 @@ $(OBJDIR)/ProcessorGraph_8c3a250a.o: ../../Source/Processors/ProcessorGraph/Proc @echo "Compiling ProcessorGraph.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/DataQueue_d6cc297a.o: ../../Source/Processors/RecordNode/DataQueue.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling DataQueue.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/RecordThread_fb797372.o: ../../Source/Processors/RecordNode/RecordThread.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling RecordThread.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/EngineConfigWindow_4fd44ceb.o: ../../Source/Processors/RecordNode/EngineConfigWindow.cpp -@mkdir -p $(OBJDIR) @echo "Compiling EngineConfigWindow.cpp" @@ -493,6 +516,36 @@ $(OBJDIR)/MatlabLikePlot_fb09c37f.o: ../../Source/Processors/Visualization/Matla @echo "Compiling MatlabLikePlot.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/TiledButtonGroupManager_e05788a6.o: ../../Source/UI/Utils/TiledButtonGroupManager.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling TiledButtonGroupManager.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/LinearButtonGroupManager_ea5cb5bf.o: ../../Source/UI/Utils/LinearButtonGroupManager.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling LinearButtonGroupManager.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/ButtonGroupManager_75d0fbfa.o: ../../Source/UI/Utils/ButtonGroupManager.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling ButtonGroupManager.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/MaterialButtonLookAndFeel_d7d19ba2.o: ../../Source/UI/LookAndFeel/MaterialButtonLookAndFeel.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling MaterialButtonLookAndFeel.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/MaterialSliderLookAndFeel_c97dd613.o: ../../Source/UI/LookAndFeel/MaterialSliderLookAndFeel.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling MaterialSliderLookAndFeel.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/CustomLookAndFeel_fcb2406a.o: ../../Source/UI/LookAndFeel/CustomLookAndFeel.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling CustomLookAndFeel.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/CustomArrowButton_206e4278.o: ../../Source/UI/CustomArrowButton.cpp -@mkdir -p $(OBJDIR) @echo "Compiling CustomArrowButton.cpp" @@ -523,11 +576,6 @@ $(OBJDIR)/ProcessorList_1ad3f3de.o: ../../Source/UI/ProcessorList.cpp @echo "Compiling ProcessorList.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -$(OBJDIR)/CustomLookAndFeel_53a8fcdb.o: ../../Source/UI/CustomLookAndFeel.cpp - -@mkdir -p $(OBJDIR) - @echo "Compiling CustomLookAndFeel.cpp" - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - $(OBJDIR)/InfoLabel_a2051bf4.o: ../../Source/UI/InfoLabel.cpp -@mkdir -p $(OBJDIR) @echo "Compiling InfoLabel.cpp" diff --git a/Builds/MacOSX/.gitignore b/Builds/MacOSX/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c545112057ddf11017534ed98cc531151a32c3f7 --- /dev/null +++ b/Builds/MacOSX/.gitignore @@ -0,0 +1 @@ +xcuserdata/ diff --git a/Builds/MacOSX/Icon.icns b/Builds/MacOSX/Icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..64ed01ba5fba70b6196bc43a81f5e2778996f869 Binary files /dev/null and b/Builds/MacOSX/Icon.icns differ diff --git a/Builds/MacOSX/Info.plist b/Builds/MacOSX/Info.plist index dabe88df3c91e6ab8b390a7d935b6b1377571a3f..b18367a8778321d93558098b0e8add11fe444719 100644 --- a/Builds/MacOSX/Info.plist +++ b/Builds/MacOSX/Info.plist @@ -6,7 +6,7 @@ <key>CFBundleExecutable</key> <string>${EXECUTABLE_NAME}</string> <key>CFBundleIconFile</key> - <string></string> + <string>Icon.icns</string> <key>CFBundleIdentifier</key> <string>org.open-ephys.gui</string> <key>CFBundleName</key> diff --git a/Builds/MacOSX/Makefile.plugins b/Builds/MacOSX/Makefile.plugins deleted file mode 100644 index 3b3a265cb34b60d949cd28b91886ed9e81d9c9c2..0000000000000000000000000000000000000000 --- a/Builds/MacOSX/Makefile.plugins +++ /dev/null @@ -1,71 +0,0 @@ -# Automatically generated makefile, created by the Introjucer -# Don't edit this file! Your changes will be overwritten when you re-save the Introjucer project! - -# (this disables dependency generation if multiple architectures are set) -DEPFLAGS := $(if $(word 2, $(TARGET_ARCH)), , -MMD) - -PLUGIN_DIR := ../../Source/Plugins - -ifndef CONFIG - CONFIG=Debug -endif - -ifeq ($(CONFIG),Debug) - BINDIR := $(CURDIR)/build - LIBDIR := $(CURDIR)/build - OBJDIR := $(CURDIR)/build/intermediate/plugins/Debug - OUTDIR := $(CURDIR)/build/Debug/plugins - - ifeq ($(TARGET_ARCH),) - TARGET_ARCH := -march=native - endif - - CPPFLAGS := $(DEPFLAGS) -D "DEBUG=1" -D "_DEBUG=1" -D "OEPLUGIN" -D "JUCER_XCODE_MAC_F6D2F4CF=1" -D "JUCE_APP_VERSION=0.3.5" -D "JUCE_APP_VERSION_HEX=0x305" -I $(CURDIR)/../../Source/Plugins/Headers - CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O3 -g -std=c++0x -fPIC - CXXFLAGS += $(CFLAGS) - LDFLAGS += $(TARGET_ARCH) -L$(BINDIR) -L$(LIBDIR) -ldl -lpthread -ldl -fPIC -rdynamic -dynamiclib -undefined dynamic_lookup - LDDEPS := - RESFLAGS := -D "DEBUG=1" -D "_DEBUG=1" -D "OEPLUGIN" -D "JUCER_XCODE_MAC_F6D2F4CF=1" -D "JUCE_APP_VERSION=0.3.5" -D "JUCE_APP_VERSION_HEX=0x305" -I $(CURDIR)/../../Source/Plugins/Headers - CLEANCMD = rm -rf $(OUTDIR)/* $(OBJDIR) -endif - -ifeq ($(CONFIG),Release) - BINDIR := $(CURDIR)/build - LIBDIR := $(CURDIR)/build - OBJDIR := $(CURDIR)/build/intermediate/plugins/Release - OUTDIR := $(CURDIR)/build/Release/plugins - - ifeq ($(TARGET_ARCH),) - TARGET_ARCH := -march=native - endif - - CPPFLAGS := $(DEPFLAGS) -D "NDEBUG=1" -D "OEPLUGIN" -D "JUCER_XCODE_MAC_F6D2F4CF=1" -D "JUCE_APP_VERSION=0.3.5" -D "JUCE_APP_VERSION_HEX=0x305" -I $(CURDIR)/../../Source/Plugins/Headers - CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3 -g -std=c++0x -fPIC - CXXFLAGS += $(CFLAGS) - LDFLAGS += $(TARGET_ARCH) -L$(BINDIR) -L$(LIBDIR) -fvisibility=hidden -ldl -lpthread -ldl -fPIC -rdynamic -dynamiclib -undefined dynamic_lookup - LDDEPS1 := - RESFLAGS := -D "NDEBUG=1" -D "OEPLUGIN" -D "JUCER_XCODE_MAC_F6D2F4CF=1" -D "JUCE_APP_VERSION=0.3.5" -D "JUCE_APP_VERSION_HEX=0x305" -I /usr/include -I /usr/include/freetype2 -I $(CURDIR)/../../Source/Plugins/Headers - CLEANCMD = rm -rf $(OUTDIR)/* $(OBJDIR) -endif - -export - -SUBDIRS := $(wildcard $(PLUGIN_DIR)/*) - -.PHONY: clean all notify $(SUBDIRS) - -all: notify $(SUBDIRS) - -notify: - @echo "Building Open-Ephys Plugins" - -$(SUBDIRS): - @if [ -f $@/Makefile ]; then $(MAKE) -C $@ ; fi - -%:: - @if [ -f $(PLUGIN_DIR)/$@/Makefile ]; then $(MAKE) -C $(PLUGIN_DIR)/$@ clean ; $(MAKE) -C $(PLUGIN_DIR)/$@ ; fi - - -clean: - @echo Cleaning open-ephys plugins - @$(CLEANCMD) diff --git a/Builds/MacOSX/OpenEphys.xcworkspace/contents.xcworkspacedata b/Builds/MacOSX/OpenEphys.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000000000000000000000000000000..f52fca6ca004ad09196a55674fa9edac007bed70 --- /dev/null +++ b/Builds/MacOSX/OpenEphys.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "group:open-ephys.xcodeproj"> + </FileRef> + <Group + location = "container:Plugins" + name = "Plugins"> + <FileRef + location = "group:ArduinoOutput/ArduinoOutput.xcodeproj"> + </FileRef> + <FileRef + location = "group:BasicSpikeDisplay/BasicSpikeDisplay.xcodeproj"> + </FileRef> + <FileRef + location = "group:CAR/CAR.xcodeproj"> + </FileRef> + <FileRef + location = "group:ChannelMappingNode/ChannelMappingNode.xcodeproj"> + </FileRef> + <FileRef + location = "group:EventBroadcaster/EventBroadcaster.xcodeproj"> + </FileRef> + <FileRef + location = "group:FilterNode/FilterNode.xcodeproj"> + </FileRef> + <FileRef + location = "group:KWIKFormat/KWIKFormat.xcodeproj"> + </FileRef> + <FileRef + location = "group:LfpDisplayNode/LfpDisplayNode.xcodeproj"> + </FileRef> + <FileRef + location = "group:NetworkEvents/NetworkEvents.xcodeproj"> + </FileRef> + <FileRef + location = "group:PhaseDetector/PhaseDetector.xcodeproj"> + </FileRef> + <FileRef + location = "group:PulsePalOutput/PulsePalOutput.xcodeproj"> + </FileRef> + <FileRef + location = "group:RecordControl/RecordControl.xcodeproj"> + </FileRef> + <FileRef + location = "group:Rectifier/Rectifier.xcodeproj"> + </FileRef> + <FileRef + location = "group:SerialInput/SerialInput.xcodeproj"> + </FileRef> + <FileRef + location = "group:SpikeSorter/SpikeSorter.xcodeproj"> + </FileRef> + </Group> +</Workspace> diff --git a/Builds/MacOSX/OpenEphys.xcworkspace/xcshareddata/xcschemes/All.xcscheme b/Builds/MacOSX/OpenEphys.xcworkspace/xcshareddata/xcschemes/All.xcscheme new file mode 100644 index 0000000000000000000000000000000000000000..6c515bb101d6b567f9f6126b07f1e5c24efc607d --- /dev/null +++ b/Builds/MacOSX/OpenEphys.xcworkspace/xcshareddata/xcschemes/All.xcscheme @@ -0,0 +1,300 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0720" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "609761DEC9151D2CDD50270C" + BuildableName = "open-ephys.app" + BlueprintName = "open-ephys" + ReferencedContainer = "container:open-ephys.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F557B11C9AF1660035F88B" + BuildableName = "ArduinoOutput.bundle" + BlueprintName = "ArduinoOutput" + ReferencedContainer = "container:Plugins/ArduinoOutput/ArduinoOutput.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F557E71C9B0C600035F88B" + BuildableName = "BasicSpikeDisplay.bundle" + BlueprintName = "BasicSpikeDisplay" + ReferencedContainer = "container:Plugins/BasicSpikeDisplay/BasicSpikeDisplay.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F558131C9B0FCA0035F88B" + BuildableName = "CAR.bundle" + BlueprintName = "CAR" + ReferencedContainer = "container:Plugins/CAR/CAR.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F558311C9B11E80035F88B" + BuildableName = "ChannelMappingNode.bundle" + BlueprintName = "ChannelMappingNode" + ReferencedContainer = "container:Plugins/ChannelMappingNode/ChannelMappingNode.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1C3F9771C99A20D00719A9F" + BuildableName = "EventBroadcaster.bundle" + BlueprintName = "EventBroadcaster" + ReferencedContainer = "container:Plugins/EventBroadcaster/EventBroadcaster.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F558741C9B1F920035F88B" + BuildableName = "FilterNode.bundle" + BlueprintName = "FilterNode" + ReferencedContainer = "container:Plugins/FilterNode/FilterNode.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F558CF1C9B23370035F88B" + BuildableName = "KWIKFormat.bundle" + BlueprintName = "KWIKFormat" + ReferencedContainer = "container:Plugins/KWIKFormat/KWIKFormat.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F558F51C9B28060035F88B" + BuildableName = "LfpDisplayNode.bundle" + BlueprintName = "LfpDisplayNode" + ReferencedContainer = "container:Plugins/LfpDisplayNode/LfpDisplayNode.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F559191C9B29D20035F88B" + BuildableName = "NetworkEvents.bundle" + BlueprintName = "NetworkEvents" + ReferencedContainer = "container:Plugins/NetworkEvents/NetworkEvents.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F5593A1C9B3A100035F88B" + BuildableName = "PhaseDetector.bundle" + BlueprintName = "PhaseDetector" + ReferencedContainer = "container:Plugins/PhaseDetector/PhaseDetector.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F5595B1C9B3B990035F88B" + BuildableName = "PulsePalOutput.bundle" + BlueprintName = "PulsePalOutput" + ReferencedContainer = "container:Plugins/PulsePalOutput/PulsePalOutput.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F559801C9B3D760035F88B" + BuildableName = "RecordControl.bundle" + BlueprintName = "RecordControl" + ReferencedContainer = "container:Plugins/RecordControl/RecordControl.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F559A11C9B3F040035F88B" + BuildableName = "Rectifier.bundle" + BlueprintName = "Rectifier" + ReferencedContainer = "container:Plugins/Rectifier/Rectifier.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F559BF1C9B40A10035F88B" + BuildableName = "SerialInput.bundle" + BlueprintName = "SerialInput" + ReferencedContainer = "container:Plugins/SerialInput/SerialInput.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "E1F559E01C9B42270035F88B" + BuildableName = "SpikeSorter.bundle" + BlueprintName = "SpikeSorter" + ReferencedContainer = "container:Plugins/SpikeSorter/SpikeSorter.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + </Testables> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "609761DEC9151D2CDD50270C" + BuildableName = "open-ephys.app" + BlueprintName = "open-ephys" + ReferencedContainer = "container:open-ephys.xcodeproj"> + </BuildableReference> + </MacroExpansion> + <AdditionalOptions> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "609761DEC9151D2CDD50270C" + BuildableName = "open-ephys.app" + BlueprintName = "open-ephys" + ReferencedContainer = "container:open-ephys.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "609761DEC9151D2CDD50270C" + BuildableName = "open-ephys.app" + BlueprintName = "open-ephys" + ReferencedContainer = "container:open-ephys.xcodeproj"> + </BuildableReference> + </MacroExpansion> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/Builds/MacOSX/Plugins/ArduinoOutput/ArduinoOutput.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/ArduinoOutput/ArduinoOutput.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..7d7f08c41f263a5de471b7020f160ab29a9a3cb4 --- /dev/null +++ b/Builds/MacOSX/Plugins/ArduinoOutput/ArduinoOutput.xcodeproj/project.pbxproj @@ -0,0 +1,234 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F557CF1C9B040E0035F88B /* ArduinoOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557C61C9B040E0035F88B /* ArduinoOutput.cpp */; }; + E1F557D01C9B040E0035F88B /* ArduinoOutputEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557C81C9B040E0035F88B /* ArduinoOutputEditor.cpp */; }; + E1F557D21C9B040E0035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557CB1C9B040E0035F88B /* OpenEphysLib.cpp */; }; + E1F557D31C9B040E0035F88B /* ofArduino.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557CD1C9B040E0035F88B /* ofArduino.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F557B21C9AF1660035F88B /* ArduinoOutput.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ArduinoOutput.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F557B51C9AF1660035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F557BE1C9AFE210035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F557BF1C9AFE210035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F557C01C9AFE210035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F557C61C9B040E0035F88B /* ArduinoOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArduinoOutput.cpp; sourceTree = "<group>"; }; + E1F557C71C9B040E0035F88B /* ArduinoOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArduinoOutput.h; sourceTree = "<group>"; }; + E1F557C81C9B040E0035F88B /* ArduinoOutputEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArduinoOutputEditor.cpp; sourceTree = "<group>"; }; + E1F557C91C9B040E0035F88B /* ArduinoOutputEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArduinoOutputEditor.h; sourceTree = "<group>"; }; + E1F557CB1C9B040E0035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; + E1F557CD1C9B040E0035F88B /* ofArduino.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofArduino.cpp; sourceTree = "<group>"; }; + E1F557CE1C9B040E0035F88B /* ofArduino.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofArduino.h; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F557AF1C9AF1660035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F557A91C9AF1660035F88B = { + isa = PBXGroup; + children = ( + E1F557BD1C9AFE210035F88B /* Config */, + E1F557B41C9AF1660035F88B /* ArduinoOutput */, + E1F557B31C9AF1660035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F557B31C9AF1660035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F557B21C9AF1660035F88B /* ArduinoOutput.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F557B41C9AF1660035F88B /* ArduinoOutput */ = { + isa = PBXGroup; + children = ( + E1F557C51C9B040E0035F88B /* Source */, + E1F557B51C9AF1660035F88B /* Info.plist */, + ); + path = ArduinoOutput; + sourceTree = "<group>"; + }; + E1F557BD1C9AFE210035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F557BE1C9AFE210035F88B /* Plugin.xcconfig */, + E1F557BF1C9AFE210035F88B /* Plugin_Debug.xcconfig */, + E1F557C01C9AFE210035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F557C51C9B040E0035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F557CC1C9B040E0035F88B /* serial */, + E1F557C71C9B040E0035F88B /* ArduinoOutput.h */, + E1F557C61C9B040E0035F88B /* ArduinoOutput.cpp */, + E1F557C91C9B040E0035F88B /* ArduinoOutputEditor.h */, + E1F557C81C9B040E0035F88B /* ArduinoOutputEditor.cpp */, + E1F557CB1C9B040E0035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/ArduinoOutput; + sourceTree = "<group>"; + }; + E1F557CC1C9B040E0035F88B /* serial */ = { + isa = PBXGroup; + children = ( + E1F557CE1C9B040E0035F88B /* ofArduino.h */, + E1F557CD1C9B040E0035F88B /* ofArduino.cpp */, + ); + path = serial; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F557B11C9AF1660035F88B /* ArduinoOutput */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F557B81C9AF1660035F88B /* Build configuration list for PBXNativeTarget "ArduinoOutput" */; + buildPhases = ( + E1F557AE1C9AF1660035F88B /* Sources */, + E1F557AF1C9AF1660035F88B /* Frameworks */, + E1F557B01C9AF1660035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ArduinoOutput; + productName = ArduinoOutput; + productReference = E1F557B21C9AF1660035F88B /* ArduinoOutput.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F557AA1C9AF1660035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F557B11C9AF1660035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F557AD1C9AF1660035F88B /* Build configuration list for PBXProject "ArduinoOutput" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F557A91C9AF1660035F88B; + productRefGroup = E1F557B31C9AF1660035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F557B11C9AF1660035F88B /* ArduinoOutput */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F557B01C9AF1660035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F557AE1C9AF1660035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F557D31C9B040E0035F88B /* ofArduino.cpp in Sources */, + E1F557D01C9B040E0035F88B /* ArduinoOutputEditor.cpp in Sources */, + E1F557CF1C9B040E0035F88B /* ArduinoOutput.cpp in Sources */, + E1F557D21C9B040E0035F88B /* OpenEphysLib.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F557B61C9AF1660035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F557BF1C9AFE210035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F557B71C9AF1660035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F557C01C9AFE210035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F557B91C9AF1660035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = ArduinoOutput/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.ArduinoOutput"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F557BA1C9AF1660035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = ArduinoOutput/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.ArduinoOutput"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F557AD1C9AF1660035F88B /* Build configuration list for PBXProject "ArduinoOutput" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F557B61C9AF1660035F88B /* Debug */, + E1F557B71C9AF1660035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F557B81C9AF1660035F88B /* Build configuration list for PBXNativeTarget "ArduinoOutput" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F557B91C9AF1660035F88B /* Debug */, + E1F557BA1C9AF1660035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F557AA1C9AF1660035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/ArduinoOutput/ArduinoOutput/Info.plist b/Builds/MacOSX/Plugins/ArduinoOutput/ArduinoOutput/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/ArduinoOutput/ArduinoOutput/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/BasicSpikeDisplay/BasicSpikeDisplay.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/BasicSpikeDisplay/BasicSpikeDisplay.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..24044814eae4e3d7ad7aa999730a3998457bbc9b --- /dev/null +++ b/Builds/MacOSX/Plugins/BasicSpikeDisplay/BasicSpikeDisplay.xcodeproj/project.pbxproj @@ -0,0 +1,254 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F558051C9B0DAC0035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557F71C9B0DAC0035F88B /* OpenEphysLib.cpp */; }; + E1F558061C9B0DAC0035F88B /* SpikeDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557F91C9B0DAC0035F88B /* SpikeDetector.cpp */; }; + E1F558071C9B0DAC0035F88B /* SpikeDetectorEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557FB1C9B0DAC0035F88B /* SpikeDetectorEditor.cpp */; }; + E1F558081C9B0DAC0035F88B /* SpikeDisplayCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557FE1C9B0DAC0035F88B /* SpikeDisplayCanvas.cpp */; }; + E1F558091C9B0DAC0035F88B /* SpikeDisplayEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558001C9B0DAC0035F88B /* SpikeDisplayEditor.cpp */; }; + E1F5580A1C9B0DAC0035F88B /* SpikeDisplayNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558021C9B0DAC0035F88B /* SpikeDisplayNode.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F557E81C9B0C600035F88B /* BasicSpikeDisplay.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BasicSpikeDisplay.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F557EB1C9B0C600035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F557F21C9B0CA90035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F557F31C9B0CA90035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F557F41C9B0CA90035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F557F71C9B0DAC0035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; + E1F557F91C9B0DAC0035F88B /* SpikeDetector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpikeDetector.cpp; sourceTree = "<group>"; }; + E1F557FA1C9B0DAC0035F88B /* SpikeDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpikeDetector.h; sourceTree = "<group>"; }; + E1F557FB1C9B0DAC0035F88B /* SpikeDetectorEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpikeDetectorEditor.cpp; sourceTree = "<group>"; }; + E1F557FC1C9B0DAC0035F88B /* SpikeDetectorEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpikeDetectorEditor.h; sourceTree = "<group>"; }; + E1F557FE1C9B0DAC0035F88B /* SpikeDisplayCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpikeDisplayCanvas.cpp; sourceTree = "<group>"; }; + E1F557FF1C9B0DAC0035F88B /* SpikeDisplayCanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpikeDisplayCanvas.h; sourceTree = "<group>"; }; + E1F558001C9B0DAC0035F88B /* SpikeDisplayEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpikeDisplayEditor.cpp; sourceTree = "<group>"; }; + E1F558011C9B0DAC0035F88B /* SpikeDisplayEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpikeDisplayEditor.h; sourceTree = "<group>"; }; + E1F558021C9B0DAC0035F88B /* SpikeDisplayNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpikeDisplayNode.cpp; sourceTree = "<group>"; }; + E1F558031C9B0DAC0035F88B /* SpikeDisplayNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpikeDisplayNode.h; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F557E51C9B0C600035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F557DF1C9B0C600035F88B = { + isa = PBXGroup; + children = ( + E1F557F11C9B0CA90035F88B /* Config */, + E1F557EA1C9B0C600035F88B /* BasicSpikeDisplay */, + E1F557E91C9B0C600035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F557E91C9B0C600035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F557E81C9B0C600035F88B /* BasicSpikeDisplay.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F557EA1C9B0C600035F88B /* BasicSpikeDisplay */ = { + isa = PBXGroup; + children = ( + E1F557F51C9B0DAC0035F88B /* Source */, + E1F557EB1C9B0C600035F88B /* Info.plist */, + ); + path = BasicSpikeDisplay; + sourceTree = "<group>"; + }; + E1F557F11C9B0CA90035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F557F21C9B0CA90035F88B /* Plugin.xcconfig */, + E1F557F31C9B0CA90035F88B /* Plugin_Debug.xcconfig */, + E1F557F41C9B0CA90035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F557F51C9B0DAC0035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F557F81C9B0DAC0035F88B /* SpikeDetector */, + E1F557FD1C9B0DAC0035F88B /* SpikeDisplayNode */, + E1F557F71C9B0DAC0035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/BasicSpikeDisplay; + sourceTree = "<group>"; + }; + E1F557F81C9B0DAC0035F88B /* SpikeDetector */ = { + isa = PBXGroup; + children = ( + E1F557FA1C9B0DAC0035F88B /* SpikeDetector.h */, + E1F557F91C9B0DAC0035F88B /* SpikeDetector.cpp */, + E1F557FC1C9B0DAC0035F88B /* SpikeDetectorEditor.h */, + E1F557FB1C9B0DAC0035F88B /* SpikeDetectorEditor.cpp */, + ); + path = SpikeDetector; + sourceTree = "<group>"; + }; + E1F557FD1C9B0DAC0035F88B /* SpikeDisplayNode */ = { + isa = PBXGroup; + children = ( + E1F557FF1C9B0DAC0035F88B /* SpikeDisplayCanvas.h */, + E1F557FE1C9B0DAC0035F88B /* SpikeDisplayCanvas.cpp */, + E1F558011C9B0DAC0035F88B /* SpikeDisplayEditor.h */, + E1F558001C9B0DAC0035F88B /* SpikeDisplayEditor.cpp */, + E1F558031C9B0DAC0035F88B /* SpikeDisplayNode.h */, + E1F558021C9B0DAC0035F88B /* SpikeDisplayNode.cpp */, + ); + path = SpikeDisplayNode; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F557E71C9B0C600035F88B /* BasicSpikeDisplay */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F557EE1C9B0C600035F88B /* Build configuration list for PBXNativeTarget "BasicSpikeDisplay" */; + buildPhases = ( + E1F557E41C9B0C600035F88B /* Sources */, + E1F557E51C9B0C600035F88B /* Frameworks */, + E1F557E61C9B0C600035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BasicSpikeDisplay; + productName = BasicSpikeDisplay; + productReference = E1F557E81C9B0C600035F88B /* BasicSpikeDisplay.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F557E01C9B0C600035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F557E71C9B0C600035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F557E31C9B0C600035F88B /* Build configuration list for PBXProject "BasicSpikeDisplay" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F557DF1C9B0C600035F88B; + productRefGroup = E1F557E91C9B0C600035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F557E71C9B0C600035F88B /* BasicSpikeDisplay */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F557E61C9B0C600035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F557E41C9B0C600035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F558071C9B0DAC0035F88B /* SpikeDetectorEditor.cpp in Sources */, + E1F558091C9B0DAC0035F88B /* SpikeDisplayEditor.cpp in Sources */, + E1F5580A1C9B0DAC0035F88B /* SpikeDisplayNode.cpp in Sources */, + E1F558081C9B0DAC0035F88B /* SpikeDisplayCanvas.cpp in Sources */, + E1F558051C9B0DAC0035F88B /* OpenEphysLib.cpp in Sources */, + E1F558061C9B0DAC0035F88B /* SpikeDetector.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F557EC1C9B0C600035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F557F31C9B0CA90035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F557ED1C9B0C600035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F557F41C9B0CA90035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F557EF1C9B0C600035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = BasicSpikeDisplay/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.BasicSpikeDisplay"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F557F01C9B0C600035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = BasicSpikeDisplay/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.BasicSpikeDisplay"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F557E31C9B0C600035F88B /* Build configuration list for PBXProject "BasicSpikeDisplay" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F557EC1C9B0C600035F88B /* Debug */, + E1F557ED1C9B0C600035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F557EE1C9B0C600035F88B /* Build configuration list for PBXNativeTarget "BasicSpikeDisplay" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F557EF1C9B0C600035F88B /* Debug */, + E1F557F01C9B0C600035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F557E01C9B0C600035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/BasicSpikeDisplay/BasicSpikeDisplay/Info.plist b/Builds/MacOSX/Plugins/BasicSpikeDisplay/BasicSpikeDisplay/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/BasicSpikeDisplay/BasicSpikeDisplay/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/CAR/CAR.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/CAR/CAR.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..a0853800fae32ef3ee6d44c5aec3eb88ece63497 --- /dev/null +++ b/Builds/MacOSX/Plugins/CAR/CAR.xcodeproj/project.pbxproj @@ -0,0 +1,220 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E15DCF7A1CA0676B00332C3A /* CAREditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E15DCF781CA0676B00332C3A /* CAREditor.cpp */; }; + E1F558261C9B105C0035F88B /* CAR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558221C9B105C0035F88B /* CAR.cpp */; }; + E1F558281C9B105C0035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558251C9B105C0035F88B /* OpenEphysLib.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E15DCF781CA0676B00332C3A /* CAREditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAREditor.cpp; sourceTree = "<group>"; }; + E15DCF791CA0676B00332C3A /* CAREditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAREditor.h; sourceTree = "<group>"; }; + E1F558141C9B0FCA0035F88B /* CAR.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CAR.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F558171C9B0FCA0035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F5581E1C9B10190035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F5581F1C9B10190035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F558201C9B10190035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F558221C9B105C0035F88B /* CAR.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAR.cpp; sourceTree = "<group>"; }; + E1F558231C9B105C0035F88B /* CAR.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAR.h; sourceTree = "<group>"; }; + E1F558251C9B105C0035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F558111C9B0FCA0035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F5580B1C9B0FCA0035F88B = { + isa = PBXGroup; + children = ( + E1F5581D1C9B10190035F88B /* Config */, + E1F558161C9B0FCA0035F88B /* CAR */, + E1F558151C9B0FCA0035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F558151C9B0FCA0035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F558141C9B0FCA0035F88B /* CAR.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F558161C9B0FCA0035F88B /* CAR */ = { + isa = PBXGroup; + children = ( + E1F558211C9B105C0035F88B /* Source */, + E1F558171C9B0FCA0035F88B /* Info.plist */, + ); + path = CAR; + sourceTree = "<group>"; + }; + E1F5581D1C9B10190035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F5581E1C9B10190035F88B /* Plugin.xcconfig */, + E1F5581F1C9B10190035F88B /* Plugin_Debug.xcconfig */, + E1F558201C9B10190035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F558211C9B105C0035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F558231C9B105C0035F88B /* CAR.h */, + E1F558221C9B105C0035F88B /* CAR.cpp */, + E15DCF791CA0676B00332C3A /* CAREditor.h */, + E15DCF781CA0676B00332C3A /* CAREditor.cpp */, + E1F558251C9B105C0035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/CAR; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F558131C9B0FCA0035F88B /* CAR */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F5581A1C9B0FCA0035F88B /* Build configuration list for PBXNativeTarget "CAR" */; + buildPhases = ( + E1F558101C9B0FCA0035F88B /* Sources */, + E1F558111C9B0FCA0035F88B /* Frameworks */, + E1F558121C9B0FCA0035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CAR; + productName = CAR; + productReference = E1F558141C9B0FCA0035F88B /* CAR.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F5580C1C9B0FCA0035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F558131C9B0FCA0035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F5580F1C9B0FCA0035F88B /* Build configuration list for PBXProject "CAR" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F5580B1C9B0FCA0035F88B; + productRefGroup = E1F558151C9B0FCA0035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F558131C9B0FCA0035F88B /* CAR */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F558121C9B0FCA0035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F558101C9B0FCA0035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F558281C9B105C0035F88B /* OpenEphysLib.cpp in Sources */, + E15DCF7A1CA0676B00332C3A /* CAREditor.cpp in Sources */, + E1F558261C9B105C0035F88B /* CAR.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F558181C9B0FCA0035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F5581F1C9B10190035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F558191C9B0FCA0035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F558201C9B10190035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F5581B1C9B0FCA0035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = CAR/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.CAR"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F5581C1C9B0FCA0035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = CAR/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.CAR"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F5580F1C9B0FCA0035F88B /* Build configuration list for PBXProject "CAR" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F558181C9B0FCA0035F88B /* Debug */, + E1F558191C9B0FCA0035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F5581A1C9B0FCA0035F88B /* Build configuration list for PBXNativeTarget "CAR" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F5581B1C9B0FCA0035F88B /* Debug */, + E1F5581C1C9B0FCA0035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F5580C1C9B0FCA0035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/CAR/CAR/Info.plist b/Builds/MacOSX/Plugins/CAR/CAR/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/CAR/CAR/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/ChannelMappingNode/ChannelMappingNode.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/ChannelMappingNode/ChannelMappingNode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..f80d59a6fe4d7b82490a497c83913bd5f6e2fe8b --- /dev/null +++ b/Builds/MacOSX/Plugins/ChannelMappingNode/ChannelMappingNode.xcodeproj/project.pbxproj @@ -0,0 +1,220 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F558461C9B12730035F88B /* ChannelMappingEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558401C9B12730035F88B /* ChannelMappingEditor.cpp */; }; + E1F558471C9B12730035F88B /* ChannelMappingNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558421C9B12730035F88B /* ChannelMappingNode.cpp */; }; + E1F558491C9B12730035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558451C9B12730035F88B /* OpenEphysLib.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F558321C9B11E80035F88B /* ChannelMappingNode.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChannelMappingNode.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F558351C9B11E80035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F5583C1C9B12240035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F5583D1C9B12240035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F5583E1C9B12240035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F558401C9B12730035F88B /* ChannelMappingEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChannelMappingEditor.cpp; sourceTree = "<group>"; }; + E1F558411C9B12730035F88B /* ChannelMappingEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChannelMappingEditor.h; sourceTree = "<group>"; }; + E1F558421C9B12730035F88B /* ChannelMappingNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChannelMappingNode.cpp; sourceTree = "<group>"; }; + E1F558431C9B12730035F88B /* ChannelMappingNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChannelMappingNode.h; sourceTree = "<group>"; }; + E1F558451C9B12730035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F5582F1C9B11E80035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F558291C9B11E80035F88B = { + isa = PBXGroup; + children = ( + E1F5583B1C9B12240035F88B /* Config */, + E1F558341C9B11E80035F88B /* ChannelMappingNode */, + E1F558331C9B11E80035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F558331C9B11E80035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F558321C9B11E80035F88B /* ChannelMappingNode.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F558341C9B11E80035F88B /* ChannelMappingNode */ = { + isa = PBXGroup; + children = ( + E1F5583F1C9B12730035F88B /* Source */, + E1F558351C9B11E80035F88B /* Info.plist */, + ); + path = ChannelMappingNode; + sourceTree = "<group>"; + }; + E1F5583B1C9B12240035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F5583C1C9B12240035F88B /* Plugin.xcconfig */, + E1F5583D1C9B12240035F88B /* Plugin_Debug.xcconfig */, + E1F5583E1C9B12240035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F5583F1C9B12730035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F558411C9B12730035F88B /* ChannelMappingEditor.h */, + E1F558401C9B12730035F88B /* ChannelMappingEditor.cpp */, + E1F558431C9B12730035F88B /* ChannelMappingNode.h */, + E1F558421C9B12730035F88B /* ChannelMappingNode.cpp */, + E1F558451C9B12730035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/ChannelMappingNode; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F558311C9B11E80035F88B /* ChannelMappingNode */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F558381C9B11E80035F88B /* Build configuration list for PBXNativeTarget "ChannelMappingNode" */; + buildPhases = ( + E1F5582E1C9B11E80035F88B /* Sources */, + E1F5582F1C9B11E80035F88B /* Frameworks */, + E1F558301C9B11E80035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ChannelMappingNode; + productName = ChannelMappingNode; + productReference = E1F558321C9B11E80035F88B /* ChannelMappingNode.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F5582A1C9B11E80035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F558311C9B11E80035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F5582D1C9B11E80035F88B /* Build configuration list for PBXProject "ChannelMappingNode" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F558291C9B11E80035F88B; + productRefGroup = E1F558331C9B11E80035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F558311C9B11E80035F88B /* ChannelMappingNode */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F558301C9B11E80035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F5582E1C9B11E80035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F558471C9B12730035F88B /* ChannelMappingNode.cpp in Sources */, + E1F558461C9B12730035F88B /* ChannelMappingEditor.cpp in Sources */, + E1F558491C9B12730035F88B /* OpenEphysLib.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F558361C9B11E80035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F5583D1C9B12240035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F558371C9B11E80035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F5583E1C9B12240035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F558391C9B11E80035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = ChannelMappingNode/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.ChannelMappingNode"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F5583A1C9B11E80035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = ChannelMappingNode/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.ChannelMappingNode"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F5582D1C9B11E80035F88B /* Build configuration list for PBXProject "ChannelMappingNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F558361C9B11E80035F88B /* Debug */, + E1F558371C9B11E80035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F558381C9B11E80035F88B /* Build configuration list for PBXNativeTarget "ChannelMappingNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F558391C9B11E80035F88B /* Debug */, + E1F5583A1C9B11E80035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F5582A1C9B11E80035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/ChannelMappingNode/ChannelMappingNode/Info.plist b/Builds/MacOSX/Plugins/ChannelMappingNode/ChannelMappingNode/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/ChannelMappingNode/ChannelMappingNode/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/Config/Plugin.xcconfig b/Builds/MacOSX/Plugins/Config/Plugin.xcconfig new file mode 100644 index 0000000000000000000000000000000000000000..1dc595d67d04b9de9759f83e147d22d1a9dffb1a --- /dev/null +++ b/Builds/MacOSX/Plugins/Config/Plugin.xcconfig @@ -0,0 +1,46 @@ +ALWAYS_SEARCH_USER_PATHS = NO +CLANG_CXX_LANGUAGE_STANDARD = c++0x +CLANG_CXX_LIBRARY = libc++ +CLANG_ENABLE_MODULES = NO +CLANG_ENABLE_OBJC_ARC = NO +CLANG_LINK_OBJC_RUNTIME = NO +CLANG_WARN_BOOL_CONVERSION = YES +CLANG_WARN_CONSTANT_CONVERSION = YES +CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR +CLANG_WARN_EMPTY_BODY = YES +CLANG_WARN_ENUM_CONVERSION = YES +CLANG_WARN_INT_CONVERSION = YES +CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR +CLANG_WARN_UNREACHABLE_CODE = YES +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CODE_SIGN_IDENTITY = +COMBINE_HIDPI_IMAGES = YES +CONFIGURATION_BUILD_DIR = $(PROJECT_DIR)/../../build/$(CONFIGURATION)/open-ephys.app/Contents/PlugIns +COPY_PHASE_STRIP = NO +DEBUG_INFORMATION_FORMAT = dwarf +ENABLE_STRICT_OBJC_MSGSEND = YES +GCC_C_LANGUAGE_STANDARD = c99 +GCC_GENERATE_DEBUGGING_SYMBOLS = YES +GCC_INLINES_ARE_PRIVATE_EXTERN = YES +GCC_NO_COMMON_BLOCKS = YES +GCC_OPTIMIZATION_LEVEL = 3 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) OEPLUGIN JUCER_XCODE_MAC_F6D2F4CF=1 JUCE_APP_VERSION=0.3.5 JUCE_APP_VERSION_HEX=0x305 +GCC_VERSION = com.apple.compilers.llvm.clang.1_0 +GCC_WARN_64_TO_32_BIT_CONVERSION = NO +GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR +GCC_WARN_CHECK_SWITCH_STATEMENTS = YES +GCC_WARN_MISSING_PARENTHESES = YES +GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES +GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES +GCC_WARN_UNDECLARED_SELECTOR = YES +GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE +GCC_WARN_UNUSED_FUNCTION = YES +GCC_WARN_UNUSED_VARIABLE = YES +HEADER_SEARCH_PATHS = ../../../../Source/Plugins/Headers $(inherited) +INSTALL_PATH = $(HOME)/Applications/open-ephys.app/Contents/PlugIns +MACOSX_DEPLOYMENT_TARGET = 10.11 +OTHER_LDFLAGS = $(inherited) -undefined dynamic_lookup +SDKROOT = macosx +SKIP_INSTALL = YES +WARNING_CFLAGS = $(inherited) -Wreorder -Wno-inconsistent-missing-override +WRAPPER_EXTENSION = bundle diff --git a/Builds/MacOSX/Plugins/Config/Plugin_Debug.xcconfig b/Builds/MacOSX/Plugins/Config/Plugin_Debug.xcconfig new file mode 100644 index 0000000000000000000000000000000000000000..29c8d2333a77469fe2ceeb0fdaaff23a1c6353be --- /dev/null +++ b/Builds/MacOSX/Plugins/Config/Plugin_Debug.xcconfig @@ -0,0 +1,7 @@ +#include "Plugin.xcconfig" + +ENABLE_TESTABILITY = YES +GCC_DYNAMIC_NO_PIC = NO +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1 _DEBUG=1 +MTL_ENABLE_DEBUG_INFO = YES +ONLY_ACTIVE_ARCH = YES diff --git a/Builds/MacOSX/Plugins/Config/Plugin_Release.xcconfig b/Builds/MacOSX/Plugins/Config/Plugin_Release.xcconfig new file mode 100644 index 0000000000000000000000000000000000000000..5b8ee46c08622cd2525d72beeb169eb74f205669 --- /dev/null +++ b/Builds/MacOSX/Plugins/Config/Plugin_Release.xcconfig @@ -0,0 +1,7 @@ +#include "Plugin.xcconfig" + +DEAD_CODE_STRIPPING = YES +ENABLE_NS_ASSERTIONS = NO +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) NDEBUG=1 _NDEBUG=1 +GCC_SYMBOLS_PRIVATE_EXTERN = YES +MTL_ENABLE_DEBUG_INFO = NO diff --git a/Builds/MacOSX/Plugins/EventBroadcaster/EventBroadcaster.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/EventBroadcaster/EventBroadcaster.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..5dd559ea8e6f96085a66ba4bc97b412bb1794aff --- /dev/null +++ b/Builds/MacOSX/Plugins/EventBroadcaster/EventBroadcaster.xcodeproj/project.pbxproj @@ -0,0 +1,244 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F557DB1C9B06500035F88B /* EventBroadcaster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557D51C9B06500035F88B /* EventBroadcaster.cpp */; }; + E1F557DC1C9B06500035F88B /* EventBroadcasterEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557D71C9B06500035F88B /* EventBroadcasterEditor.cpp */; }; + E1F557DE1C9B06500035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F557DA1C9B06500035F88B /* OpenEphysLib.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1C3F9781C99A20D00719A9F /* EventBroadcaster.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EventBroadcaster.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1C3F97B1C99A20D00719A9F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F557C21C9B020A0035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F557C31C9B020A0035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F557C41C9B020A0035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F557D51C9B06500035F88B /* EventBroadcaster.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventBroadcaster.cpp; sourceTree = "<group>"; }; + E1F557D61C9B06500035F88B /* EventBroadcaster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventBroadcaster.h; sourceTree = "<group>"; }; + E1F557D71C9B06500035F88B /* EventBroadcasterEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventBroadcasterEditor.cpp; sourceTree = "<group>"; }; + E1F557D81C9B06500035F88B /* EventBroadcasterEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventBroadcasterEditor.h; sourceTree = "<group>"; }; + E1F557DA1C9B06500035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1C3F9751C99A20D00719A9F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1C3F96F1C99A20D00719A9F = { + isa = PBXGroup; + children = ( + E1F557C11C9B020A0035F88B /* Config */, + E1C3F97A1C99A20D00719A9F /* EventBroadcaster */, + E1C3F9791C99A20D00719A9F /* Products */, + ); + sourceTree = "<group>"; + }; + E1C3F9791C99A20D00719A9F /* Products */ = { + isa = PBXGroup; + children = ( + E1C3F9781C99A20D00719A9F /* EventBroadcaster.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1C3F97A1C99A20D00719A9F /* EventBroadcaster */ = { + isa = PBXGroup; + children = ( + E1F557D41C9B06500035F88B /* Source */, + E1C3F97B1C99A20D00719A9F /* Info.plist */, + ); + path = EventBroadcaster; + sourceTree = "<group>"; + }; + E1F557C11C9B020A0035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F557C21C9B020A0035F88B /* Plugin.xcconfig */, + E1F557C31C9B020A0035F88B /* Plugin_Debug.xcconfig */, + E1F557C41C9B020A0035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F557D41C9B06500035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F557D61C9B06500035F88B /* EventBroadcaster.h */, + E1F557D51C9B06500035F88B /* EventBroadcaster.cpp */, + E1F557D81C9B06500035F88B /* EventBroadcasterEditor.h */, + E1F557D71C9B06500035F88B /* EventBroadcasterEditor.cpp */, + E1F557DA1C9B06500035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/EventBroadcaster; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1C3F9771C99A20D00719A9F /* EventBroadcaster */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1C3F97E1C99A20D00719A9F /* Build configuration list for PBXNativeTarget "EventBroadcaster" */; + buildPhases = ( + E1C3F9741C99A20D00719A9F /* Sources */, + E1C3F9751C99A20D00719A9F /* Frameworks */, + E1C3F9761C99A20D00719A9F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = EventBroadcaster; + productName = EventBroadcaster; + productReference = E1C3F9781C99A20D00719A9F /* EventBroadcaster.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1C3F9701C99A20D00719A9F /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1C3F9771C99A20D00719A9F = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1C3F9731C99A20D00719A9F /* Build configuration list for PBXProject "EventBroadcaster" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1C3F96F1C99A20D00719A9F; + productRefGroup = E1C3F9791C99A20D00719A9F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1C3F9771C99A20D00719A9F /* EventBroadcaster */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1C3F9761C99A20D00719A9F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1C3F9741C99A20D00719A9F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F557DC1C9B06500035F88B /* EventBroadcasterEditor.cpp in Sources */, + E1F557DB1C9B06500035F88B /* EventBroadcaster.cpp in Sources */, + E1F557DE1C9B06500035F88B /* OpenEphysLib.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1C3F97C1C99A20D00719A9F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F557C31C9B020A0035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1C3F97D1C99A20D00719A9F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F557C41C9B020A0035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1C3F97F1C99A20D00719A9F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + ZEROMQ, + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /opt/local/include, + ); + INFOPLIST_FILE = EventBroadcaster/Info.plist; + OTHER_LDFLAGS = ( + "$(inherited)", + /opt/local/lib/libzmq.a, + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.EventBroadcaster"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1C3F9801C99A20D00719A9F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + ZEROMQ, + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /opt/local/include, + ); + INFOPLIST_FILE = EventBroadcaster/Info.plist; + OTHER_LDFLAGS = ( + "$(inherited)", + /opt/local/lib/libzmq.a, + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.EventBroadcaster"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1C3F9731C99A20D00719A9F /* Build configuration list for PBXProject "EventBroadcaster" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1C3F97C1C99A20D00719A9F /* Debug */, + E1C3F97D1C99A20D00719A9F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1C3F97E1C99A20D00719A9F /* Build configuration list for PBXNativeTarget "EventBroadcaster" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1C3F97F1C99A20D00719A9F /* Debug */, + E1C3F9801C99A20D00719A9F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1C3F9701C99A20D00719A9F /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/EventBroadcaster/EventBroadcaster/Info.plist b/Builds/MacOSX/Plugins/EventBroadcaster/EventBroadcaster/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/EventBroadcaster/EventBroadcaster/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/FilterNode/FilterNode.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/FilterNode/FilterNode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..7dbe5f0f1743c4bc85355f16e5e322ee199d20f7 --- /dev/null +++ b/Builds/MacOSX/Plugins/FilterNode/FilterNode.xcodeproj/project.pbxproj @@ -0,0 +1,338 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F558B21C9B20070035F88B /* Bessel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558841C9B20070035F88B /* Bessel.cpp */; }; + E1F558B31C9B20070035F88B /* Biquad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558861C9B20070035F88B /* Biquad.cpp */; }; + E1F558B41C9B20070035F88B /* Butterworth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558881C9B20070035F88B /* Butterworth.cpp */; }; + E1F558B51C9B20070035F88B /* Cascade.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5588A1C9B20070035F88B /* Cascade.cpp */; }; + E1F558B61C9B20070035F88B /* ChebyshevI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5588C1C9B20070035F88B /* ChebyshevI.cpp */; }; + E1F558B71C9B20070035F88B /* ChebyshevII.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5588E1C9B20070035F88B /* ChebyshevII.cpp */; }; + E1F558B81C9B20070035F88B /* Custom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558911C9B20070035F88B /* Custom.cpp */; }; + E1F558B91C9B20070035F88B /* Design.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558931C9B20070035F88B /* Design.cpp */; }; + E1F558BB1C9B20070035F88B /* Elliptic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558971C9B20070035F88B /* Elliptic.cpp */; }; + E1F558BC1C9B20070035F88B /* Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558991C9B20070035F88B /* Filter.cpp */; }; + E1F558BD1C9B20070035F88B /* Legendre.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5589C1C9B20070035F88B /* Legendre.cpp */; }; + E1F558BE1C9B20070035F88B /* Param.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5589F1C9B20070035F88B /* Param.cpp */; }; + E1F558BF1C9B20070035F88B /* PoleFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558A11C9B20070035F88B /* PoleFilter.cpp */; }; + E1F558C01C9B20070035F88B /* RBJ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558A31C9B20070035F88B /* RBJ.cpp */; }; + E1F558C11C9B20070035F88B /* RootFinder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558A51C9B20070035F88B /* RootFinder.cpp */; }; + E1F558C21C9B20070035F88B /* State.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558A81C9B20070035F88B /* State.cpp */; }; + E1F558C31C9B20070035F88B /* FilterEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558AC1C9B20070035F88B /* FilterEditor.cpp */; }; + E1F558C41C9B20070035F88B /* FilterNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558AE1C9B20070035F88B /* FilterNode.cpp */; }; + E1F558C61C9B20070035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558B11C9B20070035F88B /* OpenEphysLib.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F558751C9B1F920035F88B /* FilterNode.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FilterNode.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F558781C9B1F920035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F5587F1C9B1FDC0035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F558801C9B1FDC0035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F558811C9B1FDC0035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F558841C9B20070035F88B /* Bessel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Bessel.cpp; sourceTree = "<group>"; }; + E1F558851C9B20070035F88B /* Bessel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bessel.h; sourceTree = "<group>"; }; + E1F558861C9B20070035F88B /* Biquad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Biquad.cpp; sourceTree = "<group>"; }; + E1F558871C9B20070035F88B /* Biquad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Biquad.h; sourceTree = "<group>"; }; + E1F558881C9B20070035F88B /* Butterworth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Butterworth.cpp; sourceTree = "<group>"; }; + E1F558891C9B20070035F88B /* Butterworth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Butterworth.h; sourceTree = "<group>"; }; + E1F5588A1C9B20070035F88B /* Cascade.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cascade.cpp; sourceTree = "<group>"; }; + E1F5588B1C9B20070035F88B /* Cascade.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cascade.h; sourceTree = "<group>"; }; + E1F5588C1C9B20070035F88B /* ChebyshevI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChebyshevI.cpp; sourceTree = "<group>"; }; + E1F5588D1C9B20070035F88B /* ChebyshevI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChebyshevI.h; sourceTree = "<group>"; }; + E1F5588E1C9B20070035F88B /* ChebyshevII.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChebyshevII.cpp; sourceTree = "<group>"; }; + E1F5588F1C9B20070035F88B /* ChebyshevII.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChebyshevII.h; sourceTree = "<group>"; }; + E1F558901C9B20070035F88B /* Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Common.h; sourceTree = "<group>"; }; + E1F558911C9B20070035F88B /* Custom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Custom.cpp; sourceTree = "<group>"; }; + E1F558921C9B20070035F88B /* Custom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Custom.h; sourceTree = "<group>"; }; + E1F558931C9B20070035F88B /* Design.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Design.cpp; sourceTree = "<group>"; }; + E1F558941C9B20070035F88B /* Design.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Design.h; sourceTree = "<group>"; }; + E1F558961C9B20070035F88B /* Dsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dsp.h; sourceTree = "<group>"; }; + E1F558971C9B20070035F88B /* Elliptic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Elliptic.cpp; sourceTree = "<group>"; }; + E1F558981C9B20070035F88B /* Elliptic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Elliptic.h; sourceTree = "<group>"; }; + E1F558991C9B20070035F88B /* Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Filter.cpp; sourceTree = "<group>"; }; + E1F5589A1C9B20070035F88B /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = "<group>"; }; + E1F5589B1C9B20070035F88B /* Layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Layout.h; sourceTree = "<group>"; }; + E1F5589C1C9B20070035F88B /* Legendre.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Legendre.cpp; sourceTree = "<group>"; }; + E1F5589D1C9B20070035F88B /* Legendre.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Legendre.h; sourceTree = "<group>"; }; + E1F5589E1C9B20070035F88B /* MathSupplement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathSupplement.h; sourceTree = "<group>"; }; + E1F5589F1C9B20070035F88B /* Param.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Param.cpp; sourceTree = "<group>"; }; + E1F558A01C9B20070035F88B /* Params.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Params.h; sourceTree = "<group>"; }; + E1F558A11C9B20070035F88B /* PoleFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PoleFilter.cpp; sourceTree = "<group>"; }; + E1F558A21C9B20070035F88B /* PoleFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PoleFilter.h; sourceTree = "<group>"; }; + E1F558A31C9B20070035F88B /* RBJ.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RBJ.cpp; sourceTree = "<group>"; }; + E1F558A41C9B20070035F88B /* RBJ.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBJ.h; sourceTree = "<group>"; }; + E1F558A51C9B20070035F88B /* RootFinder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RootFinder.cpp; sourceTree = "<group>"; }; + E1F558A61C9B20070035F88B /* RootFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootFinder.h; sourceTree = "<group>"; }; + E1F558A71C9B20070035F88B /* SmoothedFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmoothedFilter.h; sourceTree = "<group>"; }; + E1F558A81C9B20070035F88B /* State.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = State.cpp; sourceTree = "<group>"; }; + E1F558A91C9B20070035F88B /* State.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = State.h; sourceTree = "<group>"; }; + E1F558AA1C9B20070035F88B /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Types.h; sourceTree = "<group>"; }; + E1F558AB1C9B20070035F88B /* Utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utilities.h; sourceTree = "<group>"; }; + E1F558AC1C9B20070035F88B /* FilterEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilterEditor.cpp; sourceTree = "<group>"; }; + E1F558AD1C9B20070035F88B /* FilterEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilterEditor.h; sourceTree = "<group>"; }; + E1F558AE1C9B20070035F88B /* FilterNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilterNode.cpp; sourceTree = "<group>"; }; + E1F558AF1C9B20070035F88B /* FilterNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilterNode.h; sourceTree = "<group>"; }; + E1F558B11C9B20070035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F558721C9B1F920035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F5586C1C9B1F920035F88B = { + isa = PBXGroup; + children = ( + E1F5587E1C9B1FDC0035F88B /* Config */, + E1F558771C9B1F920035F88B /* FilterNode */, + E1F558761C9B1F920035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F558761C9B1F920035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F558751C9B1F920035F88B /* FilterNode.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F558771C9B1F920035F88B /* FilterNode */ = { + isa = PBXGroup; + children = ( + E1F558821C9B20070035F88B /* Source */, + E1F558781C9B1F920035F88B /* Info.plist */, + ); + path = FilterNode; + sourceTree = "<group>"; + }; + E1F5587E1C9B1FDC0035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F5587F1C9B1FDC0035F88B /* Plugin.xcconfig */, + E1F558801C9B1FDC0035F88B /* Plugin_Debug.xcconfig */, + E1F558811C9B1FDC0035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F558821C9B20070035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F558831C9B20070035F88B /* Dsp */, + E1F558AD1C9B20070035F88B /* FilterEditor.h */, + E1F558AC1C9B20070035F88B /* FilterEditor.cpp */, + E1F558AF1C9B20070035F88B /* FilterNode.h */, + E1F558AE1C9B20070035F88B /* FilterNode.cpp */, + E1F558B11C9B20070035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/FilterNode; + sourceTree = "<group>"; + }; + E1F558831C9B20070035F88B /* Dsp */ = { + isa = PBXGroup; + children = ( + E1F558851C9B20070035F88B /* Bessel.h */, + E1F558841C9B20070035F88B /* Bessel.cpp */, + E1F558871C9B20070035F88B /* Biquad.h */, + E1F558861C9B20070035F88B /* Biquad.cpp */, + E1F558891C9B20070035F88B /* Butterworth.h */, + E1F558881C9B20070035F88B /* Butterworth.cpp */, + E1F5588B1C9B20070035F88B /* Cascade.h */, + E1F5588A1C9B20070035F88B /* Cascade.cpp */, + E1F5588D1C9B20070035F88B /* ChebyshevI.h */, + E1F5588C1C9B20070035F88B /* ChebyshevI.cpp */, + E1F5588F1C9B20070035F88B /* ChebyshevII.h */, + E1F5588E1C9B20070035F88B /* ChebyshevII.cpp */, + E1F558901C9B20070035F88B /* Common.h */, + E1F558921C9B20070035F88B /* Custom.h */, + E1F558911C9B20070035F88B /* Custom.cpp */, + E1F558941C9B20070035F88B /* Design.h */, + E1F558931C9B20070035F88B /* Design.cpp */, + E1F558961C9B20070035F88B /* Dsp.h */, + E1F558981C9B20070035F88B /* Elliptic.h */, + E1F558971C9B20070035F88B /* Elliptic.cpp */, + E1F5589A1C9B20070035F88B /* Filter.h */, + E1F558991C9B20070035F88B /* Filter.cpp */, + E1F5589B1C9B20070035F88B /* Layout.h */, + E1F5589D1C9B20070035F88B /* Legendre.h */, + E1F5589C1C9B20070035F88B /* Legendre.cpp */, + E1F5589E1C9B20070035F88B /* MathSupplement.h */, + E1F558A01C9B20070035F88B /* Params.h */, + E1F5589F1C9B20070035F88B /* Param.cpp */, + E1F558A21C9B20070035F88B /* PoleFilter.h */, + E1F558A11C9B20070035F88B /* PoleFilter.cpp */, + E1F558A41C9B20070035F88B /* RBJ.h */, + E1F558A31C9B20070035F88B /* RBJ.cpp */, + E1F558A61C9B20070035F88B /* RootFinder.h */, + E1F558A51C9B20070035F88B /* RootFinder.cpp */, + E1F558A71C9B20070035F88B /* SmoothedFilter.h */, + E1F558A91C9B20070035F88B /* State.h */, + E1F558A81C9B20070035F88B /* State.cpp */, + E1F558AA1C9B20070035F88B /* Types.h */, + E1F558AB1C9B20070035F88B /* Utilities.h */, + ); + path = Dsp; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F558741C9B1F920035F88B /* FilterNode */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F5587B1C9B1F920035F88B /* Build configuration list for PBXNativeTarget "FilterNode" */; + buildPhases = ( + E1F558711C9B1F920035F88B /* Sources */, + E1F558721C9B1F920035F88B /* Frameworks */, + E1F558731C9B1F920035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FilterNode; + productName = FilterNode; + productReference = E1F558751C9B1F920035F88B /* FilterNode.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F5586D1C9B1F920035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F558741C9B1F920035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F558701C9B1F920035F88B /* Build configuration list for PBXProject "FilterNode" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F5586C1C9B1F920035F88B; + productRefGroup = E1F558761C9B1F920035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F558741C9B1F920035F88B /* FilterNode */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F558731C9B1F920035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F558711C9B1F920035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F558B51C9B20070035F88B /* Cascade.cpp in Sources */, + E1F558BE1C9B20070035F88B /* Param.cpp in Sources */, + E1F558C41C9B20070035F88B /* FilterNode.cpp in Sources */, + E1F558BB1C9B20070035F88B /* Elliptic.cpp in Sources */, + E1F558B41C9B20070035F88B /* Butterworth.cpp in Sources */, + E1F558BC1C9B20070035F88B /* Filter.cpp in Sources */, + E1F558B61C9B20070035F88B /* ChebyshevI.cpp in Sources */, + E1F558C01C9B20070035F88B /* RBJ.cpp in Sources */, + E1F558B81C9B20070035F88B /* Custom.cpp in Sources */, + E1F558B71C9B20070035F88B /* ChebyshevII.cpp in Sources */, + E1F558C21C9B20070035F88B /* State.cpp in Sources */, + E1F558C31C9B20070035F88B /* FilterEditor.cpp in Sources */, + E1F558BF1C9B20070035F88B /* PoleFilter.cpp in Sources */, + E1F558C11C9B20070035F88B /* RootFinder.cpp in Sources */, + E1F558B91C9B20070035F88B /* Design.cpp in Sources */, + E1F558B21C9B20070035F88B /* Bessel.cpp in Sources */, + E1F558C61C9B20070035F88B /* OpenEphysLib.cpp in Sources */, + E1F558B31C9B20070035F88B /* Biquad.cpp in Sources */, + E1F558BD1C9B20070035F88B /* Legendre.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F558791C9B1F920035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F558801C9B1FDC0035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F5587A1C9B1F920035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F558811C9B1FDC0035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F5587C1C9B1F920035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = FilterNode/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.FilterNode"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F5587D1C9B1F920035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = FilterNode/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.FilterNode"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F558701C9B1F920035F88B /* Build configuration list for PBXProject "FilterNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F558791C9B1F920035F88B /* Debug */, + E1F5587A1C9B1F920035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F5587B1C9B1F920035F88B /* Build configuration list for PBXNativeTarget "FilterNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F5587C1C9B1F920035F88B /* Debug */, + E1F5587D1C9B1F920035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F5586D1C9B1F920035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/FilterNode/FilterNode/Info.plist b/Builds/MacOSX/Plugins/FilterNode/FilterNode/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/FilterNode/FilterNode/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/KWIKFormat/KWIKFormat.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/KWIKFormat/KWIKFormat.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..483460fac43447a68c689bf83f724957c315b50a --- /dev/null +++ b/Builds/MacOSX/Plugins/KWIKFormat/KWIKFormat.xcodeproj/project.pbxproj @@ -0,0 +1,260 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F558E81C9B23AB0035F88B /* KwikFileSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558DF1C9B23AB0035F88B /* KwikFileSource.cpp */; }; + E1F558EA1C9B23AB0035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558E21C9B23AB0035F88B /* OpenEphysLib.cpp */; }; + E1F558EB1C9B23AB0035F88B /* HDF5FileFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558E41C9B23AB0035F88B /* HDF5FileFormat.cpp */; }; + E1F558EC1C9B23AB0035F88B /* HDF5Recording.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F558E61C9B23AB0035F88B /* HDF5Recording.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F558D01C9B23370035F88B /* KWIKFormat.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KWIKFormat.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F558D31C9B23370035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F558DA1C9B23830035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F558DB1C9B23830035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F558DC1C9B23830035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F558DF1C9B23AB0035F88B /* KwikFileSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KwikFileSource.cpp; sourceTree = "<group>"; }; + E1F558E01C9B23AB0035F88B /* KwikFileSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KwikFileSource.h; sourceTree = "<group>"; }; + E1F558E21C9B23AB0035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; + E1F558E41C9B23AB0035F88B /* HDF5FileFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDF5FileFormat.cpp; sourceTree = "<group>"; }; + E1F558E51C9B23AB0035F88B /* HDF5FileFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDF5FileFormat.h; sourceTree = "<group>"; }; + E1F558E61C9B23AB0035F88B /* HDF5Recording.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDF5Recording.cpp; sourceTree = "<group>"; }; + E1F558E71C9B23AB0035F88B /* HDF5Recording.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDF5Recording.h; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F558CD1C9B23370035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F558C71C9B23370035F88B = { + isa = PBXGroup; + children = ( + E1F558D91C9B23830035F88B /* Config */, + E1F558D21C9B23370035F88B /* KWIKFormat */, + E1F558D11C9B23370035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F558D11C9B23370035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F558D01C9B23370035F88B /* KWIKFormat.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F558D21C9B23370035F88B /* KWIKFormat */ = { + isa = PBXGroup; + children = ( + E1F558DD1C9B23AB0035F88B /* Source */, + E1F558D31C9B23370035F88B /* Info.plist */, + ); + path = KWIKFormat; + sourceTree = "<group>"; + }; + E1F558D91C9B23830035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F558DA1C9B23830035F88B /* Plugin.xcconfig */, + E1F558DB1C9B23830035F88B /* Plugin_Debug.xcconfig */, + E1F558DC1C9B23830035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F558DD1C9B23AB0035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F558DE1C9B23AB0035F88B /* FileSource */, + E1F558E31C9B23AB0035F88B /* RecordEngine */, + E1F558E21C9B23AB0035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/KWIKFormat; + sourceTree = "<group>"; + }; + E1F558DE1C9B23AB0035F88B /* FileSource */ = { + isa = PBXGroup; + children = ( + E1F558E01C9B23AB0035F88B /* KwikFileSource.h */, + E1F558DF1C9B23AB0035F88B /* KwikFileSource.cpp */, + ); + path = FileSource; + sourceTree = "<group>"; + }; + E1F558E31C9B23AB0035F88B /* RecordEngine */ = { + isa = PBXGroup; + children = ( + E1F558E51C9B23AB0035F88B /* HDF5FileFormat.h */, + E1F558E41C9B23AB0035F88B /* HDF5FileFormat.cpp */, + E1F558E71C9B23AB0035F88B /* HDF5Recording.h */, + E1F558E61C9B23AB0035F88B /* HDF5Recording.cpp */, + ); + path = RecordEngine; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F558CF1C9B23370035F88B /* KWIKFormat */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F558D61C9B23370035F88B /* Build configuration list for PBXNativeTarget "KWIKFormat" */; + buildPhases = ( + E1F558CC1C9B23370035F88B /* Sources */, + E1F558CD1C9B23370035F88B /* Frameworks */, + E1F558CE1C9B23370035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = KWIKFormat; + productName = KWIKFormat; + productReference = E1F558D01C9B23370035F88B /* KWIKFormat.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F558C81C9B23370035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F558CF1C9B23370035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F558CB1C9B23370035F88B /* Build configuration list for PBXProject "KWIKFormat" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F558C71C9B23370035F88B; + productRefGroup = E1F558D11C9B23370035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F558CF1C9B23370035F88B /* KWIKFormat */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F558CE1C9B23370035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F558CC1C9B23370035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F558EA1C9B23AB0035F88B /* OpenEphysLib.cpp in Sources */, + E1F558EC1C9B23AB0035F88B /* HDF5Recording.cpp in Sources */, + E1F558E81C9B23AB0035F88B /* KwikFileSource.cpp in Sources */, + E1F558EB1C9B23AB0035F88B /* HDF5FileFormat.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F558D41C9B23370035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F558DB1C9B23830035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F558D51C9B23370035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F558DC1C9B23830035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F558D71C9B23370035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /opt/local/include, + ); + INFOPLIST_FILE = KWIKFormat/Info.plist; + OTHER_LDFLAGS = ( + "$(inherited)", + /opt/local/lib/libhdf5.a, + /opt/local/lib/libhdf5_cpp.a, + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.KWIKFormat"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F558D81C9B23370035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /opt/local/include, + ); + INFOPLIST_FILE = KWIKFormat/Info.plist; + OTHER_LDFLAGS = ( + "$(inherited)", + /opt/local/lib/libhdf5.a, + /opt/local/lib/libhdf5_cpp.a, + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.KWIKFormat"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F558CB1C9B23370035F88B /* Build configuration list for PBXProject "KWIKFormat" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F558D41C9B23370035F88B /* Debug */, + E1F558D51C9B23370035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F558D61C9B23370035F88B /* Build configuration list for PBXNativeTarget "KWIKFormat" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F558D71C9B23370035F88B /* Debug */, + E1F558D81C9B23370035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F558C81C9B23370035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/KWIKFormat/KWIKFormat/Info.plist b/Builds/MacOSX/Plugins/KWIKFormat/KWIKFormat/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/KWIKFormat/KWIKFormat/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/LfpDisplayNode/LfpDisplayNode.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/LfpDisplayNode/LfpDisplayNode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..e0ff3357569a6680ba87a4bd267de9e132902517 --- /dev/null +++ b/Builds/MacOSX/Plugins/LfpDisplayNode/LfpDisplayNode.xcodeproj/project.pbxproj @@ -0,0 +1,226 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F5590C1C9B28660035F88B /* LfpDisplayCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559041C9B28660035F88B /* LfpDisplayCanvas.cpp */; }; + E1F5590D1C9B28660035F88B /* LfpDisplayEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559061C9B28660035F88B /* LfpDisplayEditor.cpp */; }; + E1F5590E1C9B28660035F88B /* LfpDisplayNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559081C9B28660035F88B /* LfpDisplayNode.cpp */; }; + E1F559101C9B28660035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5590B1C9B28660035F88B /* OpenEphysLib.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F558F61C9B28060035F88B /* LfpDisplayNode.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LfpDisplayNode.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F558F91C9B28060035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F559001C9B28400035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F559011C9B28400035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F559021C9B28400035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F559041C9B28660035F88B /* LfpDisplayCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LfpDisplayCanvas.cpp; sourceTree = "<group>"; }; + E1F559051C9B28660035F88B /* LfpDisplayCanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LfpDisplayCanvas.h; sourceTree = "<group>"; }; + E1F559061C9B28660035F88B /* LfpDisplayEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LfpDisplayEditor.cpp; sourceTree = "<group>"; }; + E1F559071C9B28660035F88B /* LfpDisplayEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LfpDisplayEditor.h; sourceTree = "<group>"; }; + E1F559081C9B28660035F88B /* LfpDisplayNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LfpDisplayNode.cpp; sourceTree = "<group>"; }; + E1F559091C9B28660035F88B /* LfpDisplayNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LfpDisplayNode.h; sourceTree = "<group>"; }; + E1F5590B1C9B28660035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F558F31C9B28060035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F558ED1C9B28060035F88B = { + isa = PBXGroup; + children = ( + E1F558FF1C9B28400035F88B /* Config */, + E1F558F81C9B28060035F88B /* LfpDisplayNode */, + E1F558F71C9B28060035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F558F71C9B28060035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F558F61C9B28060035F88B /* LfpDisplayNode.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F558F81C9B28060035F88B /* LfpDisplayNode */ = { + isa = PBXGroup; + children = ( + E1F559031C9B28660035F88B /* Source */, + E1F558F91C9B28060035F88B /* Info.plist */, + ); + path = LfpDisplayNode; + sourceTree = "<group>"; + }; + E1F558FF1C9B28400035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F559001C9B28400035F88B /* Plugin.xcconfig */, + E1F559011C9B28400035F88B /* Plugin_Debug.xcconfig */, + E1F559021C9B28400035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F559031C9B28660035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F559051C9B28660035F88B /* LfpDisplayCanvas.h */, + E1F559041C9B28660035F88B /* LfpDisplayCanvas.cpp */, + E1F559071C9B28660035F88B /* LfpDisplayEditor.h */, + E1F559061C9B28660035F88B /* LfpDisplayEditor.cpp */, + E1F559091C9B28660035F88B /* LfpDisplayNode.h */, + E1F559081C9B28660035F88B /* LfpDisplayNode.cpp */, + E1F5590B1C9B28660035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/LfpDisplayNode; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F558F51C9B28060035F88B /* LfpDisplayNode */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F558FC1C9B28060035F88B /* Build configuration list for PBXNativeTarget "LfpDisplayNode" */; + buildPhases = ( + E1F558F21C9B28060035F88B /* Sources */, + E1F558F31C9B28060035F88B /* Frameworks */, + E1F558F41C9B28060035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LfpDisplayNode; + productName = LfpDisplayNode; + productReference = E1F558F61C9B28060035F88B /* LfpDisplayNode.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F558EE1C9B28060035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F558F51C9B28060035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F558F11C9B28060035F88B /* Build configuration list for PBXProject "LfpDisplayNode" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F558ED1C9B28060035F88B; + productRefGroup = E1F558F71C9B28060035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F558F51C9B28060035F88B /* LfpDisplayNode */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F558F41C9B28060035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F558F21C9B28060035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F5590D1C9B28660035F88B /* LfpDisplayEditor.cpp in Sources */, + E1F559101C9B28660035F88B /* OpenEphysLib.cpp in Sources */, + E1F5590C1C9B28660035F88B /* LfpDisplayCanvas.cpp in Sources */, + E1F5590E1C9B28660035F88B /* LfpDisplayNode.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F558FA1C9B28060035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559011C9B28400035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F558FB1C9B28060035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559021C9B28400035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F558FD1C9B28060035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = LfpDisplayNode/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.LfpDisplayNode"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F558FE1C9B28060035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = LfpDisplayNode/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.LfpDisplayNode"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F558F11C9B28060035F88B /* Build configuration list for PBXProject "LfpDisplayNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F558FA1C9B28060035F88B /* Debug */, + E1F558FB1C9B28060035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F558FC1C9B28060035F88B /* Build configuration list for PBXNativeTarget "LfpDisplayNode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F558FD1C9B28060035F88B /* Debug */, + E1F558FE1C9B28060035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F558EE1C9B28060035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/LfpDisplayNode/LfpDisplayNode/Info.plist b/Builds/MacOSX/Plugins/LfpDisplayNode/LfpDisplayNode/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/LfpDisplayNode/LfpDisplayNode/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/NetworkEvents/NetworkEvents.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/NetworkEvents/NetworkEvents.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..87053731c1014f582a04c5320642c3eefa694943 --- /dev/null +++ b/Builds/MacOSX/Plugins/NetworkEvents/NetworkEvents.xcodeproj/project.pbxproj @@ -0,0 +1,244 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F5592F1C9B2A340035F88B /* NetworkEvents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559291C9B2A340035F88B /* NetworkEvents.cpp */; }; + E1F559301C9B2A340035F88B /* NetworkEventsEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5592B1C9B2A340035F88B /* NetworkEventsEditor.cpp */; }; + E1F559311C9B2A340035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5592D1C9B2A340035F88B /* OpenEphysLib.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F5591A1C9B29D20035F88B /* NetworkEvents.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NetworkEvents.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F5591D1C9B29D20035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F559241C9B2A0B0035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F559251C9B2A0B0035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F559261C9B2A0B0035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F559291C9B2A340035F88B /* NetworkEvents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkEvents.cpp; sourceTree = "<group>"; }; + E1F5592A1C9B2A340035F88B /* NetworkEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkEvents.h; sourceTree = "<group>"; }; + E1F5592B1C9B2A340035F88B /* NetworkEventsEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkEventsEditor.cpp; sourceTree = "<group>"; }; + E1F5592C1C9B2A340035F88B /* NetworkEventsEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkEventsEditor.h; sourceTree = "<group>"; }; + E1F5592D1C9B2A340035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F559171C9B29D20035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F559111C9B29D20035F88B = { + isa = PBXGroup; + children = ( + E1F559231C9B2A0B0035F88B /* Config */, + E1F5591C1C9B29D20035F88B /* NetworkEvents */, + E1F5591B1C9B29D20035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F5591B1C9B29D20035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F5591A1C9B29D20035F88B /* NetworkEvents.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F5591C1C9B29D20035F88B /* NetworkEvents */ = { + isa = PBXGroup; + children = ( + E1F559271C9B2A340035F88B /* Source */, + E1F5591D1C9B29D20035F88B /* Info.plist */, + ); + path = NetworkEvents; + sourceTree = "<group>"; + }; + E1F559231C9B2A0B0035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F559241C9B2A0B0035F88B /* Plugin.xcconfig */, + E1F559251C9B2A0B0035F88B /* Plugin_Debug.xcconfig */, + E1F559261C9B2A0B0035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F559271C9B2A340035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F5592A1C9B2A340035F88B /* NetworkEvents.h */, + E1F559291C9B2A340035F88B /* NetworkEvents.cpp */, + E1F5592C1C9B2A340035F88B /* NetworkEventsEditor.h */, + E1F5592B1C9B2A340035F88B /* NetworkEventsEditor.cpp */, + E1F5592D1C9B2A340035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/NetworkEvents; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F559191C9B29D20035F88B /* NetworkEvents */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F559201C9B29D20035F88B /* Build configuration list for PBXNativeTarget "NetworkEvents" */; + buildPhases = ( + E1F559161C9B29D20035F88B /* Sources */, + E1F559171C9B29D20035F88B /* Frameworks */, + E1F559181C9B29D20035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NetworkEvents; + productName = NetworkEvents; + productReference = E1F5591A1C9B29D20035F88B /* NetworkEvents.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F559121C9B29D20035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F559191C9B29D20035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F559151C9B29D20035F88B /* Build configuration list for PBXProject "NetworkEvents" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F559111C9B29D20035F88B; + productRefGroup = E1F5591B1C9B29D20035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F559191C9B29D20035F88B /* NetworkEvents */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F559181C9B29D20035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F559161C9B29D20035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F559301C9B2A340035F88B /* NetworkEventsEditor.cpp in Sources */, + E1F5592F1C9B2A340035F88B /* NetworkEvents.cpp in Sources */, + E1F559311C9B2A340035F88B /* OpenEphysLib.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F5591E1C9B29D20035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559251C9B2A0B0035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F5591F1C9B29D20035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559261C9B2A0B0035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F559211C9B29D20035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + ZEROMQ, + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /opt/local/include, + ); + INFOPLIST_FILE = NetworkEvents/Info.plist; + OTHER_LDFLAGS = ( + "$(inherited)", + /opt/local/lib/libzmq.a, + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.NetworkEvents"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F559221C9B29D20035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + ZEROMQ, + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /opt/local/include, + ); + INFOPLIST_FILE = NetworkEvents/Info.plist; + OTHER_LDFLAGS = ( + "$(inherited)", + /opt/local/lib/libzmq.a, + ); + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.NetworkEvents"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F559151C9B29D20035F88B /* Build configuration list for PBXProject "NetworkEvents" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F5591E1C9B29D20035F88B /* Debug */, + E1F5591F1C9B29D20035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F559201C9B29D20035F88B /* Build configuration list for PBXNativeTarget "NetworkEvents" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559211C9B29D20035F88B /* Debug */, + E1F559221C9B29D20035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F559121C9B29D20035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/NetworkEvents/NetworkEvents/Info.plist b/Builds/MacOSX/Plugins/NetworkEvents/NetworkEvents/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/NetworkEvents/NetworkEvents/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/PhaseDetector/PhaseDetector.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/PhaseDetector/PhaseDetector.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..e7711e18345558bacad93b2e5d49054994c1d006 --- /dev/null +++ b/Builds/MacOSX/Plugins/PhaseDetector/PhaseDetector.xcodeproj/project.pbxproj @@ -0,0 +1,220 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F559501C9B3A6F0035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5594A1C9B3A6F0035F88B /* OpenEphysLib.cpp */; }; + E1F559511C9B3A6F0035F88B /* PhaseDetector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5594B1C9B3A6F0035F88B /* PhaseDetector.cpp */; }; + E1F559521C9B3A6F0035F88B /* PhaseDetectorEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5594D1C9B3A6F0035F88B /* PhaseDetectorEditor.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F5593B1C9B3A100035F88B /* PhaseDetector.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PhaseDetector.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F5593E1C9B3A100035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F559451C9B3A450035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F559461C9B3A450035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F559471C9B3A450035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F5594A1C9B3A6F0035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; + E1F5594B1C9B3A6F0035F88B /* PhaseDetector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PhaseDetector.cpp; sourceTree = "<group>"; }; + E1F5594C1C9B3A6F0035F88B /* PhaseDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhaseDetector.h; sourceTree = "<group>"; }; + E1F5594D1C9B3A6F0035F88B /* PhaseDetectorEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PhaseDetectorEditor.cpp; sourceTree = "<group>"; }; + E1F5594E1C9B3A6F0035F88B /* PhaseDetectorEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhaseDetectorEditor.h; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F559381C9B3A100035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F559321C9B3A100035F88B = { + isa = PBXGroup; + children = ( + E1F559441C9B3A450035F88B /* Config */, + E1F5593D1C9B3A100035F88B /* PhaseDetector */, + E1F5593C1C9B3A100035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F5593C1C9B3A100035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F5593B1C9B3A100035F88B /* PhaseDetector.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F5593D1C9B3A100035F88B /* PhaseDetector */ = { + isa = PBXGroup; + children = ( + E1F559481C9B3A6F0035F88B /* Source */, + E1F5593E1C9B3A100035F88B /* Info.plist */, + ); + path = PhaseDetector; + sourceTree = "<group>"; + }; + E1F559441C9B3A450035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F559451C9B3A450035F88B /* Plugin.xcconfig */, + E1F559461C9B3A450035F88B /* Plugin_Debug.xcconfig */, + E1F559471C9B3A450035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F559481C9B3A6F0035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F5594C1C9B3A6F0035F88B /* PhaseDetector.h */, + E1F5594B1C9B3A6F0035F88B /* PhaseDetector.cpp */, + E1F5594E1C9B3A6F0035F88B /* PhaseDetectorEditor.h */, + E1F5594D1C9B3A6F0035F88B /* PhaseDetectorEditor.cpp */, + E1F5594A1C9B3A6F0035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/PhaseDetector; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F5593A1C9B3A100035F88B /* PhaseDetector */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F559411C9B3A100035F88B /* Build configuration list for PBXNativeTarget "PhaseDetector" */; + buildPhases = ( + E1F559371C9B3A100035F88B /* Sources */, + E1F559381C9B3A100035F88B /* Frameworks */, + E1F559391C9B3A100035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PhaseDetector; + productName = PhaseDetector; + productReference = E1F5593B1C9B3A100035F88B /* PhaseDetector.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F559331C9B3A100035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F5593A1C9B3A100035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F559361C9B3A100035F88B /* Build configuration list for PBXProject "PhaseDetector" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F559321C9B3A100035F88B; + productRefGroup = E1F5593C1C9B3A100035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F5593A1C9B3A100035F88B /* PhaseDetector */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F559391C9B3A100035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F559371C9B3A100035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F559511C9B3A6F0035F88B /* PhaseDetector.cpp in Sources */, + E1F559521C9B3A6F0035F88B /* PhaseDetectorEditor.cpp in Sources */, + E1F559501C9B3A6F0035F88B /* OpenEphysLib.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F5593F1C9B3A100035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559461C9B3A450035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F559401C9B3A100035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559471C9B3A450035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F559421C9B3A100035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = PhaseDetector/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.PhaseDetector"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F559431C9B3A100035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = PhaseDetector/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.PhaseDetector"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F559361C9B3A100035F88B /* Build configuration list for PBXProject "PhaseDetector" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F5593F1C9B3A100035F88B /* Debug */, + E1F559401C9B3A100035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F559411C9B3A100035F88B /* Build configuration list for PBXNativeTarget "PhaseDetector" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559421C9B3A100035F88B /* Debug */, + E1F559431C9B3A100035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F559331C9B3A100035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/PhaseDetector/PhaseDetector/Info.plist b/Builds/MacOSX/Plugins/PhaseDetector/PhaseDetector/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/PhaseDetector/PhaseDetector/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/PulsePalOutput/PulsePalOutput.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/PulsePalOutput/PulsePalOutput.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..96c269bc5b27b7fa38728c08e7d6907005102097 --- /dev/null +++ b/Builds/MacOSX/Plugins/PulsePalOutput/PulsePalOutput.xcodeproj/project.pbxproj @@ -0,0 +1,234 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F559741C9B3BF80035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5596B1C9B3BF80035F88B /* OpenEphysLib.cpp */; }; + E1F559751C9B3BF80035F88B /* PulsePalOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5596C1C9B3BF80035F88B /* PulsePalOutput.cpp */; }; + E1F559761C9B3BF80035F88B /* PulsePalOutputEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F5596E1C9B3BF80035F88B /* PulsePalOutputEditor.cpp */; }; + E1F559771C9B3BF80035F88B /* PulsePal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559711C9B3BF80035F88B /* PulsePal.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F5595C1C9B3B990035F88B /* PulsePalOutput.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PulsePalOutput.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F5595F1C9B3B990035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F559661C9B3BD50035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F559671C9B3BD50035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F559681C9B3BD50035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F5596B1C9B3BF80035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; + E1F5596C1C9B3BF80035F88B /* PulsePalOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PulsePalOutput.cpp; sourceTree = "<group>"; }; + E1F5596D1C9B3BF80035F88B /* PulsePalOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PulsePalOutput.h; sourceTree = "<group>"; }; + E1F5596E1C9B3BF80035F88B /* PulsePalOutputEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PulsePalOutputEditor.cpp; sourceTree = "<group>"; }; + E1F5596F1C9B3BF80035F88B /* PulsePalOutputEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PulsePalOutputEditor.h; sourceTree = "<group>"; }; + E1F559711C9B3BF80035F88B /* PulsePal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PulsePal.cpp; sourceTree = "<group>"; }; + E1F559721C9B3BF80035F88B /* PulsePal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PulsePal.h; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F559591C9B3B990035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F559531C9B3B990035F88B = { + isa = PBXGroup; + children = ( + E1F559651C9B3BD50035F88B /* Config */, + E1F5595E1C9B3B990035F88B /* PulsePalOutput */, + E1F5595D1C9B3B990035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F5595D1C9B3B990035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F5595C1C9B3B990035F88B /* PulsePalOutput.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F5595E1C9B3B990035F88B /* PulsePalOutput */ = { + isa = PBXGroup; + children = ( + E1F559691C9B3BF80035F88B /* Source */, + E1F5595F1C9B3B990035F88B /* Info.plist */, + ); + path = PulsePalOutput; + sourceTree = "<group>"; + }; + E1F559651C9B3BD50035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F559661C9B3BD50035F88B /* Plugin.xcconfig */, + E1F559671C9B3BD50035F88B /* Plugin_Debug.xcconfig */, + E1F559681C9B3BD50035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F559691C9B3BF80035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F559701C9B3BF80035F88B /* serial */, + E1F5596D1C9B3BF80035F88B /* PulsePalOutput.h */, + E1F5596C1C9B3BF80035F88B /* PulsePalOutput.cpp */, + E1F5596F1C9B3BF80035F88B /* PulsePalOutputEditor.h */, + E1F5596E1C9B3BF80035F88B /* PulsePalOutputEditor.cpp */, + E1F5596B1C9B3BF80035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/PulsePalOutput; + sourceTree = "<group>"; + }; + E1F559701C9B3BF80035F88B /* serial */ = { + isa = PBXGroup; + children = ( + E1F559721C9B3BF80035F88B /* PulsePal.h */, + E1F559711C9B3BF80035F88B /* PulsePal.cpp */, + ); + path = serial; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F5595B1C9B3B990035F88B /* PulsePalOutput */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F559621C9B3B990035F88B /* Build configuration list for PBXNativeTarget "PulsePalOutput" */; + buildPhases = ( + E1F559581C9B3B990035F88B /* Sources */, + E1F559591C9B3B990035F88B /* Frameworks */, + E1F5595A1C9B3B990035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PulsePalOutput; + productName = PulsePalOutput; + productReference = E1F5595C1C9B3B990035F88B /* PulsePalOutput.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F559541C9B3B990035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F5595B1C9B3B990035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F559571C9B3B990035F88B /* Build configuration list for PBXProject "PulsePalOutput" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F559531C9B3B990035F88B; + productRefGroup = E1F5595D1C9B3B990035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F5595B1C9B3B990035F88B /* PulsePalOutput */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F5595A1C9B3B990035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F559581C9B3B990035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F559751C9B3BF80035F88B /* PulsePalOutput.cpp in Sources */, + E1F559771C9B3BF80035F88B /* PulsePal.cpp in Sources */, + E1F559741C9B3BF80035F88B /* OpenEphysLib.cpp in Sources */, + E1F559761C9B3BF80035F88B /* PulsePalOutputEditor.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F559601C9B3B990035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559671C9B3BD50035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F559611C9B3B990035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559681C9B3BD50035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F559631C9B3B990035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = PulsePalOutput/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.PulsePalOutput"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F559641C9B3B990035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = PulsePalOutput/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.PulsePalOutput"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F559571C9B3B990035F88B /* Build configuration list for PBXProject "PulsePalOutput" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559601C9B3B990035F88B /* Debug */, + E1F559611C9B3B990035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F559621C9B3B990035F88B /* Build configuration list for PBXNativeTarget "PulsePalOutput" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559631C9B3B990035F88B /* Debug */, + E1F559641C9B3B990035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F559541C9B3B990035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/PulsePalOutput/PulsePalOutput/Info.plist b/Builds/MacOSX/Plugins/PulsePalOutput/PulsePalOutput/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/PulsePalOutput/PulsePalOutput/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/RecordControl/RecordControl.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/RecordControl/RecordControl.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..80114ca031b6e7ce492baa9a8198b0688efa3756 --- /dev/null +++ b/Builds/MacOSX/Plugins/RecordControl/RecordControl.xcodeproj/project.pbxproj @@ -0,0 +1,220 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F559961C9B3DD90035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559901C9B3DD90035F88B /* OpenEphysLib.cpp */; }; + E1F559971C9B3DD90035F88B /* RecordControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559911C9B3DD90035F88B /* RecordControl.cpp */; }; + E1F559981C9B3DD90035F88B /* RecordControlEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559931C9B3DD90035F88B /* RecordControlEditor.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F559811C9B3D760035F88B /* RecordControl.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RecordControl.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F559841C9B3D760035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F5598B1C9B3DAE0035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F5598C1C9B3DAE0035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F5598D1C9B3DAE0035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F559901C9B3DD90035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; + E1F559911C9B3DD90035F88B /* RecordControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordControl.cpp; sourceTree = "<group>"; }; + E1F559921C9B3DD90035F88B /* RecordControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordControl.h; sourceTree = "<group>"; }; + E1F559931C9B3DD90035F88B /* RecordControlEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordControlEditor.cpp; sourceTree = "<group>"; }; + E1F559941C9B3DD90035F88B /* RecordControlEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordControlEditor.h; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F5597E1C9B3D760035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F559781C9B3D760035F88B = { + isa = PBXGroup; + children = ( + E1F5598A1C9B3DAE0035F88B /* Config */, + E1F559831C9B3D760035F88B /* RecordControl */, + E1F559821C9B3D760035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F559821C9B3D760035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F559811C9B3D760035F88B /* RecordControl.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F559831C9B3D760035F88B /* RecordControl */ = { + isa = PBXGroup; + children = ( + E1F5598E1C9B3DD90035F88B /* Source */, + E1F559841C9B3D760035F88B /* Info.plist */, + ); + path = RecordControl; + sourceTree = "<group>"; + }; + E1F5598A1C9B3DAE0035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F5598B1C9B3DAE0035F88B /* Plugin.xcconfig */, + E1F5598C1C9B3DAE0035F88B /* Plugin_Debug.xcconfig */, + E1F5598D1C9B3DAE0035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F5598E1C9B3DD90035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F559921C9B3DD90035F88B /* RecordControl.h */, + E1F559911C9B3DD90035F88B /* RecordControl.cpp */, + E1F559941C9B3DD90035F88B /* RecordControlEditor.h */, + E1F559931C9B3DD90035F88B /* RecordControlEditor.cpp */, + E1F559901C9B3DD90035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/RecordControl; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F559801C9B3D760035F88B /* RecordControl */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F559871C9B3D760035F88B /* Build configuration list for PBXNativeTarget "RecordControl" */; + buildPhases = ( + E1F5597D1C9B3D760035F88B /* Sources */, + E1F5597E1C9B3D760035F88B /* Frameworks */, + E1F5597F1C9B3D760035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RecordControl; + productName = RecordControl; + productReference = E1F559811C9B3D760035F88B /* RecordControl.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F559791C9B3D760035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F559801C9B3D760035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F5597C1C9B3D760035F88B /* Build configuration list for PBXProject "RecordControl" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F559781C9B3D760035F88B; + productRefGroup = E1F559821C9B3D760035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F559801C9B3D760035F88B /* RecordControl */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F5597F1C9B3D760035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F5597D1C9B3D760035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F559961C9B3DD90035F88B /* OpenEphysLib.cpp in Sources */, + E1F559971C9B3DD90035F88B /* RecordControl.cpp in Sources */, + E1F559981C9B3DD90035F88B /* RecordControlEditor.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F559851C9B3D760035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F5598C1C9B3DAE0035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F559861C9B3D760035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F5598D1C9B3DAE0035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F559881C9B3D760035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = RecordControl/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.RecordControl"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F559891C9B3D760035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = RecordControl/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.RecordControl"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F5597C1C9B3D760035F88B /* Build configuration list for PBXProject "RecordControl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559851C9B3D760035F88B /* Debug */, + E1F559861C9B3D760035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F559871C9B3D760035F88B /* Build configuration list for PBXNativeTarget "RecordControl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559881C9B3D760035F88B /* Debug */, + E1F559891C9B3D760035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F559791C9B3D760035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/RecordControl/RecordControl/Info.plist b/Builds/MacOSX/Plugins/RecordControl/RecordControl/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/RecordControl/RecordControl/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/Rectifier/Rectifier.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/Rectifier/Rectifier.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..a6c6fe6ec2ced6eb865b6f8b29941f64a745e64d --- /dev/null +++ b/Builds/MacOSX/Plugins/Rectifier/Rectifier.xcodeproj/project.pbxproj @@ -0,0 +1,214 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F559B51C9B3F660035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559B11C9B3F660035F88B /* OpenEphysLib.cpp */; }; + E1F559B61C9B3F660035F88B /* Rectifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559B21C9B3F660035F88B /* Rectifier.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F559A21C9B3F040035F88B /* Rectifier.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Rectifier.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F559A51C9B3F040035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F559AC1C9B3F330035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F559AD1C9B3F330035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F559AE1C9B3F330035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F559B11C9B3F660035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; + E1F559B21C9B3F660035F88B /* Rectifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Rectifier.cpp; sourceTree = "<group>"; }; + E1F559B31C9B3F660035F88B /* Rectifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Rectifier.h; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F5599F1C9B3F040035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F559991C9B3F040035F88B = { + isa = PBXGroup; + children = ( + E1F559AB1C9B3F330035F88B /* Config */, + E1F559A41C9B3F040035F88B /* Rectifier */, + E1F559A31C9B3F040035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F559A31C9B3F040035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F559A21C9B3F040035F88B /* Rectifier.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F559A41C9B3F040035F88B /* Rectifier */ = { + isa = PBXGroup; + children = ( + E1F559AF1C9B3F660035F88B /* Source */, + E1F559A51C9B3F040035F88B /* Info.plist */, + ); + path = Rectifier; + sourceTree = "<group>"; + }; + E1F559AB1C9B3F330035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F559AC1C9B3F330035F88B /* Plugin.xcconfig */, + E1F559AD1C9B3F330035F88B /* Plugin_Debug.xcconfig */, + E1F559AE1C9B3F330035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F559AF1C9B3F660035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F559B31C9B3F660035F88B /* Rectifier.h */, + E1F559B21C9B3F660035F88B /* Rectifier.cpp */, + E1F559B11C9B3F660035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/Rectifier; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F559A11C9B3F040035F88B /* Rectifier */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F559A81C9B3F040035F88B /* Build configuration list for PBXNativeTarget "Rectifier" */; + buildPhases = ( + E1F5599E1C9B3F040035F88B /* Sources */, + E1F5599F1C9B3F040035F88B /* Frameworks */, + E1F559A01C9B3F040035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Rectifier; + productName = Rectifier; + productReference = E1F559A21C9B3F040035F88B /* Rectifier.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F5599A1C9B3F040035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F559A11C9B3F040035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F5599D1C9B3F040035F88B /* Build configuration list for PBXProject "Rectifier" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F559991C9B3F040035F88B; + productRefGroup = E1F559A31C9B3F040035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F559A11C9B3F040035F88B /* Rectifier */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F559A01C9B3F040035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F5599E1C9B3F040035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F559B61C9B3F660035F88B /* Rectifier.cpp in Sources */, + E1F559B51C9B3F660035F88B /* OpenEphysLib.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F559A61C9B3F040035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559AD1C9B3F330035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F559A71C9B3F040035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559AE1C9B3F330035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F559A91C9B3F040035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = Rectifier/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.Rectifier"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F559AA1C9B3F040035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = Rectifier/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.Rectifier"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F5599D1C9B3F040035F88B /* Build configuration list for PBXProject "Rectifier" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559A61C9B3F040035F88B /* Debug */, + E1F559A71C9B3F040035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F559A81C9B3F040035F88B /* Build configuration list for PBXNativeTarget "Rectifier" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559A91C9B3F040035F88B /* Debug */, + E1F559AA1C9B3F040035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F5599A1C9B3F040035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/Rectifier/Rectifier/Info.plist b/Builds/MacOSX/Plugins/Rectifier/Rectifier/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/Rectifier/Rectifier/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/SerialInput/SerialInput.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/SerialInput/SerialInput.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..080deb3599229e7a84333a008086d6b6d02763cf --- /dev/null +++ b/Builds/MacOSX/Plugins/SerialInput/SerialInput.xcodeproj/project.pbxproj @@ -0,0 +1,220 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F559D51C9B40FF0035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559CF1C9B40FF0035F88B /* OpenEphysLib.cpp */; }; + E1F559D61C9B40FF0035F88B /* SerialInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559D01C9B40FF0035F88B /* SerialInput.cpp */; }; + E1F559D71C9B40FF0035F88B /* SerialInputEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559D21C9B40FF0035F88B /* SerialInputEditor.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F559C01C9B40A10035F88B /* SerialInput.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SerialInput.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F559C31C9B40A10035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F559CA1C9B40DA0035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F559CB1C9B40DA0035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F559CC1C9B40DA0035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F559CF1C9B40FF0035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; + E1F559D01C9B40FF0035F88B /* SerialInput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialInput.cpp; sourceTree = "<group>"; }; + E1F559D11C9B40FF0035F88B /* SerialInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SerialInput.h; sourceTree = "<group>"; }; + E1F559D21C9B40FF0035F88B /* SerialInputEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialInputEditor.cpp; sourceTree = "<group>"; }; + E1F559D31C9B40FF0035F88B /* SerialInputEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SerialInputEditor.h; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F559BD1C9B40A10035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F559B71C9B40A10035F88B = { + isa = PBXGroup; + children = ( + E1F559C91C9B40DA0035F88B /* Config */, + E1F559C21C9B40A10035F88B /* SerialInput */, + E1F559C11C9B40A10035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F559C11C9B40A10035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F559C01C9B40A10035F88B /* SerialInput.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F559C21C9B40A10035F88B /* SerialInput */ = { + isa = PBXGroup; + children = ( + E1F559CD1C9B40FF0035F88B /* Source */, + E1F559C31C9B40A10035F88B /* Info.plist */, + ); + path = SerialInput; + sourceTree = "<group>"; + }; + E1F559C91C9B40DA0035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F559CA1C9B40DA0035F88B /* Plugin.xcconfig */, + E1F559CB1C9B40DA0035F88B /* Plugin_Debug.xcconfig */, + E1F559CC1C9B40DA0035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F559CD1C9B40FF0035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F559D11C9B40FF0035F88B /* SerialInput.h */, + E1F559D01C9B40FF0035F88B /* SerialInput.cpp */, + E1F559D31C9B40FF0035F88B /* SerialInputEditor.h */, + E1F559D21C9B40FF0035F88B /* SerialInputEditor.cpp */, + E1F559CF1C9B40FF0035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/SerialInput; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F559BF1C9B40A10035F88B /* SerialInput */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F559C61C9B40A10035F88B /* Build configuration list for PBXNativeTarget "SerialInput" */; + buildPhases = ( + E1F559BC1C9B40A10035F88B /* Sources */, + E1F559BD1C9B40A10035F88B /* Frameworks */, + E1F559BE1C9B40A10035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SerialInput; + productName = SerialInput; + productReference = E1F559C01C9B40A10035F88B /* SerialInput.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F559B81C9B40A10035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F559BF1C9B40A10035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F559BB1C9B40A10035F88B /* Build configuration list for PBXProject "SerialInput" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F559B71C9B40A10035F88B; + productRefGroup = E1F559C11C9B40A10035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F559BF1C9B40A10035F88B /* SerialInput */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F559BE1C9B40A10035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F559BC1C9B40A10035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F559D71C9B40FF0035F88B /* SerialInputEditor.cpp in Sources */, + E1F559D61C9B40FF0035F88B /* SerialInput.cpp in Sources */, + E1F559D51C9B40FF0035F88B /* OpenEphysLib.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F559C41C9B40A10035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559CB1C9B40DA0035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F559C51C9B40A10035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559CC1C9B40DA0035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F559C71C9B40A10035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = SerialInput/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.SerialInput"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F559C81C9B40A10035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = SerialInput/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.SerialInput"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F559BB1C9B40A10035F88B /* Build configuration list for PBXProject "SerialInput" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559C41C9B40A10035F88B /* Debug */, + E1F559C51C9B40A10035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F559C61C9B40A10035F88B /* Build configuration list for PBXNativeTarget "SerialInput" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559C71C9B40A10035F88B /* Debug */, + E1F559C81C9B40A10035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F559B81C9B40A10035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/SerialInput/SerialInput/Info.plist b/Builds/MacOSX/Plugins/SerialInput/SerialInput/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/SerialInput/SerialInput/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/Plugins/SpikeSorter/SpikeSorter.xcodeproj/project.pbxproj b/Builds/MacOSX/Plugins/SpikeSorter/SpikeSorter.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..e59f98c553b819f7b6b4f16cfbce00d7a570239c --- /dev/null +++ b/Builds/MacOSX/Plugins/SpikeSorter/SpikeSorter.xcodeproj/project.pbxproj @@ -0,0 +1,232 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + E1F559FA1C9B428E0035F88B /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559F01C9B428E0035F88B /* OpenEphysLib.cpp */; }; + E1F559FB1C9B428E0035F88B /* SpikeSortBoxes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559F11C9B428E0035F88B /* SpikeSortBoxes.cpp */; }; + E1F559FC1C9B428E0035F88B /* SpikeSorter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559F31C9B428E0035F88B /* SpikeSorter.cpp */; }; + E1F559FD1C9B428E0035F88B /* SpikeSorterCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559F51C9B428E0035F88B /* SpikeSorterCanvas.cpp */; }; + E1F559FE1C9B428E0035F88B /* SpikeSorterEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1F559F71C9B428E0035F88B /* SpikeSorterEditor.cpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + E1F559E11C9B42270035F88B /* SpikeSorter.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SpikeSorter.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E1F559E41C9B42270035F88B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + E1F559EB1C9B42650035F88B /* Plugin.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin.xcconfig; sourceTree = "<group>"; }; + E1F559EC1C9B42650035F88B /* Plugin_Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Debug.xcconfig; sourceTree = "<group>"; }; + E1F559ED1C9B42650035F88B /* Plugin_Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Plugin_Release.xcconfig; sourceTree = "<group>"; }; + E1F559F01C9B428E0035F88B /* OpenEphysLib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenEphysLib.cpp; sourceTree = "<group>"; }; + E1F559F11C9B428E0035F88B /* SpikeSortBoxes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpikeSortBoxes.cpp; sourceTree = "<group>"; }; + E1F559F21C9B428E0035F88B /* SpikeSortBoxes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpikeSortBoxes.h; sourceTree = "<group>"; }; + E1F559F31C9B428E0035F88B /* SpikeSorter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpikeSorter.cpp; sourceTree = "<group>"; }; + E1F559F41C9B428E0035F88B /* SpikeSorter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpikeSorter.h; sourceTree = "<group>"; }; + E1F559F51C9B428E0035F88B /* SpikeSorterCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpikeSorterCanvas.cpp; sourceTree = "<group>"; }; + E1F559F61C9B428E0035F88B /* SpikeSorterCanvas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpikeSorterCanvas.h; sourceTree = "<group>"; }; + E1F559F71C9B428E0035F88B /* SpikeSorterEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpikeSorterEditor.cpp; sourceTree = "<group>"; }; + E1F559F81C9B428E0035F88B /* SpikeSorterEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpikeSorterEditor.h; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1F559DE1C9B42270035F88B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1F559D81C9B42270035F88B = { + isa = PBXGroup; + children = ( + E1F559EA1C9B42650035F88B /* Config */, + E1F559E31C9B42270035F88B /* SpikeSorter */, + E1F559E21C9B42270035F88B /* Products */, + ); + sourceTree = "<group>"; + }; + E1F559E21C9B42270035F88B /* Products */ = { + isa = PBXGroup; + children = ( + E1F559E11C9B42270035F88B /* SpikeSorter.bundle */, + ); + name = Products; + sourceTree = "<group>"; + }; + E1F559E31C9B42270035F88B /* SpikeSorter */ = { + isa = PBXGroup; + children = ( + E1F559EE1C9B428E0035F88B /* Source */, + E1F559E41C9B42270035F88B /* Info.plist */, + ); + path = SpikeSorter; + sourceTree = "<group>"; + }; + E1F559EA1C9B42650035F88B /* Config */ = { + isa = PBXGroup; + children = ( + E1F559EB1C9B42650035F88B /* Plugin.xcconfig */, + E1F559EC1C9B42650035F88B /* Plugin_Debug.xcconfig */, + E1F559ED1C9B42650035F88B /* Plugin_Release.xcconfig */, + ); + name = Config; + path = ../Config; + sourceTree = "<group>"; + }; + E1F559EE1C9B428E0035F88B /* Source */ = { + isa = PBXGroup; + children = ( + E1F559F21C9B428E0035F88B /* SpikeSortBoxes.h */, + E1F559F11C9B428E0035F88B /* SpikeSortBoxes.cpp */, + E1F559F41C9B428E0035F88B /* SpikeSorter.h */, + E1F559F31C9B428E0035F88B /* SpikeSorter.cpp */, + E1F559F61C9B428E0035F88B /* SpikeSorterCanvas.h */, + E1F559F51C9B428E0035F88B /* SpikeSorterCanvas.cpp */, + E1F559F81C9B428E0035F88B /* SpikeSorterEditor.h */, + E1F559F71C9B428E0035F88B /* SpikeSorterEditor.cpp */, + E1F559F01C9B428E0035F88B /* OpenEphysLib.cpp */, + ); + name = Source; + path = ../../../../../Source/Plugins/SpikeSorter; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1F559E01C9B42270035F88B /* SpikeSorter */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1F559E71C9B42270035F88B /* Build configuration list for PBXNativeTarget "SpikeSorter" */; + buildPhases = ( + E1F559DD1C9B42270035F88B /* Sources */, + E1F559DE1C9B42270035F88B /* Frameworks */, + E1F559DF1C9B42270035F88B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SpikeSorter; + productName = SpikeSorter; + productReference = E1F559E11C9B42270035F88B /* SpikeSorter.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1F559D91C9B42270035F88B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Open Ephys"; + TargetAttributes = { + E1F559E01C9B42270035F88B = { + CreatedOnToolsVersion = 7.2.1; + }; + }; + }; + buildConfigurationList = E1F559DC1C9B42270035F88B /* Build configuration list for PBXProject "SpikeSorter" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = E1F559D81C9B42270035F88B; + productRefGroup = E1F559E21C9B42270035F88B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1F559E01C9B42270035F88B /* SpikeSorter */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1F559DF1C9B42270035F88B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1F559DD1C9B42270035F88B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1F559FB1C9B428E0035F88B /* SpikeSortBoxes.cpp in Sources */, + E1F559FD1C9B428E0035F88B /* SpikeSorterCanvas.cpp in Sources */, + E1F559FA1C9B428E0035F88B /* OpenEphysLib.cpp in Sources */, + E1F559FE1C9B428E0035F88B /* SpikeSorterEditor.cpp in Sources */, + E1F559FC1C9B428E0035F88B /* SpikeSorter.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + E1F559E51C9B42270035F88B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559EC1C9B42650035F88B /* Plugin_Debug.xcconfig */; + buildSettings = { + }; + name = Debug; + }; + E1F559E61C9B42270035F88B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1F559ED1C9B42650035F88B /* Plugin_Release.xcconfig */; + buildSettings = { + }; + name = Release; + }; + E1F559E81C9B42270035F88B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = SpikeSorter/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.SpikeSorter"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + E1F559E91C9B42270035F88B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = SpikeSorter/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = "org.open-ephys.gui.plugin.SpikeSorter"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1F559DC1C9B42270035F88B /* Build configuration list for PBXProject "SpikeSorter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559E51C9B42270035F88B /* Debug */, + E1F559E61C9B42270035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1F559E71C9B42270035F88B /* Build configuration list for PBXNativeTarget "SpikeSorter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1F559E81C9B42270035F88B /* Debug */, + E1F559E91C9B42270035F88B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1F559D91C9B42270035F88B /* Project object */; +} diff --git a/Builds/MacOSX/Plugins/SpikeSorter/SpikeSorter/Info.plist b/Builds/MacOSX/Plugins/SpikeSorter/SpikeSorter/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a79179f900894f4b66ce9ecfb42611ffb1f9274e --- /dev/null +++ b/Builds/MacOSX/Plugins/SpikeSorter/SpikeSorter/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2016 Open Ephys. All rights reserved.</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj index 40589b10665f61a3313e42e3dbc2a812450b7126..ca65fc7961e97d1afff5167acda3b4773d8e1287 100644 --- a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj @@ -19,17 +19,15 @@ CA4DCF67B48352BE633A616D = {isa = PBXBuildFile; fileRef = C055D09224D84121A3EBB29F; }; 512D7D16D0A95BDD0D6D6E45 = {isa = PBXBuildFile; fileRef = 4FD13AA663EEE7CC2F83033D; }; 2D2BDB63CBD0BED07FF9E44B = {isa = PBXBuildFile; fileRef = BBE1DB78E35135B41537DCB5; }; + 7E68BE958652C77EF1E93AC1 = {isa = PBXBuildFile; fileRef = 0618303B4E1BF577974A03FE; }; 4FA2949D3023FC2E377AFFB6 = {isa = PBXBuildFile; fileRef = 61317B5191E05925F232E18C; }; CFBB591627F730A6C98ECA25 = {isa = PBXBuildFile; fileRef = 71086F59DD72696364603E33; }; - F08929D23989E83088DD8914 = {isa = PBXBuildFile; fileRef = 12648B73338F2CF28CED2614; }; 14BDAEA656AAFA60334CC55C = {isa = PBXBuildFile; fileRef = 420B0E95F1300ABFDC125DBF; }; - 0ADE6EC5E6FCAC79C9EDA534 = {isa = PBXBuildFile; fileRef = DB4FF7675E5C98CF62DA8A2E; }; C853FCE2F6C91B3643322CF0 = {isa = PBXBuildFile; fileRef = 9F577889CB6C54A2F7B1CA80; }; - 02AAF08AB7A31598784F5EAF = {isa = PBXBuildFile; fileRef = 7B42B28FDB2E3AC67EF296F8; }; 0AE243437B40602D35435C32 = {isa = PBXBuildFile; fileRef = B04D87ED6AA4897B6CD3CCF6; }; - 425B09B8D50623B880FD03D6 = {isa = PBXBuildFile; fileRef = E79259F2164D16553A69B458; }; B04B9CA1E59D544793808F25 = {isa = PBXBuildFile; fileRef = 524466E331502DEC89862D66; }; 28B77947820CAE30A5E2DE22 = {isa = PBXBuildFile; fileRef = 9AD7314174B2AB01FBF7E1E1; }; + CB568964BDF3E65207B81CCA = {isa = PBXBuildFile; fileRef = 72D50E371901970C428D9E8B; }; 9252537C12447F047243DEE9 = {isa = PBXBuildFile; fileRef = 041038F6E67FE0409D8ECC74; }; B081F3F4FA6D8C35E2EEE778 = {isa = PBXBuildFile; fileRef = CB5C14E82DE06F767EAD62F9; }; 7398C5E00B9093F78C697706 = {isa = PBXBuildFile; fileRef = 777D9B0FE3C110ADA980BD09; }; @@ -51,13 +49,9 @@ AE80C3A6186F3A4D537489A0 = {isa = PBXBuildFile; fileRef = 66D578EAADBAD326A09FD25E; }; FDC3F3F6332D07F15FED8EA1 = {isa = PBXBuildFile; fileRef = 541E3B77D21FF049426506C1; }; 07A712AC1BFF4BBB74914575 = {isa = PBXBuildFile; fileRef = D39560BC785A81E49F6C502D; }; - D761F014D76825DEFE0A7582 = {isa = PBXBuildFile; fileRef = FCA5573BA018F7E8106B89FF; }; 8352817FEDC7542D3E65B49A = {isa = PBXBuildFile; fileRef = DA4EAC64A750D0C3DEE83C5D; }; - 5D49C3544A04DDC85CAB84FA = {isa = PBXBuildFile; fileRef = C15024C101ECE85FDDCD770D; }; 44DB81313BDDF1ECB6AD33FE = {isa = PBXBuildFile; fileRef = 1F22CC8D992B8B49D57DDB3F; }; - 7598258C53F4559D2A4CD163 = {isa = PBXBuildFile; fileRef = 19B08AF9187EC45ECDE87602; }; C45009DBCD71E9E234BFCE97 = {isa = PBXBuildFile; fileRef = FA8CC6FD54A9F20DA755F2EA; }; - DE86EB9584E75F21AA2D1404 = {isa = PBXBuildFile; fileRef = 74BAC33D6BC1D961F04DCC72; }; 11375775EC137CE30502F397 = {isa = PBXBuildFile; fileRef = C848F80F175057CDC43A0DF4; }; 763159B0A13FA88D3DCCAA4B = {isa = PBXBuildFile; fileRef = 29C859E4FEC33981B0C5ABBA; }; 5885BE052A89E9971DEA4197 = {isa = PBXBuildFile; fileRef = 41D761E3938095C42824143D; }; @@ -65,89 +59,54 @@ 138A4742F7B3F263D5ABF0F9 = {isa = PBXBuildFile; fileRef = 826FBF8BB35A562476C6B30B; }; 203844FDF36CFE38A7DAABE7 = {isa = PBXBuildFile; fileRef = F06884C6399CB102B1E8A24E; }; FAE745870674A07A65690433 = {isa = PBXBuildFile; fileRef = 788F8B7719B70465762B634B; }; - 58C57FE9863EA52A46672FD9 = {isa = PBXBuildFile; fileRef = F09FD6D9CA4997216ADBF54F; }; 24CC7E9A7E87F762D4AB0467 = {isa = PBXBuildFile; fileRef = 92602D7166325C7232B85EDD; }; - 1621D0850A6D6773B7F4853B = {isa = PBXBuildFile; fileRef = 0287B009511521BEAAE8A52C; }; 52AE3F7AEED81BA9ED5C4830 = {isa = PBXBuildFile; fileRef = E216D095C98F850A5FB6FB0F; }; - 50C545252FEF7B6F9D82092D = {isa = PBXBuildFile; fileRef = 70F06DBCA3948BCC1062E36F; }; 029C3B11BE586DA100895A60 = {isa = PBXBuildFile; fileRef = 28CCF04CCC028BAE0AEE5840; }; - 547264A139B1D525A86114DF = {isa = PBXBuildFile; fileRef = 15870472BA2B1779521A21BD; }; 6702EEA4E99D503C0EE933C4 = {isa = PBXBuildFile; fileRef = D3AE8303545E28D793312F46; }; - B3DDA21DDD467F64AF8556B0 = {isa = PBXBuildFile; fileRef = 984BC60C0AFF3EDED692FA01; }; 7F188166D38DA7FB23311413 = {isa = PBXBuildFile; fileRef = 04C6B933E1603B4D0916570D; }; - 3135B9FED0BF40A73C5EFE84 = {isa = PBXBuildFile; fileRef = C51CD15B311D0AAC08D0B908; }; AA16BE5A6BBD024C8FCFCDA8 = {isa = PBXBuildFile; fileRef = CAA3B9396EA62166234DAEF1; }; - 46511E0CF49A1F753F2EC949 = {isa = PBXBuildFile; fileRef = B23E6EBB5F99CF7FC72FAC4E; }; 4976529FC367F5F6A0D04370 = {isa = PBXBuildFile; fileRef = A76B04F4829C862D4B8F66B3; }; - 3F6A34906F13DE5E65F9F785 = {isa = PBXBuildFile; fileRef = 1A05C5AF5447448AAF869508; }; 68EBB4CEB08BD3DEAC450B95 = {isa = PBXBuildFile; fileRef = 34834859523571912C55AC94; }; - 53942219C91A015CCEF6F751 = {isa = PBXBuildFile; fileRef = D5DC73F860143308ADF769C1; }; 24800AF87AD21CE652552EDE = {isa = PBXBuildFile; fileRef = 56F810EF10E01535A417B671; }; - 7D393CD459AD73307B4B26A2 = {isa = PBXBuildFile; fileRef = BF8C15407347975836BFA88F; }; B49852F77C0C392C159A1914 = {isa = PBXBuildFile; fileRef = C5654EAA7B65445CF1340983; }; - F1CFB5BF336DF4A46A570280 = {isa = PBXBuildFile; fileRef = 012F05BBF926C8F39AC7871B; }; 6D00BABD3FE1AA0EAA267C1C = {isa = PBXBuildFile; fileRef = 07B84F46CF90D04BB6B673C5; }; - 6B56E0463FF3D580F0C84407 = {isa = PBXBuildFile; fileRef = CA50A6F43BD78D01A8BE974B; }; AD371C6F383F03EF392B6581 = {isa = PBXBuildFile; fileRef = BAA5B3AD1A27F8C4D37A6869; }; - 4DF3A59A371DE10E4FFFF642 = {isa = PBXBuildFile; fileRef = 8C639E4F97B7D6070028623A; }; 4EF2825142BBAA76FD55FE26 = {isa = PBXBuildFile; fileRef = BC1543B1F822FEEDCB9AC26D; }; - CDB3C038ABFCB6A8EAA27D79 = {isa = PBXBuildFile; fileRef = 8F058EA775325F9C5650944E; }; 3B05807D08271664EEC4977C = {isa = PBXBuildFile; fileRef = AEFC8A0A9A35F50E59FDE678; }; - 27A764088D184F9898FC8B4F = {isa = PBXBuildFile; fileRef = 9EB2B238943CCC32B587881C; }; F2586A2DCEF44961AEA247E8 = {isa = PBXBuildFile; fileRef = 934B37E2BECD69E6E27051F6; }; - 9354508D753345076D5C79E6 = {isa = PBXBuildFile; fileRef = 362898B655ABFFA23A69BBFA; }; 3E7939ABAA984EE8BFC8CEDD = {isa = PBXBuildFile; fileRef = 4F5D51C5F8174E3824EF8B42; }; - CD6ACBFB0637B64B9CA1A91F = {isa = PBXBuildFile; fileRef = 811BCA5BE226C5188BC5E9B9; }; BAC379C03C2E7995F2393EF5 = {isa = PBXBuildFile; fileRef = 4CB63EE1552BBFDEB1DADB0A; }; - 326F93591218D713F4230961 = {isa = PBXBuildFile; fileRef = B695B24906116ADEFC9D9B5C; }; + 0326A368BA8F70C74A8A12A7 = {isa = PBXBuildFile; fileRef = 74E31DA11A4C1244B78A077A; }; + F7E069E1FC1BB7EF856AA083 = {isa = PBXBuildFile; fileRef = 699B3251715DE04674E0E0C4; }; E1247DDF1C88D99691499E52 = {isa = PBXBuildFile; fileRef = 7DB22AC6407EEA88F3FFA16D; }; - 960C8D7486F047112BD4468B = {isa = PBXBuildFile; fileRef = 398BF0B03B719107E6093F98; }; 0A8D8C2D02858F0F08356EA9 = {isa = PBXBuildFile; fileRef = E39CC410838072043E3C30DC; }; - D4995270E6CB321A9F344EB1 = {isa = PBXBuildFile; fileRef = 9B1962D340B217B19B077F2A; }; AEDA8F23648EABF79215B566 = {isa = PBXBuildFile; fileRef = F716728550EBD8FA7B9CA7EF; }; - D909F61CF9323366A2143DB2 = {isa = PBXBuildFile; fileRef = 25B79E00075CCF59F0A4A7D7; }; B806F023DF817BB2D59FEEFD = {isa = PBXBuildFile; fileRef = 949422DF0532222450E95926; }; - 1419982AA3FEFD48742EC391 = {isa = PBXBuildFile; fileRef = B657AEAFB3404A5CB270C413; }; 7B69E73AF79BB2B10BAA559C = {isa = PBXBuildFile; fileRef = 242B80832B3C8FF4F3CC18F1; }; - 30D2FF80A059C4F2F2641452 = {isa = PBXBuildFile; fileRef = A7BF9312D81FF5DCEAB8AC47; }; 74A14124A3B0C5FB13583B57 = {isa = PBXBuildFile; fileRef = 326F8386BCD4E4189D0CC00F; }; - BABD91F2DC4EDF91E155CC42 = {isa = PBXBuildFile; fileRef = B5D805B691B1C38D959F6B54; }; 4910924155F31E96B9BAD050 = {isa = PBXBuildFile; fileRef = B9068FF0373FA8321C33C42C; }; - FE0BEC4F57D0EA019EF6D24A = {isa = PBXBuildFile; fileRef = E1E9FAB63BD90C10F2BEF74C; }; 66DE280C28A69B2002C40A86 = {isa = PBXBuildFile; fileRef = 607CC2BFCB0622B3348FA1AD; }; - B1CFD7C1DD7724CD38FA1FEC = {isa = PBXBuildFile; fileRef = 385F66531BAB16BA754E901E; }; 5BF488044E143A2727CE2BDB = {isa = PBXBuildFile; fileRef = 0646A83E4EE738EE5D914DA6; }; 1B620FC17AAECA4C5DE741E2 = {isa = PBXBuildFile; fileRef = 66463AB11EA4D6341C32F27E; }; - E4DFAFCE9800EE2C9F8A8AAF = {isa = PBXBuildFile; fileRef = FFFBDB9A00240D797751FEE6; }; 19BB86C918F89D1377F8A0E1 = {isa = PBXBuildFile; fileRef = 5894D40A0E8FA6E9B3EBF9D9; }; - 284D8B7D3CDE3742B3468855 = {isa = PBXBuildFile; fileRef = ADCB42E4C5641007A4B78025; }; - AE270975F90CC92C27F80B05 = {isa = PBXBuildFile; fileRef = 215E1BD79B5870D5356810F0; }; 89223664B6CB2A912E36B091 = {isa = PBXBuildFile; fileRef = F115ED75E977A54AAF036B2C; }; - 39914728A9B138EB9A04CF34 = {isa = PBXBuildFile; fileRef = AE3D7946F13CE32AE41DD1B7; }; + 97B42624998C8E4E2A5C9BA7 = {isa = PBXBuildFile; fileRef = C25C0DDD703C77F4FDCE4DE6; }; + EE60D8FC7DCEC9C9AE545F4D = {isa = PBXBuildFile; fileRef = 6F201AA651C426427E515AF2; }; + 43BDE8C7A1D17FC0CD2EF00D = {isa = PBXBuildFile; fileRef = 0BD711FD3C982C60B294F311; }; + 5A43E4E1547CBD9C2A635AEE = {isa = PBXBuildFile; fileRef = 3A3EFEB7D30A6E75D5A1D1B1; }; + 8C78E9A851776185755D708E = {isa = PBXBuildFile; fileRef = BDD36C3C308596F8CCCBF163; }; + FCB05BDFCBD2EFD9DF49D5AC = {isa = PBXBuildFile; fileRef = 1901A338916E925CC2E03E42; }; BA608CEFC85F7AB9E30E0EB3 = {isa = PBXBuildFile; fileRef = F960CC94B136201BDA148EEA; }; - 8EB38EF63AACA70DFEC4CF94 = {isa = PBXBuildFile; fileRef = C59B01C8DB5B3B4773032E12; }; D499273B65D901D0A101CAAA = {isa = PBXBuildFile; fileRef = E5C1D021C0FD6FAD082C5D75; }; - 14133143519D06FC6F4C88C6 = {isa = PBXBuildFile; fileRef = BA422CC894B825834A0C5479; }; 95AE939ADE096394CCD2526F = {isa = PBXBuildFile; fileRef = 9F3B3184EC6D42CEA35D6ED8; }; - 6DC53D380636F5A30B52BAC8 = {isa = PBXBuildFile; fileRef = E93BE115650B1CB80EACB841; }; E85DA5FC9A162F129ABA7113 = {isa = PBXBuildFile; fileRef = 0987F7E90136D0E08A606A22; }; - B37D32878D75EDCD4400826A = {isa = PBXBuildFile; fileRef = 48F6281AB92B232E5187D00C; }; 6A13D8F42A330E2C410B43E3 = {isa = PBXBuildFile; fileRef = 7E875E681E18D693D5ADB2FB; }; - 736608BBA6321E460BDBBBC8 = {isa = PBXBuildFile; fileRef = 57FBA8BC3104D3AF41FBECD8; }; 13F1111511DD01E843E631CA = {isa = PBXBuildFile; fileRef = 79C91DDF3BC3F15D0338E504; }; - D4EC5BCFAB683EA0A4473AA6 = {isa = PBXBuildFile; fileRef = 105B1452DF6CE1D80D69A9D1; }; - 9A80E3D1D1758A31D2169497 = {isa = PBXBuildFile; fileRef = 3774BBCA6CB133D9A854CF71; }; - 715C8221533FB1B9DD03F721 = {isa = PBXBuildFile; fileRef = 19148DBA36B94FA639DF3A72; }; F4397EAE00E0B9F96C8B6C07 = {isa = PBXBuildFile; fileRef = 17E13CCDA0C82F92EAB05BE6; }; - 12088E12BCA721D0832B39FD = {isa = PBXBuildFile; fileRef = D2696B30CBEAD7CE72510AFA; }; 09673DA3B4D6EA61DEFC0C46 = {isa = PBXBuildFile; fileRef = 47A3942AC30A3212C01F1CAF; }; - 968E9B7C2E1974474E51F26E = {isa = PBXBuildFile; fileRef = 7D9374931D760ADC65DCBFC6; }; 58D3FF3B1F462634167BDFB5 = {isa = PBXBuildFile; fileRef = 610E487E060C42B52FD5AAC9; }; - 6DA67142BD5D41B90A19121B = {isa = PBXBuildFile; fileRef = 0FE8ACC50ED8E7FFC9E6B9B4; }; 3162B66BC8118715AAA527D7 = {isa = PBXBuildFile; fileRef = D2A3B4CDD296B4CEC6902FD7; }; - 4300909A1BAF9464663A9CF3 = {isa = PBXBuildFile; fileRef = 3FC794735FA8DDA39A62224B; }; 004E78BC139419671A9EA137 = {isa = PBXBuildFile; fileRef = E08E877C3A6283CF5C803957; }; - 63181788D187F9A15BBE03D9 = {isa = PBXBuildFile; fileRef = BB26BA9CFAE8C836251E8EAF; }; 6306AA945375749C4FE834E6 = {isa = PBXBuildFile; fileRef = 2C89EC72FF6A7118EF459DC3; }; AD7D05519200FB0EE1C7617A = {isa = PBXBuildFile; fileRef = A512C5B237A77EF6FB8E11A0; }; C2475E008FEB33B3EA7B6C7F = {isa = PBXBuildFile; fileRef = DF3C9A1DD67E879E4E0A2727; }; @@ -189,7 +148,9 @@ 05C35036E964AAD6024E0766 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "MergerA-01.png"; path = "../../Resources/Images/Buttons/MergerA-01.png"; sourceTree = "SOURCE_ROOT"; }; 05DCAE8CA29532E2169D7AC1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Matrix3D.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_Matrix3D.h"; sourceTree = "SOURCE_ROOT"; }; 06072EC6BCD3B7D8C17C2402 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioProcessor.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp"; sourceTree = "SOURCE_ROOT"; }; + 0618303B4E1BF577974A03FE = {isa = PBXFileReference; lastKnownFileType = file.icns; name = Icon.icns; path = Icon.icns; sourceTree = "SOURCE_ROOT"; }; 0646A83E4EE738EE5D914DA6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Visualizer.cpp; path = ../../Source/Processors/Visualization/Visualizer.cpp; sourceTree = "SOURCE_ROOT"; }; + 066A1CD777247BC8142A7DAA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = EventQueue.h; path = ../../Source/Processors/RecordNode/EventQueue.h; sourceTree = "SOURCE_ROOT"; }; 078625CF5C083AD538D23401 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioCDReader.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp"; sourceTree = "SOURCE_ROOT"; }; 0790CCE2FCFDFA6944DFC402 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; 07B84F46CF90D04BB6B673C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Merger.cpp; path = ../../Source/Processors/Merger/Merger.cpp; sourceTree = "SOURCE_ROOT"; }; @@ -217,6 +178,7 @@ 0B5B63E563EFA7E816DE3DCA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OutputStream.h"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_OutputStream.h"; sourceTree = "SOURCE_ROOT"; }; 0BB4380EDFEAAE0DAB255B90 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_BlowFish.cpp"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.cpp"; sourceTree = "SOURCE_ROOT"; }; 0BCAC20DAB10B957168B85D6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Result.h"; path = "../../JuceLibraryCode/modules/juce_core/misc/juce_Result.h"; sourceTree = "SOURCE_ROOT"; }; + 0BD711FD3C982C60B294F311 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ButtonGroupManager.cpp; path = ../../Source/UI/Utils/ButtonGroupManager.cpp; sourceTree = "SOURCE_ROOT"; }; 0BF3932F3EA1149C2F7E31F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_IPAddress.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_IPAddress.cpp"; sourceTree = "SOURCE_ROOT"; }; 0C646E9950FB580B21E1F2BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_WindowsMediaAudioFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; 0CCB1C4D687001E04DE1DD9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_SubregionStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_SubregionStream.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -248,6 +210,7 @@ 13D9DC48F19699485F9888A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PathIterator.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_PathIterator.h"; sourceTree = "SOURCE_ROOT"; }; 1463D2DAB3A1D8CEE825056A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h"; sourceTree = "SOURCE_ROOT"; }; 146C6A6E3C6B17F2AF475B50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLFrameBuffer.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp"; sourceTree = "SOURCE_ROOT"; }; + 148FE750B55B2F7EA3899408 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LinearSmoothedValueAtomic.h; path = ../../Source/Processors/Dsp/LinearSmoothedValueAtomic.h; sourceTree = "SOURCE_ROOT"; }; 14DD0220B41F74C01A9DC676 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GlyphArrangement.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.h"; sourceTree = "SOURCE_ROOT"; }; 14FE601229C9A40C6E182F28 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MouseCursor.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm"; sourceTree = "SOURCE_ROOT"; }; 1518D2BA7FCAF267EF1F02E6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Windowing.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -268,12 +231,13 @@ 17E13CCDA0C82F92EAB05BE6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = InfoLabel.cpp; path = ../../Source/UI/InfoLabel.cpp; sourceTree = "SOURCE_ROOT"; }; 17FB020EFEAED8493D3CB121 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h"; sourceTree = "SOURCE_ROOT"; }; 1819C1C4DE5FEEDEA143E3D2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_MainMenu.mm"; path = "../../JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_MainMenu.mm"; sourceTree = "SOURCE_ROOT"; }; + 18A11ED5F07AA76D8253A66A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MaterialButtonLookAndFeel.h; path = ../../Source/UI/LookAndFeel/MaterialButtonLookAndFeel.h; sourceTree = "SOURCE_ROOT"; }; 18A730DF335EEB3A4D13FDCA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MessageManager.cpp"; path = "../../JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp"; sourceTree = "SOURCE_ROOT"; }; 18B410DA5435C02C82BA13F8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BooleanPropertyComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; 18C2F9CA38393D106FB834E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioPluginFormat.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp"; sourceTree = "SOURCE_ROOT"; }; 18CFDBCD4A5B80E78DADCFEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectanglePlacement.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/placement/juce_RectanglePlacement.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1901A338916E925CC2E03E42 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CustomLookAndFeel.cpp; path = ../../Source/UI/LookAndFeel/CustomLookAndFeel.cpp; sourceTree = "SOURCE_ROOT"; }; 19043050D1DADAEAB48FB803 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioCDBurner.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h"; sourceTree = "SOURCE_ROOT"; }; - 19148DBA36B94FA639DF3A72 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CustomLookAndFeel.h; path = ../../Source/UI/CustomLookAndFeel.h; sourceTree = "SOURCE_ROOT"; }; 193FED8339417E8E6264957A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ElementComparator.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ElementComparator.h"; sourceTree = "SOURCE_ROOT"; }; 196499CECF3848D933A5C905 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OpenEphysPlugin.h; path = ../../Source/Processors/PluginManager/OpenEphysPlugin.h; sourceTree = "SOURCE_ROOT"; }; 19A8A8E1BF043B390E02C429 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Messaging.cpp"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -285,6 +249,7 @@ 1AEEC114AFAB6E81205FBCD1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AttributedString.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_AttributedString.h"; sourceTree = "SOURCE_ROOT"; }; 1B27BF1CF3F235A55CD5107D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResamplingAudioSource.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; }; 1BF01252E3A30560525CE057 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; + 1C386A08A3C69F4D05595122 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MaterialSliderLookAndFeel.h; path = ../../Source/UI/LookAndFeel/MaterialSliderLookAndFeel.h; sourceTree = "SOURCE_ROOT"; }; 1C4227B9237C06B69587F551 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V3.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp"; sourceTree = "SOURCE_ROOT"; }; 1C474C73937D98E9D3FFEEC0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FilePreviewComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; }; 1C639F4C139C8D7753AA9BB6 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_gui_extra/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; @@ -316,6 +281,7 @@ 23F048594D4C9AD8C3399877 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_SystemStats.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp"; sourceTree = "SOURCE_ROOT"; }; 242B80832B3C8FF4F3CC18F1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SourceNode.cpp; path = ../../Source/Processors/SourceNode/SourceNode.cpp; sourceTree = "SOURCE_ROOT"; }; 243817BA562AD7FA76C834C9 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; }; + 247E9C92B402D44790933486 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-large.png"; path = "../../Resources/Icons/icon-large.png"; sourceTree = "SOURCE_ROOT"; }; 24D86195580EFB86AC084DCC = {isa = PBXFileReference; lastKnownFileType = file.otf; name = "cpmono_extra_light.otf"; path = "../../Resources/Fonts/cpmono_extra_light.otf"; sourceTree = "SOURCE_ROOT"; }; 25433DB6D2EAEBB307EFB960 = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_graphics/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; 2560987BB222D7CED27EAC87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WildcardFileFilter.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_WildcardFileFilter.h"; sourceTree = "SOURCE_ROOT"; }; @@ -324,6 +290,7 @@ 25DCA4D0E86DFB51AF637D21 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; 25F7BEADC001FA3D1EA9B32C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawablePath.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp"; sourceTree = "SOURCE_ROOT"; }; 261B5AA82F2A86CC5500D8D2 = {isa = PBXFileReference; lastKnownFileType = image.png; name = ArduinoIcon.png; path = ../../Resources/Images/Icons/ArduinoIcon.png; sourceTree = "SOURCE_ROOT"; }; + 2635ADCB645C983D2F64F621 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon-small.png"; path = "../../Resources/Icons/icon-small.png"; sourceTree = "SOURCE_ROOT"; }; 266FC6DA3123E576811DD828 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FlacAudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; 26FF78F12CCB8725C0DAF9C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MidiInput.h"; path = "../../JuceLibraryCode/modules/juce_audio_devices/midi_io/juce_MidiInput.h"; sourceTree = "SOURCE_ROOT"; }; 27313EA12BC45638321922CA = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; @@ -378,7 +345,7 @@ 362898B655ABFFA23A69BBFA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ParameterEditor.h; path = ../../Source/Processors/Parameter/ParameterEditor.h; sourceTree = "SOURCE_ROOT"; }; 3663C981D28BF165C1B601A7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OptionalScopedPointer.h"; path = "../../JuceLibraryCode/modules/juce_core/memory/juce_OptionalScopedPointer.h"; sourceTree = "SOURCE_ROOT"; }; 36A9736F04AAA2F8E9D711BB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SpinLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_SpinLock.h"; sourceTree = "SOURCE_ROOT"; }; - 3774BBCA6CB133D9A854CF71 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CustomLookAndFeel.cpp; path = ../../Source/UI/CustomLookAndFeel.cpp; sourceTree = "SOURCE_ROOT"; }; + 36BE4BA79883C88072EE385B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CustomLookAndFeel.h; path = ../../Source/UI/LookAndFeel/CustomLookAndFeel.h; sourceTree = "SOURCE_ROOT"; }; 381F5DC605AE69088004DF80 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "PipelineB-01.png"; path = "../../Resources/Images/Buttons/PipelineB-01.png"; sourceTree = "SOURCE_ROOT"; }; 3846F3FA0FC28CE322073E94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Utilities.h; path = ../../Source/Processors/Dsp/Utilities.h; sourceTree = "SOURCE_ROOT"; }; 385F66531BAB16BA754E901E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SplitterEditor.h; path = ../../Source/Processors/Splitter/SplitterEditor.h; sourceTree = "SOURCE_ROOT"; }; @@ -394,6 +361,7 @@ 398BF0B03B719107E6093F98 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = EngineConfigWindow.h; path = ../../Source/Processors/RecordNode/EngineConfigWindow.h; sourceTree = "SOURCE_ROOT"; }; 39F287BE4C0B4F3BD4A949FD = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; 3A2C762575D9728B1F822ED3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AsyncUpdater.cpp"; path = "../../JuceLibraryCode/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp"; sourceTree = "SOURCE_ROOT"; }; + 3A3EFEB7D30A6E75D5A1D1B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MaterialButtonLookAndFeel.cpp; path = ../../Source/UI/LookAndFeel/MaterialButtonLookAndFeel.cpp; sourceTree = "SOURCE_ROOT"; }; 3A6E9EC3DA618EBA06B9DEEB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioSubsectionReader.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h"; sourceTree = "SOURCE_ROOT"; }; 3A6FE617A781EEFFD39E1216 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_neutral-02.png"; path = "../../Resources/Images/Icons/RadioButtons_neutral-02.png"; sourceTree = "SOURCE_ROOT"; }; 3A71F2C959CA7DD3C33DC411 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CarbonViewWrapperComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h"; sourceTree = "SOURCE_ROOT"; }; @@ -578,6 +546,7 @@ 617F5DFAAE97F48FA996A781 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableRectangle.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h"; sourceTree = "SOURCE_ROOT"; }; 61B0CBF705D5FC0431776286 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OpenGLShaderProgram.cpp"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp"; sourceTree = "SOURCE_ROOT"; }; 627956A7A1CB15251D02C8C5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedXLock.h"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_ScopedXLock.h"; sourceTree = "SOURCE_ROOT"; }; + 6397CF41ED94FBCD411C5E02 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TiledButtonGroupManager.h; path = ../../Source/UI/Utils/TiledButtonGroupManager.h; sourceTree = "SOURCE_ROOT"; }; 63AF6BE7FE2A9E7882743B4F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Network.mm"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_mac_Network.mm"; sourceTree = "SOURCE_ROOT"; }; 63F4150ABBA43B2215230034 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IIRFilter.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.h"; sourceTree = "SOURCE_ROOT"; }; 642325267C5F1AC2F65B647D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AnimatedPositionBehaviours.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h"; sourceTree = "SOURCE_ROOT"; }; @@ -611,6 +580,7 @@ 693E9C5C9A435F791921DAAE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioDeviceManager.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp"; sourceTree = "SOURCE_ROOT"; }; 696F2DC49934E6F01A2DF9FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileTreeComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; 698B0EC670DA47934444381B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Network.cpp"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_win32_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; + 699B3251715DE04674E0E0C4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = RecordThread.cpp; path = ../../Source/Processors/RecordNode/RecordThread.cpp; sourceTree = "SOURCE_ROOT"; }; 6A559D9595A54EF52BF0773A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Range.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Range.h"; sourceTree = "SOURCE_ROOT"; }; 6A63308EBE68478531604BA4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsList.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp"; sourceTree = "SOURCE_ROOT"; }; 6ABF91320A2EB6D307091AEE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_CameraDevice.mm"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_mac_CameraDevice.mm"; sourceTree = "SOURCE_ROOT"; }; @@ -637,6 +607,7 @@ 6E2F243D8F70CC92391204A4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MultiDocumentPanel.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h"; sourceTree = "SOURCE_ROOT"; }; 6EA1CC7DACDDBA863179521A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TemporaryFile.cpp"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_TemporaryFile.cpp"; sourceTree = "SOURCE_ROOT"; }; 6EF4EFD6D74D2573AC6B6A6F = {isa = PBXFileReference; lastKnownFileType = file; name = "juce_module_info"; path = "../../JuceLibraryCode/modules/juce_audio_devices/juce_module_info"; sourceTree = "SOURCE_ROOT"; }; + 6F201AA651C426427E515AF2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LinearButtonGroupManager.cpp; path = ../../Source/UI/Utils/LinearButtonGroupManager.cpp; sourceTree = "SOURCE_ROOT"; }; 6F9B89F7AD0E13887871D4FE = {isa = PBXFileReference; lastKnownFileType = image.png; name = SourceDrop.png; path = ../../Resources/Images/Icons/SourceDrop.png; sourceTree = "SOURCE_ROOT"; }; 6FE8B0DD6116E6A3456ECF09 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_UIViewComponent.mm"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm"; sourceTree = "SOURCE_ROOT"; }; 700597338DEC9AB65C4C8A5E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableText.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableText.h"; sourceTree = "SOURCE_ROOT"; }; @@ -647,6 +618,7 @@ 71CF8F6995DF1BA2038C21D6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AlertWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_AlertWindow.h"; sourceTree = "SOURCE_ROOT"; }; 7291F19253205B1A5138908E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DynamicObject.cpp"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.cpp"; sourceTree = "SOURCE_ROOT"; }; 72C33BA70B9EE82E39F1EC6C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MP3AudioFormat.h"; path = "../../JuceLibraryCode/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h"; sourceTree = "SOURCE_ROOT"; }; + 72D50E371901970C428D9E8B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LinearSmoothedValueAtomic.cpp; path = ../../Source/Processors/Dsp/LinearSmoothedValueAtomic.cpp; sourceTree = "SOURCE_ROOT"; }; 72FCE41894123FC5DB01566B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_win32.h"; path = "../../JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_win32.h"; sourceTree = "SOURCE_ROOT"; }; 7346D1276C3289FD68C8592B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileFilter.h"; path = "../../JuceLibraryCode/modules/juce_core/files/juce_FileFilter.h"; sourceTree = "SOURCE_ROOT"; }; 7387114E34496F4606550863 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HyperlinkButton.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -656,12 +628,14 @@ 74A81014471CC0EB0D5E6571 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ValueTree.cpp"; path = "../../JuceLibraryCode/modules/juce_data_structures/values/juce_ValueTree.cpp"; sourceTree = "SOURCE_ROOT"; }; 74BAC33D6BC1D961F04DCC72 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Channel.h; path = ../../Source/Processors/Channel/Channel.h; sourceTree = "SOURCE_ROOT"; }; 74DE857CEFA10BC49FF591DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Synthesiser.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h"; sourceTree = "SOURCE_ROOT"; }; + 74E31DA11A4C1244B78A077A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DataQueue.cpp; path = ../../Source/Processors/RecordNode/DataQueue.cpp; sourceTree = "SOURCE_ROOT"; }; 753B81CCB5A6B6929679E7B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Application.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/application/juce_Application.h"; sourceTree = "SOURCE_ROOT"; }; 7555A13E69B99B1B6C7295FD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InputStream.cpp"; path = "../../JuceLibraryCode/modules/juce_core/streams/juce_InputStream.cpp"; sourceTree = "SOURCE_ROOT"; }; 75A4EEE127FAB86D65FF5F6E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinatePositioner.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp"; sourceTree = "SOURCE_ROOT"; }; 75E0C433EC27CFB712CD9F75 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginListComponent.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/scanning/juce_PluginListComponent.h"; sourceTree = "SOURCE_ROOT"; }; 75FCE8908DD9055F90E93716 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableBorderComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; 76140C0485FDDA98C3D98E2A = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OldSchoolLookAndFeel.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/lookandfeel/juce_OldSchoolLookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; }; + 762A0D03A828BA95B3B9C209 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RecordThread.h; path = ../../Source/Processors/RecordNode/RecordThread.h; sourceTree = "SOURCE_ROOT"; }; 766923F74E30FF5D6B12E7CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableComposite.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableComposite.h"; sourceTree = "SOURCE_ROOT"; }; 76E89CBE70BF8F2476B7AA34 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SortedSet.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_SortedSet.h"; sourceTree = "SOURCE_ROOT"; }; 7719FB81DDF23CF0164B131D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BlowFish.h"; path = "../../JuceLibraryCode/modules/juce_cryptography/encryption/juce_BlowFish.h"; sourceTree = "SOURCE_ROOT"; }; @@ -780,6 +754,7 @@ 8F29CAC0059E3697A5A3652F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_URL.cpp"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_URL.cpp"; sourceTree = "SOURCE_ROOT"; }; 8F3C158B4FB92CFC48324896 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SelectedItemSet.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h"; sourceTree = "SOURCE_ROOT"; }; 8F7B13BF318C11900A2277DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlDocument.h"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.h"; sourceTree = "SOURCE_ROOT"; }; + 8FB4ED771FADEC613566CE7D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ButtonGroupManager.h; path = ../../Source/UI/Utils/ButtonGroupManager.h; sourceTree = "SOURCE_ROOT"; }; 901C720965646841A94EB099 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ActiveXControlComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h"; sourceTree = "SOURCE_ROOT"; }; 901DB6D5FE9134F2ADB9AE46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ChildProcess.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; 90607327D7A1BB3C2C4E9264 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Random.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_Random.h"; sourceTree = "SOURCE_ROOT"; }; @@ -854,6 +829,7 @@ 9F845E950F19FEC4E6C88F91 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Typeface.h"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_Typeface.h"; sourceTree = "SOURCE_ROOT"; }; 9FC97A1CFD250F7215B4E397 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AudioCDBurner.mm"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm"; sourceTree = "SOURCE_ROOT"; }; 9FDCF1E2B4651E58240400B9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextEditor.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TextEditor.h"; sourceTree = "SOURCE_ROOT"; }; + A010F4CC42989CB1E73A8A94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DataQueue.h; path = ../../Source/Processors/RecordNode/DataQueue.h; sourceTree = "SOURCE_ROOT"; }; A0434BD0EE742DF9089E2750 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RHD2000Editor.h; path = ../../Source/Processors/DataThreads/RhythmNode/RHD2000Editor.h; sourceTree = "SOURCE_ROOT"; }; A0D768F1B92568344DAC9F0B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Fonts.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_Fonts.cpp"; sourceTree = "SOURCE_ROOT"; }; A15596CDCC27B86FC070D7FA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Desktop.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Desktop.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -990,6 +966,7 @@ BD1D02C70CCE095217581A5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MessageManager.mm"; path = "../../JuceLibraryCode/modules/juce_events/native/juce_ios_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; BD59A961F87AB628777894DC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioThumbnailCache.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp"; sourceTree = "SOURCE_ROOT"; }; BD6FDA7B037CF3535431BFC8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SmoothedFilter.h; path = ../../Source/Processors/Dsp/SmoothedFilter.h; sourceTree = "SOURCE_ROOT"; }; + BDD36C3C308596F8CCCBF163 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MaterialSliderLookAndFeel.cpp; path = ../../Source/UI/LookAndFeel/MaterialSliderLookAndFeel.cpp; sourceTree = "SOURCE_ROOT"; }; BDFF189EC742274DD2629196 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectangleList.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_RectangleList.cpp"; sourceTree = "SOURCE_ROOT"; }; BE506F381B90833512348968 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FloatVectorOperations.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp"; sourceTree = "SOURCE_ROOT"; }; BEC4B69320BE492526794DFB = {isa = PBXFileReference; lastKnownFileType = image.png; name = wifi.png; path = ../../Resources/Images/Icons/wifi.png; sourceTree = "SOURCE_ROOT"; }; @@ -1013,6 +990,7 @@ C1B540E49C0EBA03ACDBBDFB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RBJ.h; path = ../../Source/Processors/Dsp/RBJ.h; sourceTree = "SOURCE_ROOT"; }; C1E1CCE5796B40E0A45FB021 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioThumbnail.h"; path = "../../JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnail.h"; sourceTree = "SOURCE_ROOT"; }; C209C7633D01E525231EE894 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlyphArrangement.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"; sourceTree = "SOURCE_ROOT"; }; + C25C0DDD703C77F4FDCE4DE6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = TiledButtonGroupManager.cpp; path = ../../Source/UI/Utils/TiledButtonGroupManager.cpp; sourceTree = "SOURCE_ROOT"; }; C2746A86EC16D3EA9FAC2C1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlElement.cpp"; path = "../../JuceLibraryCode/modules/juce_core/xml/juce_XmlElement.cpp"; sourceTree = "SOURCE_ROOT"; }; C29E664781AA2396C8D59543 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_events.mm"; path = "../../JuceLibraryCode/modules/juce_events/juce_events.mm"; sourceTree = "SOURCE_ROOT"; }; C2D1409D20E154E43569C725 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImagePreviewComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1033,6 +1011,7 @@ C679AE9BBB9B1EE3BAB09E11 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBasedDocument.h"; path = "../../JuceLibraryCode/modules/juce_gui_extra/documents/juce_FileBasedDocument.h"; sourceTree = "SOURCE_ROOT"; }; C67AA7952D9EF7E248118B85 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPool.cpp"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPool.cpp"; sourceTree = "SOURCE_ROOT"; }; C67C5EC0EE8DBC501C8AA395 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_NamedPipe.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_NamedPipe.h"; sourceTree = "SOURCE_ROOT"; }; + C6B404239BFB396294D92170 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LinearButtonGroupManager.h; path = ../../Source/UI/Utils/LinearButtonGroupManager.h; sourceTree = "SOURCE_ROOT"; }; C6BDC4DAD5B40321DA67462A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandTarget.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h"; sourceTree = "SOURCE_ROOT"; }; C6E19D3864B40A52BCC49315 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ModifierKeys.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h"; sourceTree = "SOURCE_ROOT"; }; C7359F50186E4017FE1724DA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PlaceholderProcessorEditor.h; path = ../../Source/Processors/PlaceholderProcessor/PlaceholderProcessorEditor.h; sourceTree = "SOURCE_ROOT"; }; @@ -1179,26 +1158,27 @@ E7ACE8C1456403A574236451 = {isa = PBXFileReference; lastKnownFileType = file; name = "cpmono-bold-serialized"; path = "../../Resources/Fonts/cpmono-bold-serialized"; sourceTree = "SOURCE_ROOT"; }; E7EE416EF527C7506B499070 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BigInteger.h"; path = "../../JuceLibraryCode/modules/juce_core/maths/juce_BigInteger.h"; sourceTree = "SOURCE_ROOT"; }; E835BEB3C42E4B241804BE13 = {isa = PBXFileReference; lastKnownFileType = file; name = "cpmono-light-serialized"; path = "../../Resources/Fonts/cpmono-light-serialized"; sourceTree = "SOURCE_ROOT"; }; - E8964C0BE264A55753BC6B7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; E8D51D470C9955D7D03D5469 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ChebyshevII.h; path = ../../Source/Processors/Dsp/ChebyshevII.h; sourceTree = "SOURCE_ROOT"; }; - E91923510CB2280C3A3B9E9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LocalisedStrings.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.h"; sourceTree = "SOURCE_ROOT"; }; E946426F95E0240683CB3337 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawablePath.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawablePath.h"; sourceTree = "SOURCE_ROOT"; }; - E97684DCE824DEDA6683C6CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Synthesiser.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp"; sourceTree = "SOURCE_ROOT"; }; - EA2FC92CECD1EDA1F07DC59C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h"; sourceTree = "SOURCE_ROOT"; }; - EA354D7D8E48D461415D52D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; - EA73332E3D5AEC04ADDFBB2A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDataConverters.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"; sourceTree = "SOURCE_ROOT"; }; EA9518CDEA7049C21D5CE2D5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Process.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_Process.h"; sourceTree = "SOURCE_ROOT"; }; - EAB2319C7AA57E06A2247CDF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; }; + EAB6A66678B122C578B16445 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; + EAC262A83CD2BEA14542AE89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPool.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPool.h"; sourceTree = "SOURCE_ROOT"; }; + EAEA49B9394D802B79CA8164 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; + EF3F9AA8D70E1D4D55F13182 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioThumbnail.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp"; sourceTree = "SOURCE_ROOT"; }; F5A00ACFA3D76168F22F1205 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 99E1BC08B886CFDD2CCFD462 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "open-ephys.app"; sourceTree = "BUILT_PRODUCTS_DIR"; }; E39CC410838072043E3C30DC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = OriginalRecording.cpp; path = ../../Source/Processors/RecordNode/OriginalRecording.cpp; sourceTree = "SOURCE_ROOT"; }; + E8964C0BE264A55753BC6B7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Midi.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp"; sourceTree = "SOURCE_ROOT"; }; + E91923510CB2280C3A3B9E9C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LocalisedStrings.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_LocalisedStrings.h"; sourceTree = "SOURCE_ROOT"; }; E91A272EF06892937CB4B9CE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentDragger.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp"; sourceTree = "SOURCE_ROOT"; }; E93BE115650B1CB80EACB841 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = EditorViewportButtons.h; path = ../../Source/UI/EditorViewportButtons.h; sourceTree = "SOURCE_ROOT"; }; + E97684DCE824DEDA6683C6CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Synthesiser.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp"; sourceTree = "SOURCE_ROOT"; }; + EA2FC92CECD1EDA1F07DC59C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipWindow.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h"; sourceTree = "SOURCE_ROOT"; }; + EA354D7D8E48D461415D52D8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; + EA73332E3D5AEC04ADDFBB2A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioDataConverters.h"; path = "../../JuceLibraryCode/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h"; sourceTree = "SOURCE_ROOT"; }; + EAB2319C7AA57E06A2247CDF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_BorderSize.h"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_BorderSize.h"; sourceTree = "SOURCE_ROOT"; }; EAB637B566FEBBDADA654262 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTMidiEventList.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h"; sourceTree = "SOURCE_ROOT"; }; - EAB6A66678B122C578B16445 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; - EAC262A83CD2BEA14542AE89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPool.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPool.h"; sourceTree = "SOURCE_ROOT"; }; EAC7A64301F0BF2C5E33A1F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_InterprocessConnectionServer.cpp"; path = "../../JuceLibraryCode/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp"; sourceTree = "SOURCE_ROOT"; }; - EAEA49B9394D802B79CA8164 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../JuceLibraryCode/modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; EB5F9A50EB53A57D6AE303C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_QuickTimeMovieComponent.mm"; path = "../../JuceLibraryCode/modules/juce_video/native/juce_mac_QuickTimeMovieComponent.mm"; sourceTree = "SOURCE_ROOT"; }; EBD8622EAEF10558809888B7 = {isa = PBXFileReference; lastKnownFileType = image.png; name = "RadioButtons_selected_over-01.png"; path = "../../Resources/Images/Icons/RadioButtons_selected_over-01.png"; sourceTree = "SOURCE_ROOT"; }; EC95A2CF4B33EA37DA5FC1AC = {isa = PBXFileReference; lastKnownFileType = file.ttf; name = nordic.ttf; path = ../../Resources/Fonts/nordic.ttf; sourceTree = "SOURCE_ROOT"; }; @@ -1215,7 +1195,6 @@ EEA51B7EF1CF19028C6672E0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DocumentWindow.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; EEFC66D2DF5FD66B4D83B22F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Component.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.h"; sourceTree = "SOURCE_ROOT"; }; EF059B26886B32000BCF8CFF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseInputSource.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/mouse/juce_MouseInputSource.h"; sourceTree = "SOURCE_ROOT"; }; - EF3F9AA8D70E1D4D55F13182 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AudioThumbnail.cpp"; path = "../../JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp"; sourceTree = "SOURCE_ROOT"; }; EF4A6E0E1232071252ACCD7B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeParallelogram.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h"; sourceTree = "SOURCE_ROOT"; }; EF610B2A17D9B1C0D24DCE67 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_android_JNIHelpers.h"; path = "../../JuceLibraryCode/modules/juce_core/native/juce_android_JNIHelpers.h"; sourceTree = "SOURCE_ROOT"; }; EF7B66764093D950724EFE70 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLShaderProgram.h"; path = "../../JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.h"; sourceTree = "SOURCE_ROOT"; }; @@ -1282,6 +1261,9 @@ FF3E5A9F8B9250790C6DA089 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_URL.h"; path = "../../JuceLibraryCode/modules/juce_core/network/juce_URL.h"; sourceTree = "SOURCE_ROOT"; }; FFBB9CE85A7C91FB11E4AEC8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; FFFBDB9A00240D797751FEE6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DataWindow.h; path = ../../Source/Processors/Visualization/DataWindow.h; sourceTree = "SOURCE_ROOT"; }; + 96FE247BE1A4EDB506200392 = {isa = PBXGroup; children = ( + 247E9C92B402D44790933486, + 2635ADCB645C983D2F64F621, ); name = Icons; sourceTree = "<group>"; }; 9ADE9FD3E8A58C12B4B2D8B2 = {isa = PBXGroup; children = ( B081687E52C6A5157CFCCB17, E7ACE8C1456403A574236451, @@ -1353,6 +1335,7 @@ 048B10371EA2D5C7D883CC70, 5B916D6239703986EFCDB624, ); name = Images; sourceTree = "<group>"; }; B9646290EA6B6995F8AEEAFB = {isa = PBXGroup; children = ( + 96FE247BE1A4EDB506200392, 9ADE9FD3E8A58C12B4B2D8B2, 78AACAE5A74DDE52FE5848AF, ); name = Resources; sourceTree = "<group>"; }; B016FBDF648372A23D7EAAD8 = {isa = PBXGroup; children = ( @@ -1367,6 +1350,8 @@ 9AD7314174B2AB01FBF7E1E1, E46FFF196BAA78472FF1C0B4, ); name = PlaceholderProcessor; sourceTree = "<group>"; }; F74BE11F6446ACF243895BFF = {isa = PBXGroup; children = ( + 72D50E371901970C428D9E8B, + 148FE750B55B2F7EA3899408, 041038F6E67FE0409D8ECC74, AAF5C27D2EEDD254A3652717, CB5C14E82DE06F767EAD62F9, @@ -1489,6 +1474,11 @@ 4CB63EE1552BBFDEB1DADB0A, B695B24906116ADEFC9D9B5C, ); name = ProcessorGraph; sourceTree = "<group>"; }; 0E7092A11A3C96E5ECA71CDA = {isa = PBXGroup; children = ( + 74E31DA11A4C1244B78A077A, + A010F4CC42989CB1E73A8A94, + 066A1CD777247BC8142A7DAA, + 699B3251715DE04674E0E0C4, + 762A0D03A828BA95B3B9C209, 7DB22AC6407EEA88F3FFA16D, 398BF0B03B719107E6093F98, E39CC410838072043E3C30DC, @@ -1536,7 +1526,23 @@ CB7739DB9922F30C029B2A02, E2624A71F15AE5C96B34505B, C4B85C0286AC2510730355E3, ); name = Processors; sourceTree = "<group>"; }; + 9FD23BB71495B921F7AC315C = {isa = PBXGroup; children = ( + C25C0DDD703C77F4FDCE4DE6, + 6397CF41ED94FBCD411C5E02, + 6F201AA651C426427E515AF2, + C6B404239BFB396294D92170, + 0BD711FD3C982C60B294F311, + 8FB4ED771FADEC613566CE7D, ); name = Utils; sourceTree = "<group>"; }; + 25D496F2BBBF4F8E2BC09479 = {isa = PBXGroup; children = ( + 3A3EFEB7D30A6E75D5A1D1B1, + 18A11ED5F07AA76D8253A66A, + BDD36C3C308596F8CCCBF163, + 1C386A08A3C69F4D05595122, + 1901A338916E925CC2E03E42, + 36BE4BA79883C88072EE385B, ); name = LookAndFeel; sourceTree = "<group>"; }; 1D78FCCF430CD91FD1DBD95B = {isa = PBXGroup; children = ( + 9FD23BB71495B921F7AC315C, + 25D496F2BBBF4F8E2BC09479, F960CC94B136201BDA148EEA, C59B01C8DB5B3B4773032E12, E5C1D021C0FD6FAD082C5D75, @@ -1549,8 +1555,6 @@ 57FBA8BC3104D3AF41FBECD8, 79C91DDF3BC3F15D0338E504, 105B1452DF6CE1D80D69A9D1, - 3774BBCA6CB133D9A854CF71, - 19148DBA36B94FA639DF3A72, 17E13CCDA0C82F92EAB05BE6, D2696B30CBEAD7CE72510AFA, 47A3942AC30A3212C01F1CAF, @@ -2647,6 +2651,7 @@ 469F0AB7234589951A8F29FA = {isa = PBXGroup; children = ( 46EF49B14DF7357A8287D9D8, BBE1DB78E35135B41537DCB5, + 0618303B4E1BF577974A03FE, 61317B5191E05925F232E18C, ); name = Resources; sourceTree = "<group>"; }; 008433D940C09C1A15B916BA = {isa = PBXGroup; children = ( 39F287BE4C0B4F3BD4A949FD, @@ -2690,7 +2695,7 @@ INSTALL_PATH = "$(HOME)/Applications"; LIBRARY_SEARCH_PATHS = ("$(inherited)", "\"/opt/local/lib\"", "\"/usr/local/lib\""); MACOSX_DEPLOYMENT_TARGET_ppc = 10.4; - OTHER_CPLUSPLUSFLAGS = "-fPIC"; + OTHER_CPLUSPLUSFLAGS = "-fPIC -Wno-inconsistent-missing-override"; OTHER_LDFLAGS = "-ldl -fPIC -rdynamic"; SDKROOT_ppc = macosx10.5; }; name = Debug; }; 7A6F9B742B69F66DC3E29FA8 = {isa = XCBuildConfiguration; buildSettings = { @@ -2714,7 +2719,7 @@ INSTALL_PATH = "$(HOME)/Applications"; LIBRARY_SEARCH_PATHS = ("$(inherited)", "\"/opt/local/lib\"", "\"/usr/local/lib\""); MACOSX_DEPLOYMENT_TARGET_ppc = 10.4; - OTHER_CPLUSPLUSFLAGS = "-fPIC"; + OTHER_CPLUSPLUSFLAGS = "-fPIC -Wno-inconsistent-missing-override"; OTHER_LDFLAGS = "-ldl -fPIC -rdynamic"; SDKROOT_ppc = macosx10.5; }; name = Release; }; C8018C9A4DA633CA60663294 = {isa = XCBuildConfiguration; buildSettings = { @@ -2756,18 +2761,16 @@ 7A6F9B742B69F66DC3E29FA8, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; 256EEB2E7946EFA9B0774D25 = {isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 2D2BDB63CBD0BED07FF9E44B, + 7E68BE958652C77EF1E93AC1, 4FA2949D3023FC2E377AFFB6, ); runOnlyForDeploymentPostprocessing = 0; }; 0C1B429379FBBA77A635B49A = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( CFBB591627F730A6C98ECA25, - F08929D23989E83088DD8914, 14BDAEA656AAFA60334CC55C, - 0ADE6EC5E6FCAC79C9EDA534, C853FCE2F6C91B3643322CF0, - 02AAF08AB7A31598784F5EAF, 0AE243437B40602D35435C32, - 425B09B8D50623B880FD03D6, B04B9CA1E59D544793808F25, 28B77947820CAE30A5E2DE22, + CB568964BDF3E65207B81CCA, 9252537C12447F047243DEE9, B081F3F4FA6D8C35E2EEE778, 7398C5E00B9093F78C697706, @@ -2789,13 +2792,9 @@ AE80C3A6186F3A4D537489A0, FDC3F3F6332D07F15FED8EA1, 07A712AC1BFF4BBB74914575, - D761F014D76825DEFE0A7582, 8352817FEDC7542D3E65B49A, - 5D49C3544A04DDC85CAB84FA, 44DB81313BDDF1ECB6AD33FE, - 7598258C53F4559D2A4CD163, C45009DBCD71E9E234BFCE97, - DE86EB9584E75F21AA2D1404, 11375775EC137CE30502F397, 763159B0A13FA88D3DCCAA4B, 5885BE052A89E9971DEA4197, @@ -2803,89 +2802,54 @@ 138A4742F7B3F263D5ABF0F9, 203844FDF36CFE38A7DAABE7, FAE745870674A07A65690433, - 58C57FE9863EA52A46672FD9, 24CC7E9A7E87F762D4AB0467, - 1621D0850A6D6773B7F4853B, 52AE3F7AEED81BA9ED5C4830, - 50C545252FEF7B6F9D82092D, 029C3B11BE586DA100895A60, - 547264A139B1D525A86114DF, 6702EEA4E99D503C0EE933C4, - B3DDA21DDD467F64AF8556B0, 7F188166D38DA7FB23311413, - 3135B9FED0BF40A73C5EFE84, AA16BE5A6BBD024C8FCFCDA8, - 46511E0CF49A1F753F2EC949, 4976529FC367F5F6A0D04370, - 3F6A34906F13DE5E65F9F785, 68EBB4CEB08BD3DEAC450B95, - 53942219C91A015CCEF6F751, 24800AF87AD21CE652552EDE, - 7D393CD459AD73307B4B26A2, B49852F77C0C392C159A1914, - F1CFB5BF336DF4A46A570280, 6D00BABD3FE1AA0EAA267C1C, - 6B56E0463FF3D580F0C84407, AD371C6F383F03EF392B6581, - 4DF3A59A371DE10E4FFFF642, 4EF2825142BBAA76FD55FE26, - CDB3C038ABFCB6A8EAA27D79, 3B05807D08271664EEC4977C, - 27A764088D184F9898FC8B4F, F2586A2DCEF44961AEA247E8, - 9354508D753345076D5C79E6, 3E7939ABAA984EE8BFC8CEDD, - CD6ACBFB0637B64B9CA1A91F, BAC379C03C2E7995F2393EF5, - 326F93591218D713F4230961, + 0326A368BA8F70C74A8A12A7, + F7E069E1FC1BB7EF856AA083, E1247DDF1C88D99691499E52, - 960C8D7486F047112BD4468B, 0A8D8C2D02858F0F08356EA9, - D4995270E6CB321A9F344EB1, AEDA8F23648EABF79215B566, - D909F61CF9323366A2143DB2, B806F023DF817BB2D59FEEFD, - 1419982AA3FEFD48742EC391, 7B69E73AF79BB2B10BAA559C, - 30D2FF80A059C4F2F2641452, 74A14124A3B0C5FB13583B57, - BABD91F2DC4EDF91E155CC42, 4910924155F31E96B9BAD050, - FE0BEC4F57D0EA019EF6D24A, 66DE280C28A69B2002C40A86, - B1CFD7C1DD7724CD38FA1FEC, 5BF488044E143A2727CE2BDB, 1B620FC17AAECA4C5DE741E2, - E4DFAFCE9800EE2C9F8A8AAF, 19BB86C918F89D1377F8A0E1, - 284D8B7D3CDE3742B3468855, - AE270975F90CC92C27F80B05, 89223664B6CB2A912E36B091, - 39914728A9B138EB9A04CF34, + 97B42624998C8E4E2A5C9BA7, + EE60D8FC7DCEC9C9AE545F4D, + 43BDE8C7A1D17FC0CD2EF00D, + 5A43E4E1547CBD9C2A635AEE, + 8C78E9A851776185755D708E, + FCB05BDFCBD2EFD9DF49D5AC, BA608CEFC85F7AB9E30E0EB3, - 8EB38EF63AACA70DFEC4CF94, D499273B65D901D0A101CAAA, - 14133143519D06FC6F4C88C6, 95AE939ADE096394CCD2526F, - 6DC53D380636F5A30B52BAC8, E85DA5FC9A162F129ABA7113, - B37D32878D75EDCD4400826A, 6A13D8F42A330E2C410B43E3, - 736608BBA6321E460BDBBBC8, 13F1111511DD01E843E631CA, - D4EC5BCFAB683EA0A4473AA6, - 9A80E3D1D1758A31D2169497, - 715C8221533FB1B9DD03F721, F4397EAE00E0B9F96C8B6C07, - 12088E12BCA721D0832B39FD, 09673DA3B4D6EA61DEFC0C46, - 968E9B7C2E1974474E51F26E, 58D3FF3B1F462634167BDFB5, - 6DA67142BD5D41B90A19121B, 3162B66BC8118715AAA527D7, - 4300909A1BAF9464663A9CF3, 004E78BC139419671A9EA137, - 63181788D187F9A15BBE03D9, 6306AA945375749C4FE834E6, AD7D05519200FB0EE1C7617A, C2475E008FEB33B3EA7B6C7F, @@ -2915,10 +2879,12 @@ CAB9D9DEF279F93132B45F90, CA4DCF67B48352BE633A616D, 512D7D16D0A95BDD0D6D6E45, ); runOnlyForDeploymentPostprocessing = 0; }; + 51D24AA2F6AD5542880D67DB = {isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; name = "Post-build script"; shellPath = /bin/sh; shellScript = "# Copy Rhythm-related files to application bundle's Resources folder\nsrcdir=\"${PROJECT_DIR}/../../Resources\"\ndstdir=\"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}\"\n/usr/bin/rsync -a \"$srcdir/Bitfiles/rhd2000.bit\" \"$srcdir/Bitfiles/rhd2000_usb3.bit\" \"$srcdir/DLLs/libokFrontPanel.dylib\" \"$dstdir\""; }; 609761DEC9151D2CDD50270C = {isa = PBXNativeTarget; buildConfigurationList = B0259CB1FA28CEC89ED4FA14; buildPhases = ( 256EEB2E7946EFA9B0774D25, 0C1B429379FBBA77A635B49A, - 7BE915E5A64C787EBF13A8E7, ); buildRules = ( ); dependencies = ( ); name = "open-ephys"; productName = "open-ephys"; productReference = 99E1BC08B886CFDD2CCFD462; productInstallPath = "$(HOME)/Applications"; productType = "com.apple.product-type.application"; }; + 7BE915E5A64C787EBF13A8E7, + 51D24AA2F6AD5542880D67DB, ); buildRules = ( ); dependencies = ( ); name = "open-ephys"; productName = "open-ephys"; productReference = 99E1BC08B886CFDD2CCFD462; productInstallPath = "$(HOME)/Applications"; productType = "com.apple.product-type.application"; }; 41375E3272D6505F75FDEEEB = {isa = PBXProject; buildConfigurationList = 3B096175C0B17BFA58475A08; attributes = { LastUpgradeCheck = 0440; }; compatibilityVersion = "Xcode 3.2"; hasScannedForEncodings = 0; mainGroup = A7589AF92E6E958E1F866761; projectDirPath = ""; projectRoot = ""; targets = ( 609761DEC9151D2CDD50270C ); }; }; rootObject = 41375E3272D6505F75FDEEEB; diff --git a/Builds/VisualStudio2012/icon.ico b/Builds/VisualStudio2012/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f821f998fe7af528dcb37f888876f70a09620f5b Binary files /dev/null and b/Builds/VisualStudio2012/icon.ico differ diff --git a/Builds/VisualStudio2012/open-ephys.vcxproj b/Builds/VisualStudio2012/open-ephys.vcxproj index 6cce270234c3c89cd2f1b978bad4dfcd40b282d6..0c0301996c320dbea3b6c93fc7714c1c3f8c7a4e 100644 --- a/Builds/VisualStudio2012/open-ephys.vcxproj +++ b/Builds/VisualStudio2012/open-ephys.vcxproj @@ -261,6 +261,7 @@ <ClCompile Include="..\..\Source\Audio\AudioComponent.cpp"/> <ClCompile Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessorEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessor.cpp"/> + <ClCompile Include="..\..\Source\Processors\Dsp\LinearSmoothedValueAtomic.cpp"/> <ClCompile Include="..\..\Source\Processors\Dsp\Bessel.cpp"/> <ClCompile Include="..\..\Source\Processors\Dsp\Biquad.cpp"/> <ClCompile Include="..\..\Source\Processors\Dsp\Butterworth.cpp"/> @@ -309,6 +310,8 @@ <ClCompile Include="..\..\Source\Processors\Parameter\ParameterEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\Parameter\Parameter.cpp"/> <ClCompile Include="..\..\Source\Processors\ProcessorGraph\ProcessorGraph.cpp"/> + <ClCompile Include="..\..\Source\Processors\RecordNode\DataQueue.cpp"/> + <ClCompile Include="..\..\Source\Processors\RecordNode\RecordThread.cpp"/> <ClCompile Include="..\..\Source\Processors\RecordNode\EngineConfigWindow.cpp"/> <ClCompile Include="..\..\Source\Processors\RecordNode\OriginalRecording.cpp"/> <ClCompile Include="..\..\Source\Processors\RecordNode\RecordEngine.cpp"/> @@ -321,13 +324,18 @@ <ClCompile Include="..\..\Source\Processors\Visualization\DataWindow.cpp"/> <ClCompile Include="..\..\Source\Processors\Visualization\SpikeObject.cpp"/> <ClCompile Include="..\..\Source\Processors\Visualization\MatlabLikePlot.cpp"/> + <ClCompile Include="..\..\Source\UI\Utils\TiledButtonGroupManager.cpp"/> + <ClCompile Include="..\..\Source\UI\Utils\LinearButtonGroupManager.cpp"/> + <ClCompile Include="..\..\Source\UI\Utils\ButtonGroupManager.cpp"/> + <ClCompile Include="..\..\Source\UI\LookAndFeel\MaterialButtonLookAndFeel.cpp"/> + <ClCompile Include="..\..\Source\UI\LookAndFeel\MaterialSliderLookAndFeel.cpp"/> + <ClCompile Include="..\..\Source\UI\LookAndFeel\CustomLookAndFeel.cpp"/> <ClCompile Include="..\..\Source\UI\CustomArrowButton.cpp"/> <ClCompile Include="..\..\Source\UI\GraphViewer.cpp"/> <ClCompile Include="..\..\Source\UI\EditorViewportButtons.cpp"/> <ClCompile Include="..\..\Source\UI\SignalChainManager.cpp"/> <ClCompile Include="..\..\Source\UI\EditorViewport.cpp"/> <ClCompile Include="..\..\Source\UI\ProcessorList.cpp"/> - <ClCompile Include="..\..\Source\UI\CustomLookAndFeel.cpp"/> <ClCompile Include="..\..\Source\UI\InfoLabel.cpp"/> <ClCompile Include="..\..\Source\UI\DataViewport.cpp"/> <ClCompile Include="..\..\Source\UI\ControlPanel.cpp"/> @@ -1464,6 +1472,7 @@ <ClInclude Include="..\..\Source\Audio\AudioComponent.h"/> <ClInclude Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessorEditor.h"/> <ClInclude Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessor.h"/> + <ClInclude Include="..\..\Source\Processors\Dsp\LinearSmoothedValueAtomic.h"/> <ClInclude Include="..\..\Source\Processors\Dsp\Bessel.h"/> <ClInclude Include="..\..\Source\Processors\Dsp\Biquad.h"/> <ClInclude Include="..\..\Source\Processors\Dsp\Butterworth.h"/> @@ -1520,6 +1529,9 @@ <ClInclude Include="..\..\Source\Processors\Parameter\ParameterEditor.h"/> <ClInclude Include="..\..\Source\Processors\Parameter\Parameter.h"/> <ClInclude Include="..\..\Source\Processors\ProcessorGraph\ProcessorGraph.h"/> + <ClInclude Include="..\..\Source\Processors\RecordNode\DataQueue.h"/> + <ClInclude Include="..\..\Source\Processors\RecordNode\EventQueue.h"/> + <ClInclude Include="..\..\Source\Processors\RecordNode\RecordThread.h"/> <ClInclude Include="..\..\Source\Processors\RecordNode\EngineConfigWindow.h"/> <ClInclude Include="..\..\Source\Processors\RecordNode\OriginalRecording.h"/> <ClInclude Include="..\..\Source\Processors\RecordNode\RecordEngine.h"/> @@ -1532,13 +1544,18 @@ <ClInclude Include="..\..\Source\Processors\Visualization\SpikeObject.h"/> <ClInclude Include="..\..\Source\Processors\Visualization\Visualizer.h"/> <ClInclude Include="..\..\Source\Processors\Visualization\MatlabLikePlot.h"/> + <ClInclude Include="..\..\Source\UI\Utils\TiledButtonGroupManager.h"/> + <ClInclude Include="..\..\Source\UI\Utils\LinearButtonGroupManager.h"/> + <ClInclude Include="..\..\Source\UI\Utils\ButtonGroupManager.h"/> + <ClInclude Include="..\..\Source\UI\LookAndFeel\MaterialButtonLookAndFeel.h"/> + <ClInclude Include="..\..\Source\UI\LookAndFeel\MaterialSliderLookAndFeel.h"/> + <ClInclude Include="..\..\Source\UI\LookAndFeel\CustomLookAndFeel.h"/> <ClInclude Include="..\..\Source\UI\CustomArrowButton.h"/> <ClInclude Include="..\..\Source\UI\GraphViewer.h"/> <ClInclude Include="..\..\Source\UI\EditorViewportButtons.h"/> <ClInclude Include="..\..\Source\UI\SignalChainManager.h"/> <ClInclude Include="..\..\Source\UI\EditorViewport.h"/> <ClInclude Include="..\..\Source\UI\ProcessorList.h"/> - <ClInclude Include="..\..\Source\UI\CustomLookAndFeel.h"/> <ClInclude Include="..\..\Source\UI\InfoLabel.h"/> <ClInclude Include="..\..\Source\UI\DataViewport.h"/> <ClInclude Include="..\..\Source\UI\ControlPanel.h"/> @@ -1997,6 +2014,8 @@ <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> + <None Include="..\..\Resources\Icons\icon-large.png"/> + <None Include="..\..\Resources\Icons\icon-small.png"/> <None Include="..\..\Resources\Fonts\cpmono-black-serialized"/> <None Include="..\..\Resources\Fonts\cpmono-bold-serialized"/> <None Include="..\..\Resources\Fonts\cpmono-extralight-serialized"/> @@ -2075,6 +2094,7 @@ <None Include="..\..\JuceLibraryCode\modules\juce_gui_extra\juce_module_info"/> <None Include="..\..\JuceLibraryCode\modules\juce_opengl\juce_module_info"/> <None Include="..\..\JuceLibraryCode\modules\juce_video\juce_module_info"/> + <None Include=".\icon.ico"/> </ItemGroup> <ItemGroup> <ResourceCompile Include=".\resources.rc"/> diff --git a/Builds/VisualStudio2012/open-ephys.vcxproj.filters b/Builds/VisualStudio2012/open-ephys.vcxproj.filters index e261194e312d2db8e43e16e7ea214d7ac7d03de7..426497b4220dc8a3017291cc97f20dbd61b82d8b 100644 --- a/Builds/VisualStudio2012/open-ephys.vcxproj.filters +++ b/Builds/VisualStudio2012/open-ephys.vcxproj.filters @@ -8,6 +8,9 @@ <Filter Include="open-ephys\Resources"> <UniqueIdentifier>{4FB3688D-1CC4-C459-F92E-F1764A198374}</UniqueIdentifier> </Filter> + <Filter Include="open-ephys\Resources\Icons"> + <UniqueIdentifier>{675098C0-65B1-49FA-E68F-4DFD81A91FE3}</UniqueIdentifier> + </Filter> <Filter Include="open-ephys\Resources\Fonts"> <UniqueIdentifier>{1DC91498-AFB8-F53B-37B4-DA354ACC7637}</UniqueIdentifier> </Filter> @@ -98,6 +101,12 @@ <Filter Include="open-ephys\Source\UI"> <UniqueIdentifier>{717A0FE3-E079-E4BD-8F50-15A1953825C5}</UniqueIdentifier> </Filter> + <Filter Include="open-ephys\Source\UI\Utils"> + <UniqueIdentifier>{DC42A3E4-435B-C857-DF58-C5BB3E866E6B}</UniqueIdentifier> + </Filter> + <Filter Include="open-ephys\Source\UI\LookAndFeel"> + <UniqueIdentifier>{82473DF0-9747-E952-2C6D-DAC4DD6B3807}</UniqueIdentifier> + </Filter> <Filter Include="Juce Modules"> <UniqueIdentifier>{422C46B7-0467-2DB0-BF3C-16DFCAFD69AC}</UniqueIdentifier> </Filter> @@ -415,6 +424,9 @@ <ClCompile Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessor.cpp"> <Filter>open-ephys\Source\Processors\PlaceholderProcessor</Filter> </ClCompile> + <ClCompile Include="..\..\Source\Processors\Dsp\LinearSmoothedValueAtomic.cpp"> + <Filter>open-ephys\Source\Processors\Dsp</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Processors\Dsp\Bessel.cpp"> <Filter>open-ephys\Source\Processors\Dsp</Filter> </ClCompile> @@ -559,6 +571,12 @@ <ClCompile Include="..\..\Source\Processors\ProcessorGraph\ProcessorGraph.cpp"> <Filter>open-ephys\Source\Processors\ProcessorGraph</Filter> </ClCompile> + <ClCompile Include="..\..\Source\Processors\RecordNode\DataQueue.cpp"> + <Filter>open-ephys\Source\Processors\RecordNode</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\Processors\RecordNode\RecordThread.cpp"> + <Filter>open-ephys\Source\Processors\RecordNode</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Processors\RecordNode\EngineConfigWindow.cpp"> <Filter>open-ephys\Source\Processors\RecordNode</Filter> </ClCompile> @@ -595,6 +613,24 @@ <ClCompile Include="..\..\Source\Processors\Visualization\MatlabLikePlot.cpp"> <Filter>open-ephys\Source\Processors\Visualization</Filter> </ClCompile> + <ClCompile Include="..\..\Source\UI\Utils\TiledButtonGroupManager.cpp"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\UI\Utils\LinearButtonGroupManager.cpp"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\UI\Utils\ButtonGroupManager.cpp"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\UI\LookAndFeel\MaterialButtonLookAndFeel.cpp"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\UI\LookAndFeel\MaterialSliderLookAndFeel.cpp"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\UI\LookAndFeel\CustomLookAndFeel.cpp"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClCompile> <ClCompile Include="..\..\Source\UI\CustomArrowButton.cpp"> <Filter>open-ephys\Source\UI</Filter> </ClCompile> @@ -613,9 +649,6 @@ <ClCompile Include="..\..\Source\UI\ProcessorList.cpp"> <Filter>open-ephys\Source\UI</Filter> </ClCompile> - <ClCompile Include="..\..\Source\UI\CustomLookAndFeel.cpp"> - <Filter>open-ephys\Source\UI</Filter> - </ClCompile> <ClCompile Include="..\..\Source\UI\InfoLabel.cpp"> <Filter>open-ephys\Source\UI</Filter> </ClCompile> @@ -1881,6 +1914,9 @@ <ClInclude Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessor.h"> <Filter>open-ephys\Source\Processors\PlaceholderProcessor</Filter> </ClInclude> + <ClInclude Include="..\..\Source\Processors\Dsp\LinearSmoothedValueAtomic.h"> + <Filter>open-ephys\Source\Processors\Dsp</Filter> + </ClInclude> <ClInclude Include="..\..\Source\Processors\Dsp\Bessel.h"> <Filter>open-ephys\Source\Processors\Dsp</Filter> </ClInclude> @@ -2049,6 +2085,15 @@ <ClInclude Include="..\..\Source\Processors\ProcessorGraph\ProcessorGraph.h"> <Filter>open-ephys\Source\Processors\ProcessorGraph</Filter> </ClInclude> + <ClInclude Include="..\..\Source\Processors\RecordNode\DataQueue.h"> + <Filter>open-ephys\Source\Processors\RecordNode</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Processors\RecordNode\EventQueue.h"> + <Filter>open-ephys\Source\Processors\RecordNode</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Processors\RecordNode\RecordThread.h"> + <Filter>open-ephys\Source\Processors\RecordNode</Filter> + </ClInclude> <ClInclude Include="..\..\Source\Processors\RecordNode\EngineConfigWindow.h"> <Filter>open-ephys\Source\Processors\RecordNode</Filter> </ClInclude> @@ -2085,6 +2130,24 @@ <ClInclude Include="..\..\Source\Processors\Visualization\MatlabLikePlot.h"> <Filter>open-ephys\Source\Processors\Visualization</Filter> </ClInclude> + <ClInclude Include="..\..\Source\UI\Utils\TiledButtonGroupManager.h"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\UI\Utils\LinearButtonGroupManager.h"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\UI\Utils\ButtonGroupManager.h"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\UI\LookAndFeel\MaterialButtonLookAndFeel.h"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\UI\LookAndFeel\MaterialSliderLookAndFeel.h"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\UI\LookAndFeel\CustomLookAndFeel.h"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClInclude> <ClInclude Include="..\..\Source\UI\CustomArrowButton.h"> <Filter>open-ephys\Source\UI</Filter> </ClInclude> @@ -2103,9 +2166,6 @@ <ClInclude Include="..\..\Source\UI\ProcessorList.h"> <Filter>open-ephys\Source\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\UI\CustomLookAndFeel.h"> - <Filter>open-ephys\Source\UI</Filter> - </ClInclude> <ClInclude Include="..\..\Source\UI\InfoLabel.h"> <Filter>open-ephys\Source\UI</Filter> </ClInclude> @@ -3476,6 +3536,12 @@ </ClInclude> </ItemGroup> <ItemGroup> + <None Include="..\..\Resources\Icons\icon-large.png"> + <Filter>open-ephys\Resources\Icons</Filter> + </None> + <None Include="..\..\Resources\Icons\icon-small.png"> + <Filter>open-ephys\Resources\Icons</Filter> + </None> <None Include="..\..\Resources\Fonts\cpmono-black-serialized"> <Filter>open-ephys\Resources\Fonts</Filter> </None> @@ -3710,6 +3776,9 @@ <None Include="..\..\JuceLibraryCode\modules\juce_video\juce_module_info"> <Filter>Juce Modules\juce_video</Filter> </None> + <None Include=".\icon.ico"> + <Filter>Juce Library Code</Filter> + </None> </ItemGroup> <ItemGroup> <ResourceCompile Include=".\resources.rc"> diff --git a/Builds/VisualStudio2012/resources.rc b/Builds/VisualStudio2012/resources.rc index 04df04cba4b9a59076d5287cb6cc17c97c0b1fb3..a77c83e23842ab4580010a3d22d9fee8c6c42312 100644 --- a/Builds/VisualStudio2012/resources.rc +++ b/Builds/VisualStudio2012/resources.rc @@ -28,3 +28,6 @@ BEGIN END #endif + +IDI_ICON1 ICON DISCARDABLE "icon.ico" +IDI_ICON2 ICON DISCARDABLE "icon.ico" \ No newline at end of file diff --git a/Builds/VisualStudio2013/Plugins/CommonAvgRef/CommonAvgRef.vcxproj b/Builds/VisualStudio2013/Plugins/CommonAvgRef/CommonAvgRef.vcxproj index 0dc471bdd4b2c040071c98e879db4666e2cd6dba..73233fcdfb2685739776c57d861e24b391612286 100644 --- a/Builds/VisualStudio2013/Plugins/CommonAvgRef/CommonAvgRef.vcxproj +++ b/Builds/VisualStudio2013/Plugins/CommonAvgRef/CommonAvgRef.vcxproj @@ -120,10 +120,12 @@ </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="..\..\..\..\Source\Plugins\CAR\CAR.cpp" /> + <ClCompile Include="..\..\..\..\Source\Plugins\CAR\CAREditor.cpp" /> <ClCompile Include="..\..\..\..\Source\Plugins\CAR\OpenEphysLib.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\..\Source\Plugins\CAR\CAR.h" /> + <ClInclude Include="..\..\..\..\Source\Plugins\CAR\CAREditor.h" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/Builds/VisualStudio2013/Plugins/CommonAvgRef/CommonAvgRef.vcxproj.filters b/Builds/VisualStudio2013/Plugins/CommonAvgRef/CommonAvgRef.vcxproj.filters index 8756cde51d292f27fa1b3f7370eb77ef5a8e974f..2648902678062385cf0e1ceac00372a17ab25761 100644 --- a/Builds/VisualStudio2013/Plugins/CommonAvgRef/CommonAvgRef.vcxproj.filters +++ b/Builds/VisualStudio2013/Plugins/CommonAvgRef/CommonAvgRef.vcxproj.filters @@ -21,10 +21,16 @@ <ClCompile Include="..\..\..\..\Source\Plugins\CAR\OpenEphysLib.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\Source\Plugins\CAR\CAREditor.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\..\Source\Plugins\CAR\CAR.h"> <Filter>Source Files</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\Source\Plugins\CAR\CAREditor.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> </Project> \ No newline at end of file diff --git a/Builds/VisualStudio2013/icon.ico b/Builds/VisualStudio2013/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f821f998fe7af528dcb37f888876f70a09620f5b Binary files /dev/null and b/Builds/VisualStudio2013/icon.ico differ diff --git a/Builds/VisualStudio2013/open-ephys.vcxproj b/Builds/VisualStudio2013/open-ephys.vcxproj index 818d8d61995d78e0290233719f3d273984299487..9f63c1204dbeb10b41b1d9e00f6323bd93882e75 100644 --- a/Builds/VisualStudio2013/open-ephys.vcxproj +++ b/Builds/VisualStudio2013/open-ephys.vcxproj @@ -265,6 +265,7 @@ <ClCompile Include="..\..\Source\Audio\AudioComponent.cpp"/> <ClCompile Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessorEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessor.cpp"/> + <ClCompile Include="..\..\Source\Processors\Dsp\LinearSmoothedValueAtomic.cpp"/> <ClCompile Include="..\..\Source\Processors\Dsp\Bessel.cpp"/> <ClCompile Include="..\..\Source\Processors\Dsp\Biquad.cpp"/> <ClCompile Include="..\..\Source\Processors\Dsp\Butterworth.cpp"/> @@ -313,6 +314,8 @@ <ClCompile Include="..\..\Source\Processors\Parameter\ParameterEditor.cpp"/> <ClCompile Include="..\..\Source\Processors\Parameter\Parameter.cpp"/> <ClCompile Include="..\..\Source\Processors\ProcessorGraph\ProcessorGraph.cpp"/> + <ClCompile Include="..\..\Source\Processors\RecordNode\DataQueue.cpp"/> + <ClCompile Include="..\..\Source\Processors\RecordNode\RecordThread.cpp"/> <ClCompile Include="..\..\Source\Processors\RecordNode\EngineConfigWindow.cpp"/> <ClCompile Include="..\..\Source\Processors\RecordNode\OriginalRecording.cpp"/> <ClCompile Include="..\..\Source\Processors\RecordNode\RecordEngine.cpp"/> @@ -325,13 +328,18 @@ <ClCompile Include="..\..\Source\Processors\Visualization\DataWindow.cpp"/> <ClCompile Include="..\..\Source\Processors\Visualization\SpikeObject.cpp"/> <ClCompile Include="..\..\Source\Processors\Visualization\MatlabLikePlot.cpp"/> + <ClCompile Include="..\..\Source\UI\Utils\TiledButtonGroupManager.cpp"/> + <ClCompile Include="..\..\Source\UI\Utils\LinearButtonGroupManager.cpp"/> + <ClCompile Include="..\..\Source\UI\Utils\ButtonGroupManager.cpp"/> + <ClCompile Include="..\..\Source\UI\LookAndFeel\MaterialButtonLookAndFeel.cpp"/> + <ClCompile Include="..\..\Source\UI\LookAndFeel\MaterialSliderLookAndFeel.cpp"/> + <ClCompile Include="..\..\Source\UI\LookAndFeel\CustomLookAndFeel.cpp"/> <ClCompile Include="..\..\Source\UI\CustomArrowButton.cpp"/> <ClCompile Include="..\..\Source\UI\GraphViewer.cpp"/> <ClCompile Include="..\..\Source\UI\EditorViewportButtons.cpp"/> <ClCompile Include="..\..\Source\UI\SignalChainManager.cpp"/> <ClCompile Include="..\..\Source\UI\EditorViewport.cpp"/> <ClCompile Include="..\..\Source\UI\ProcessorList.cpp"/> - <ClCompile Include="..\..\Source\UI\CustomLookAndFeel.cpp"/> <ClCompile Include="..\..\Source\UI\InfoLabel.cpp"/> <ClCompile Include="..\..\Source\UI\DataViewport.cpp"/> <ClCompile Include="..\..\Source\UI\ControlPanel.cpp"/> @@ -1468,6 +1476,7 @@ <ClInclude Include="..\..\Source\Audio\AudioComponent.h"/> <ClInclude Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessorEditor.h"/> <ClInclude Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessor.h"/> + <ClInclude Include="..\..\Source\Processors\Dsp\LinearSmoothedValueAtomic.h"/> <ClInclude Include="..\..\Source\Processors\Dsp\Bessel.h"/> <ClInclude Include="..\..\Source\Processors\Dsp\Biquad.h"/> <ClInclude Include="..\..\Source\Processors\Dsp\Butterworth.h"/> @@ -1524,6 +1533,9 @@ <ClInclude Include="..\..\Source\Processors\Parameter\ParameterEditor.h"/> <ClInclude Include="..\..\Source\Processors\Parameter\Parameter.h"/> <ClInclude Include="..\..\Source\Processors\ProcessorGraph\ProcessorGraph.h"/> + <ClInclude Include="..\..\Source\Processors\RecordNode\DataQueue.h"/> + <ClInclude Include="..\..\Source\Processors\RecordNode\EventQueue.h"/> + <ClInclude Include="..\..\Source\Processors\RecordNode\RecordThread.h"/> <ClInclude Include="..\..\Source\Processors\RecordNode\EngineConfigWindow.h"/> <ClInclude Include="..\..\Source\Processors\RecordNode\OriginalRecording.h"/> <ClInclude Include="..\..\Source\Processors\RecordNode\RecordEngine.h"/> @@ -1536,13 +1548,18 @@ <ClInclude Include="..\..\Source\Processors\Visualization\SpikeObject.h"/> <ClInclude Include="..\..\Source\Processors\Visualization\Visualizer.h"/> <ClInclude Include="..\..\Source\Processors\Visualization\MatlabLikePlot.h"/> + <ClInclude Include="..\..\Source\UI\Utils\TiledButtonGroupManager.h"/> + <ClInclude Include="..\..\Source\UI\Utils\LinearButtonGroupManager.h"/> + <ClInclude Include="..\..\Source\UI\Utils\ButtonGroupManager.h"/> + <ClInclude Include="..\..\Source\UI\LookAndFeel\MaterialButtonLookAndFeel.h"/> + <ClInclude Include="..\..\Source\UI\LookAndFeel\MaterialSliderLookAndFeel.h"/> + <ClInclude Include="..\..\Source\UI\LookAndFeel\CustomLookAndFeel.h"/> <ClInclude Include="..\..\Source\UI\CustomArrowButton.h"/> <ClInclude Include="..\..\Source\UI\GraphViewer.h"/> <ClInclude Include="..\..\Source\UI\EditorViewportButtons.h"/> <ClInclude Include="..\..\Source\UI\SignalChainManager.h"/> <ClInclude Include="..\..\Source\UI\EditorViewport.h"/> <ClInclude Include="..\..\Source\UI\ProcessorList.h"/> - <ClInclude Include="..\..\Source\UI\CustomLookAndFeel.h"/> <ClInclude Include="..\..\Source\UI\InfoLabel.h"/> <ClInclude Include="..\..\Source\UI\DataViewport.h"/> <ClInclude Include="..\..\Source\UI\ControlPanel.h"/> @@ -2001,6 +2018,8 @@ <ClInclude Include="..\..\JuceLibraryCode\JuceHeader.h"/> </ItemGroup> <ItemGroup> + <None Include="..\..\Resources\Icons\icon-large.png"/> + <None Include="..\..\Resources\Icons\icon-small.png"/> <None Include="..\..\Resources\Fonts\cpmono-black-serialized"/> <None Include="..\..\Resources\Fonts\cpmono-bold-serialized"/> <None Include="..\..\Resources\Fonts\cpmono-extralight-serialized"/> @@ -2079,6 +2098,7 @@ <None Include="..\..\JuceLibraryCode\modules\juce_gui_extra\juce_module_info"/> <None Include="..\..\JuceLibraryCode\modules\juce_opengl\juce_module_info"/> <None Include="..\..\JuceLibraryCode\modules\juce_video\juce_module_info"/> + <None Include=".\icon.ico"/> </ItemGroup> <ItemGroup> <ResourceCompile Include=".\resources.rc"/> diff --git a/Builds/VisualStudio2013/open-ephys.vcxproj.filters b/Builds/VisualStudio2013/open-ephys.vcxproj.filters index c776c1c33a61c805fabe48e1a0c9563742986cf1..f8f2090e35b7ca5a7505fb05e4ad517e1e98feb9 100644 --- a/Builds/VisualStudio2013/open-ephys.vcxproj.filters +++ b/Builds/VisualStudio2013/open-ephys.vcxproj.filters @@ -8,6 +8,9 @@ <Filter Include="open-ephys\Resources"> <UniqueIdentifier>{4FB3688D-1CC4-C459-F92E-F1764A198374}</UniqueIdentifier> </Filter> + <Filter Include="open-ephys\Resources\Icons"> + <UniqueIdentifier>{675098C0-65B1-49FA-E68F-4DFD81A91FE3}</UniqueIdentifier> + </Filter> <Filter Include="open-ephys\Resources\Fonts"> <UniqueIdentifier>{1DC91498-AFB8-F53B-37B4-DA354ACC7637}</UniqueIdentifier> </Filter> @@ -98,6 +101,12 @@ <Filter Include="open-ephys\Source\UI"> <UniqueIdentifier>{717A0FE3-E079-E4BD-8F50-15A1953825C5}</UniqueIdentifier> </Filter> + <Filter Include="open-ephys\Source\UI\Utils"> + <UniqueIdentifier>{DC42A3E4-435B-C857-DF58-C5BB3E866E6B}</UniqueIdentifier> + </Filter> + <Filter Include="open-ephys\Source\UI\LookAndFeel"> + <UniqueIdentifier>{82473DF0-9747-E952-2C6D-DAC4DD6B3807}</UniqueIdentifier> + </Filter> <Filter Include="Juce Modules"> <UniqueIdentifier>{422C46B7-0467-2DB0-BF3C-16DFCAFD69AC}</UniqueIdentifier> </Filter> @@ -415,6 +424,9 @@ <ClCompile Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessor.cpp"> <Filter>open-ephys\Source\Processors\PlaceholderProcessor</Filter> </ClCompile> + <ClCompile Include="..\..\Source\Processors\Dsp\LinearSmoothedValueAtomic.cpp"> + <Filter>open-ephys\Source\Processors\Dsp</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Processors\Dsp\Bessel.cpp"> <Filter>open-ephys\Source\Processors\Dsp</Filter> </ClCompile> @@ -559,6 +571,12 @@ <ClCompile Include="..\..\Source\Processors\ProcessorGraph\ProcessorGraph.cpp"> <Filter>open-ephys\Source\Processors\ProcessorGraph</Filter> </ClCompile> + <ClCompile Include="..\..\Source\Processors\RecordNode\DataQueue.cpp"> + <Filter>open-ephys\Source\Processors\RecordNode</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\Processors\RecordNode\RecordThread.cpp"> + <Filter>open-ephys\Source\Processors\RecordNode</Filter> + </ClCompile> <ClCompile Include="..\..\Source\Processors\RecordNode\EngineConfigWindow.cpp"> <Filter>open-ephys\Source\Processors\RecordNode</Filter> </ClCompile> @@ -595,6 +613,24 @@ <ClCompile Include="..\..\Source\Processors\Visualization\MatlabLikePlot.cpp"> <Filter>open-ephys\Source\Processors\Visualization</Filter> </ClCompile> + <ClCompile Include="..\..\Source\UI\Utils\TiledButtonGroupManager.cpp"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\UI\Utils\LinearButtonGroupManager.cpp"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\UI\Utils\ButtonGroupManager.cpp"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\UI\LookAndFeel\MaterialButtonLookAndFeel.cpp"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\UI\LookAndFeel\MaterialSliderLookAndFeel.cpp"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClCompile> + <ClCompile Include="..\..\Source\UI\LookAndFeel\CustomLookAndFeel.cpp"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClCompile> <ClCompile Include="..\..\Source\UI\CustomArrowButton.cpp"> <Filter>open-ephys\Source\UI</Filter> </ClCompile> @@ -613,9 +649,6 @@ <ClCompile Include="..\..\Source\UI\ProcessorList.cpp"> <Filter>open-ephys\Source\UI</Filter> </ClCompile> - <ClCompile Include="..\..\Source\UI\CustomLookAndFeel.cpp"> - <Filter>open-ephys\Source\UI</Filter> - </ClCompile> <ClCompile Include="..\..\Source\UI\InfoLabel.cpp"> <Filter>open-ephys\Source\UI</Filter> </ClCompile> @@ -1881,6 +1914,9 @@ <ClInclude Include="..\..\Source\Processors\PlaceholderProcessor\PlaceholderProcessor.h"> <Filter>open-ephys\Source\Processors\PlaceholderProcessor</Filter> </ClInclude> + <ClInclude Include="..\..\Source\Processors\Dsp\LinearSmoothedValueAtomic.h"> + <Filter>open-ephys\Source\Processors\Dsp</Filter> + </ClInclude> <ClInclude Include="..\..\Source\Processors\Dsp\Bessel.h"> <Filter>open-ephys\Source\Processors\Dsp</Filter> </ClInclude> @@ -2049,6 +2085,15 @@ <ClInclude Include="..\..\Source\Processors\ProcessorGraph\ProcessorGraph.h"> <Filter>open-ephys\Source\Processors\ProcessorGraph</Filter> </ClInclude> + <ClInclude Include="..\..\Source\Processors\RecordNode\DataQueue.h"> + <Filter>open-ephys\Source\Processors\RecordNode</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Processors\RecordNode\EventQueue.h"> + <Filter>open-ephys\Source\Processors\RecordNode</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\Processors\RecordNode\RecordThread.h"> + <Filter>open-ephys\Source\Processors\RecordNode</Filter> + </ClInclude> <ClInclude Include="..\..\Source\Processors\RecordNode\EngineConfigWindow.h"> <Filter>open-ephys\Source\Processors\RecordNode</Filter> </ClInclude> @@ -2085,6 +2130,24 @@ <ClInclude Include="..\..\Source\Processors\Visualization\MatlabLikePlot.h"> <Filter>open-ephys\Source\Processors\Visualization</Filter> </ClInclude> + <ClInclude Include="..\..\Source\UI\Utils\TiledButtonGroupManager.h"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\UI\Utils\LinearButtonGroupManager.h"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\UI\Utils\ButtonGroupManager.h"> + <Filter>open-ephys\Source\UI\Utils</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\UI\LookAndFeel\MaterialButtonLookAndFeel.h"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\UI\LookAndFeel\MaterialSliderLookAndFeel.h"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClInclude> + <ClInclude Include="..\..\Source\UI\LookAndFeel\CustomLookAndFeel.h"> + <Filter>open-ephys\Source\UI\LookAndFeel</Filter> + </ClInclude> <ClInclude Include="..\..\Source\UI\CustomArrowButton.h"> <Filter>open-ephys\Source\UI</Filter> </ClInclude> @@ -2103,9 +2166,6 @@ <ClInclude Include="..\..\Source\UI\ProcessorList.h"> <Filter>open-ephys\Source\UI</Filter> </ClInclude> - <ClInclude Include="..\..\Source\UI\CustomLookAndFeel.h"> - <Filter>open-ephys\Source\UI</Filter> - </ClInclude> <ClInclude Include="..\..\Source\UI\InfoLabel.h"> <Filter>open-ephys\Source\UI</Filter> </ClInclude> @@ -3476,6 +3536,12 @@ </ClInclude> </ItemGroup> <ItemGroup> + <None Include="..\..\Resources\Icons\icon-large.png"> + <Filter>open-ephys\Resources\Icons</Filter> + </None> + <None Include="..\..\Resources\Icons\icon-small.png"> + <Filter>open-ephys\Resources\Icons</Filter> + </None> <None Include="..\..\Resources\Fonts\cpmono-black-serialized"> <Filter>open-ephys\Resources\Fonts</Filter> </None> @@ -3710,6 +3776,9 @@ <None Include="..\..\JuceLibraryCode\modules\juce_video\juce_module_info"> <Filter>Juce Modules\juce_video</Filter> </None> + <None Include=".\icon.ico"> + <Filter>Juce Library Code</Filter> + </None> </ItemGroup> <ItemGroup> <ResourceCompile Include=".\resources.rc"> diff --git a/Builds/VisualStudio2013/resources.rc b/Builds/VisualStudio2013/resources.rc index 04df04cba4b9a59076d5287cb6cc17c97c0b1fb3..a77c83e23842ab4580010a3d22d9fee8c6c42312 100644 --- a/Builds/VisualStudio2013/resources.rc +++ b/Builds/VisualStudio2013/resources.rc @@ -28,3 +28,6 @@ BEGIN END #endif + +IDI_ICON1 ICON DISCARDABLE "icon.ico" +IDI_ICON2 ICON DISCARDABLE "icon.ico" \ No newline at end of file diff --git a/JuceLibraryCode/BinaryData.cpp b/JuceLibraryCode/BinaryData.cpp index f9eeecc25710c33eb86f9b7cfb463dd1c2507dc2..2ebfe70c4bf6f8b9c5e6af7971745503c7f95775 100644 --- a/JuceLibraryCode/BinaryData.cpp +++ b/JuceLibraryCode/BinaryData.cpp @@ -7,8 +7,879 @@ namespace BinaryData { -//================== cpmono-black-serialized ================== +//================== icon-large.png ================== static const unsigned char temp_binary_data_0[] = +{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,244,0,0,1,244,8,6,0,0,0,203,214,223,138,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,10,79,105,67,67,80,80,104,111,116,111,115,104,111,112,32,73,67,67,32,112,114,111,102,105,108,101, +0,0,120,218,157,83,103,84,83,233,22,61,247,222,244,66,75,136,128,148,75,111,82,21,8,32,82,66,139,128,20,145,38,42,33,9,16,74,136,33,161,217,21,81,193,17,69,69,4,27,200,160,136,3,142,142,128,140,21,81,44,12,138,10,216,7,228,33,162,142,131,163,136,138, +202,251,225,123,163,107,214,188,247,230,205,254,181,215,62,231,172,243,157,179,207,7,192,8,12,150,72,51,81,53,128,12,169,66,30,17,224,131,199,196,198,225,228,46,64,129,10,36,112,0,16,8,179,100,33,115,253,35,1,0,248,126,60,60,43,34,192,7,190,0,1,120,211, +11,8,0,192,77,155,192,48,28,135,255,15,234,66,153,92,1,128,132,1,192,116,145,56,75,8,128,20,0,64,122,142,66,166,0,64,70,1,128,157,152,38,83,0,160,4,0,96,203,99,98,227,0,80,45,0,96,39,127,230,211,0,128,157,248,153,123,1,0,91,148,33,21,1,160,145,0,32,19, +101,136,68,0,104,59,0,172,207,86,138,69,0,88,48,0,20,102,75,196,57,0,216,45,0,48,73,87,102,72,0,176,183,0,192,206,16,11,178,0,8,12,0,48,81,136,133,41,0,4,123,0,96,200,35,35,120,0,132,153,0,20,70,242,87,60,241,43,174,16,231,42,0,0,120,153,178,60,185,36, +57,69,129,91,8,45,113,7,87,87,46,30,40,206,73,23,43,20,54,97,2,97,154,64,46,194,121,153,25,50,129,52,15,224,243,204,0,0,160,145,21,17,224,131,243,253,120,206,14,174,206,206,54,142,182,14,95,45,234,191,6,255,34,98,98,227,254,229,207,171,112,64,0,0,225, +116,126,209,254,44,47,179,26,128,59,6,128,109,254,162,37,238,4,104,94,11,160,117,247,139,102,178,15,64,181,0,160,233,218,87,243,112,248,126,60,60,69,161,144,185,217,217,229,228,228,216,74,196,66,91,97,202,87,125,254,103,194,95,192,87,253,108,249,126, +60,252,247,245,224,190,226,36,129,50,93,129,71,4,248,224,194,204,244,76,165,28,207,146,9,132,98,220,230,143,71,252,183,11,255,252,29,211,34,196,73,98,185,88,42,20,227,81,18,113,142,68,154,140,243,50,165,34,137,66,146,41,197,37,210,255,100,226,223,44, +251,3,62,223,53,0,176,106,62,1,123,145,45,168,93,99,3,246,75,39,16,88,116,192,226,247,0,0,242,187,111,193,212,40,8,3,128,104,131,225,207,119,255,239,63,253,71,160,37,0,128,102,73,146,113,0,0,94,68,36,46,84,202,179,63,199,8,0,0,68,160,129,42,176,65,27, +244,193,24,44,192,6,28,193,5,220,193,11,252,96,54,132,66,36,196,194,66,16,66,10,100,128,28,114,96,41,172,130,66,40,134,205,176,29,42,96,47,212,64,29,52,192,81,104,134,147,112,14,46,194,85,184,14,61,112,15,250,97,8,158,193,40,188,129,9,4,65,200,8,19,97, +33,218,136,1,98,138,88,35,142,8,23,153,133,248,33,193,72,4,18,139,36,32,201,136,20,81,34,75,145,53,72,49,82,138,84,32,85,72,29,242,61,114,2,57,135,92,70,186,145,59,200,0,50,130,252,134,188,71,49,148,129,178,81,61,212,12,181,67,185,168,55,26,132,70,162, +11,208,100,116,49,154,143,22,160,155,208,114,180,26,61,140,54,161,231,208,171,104,15,218,143,62,67,199,48,192,232,24,7,51,196,108,48,46,198,195,66,177,56,44,9,147,99,203,177,34,172,12,171,198,26,176,86,172,3,187,137,245,99,207,177,119,4,18,129,69,192, +9,54,4,119,66,32,97,30,65,72,88,76,88,78,216,72,168,32,28,36,52,17,218,9,55,9,3,132,81,194,39,34,147,168,75,180,38,186,17,249,196,24,98,50,49,135,88,72,44,35,214,18,143,19,47,16,123,136,67,196,55,36,18,137,67,50,39,185,144,2,73,177,164,84,210,18,210, +70,210,110,82,35,233,44,169,155,52,72,26,35,147,201,218,100,107,178,7,57,148,44,32,43,200,133,228,157,228,195,228,51,228,27,228,33,242,91,10,157,98,64,113,164,248,83,226,40,82,202,106,74,25,229,16,229,52,229,6,101,152,50,65,85,163,154,82,221,168,161, +84,17,53,143,90,66,173,161,182,82,175,81,135,168,19,52,117,154,57,205,131,22,73,75,165,173,162,149,211,26,104,23,104,247,105,175,232,116,186,17,221,149,30,78,151,208,87,210,203,233,71,232,151,232,3,244,119,12,13,134,21,131,199,136,103,40,25,155,24,7, +24,103,25,119,24,175,152,76,166,25,211,139,25,199,84,48,55,49,235,152,231,153,15,153,111,85,88,42,182,42,124,21,145,202,10,149,74,149,38,149,27,42,47,84,169,170,166,170,222,170,11,85,243,85,203,84,143,169,94,83,125,174,70,85,51,83,227,169,9,212,150,171, +85,170,157,80,235,83,27,83,103,169,59,168,135,170,103,168,111,84,63,164,126,89,253,137,6,89,195,76,195,79,67,164,81,160,177,95,227,188,198,32,11,99,25,179,120,44,33,107,13,171,134,117,129,53,196,38,177,205,217,124,118,42,187,152,253,29,187,139,61,170, +169,161,57,67,51,74,51,87,179,82,243,148,102,63,7,227,152,113,248,156,116,78,9,231,40,167,151,243,126,138,222,20,239,41,226,41,27,166,52,76,185,49,101,92,107,170,150,151,150,88,171,72,171,81,171,71,235,189,54,174,237,167,157,166,189,69,187,89,251,129, +14,65,199,74,39,92,39,71,103,143,206,5,157,231,83,217,83,221,167,10,167,22,77,61,58,245,174,46,170,107,165,27,161,187,68,119,191,110,167,238,152,158,190,94,128,158,76,111,167,222,121,189,231,250,28,125,47,253,84,253,109,250,167,245,71,12,88,6,179,12, +36,6,219,12,206,24,60,197,53,113,111,60,29,47,199,219,241,81,67,93,195,64,67,165,97,149,97,151,225,132,145,185,209,60,163,213,70,141,70,15,140,105,198,92,227,36,227,109,198,109,198,163,38,6,38,33,38,75,77,234,77,238,154,82,77,185,166,41,166,59,76,59, +76,199,205,204,205,162,205,214,153,53,155,61,49,215,50,231,155,231,155,215,155,223,183,96,90,120,90,44,182,168,182,184,101,73,178,228,90,166,89,238,182,188,110,133,90,57,89,165,88,85,90,93,179,70,173,157,173,37,214,187,173,187,167,17,167,185,78,147,78, +171,158,214,103,195,176,241,182,201,182,169,183,25,176,229,216,6,219,174,182,109,182,125,97,103,98,23,103,183,197,174,195,238,147,189,147,125,186,125,141,253,61,7,13,135,217,14,171,29,90,29,126,115,180,114,20,58,86,58,222,154,206,156,238,63,125,197,244, +150,233,47,103,88,207,16,207,216,51,227,182,19,203,41,196,105,157,83,155,211,71,103,23,103,185,115,131,243,136,139,137,75,130,203,46,151,62,46,155,27,198,221,200,189,228,74,116,245,113,93,225,122,210,245,157,155,179,155,194,237,168,219,175,238,54,238, +105,238,135,220,159,204,52,159,41,158,89,51,115,208,195,200,67,224,81,229,209,63,11,159,149,48,107,223,172,126,79,67,79,129,103,181,231,35,47,99,47,145,87,173,215,176,183,165,119,170,247,97,239,23,62,246,62,114,159,227,62,227,60,55,222,50,222,89,95,204, +55,192,183,200,183,203,79,195,111,158,95,133,223,67,127,35,255,100,255,122,255,209,0,167,128,37,1,103,3,137,129,65,129,91,2,251,248,122,124,33,191,142,63,58,219,101,246,178,217,237,65,140,160,185,65,21,65,143,130,173,130,229,193,173,33,104,200,236,144, +173,33,247,231,152,206,145,206,105,14,133,80,126,232,214,208,7,97,230,97,139,195,126,12,39,133,135,133,87,134,63,142,112,136,88,26,209,49,151,53,119,209,220,67,115,223,68,250,68,150,68,222,155,103,49,79,57,175,45,74,53,42,62,170,46,106,60,218,55,186, +52,186,63,198,46,102,89,204,213,88,157,88,73,108,75,28,57,46,42,174,54,110,108,190,223,252,237,243,135,226,157,226,11,227,123,23,152,47,200,93,112,121,161,206,194,244,133,167,22,169,46,18,44,58,150,64,76,136,78,56,148,240,65,16,42,168,22,140,37,242,19, +119,37,142,10,121,194,29,194,103,34,47,209,54,209,136,216,67,92,42,30,78,242,72,42,77,122,146,236,145,188,53,121,36,197,51,165,44,229,185,132,39,169,144,188,76,13,76,221,155,58,158,22,154,118,32,109,50,61,58,189,49,131,146,145,144,113,66,170,33,77,147, +182,103,234,103,230,102,118,203,172,101,133,178,254,197,110,139,183,47,30,149,7,201,107,179,144,172,5,89,45,10,182,66,166,232,84,90,40,215,42,7,178,103,101,87,102,191,205,137,202,57,150,171,158,43,205,237,204,179,202,219,144,55,156,239,159,255,237,18, +194,18,225,146,182,165,134,75,87,45,29,88,230,189,172,106,57,178,60,113,121,219,10,227,21,5,43,134,86,6,172,60,184,138,182,42,109,213,79,171,237,87,151,174,126,189,38,122,77,107,129,94,193,202,130,193,181,1,107,235,11,85,10,229,133,125,235,220,215,237, +93,79,88,47,89,223,181,97,250,134,157,27,62,21,137,138,174,20,219,23,151,21,127,216,40,220,120,229,27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,102,210,102,233,230,222,45,158,91,14,150,170,151,230,151,14,110,13,217,218,180,13,223,86,180, +237,245,246,69,219,47,151,205,40,219,187,131,182,67,185,163,191,60,184,188,101,167,201,206,205,59,63,84,164,84,244,84,250,84,54,238,210,221,181,97,215,248,110,209,238,27,123,188,246,52,236,213,219,91,188,247,253,62,201,190,219,85,1,85,77,213,102,213, +101,251,73,251,179,247,63,174,137,170,233,248,150,251,109,93,173,78,109,113,237,199,3,210,3,253,7,35,14,182,215,185,212,213,29,210,61,84,82,143,214,43,235,71,14,199,31,190,254,157,239,119,45,13,54,13,85,141,156,198,226,35,112,68,121,228,233,247,9,223, +247,30,13,58,218,118,140,123,172,225,7,211,31,118,29,103,29,47,106,66,154,242,154,70,155,83,154,251,91,98,91,186,79,204,62,209,214,234,222,122,252,71,219,31,15,156,52,60,89,121,74,243,84,201,105,218,233,130,211,147,103,242,207,140,157,149,157,125,126, +46,249,220,96,219,162,182,123,231,99,206,223,106,15,111,239,186,16,116,225,210,69,255,139,231,59,188,59,206,92,242,184,116,242,178,219,229,19,87,184,87,154,175,58,95,109,234,116,234,60,254,147,211,79,199,187,156,187,154,174,185,92,107,185,238,122,189, +181,123,102,247,233,27,158,55,206,221,244,189,121,241,22,255,214,213,158,57,61,221,189,243,122,111,247,197,247,245,223,22,221,126,114,39,253,206,203,187,217,119,39,238,173,188,79,188,95,244,64,237,65,217,67,221,135,213,63,91,254,220,216,239,220,127,106, +192,119,160,243,209,220,71,247,6,133,131,207,254,145,245,143,15,67,5,143,153,143,203,134,13,134,235,158,56,62,57,57,226,63,114,253,233,252,167,67,207,100,207,38,158,23,254,162,254,203,174,23,22,47,126,248,213,235,215,206,209,152,209,161,151,242,151,147, +191,109,124,165,253,234,192,235,25,175,219,198,194,198,30,190,201,120,51,49,94,244,86,251,237,193,119,220,119,29,239,163,223,15,79,228,124,32,127,40,255,104,249,177,245,83,208,167,251,147,25,147,147,255,4,3,152,243,252,99,51,45,219,0,0,0,32,99,72,82, +77,0,0,122,37,0,0,128,131,0,0,249,255,0,0,128,233,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,111,146,95,197,70,0,0,203,3,73,68,65,84,120,218,236,189,119,156,165,89,93,231,255,62,231,73,55,85,142,93,157,211,116,247,4,194,128,136,100,145,32,136,136,128,10, +102,113,65,16,112,205,235,170,192,46,186,230,117,5,179,96,252,169,128,74,16,16,21,201,57,14,204,12,211,57,167,170,234,202,55,63,233,156,223,31,207,115,111,87,236,174,91,117,187,187,170,251,188,95,20,53,85,93,55,61,225,124,206,55,11,173,53,6,131,193,96, +48,24,54,55,210,28,2,131,193,96,48,24,140,160,27,12,6,131,193,96,48,130,110,48,24,12,6,131,193,8,186,193,96,48,24,12,6,35,232,6,131,193,96,48,24,65,55,24,12,6,131,193,96,4,221,96,48,24,12,6,131,17,116,131,193,96,48,24,12,70,208,13,6,131,193,96,48,130, +110,48,24,12,6,131,193,8,186,193,96,48,24,12,6,35,232,6,131,193,96,48,24,140,160,27,12,6,131,193,112,59,98,155,67,176,0,11,200,164,223,61,160,23,184,27,232,4,246,166,199,203,140,167,51,24,12,134,246,35,128,16,56,9,148,128,135,129,34,224,3,81,250,61,54, +135,201,8,250,181,144,128,3,28,4,238,7,30,11,12,2,247,165,191,47,164,199,41,155,94,112,6,131,193,96,184,49,104,160,154,10,119,9,8,128,111,0,99,192,215,128,7,128,227,169,192,43,115,184,22,237,136,238,192,121,232,121,160,7,216,7,124,59,240,84,224,192,60, +225,182,204,101,97,48,24,12,27,142,56,21,242,18,112,4,248,20,240,31,192,25,96,38,221,8,24,65,191,3,24,76,5,252,30,224,59,128,103,3,57,115,127,24,12,6,195,166,167,8,124,24,248,119,224,48,112,2,152,50,130,126,251,241,45,192,147,129,231,1,207,52,215,189, +193,96,48,220,246,86,252,71,83,203,253,211,192,87,140,160,111,110,186,128,239,2,94,8,60,9,216,98,174,113,131,193,96,184,227,184,0,124,30,248,215,244,171,98,4,125,243,208,15,252,76,42,230,123,73,178,213,13,6,131,193,112,103,83,37,201,156,127,55,240,86, +96,214,8,250,198,101,0,120,61,240,74,96,216,92,187,6,131,193,96,88,6,13,92,6,254,52,253,154,54,130,190,113,216,3,124,47,240,115,169,117,110,48,24,12,6,195,106,24,3,126,7,120,15,112,206,8,250,173,163,3,248,65,224,23,128,221,230,186,52,24,12,6,195,26,57, +10,252,46,240,143,64,221,8,250,205,229,121,192,79,145,212,143,27,12,6,131,193,208,14,62,0,188,133,36,67,222,8,250,13,102,16,248,13,224,197,36,77,97,12,6,131,193,96,104,39,147,192,59,129,55,146,52,170,49,130,126,3,248,78,224,183,129,67,230,122,51,24,12, +6,195,13,230,65,146,144,238,127,25,65,111,31,61,36,101,104,191,68,210,83,221,96,48,24,12,134,155,65,13,248,53,224,143,73,58,209,25,65,95,7,247,2,127,0,124,155,185,174,12,6,131,193,112,139,248,32,240,179,36,237,100,55,60,27,113,30,250,139,129,247,25,49, +55,24,12,6,195,45,230,5,169,30,61,207,8,122,235,252,20,240,55,36,157,222,12,6,131,193,96,184,213,220,13,252,61,240,227,27,253,141,110,20,151,123,30,248,95,192,127,199,196,203,13,6,131,193,176,241,168,147,52,163,249,13,192,55,130,190,60,89,224,255,2,175, +49,215,139,193,96,48,24,54,56,255,23,248,159,64,184,209,222,216,173,118,185,143,144,36,191,25,49,55,24,12,6,195,102,224,231,128,223,35,233,143,98,44,244,148,61,192,223,2,79,49,215,135,193,96,48,24,54,25,31,38,137,171,95,188,211,5,61,11,188,131,100,212, +169,193,96,48,24,12,155,145,70,178,92,176,17,222,204,173,112,185,231,128,223,39,233,0,103,48,24,12,6,195,102,229,101,36,73,114,222,157,104,161,59,36,13,240,77,204,220,96,48,24,12,183,3,154,36,81,238,127,0,234,78,178,208,95,107,196,220,96,48,24,12,183, +17,130,36,81,238,150,215,169,223,76,11,253,229,36,51,103,13,6,131,193,96,184,221,8,129,151,2,239,191,221,5,253,155,129,15,1,189,230,156,27,12,6,131,225,54,101,20,248,118,224,161,91,241,226,55,195,229,190,11,248,35,35,230,6,131,193,96,184,205,217,2,252, +33,73,143,149,219,82,208,223,8,60,222,156,103,131,193,96,48,220,1,60,13,248,197,91,241,194,55,218,229,254,10,224,47,205,249,53,24,12,6,195,29,68,4,252,32,240,174,219,69,208,15,2,255,70,210,17,206,96,48,24,12,134,59,137,99,192,115,129,115,55,235,5,111, +148,203,221,37,41,182,55,98,110,48,24,12,134,59,145,3,192,175,115,19,203,195,111,212,11,125,31,240,221,230,124,26,12,6,131,225,14,230,7,129,23,221,172,23,187,17,46,247,94,224,1,96,167,57,151,6,131,193,96,184,195,57,10,124,19,80,222,140,22,250,255,49, +98,110,48,24,12,6,3,144,228,147,189,233,102,188,80,187,5,253,73,192,75,204,249,51,24,12,6,131,161,201,203,128,199,108,38,65,119,129,159,2,6,204,185,51,24,12,6,131,161,201,54,146,57,38,246,102,17,244,39,3,207,51,231,205,96,48,24,12,134,37,188,20,120,236, +102,16,244,44,240,35,64,167,57,103,6,131,193,96,48,44,161,23,248,97,18,111,246,13,161,93,89,238,79,2,62,65,50,239,220,96,48,24,12,6,195,82,124,146,140,247,135,55,170,133,110,3,175,54,98,110,48,24,12,6,195,53,241,128,159,220,200,22,250,65,224,171,64,206, +156,43,131,193,96,48,24,174,201,44,240,104,224,252,70,180,208,191,223,136,185,193,96,48,24,12,171,162,27,120,249,70,180,208,179,192,73,110,209,236,87,131,193,96,48,24,54,33,39,128,67,64,188,145,44,244,23,25,49,55,24,12,6,131,161,37,246,0,47,104,247,147, +174,87,208,127,200,156,23,131,193,96,48,24,90,194,2,126,96,35,9,250,33,224,113,230,188,24,12,6,131,193,208,50,79,0,118,111,20,65,127,41,208,111,206,137,193,96,48,24,12,45,179,21,248,174,141,34,232,79,224,38,14,110,55,24,12,6,131,225,54,194,166,205,94, +238,181,10,242,62,224,46,115,62,12,6,131,193,96,88,51,247,1,59,110,181,160,63,41,21,117,131,193,96,48,24,12,107,227,110,224,254,91,45,232,119,99,220,237,6,131,193,96,48,172,7,7,56,112,43,5,189,147,155,48,168,221,96,48,24,12,134,59,128,111,162,77,221, +86,215,34,232,251,72,250,208,26,12,6,131,193,96,88,31,143,163,77,113,244,181,8,250,8,48,108,206,129,193,96,48,24,12,235,102,39,48,112,171,4,125,151,57,254,6,131,193,96,48,180,5,65,155,26,204,200,22,95,212,1,238,49,199,223,96,48,24,12,134,182,113,47,73, +59,216,155,38,232,30,208,101,4,221,96,48,24,12,134,182,242,40,32,127,51,5,221,33,201,196,219,110,142,189,193,96,48,24,12,109,99,39,224,222,76,65,119,129,2,38,33,206,96,48,24,12,134,118,178,131,54,148,174,181,34,232,86,106,165,103,204,177,55,24,12,6,131, +161,109,228,72,122,187,223,52,65,127,60,102,92,170,193,96,48,24,12,55,130,199,223,76,65,207,1,89,115,204,13,6,131,193,96,104,59,235,214,215,86,76,252,189,192,144,57,230,6,131,193,96,48,180,157,189,55,211,66,239,33,41,91,51,24,12,6,131,193,208,94,122, +110,166,160,199,128,50,199,220,96,48,24,12,134,182,19,223,76,65,55,24,12,6,131,193,176,65,49,130,110,48,24,12,6,131,17,116,131,193,96,48,24,12,70,208,13,6,131,193,96,48,24,65,55,24,12,6,131,193,96,4,221,96,48,24,12,6,35,232,6,131,193,96,48,24,140,160, +27,12,6,131,193,96,48,130,110,48,24,12,6,131,193,8,186,193,96,48,24,12,70,208,13,6,131,193,96,48,24,65,55,24,12,6,131,193,96,4,221,96,48,24,12,6,131,17,116,131,193,96,48,24,110,75,236,86,31,160,181,54,71,205,96,48,24,12,134,54,34,132,48,22,186,193,96, +48,24,12,6,35,232,6,131,193,96,48,24,65,55,24,12,6,131,193,96,4,221,96,48,24,12,6,131,17,116,131,193,96,48,24,12,70,208,13,6,131,193,96,184,19,5,93,107,109,74,214,12,6,131,193,96,184,1,180,67,95,141,133,110,48,24,12,6,195,157,100,161,27,12,6,131,193, +96,48,130,110,48,24,12,6,131,193,8,186,193,96,48,24,12,6,35,232,6,131,193,96,48,24,65,55,24,12,6,131,193,96,4,221,96,48,24,12,6,131,17,116,131,193,96,48,24,12,70,208,13,6,131,193,96,48,130,110,48,24,12,6,131,193,8,186,193,96,48,24,12,6,35,232,6,131,193, +96,48,24,140,160,27,12,6,131,193,96,4,221,96,48,24,12,6,131,17,116,131,193,96,48,24,12,70,208,13,6,131,193,96,48,24,65,55,24,12,6,131,193,8,186,193,96,48,24,12,6,35,232,6,131,193,96,48,24,140,160,27,12,6,131,193,96,48,130,110,48,24,12,6,131,17,116,131, +193,96,48,24,12,70,208,13,6,131,193,96,48,24,65,55,24,12,6,131,193,176,118,108,115,8,12,6,131,193,176,26,132,16,75,126,167,181,54,7,198,8,186,193,96,48,24,54,140,88,47,251,139,133,191,45,5,53,190,126,238,12,199,47,159,167,39,159,227,41,7,239,103,176, +80,48,194,110,4,221,96,48,24,12,55,85,172,197,114,210,173,65,67,164,33,70,163,53,4,74,115,197,87,156,172,135,124,174,20,243,249,83,135,169,124,230,61,68,151,143,83,42,205,80,169,251,56,142,69,33,155,229,174,253,7,121,227,15,255,20,247,237,216,111,132, +221,8,186,193,96,48,24,218,34,220,203,10,118,67,183,53,229,72,51,27,197,132,74,163,52,84,149,226,82,61,226,112,41,228,19,115,117,30,174,134,136,88,163,1,141,32,22,154,240,200,23,136,62,242,23,48,51,10,40,164,16,72,33,240,53,20,103,166,24,29,189,204,119, +60,252,48,111,122,245,47,242,138,111,125,190,57,9,70,208,13,6,131,193,176,106,107,91,136,21,255,189,22,41,46,249,17,23,131,171,194,93,138,20,23,235,17,15,150,2,62,57,231,51,21,196,136,212,144,150,34,201,142,182,132,64,138,121,59,3,13,28,255,10,242,191, +222,142,91,28,5,219,2,172,5,175,101,165,63,251,51,87,120,195,91,222,68,193,113,249,190,167,60,203,88,233,70,208,13,6,131,193,176,26,107,59,82,138,75,245,152,135,42,33,231,253,8,173,52,145,134,185,48,177,184,191,81,14,120,176,26,18,68,10,33,64,34,176, +4,184,66,224,73,65,94,174,188,33,192,18,16,196,112,113,14,62,243,207,80,28,5,105,93,243,189,90,150,77,117,110,142,223,250,187,63,225,241,7,238,99,239,192,144,17,117,35,232,6,131,193,112,167,89,219,203,11,183,214,154,81,63,226,72,57,224,115,37,159,203, +245,24,153,198,183,75,177,98,194,143,57,94,143,24,11,98,80,26,1,72,33,176,5,184,82,208,41,4,194,181,90,123,67,150,128,114,0,151,202,112,254,48,76,157,88,209,131,191,152,172,235,114,242,212,81,222,241,209,127,227,87,95,246,10,115,114,141,160,27,12,6,195, +109,32,210,43,27,215,169,90,39,223,2,173,153,246,99,206,212,66,190,52,23,242,217,162,207,108,24,35,129,80,105,170,177,102,54,82,92,9,99,42,177,70,166,79,219,112,145,187,18,6,236,54,182,19,153,170,193,165,89,136,93,152,251,58,40,127,213,130,46,164,36, +170,151,184,112,246,68,234,97,16,198,74,55,130,110,48,24,12,155,215,178,6,77,160,52,149,72,19,170,36,193,172,22,107,198,252,136,163,229,128,143,204,214,249,122,57,66,43,133,214,16,3,145,210,212,211,47,53,239,53,18,171,59,117,149,219,226,6,125,24,1,177, +130,241,50,92,41,131,214,224,88,80,62,15,58,2,225,172,250,169,92,199,229,210,149,43,140,78,78,178,165,191,223,92,40,70,208,13,6,131,97,163,139,118,34,194,19,65,226,242,14,117,146,124,86,78,19,210,30,46,5,124,108,214,231,66,61,2,173,231,61,131,104,254, +183,88,244,98,2,240,164,184,185,31,80,8,168,133,73,188,188,20,164,191,179,33,154,0,85,108,122,18,86,45,40,182,205,133,209,139,156,62,119,134,45,253,253,198,74,55,130,110,48,24,12,55,81,215,174,83,234,53,25,68,156,168,69,156,173,71,68,74,19,107,77,49, +210,92,174,69,60,88,246,249,98,41,164,18,169,196,29,46,146,60,112,91,10,92,33,112,4,215,204,72,191,165,31,90,0,179,117,184,52,7,245,136,102,138,187,116,161,126,24,172,185,36,25,174,5,61,214,196,228,157,14,234,51,33,181,90,149,108,54,103,46,48,35,232, +6,131,193,112,179,132,91,51,23,196,156,172,134,124,161,228,115,33,77,62,11,181,166,20,41,198,252,152,99,213,144,211,169,160,75,18,237,179,133,192,149,130,140,16,100,28,185,185,14,132,214,48,86,74,220,236,177,190,42,230,13,211,221,63,7,121,63,17,244,72, +175,42,142,174,181,198,114,92,118,231,251,169,93,153,100,102,118,150,76,38,107,46,60,35,232,6,131,193,176,10,109,90,241,23,75,187,161,21,67,197,133,90,196,3,165,128,207,21,125,38,210,90,236,80,105,42,177,98,42,84,92,240,35,230,34,189,32,126,109,11,129, +43,160,207,150,183,199,1,11,99,184,56,11,115,245,196,250,158,47,230,194,130,120,26,226,9,200,217,224,41,136,162,85,61,117,68,204,96,161,135,199,245,108,67,106,56,119,238,28,185,108,142,238,238,110,227,118,55,130,110,48,24,140,96,115,205,228,51,149,150, +113,133,58,249,185,30,195,149,32,226,68,37,228,147,179,117,190,80,14,136,66,141,38,169,211,14,148,166,18,39,101,95,81,42,50,2,145,102,141,39,226,221,239,136,219,247,64,22,235,112,169,8,245,240,170,219,125,1,14,4,231,32,28,77,92,239,121,13,181,232,186, +110,247,72,67,214,129,103,12,246,177,53,63,140,95,247,41,205,21,169,213,106,20,10,5,44,203,50,23,179,17,116,131,193,112,103,139,54,160,53,179,97,204,100,164,8,84,210,107,188,18,43,198,252,136,111,164,157,207,30,169,70,160,84,227,207,209,128,74,123,147, +207,127,29,145,38,165,121,82,144,65,220,25,7,88,166,46,246,201,50,92,46,37,46,246,21,227,250,50,77,136,155,5,145,3,79,64,214,134,74,176,244,49,233,113,14,132,166,55,35,121,206,96,129,39,245,12,18,226,32,107,117,132,238,226,216,177,99,88,150,197,224,224, +160,177,210,141,160,27,12,134,219,75,184,87,22,209,82,24,115,190,30,113,222,111,180,44,213,20,67,205,101,63,226,235,165,128,207,148,124,102,252,184,153,124,38,210,238,103,142,72,190,47,167,99,242,78,17,237,107,137,121,168,224,242,28,76,85,105,166,211, +47,139,5,186,8,234,2,232,244,143,108,153,180,124,181,44,136,226,228,215,66,32,4,68,105,6,224,129,188,195,119,13,120,236,244,178,196,238,46,32,38,170,41,84,172,136,162,144,147,39,79,210,223,223,143,148,210,136,186,17,116,131,193,176,169,132,251,26,214, +182,31,43,206,213,35,190,86,10,56,95,143,208,42,73,62,43,70,138,81,63,226,145,74,200,145,106,136,31,55,146,207,18,177,246,164,192,19,130,174,219,33,142,125,179,176,4,20,125,24,45,37,174,118,107,153,99,167,231,153,218,8,8,175,64,245,56,224,38,127,223, +233,160,3,141,240,4,178,20,36,225,118,33,8,4,120,150,224,153,93,14,223,214,225,146,21,26,95,122,8,103,24,161,21,42,208,168,56,198,150,14,190,239,115,241,226,69,182,111,223,110,202,216,140,160,27,12,134,141,105,109,47,47,220,97,172,184,228,135,28,46,135, +124,190,232,115,201,79,146,207,2,173,41,71,138,137,32,230,76,61,98,34,80,104,173,211,82,175,171,194,221,101,73,132,9,185,174,127,87,117,165,146,100,177,215,35,144,50,113,187,55,69,60,61,117,150,4,199,6,207,130,108,14,162,16,50,21,176,11,96,75,68,168, +112,34,141,22,14,150,35,144,213,136,72,194,144,37,120,65,135,203,125,89,11,1,248,26,180,211,135,192,2,98,116,172,209,129,66,8,129,239,251,140,143,143,179,117,235,86,19,75,55,130,110,48,24,110,173,72,39,22,156,34,137,75,107,146,228,178,169,48,226,84,37, +226,115,115,62,159,41,250,212,162,164,243,89,164,147,142,103,197,72,49,29,41,234,177,110,62,191,20,105,203,82,33,232,119,140,181,189,22,244,188,243,160,23,228,8,8,28,9,196,160,199,230,96,178,146,252,161,155,186,205,51,169,112,103,92,112,4,201,31,139, +52,54,97,129,140,97,238,2,168,76,210,29,78,128,14,4,210,78,38,175,69,57,11,81,143,184,203,177,120,65,151,203,22,71,16,167,215,5,8,132,183,7,180,106,94,76,81,58,52,198,113,28,102,103,103,57,123,246,44,123,247,238,53,86,186,17,116,131,193,208,62,209,22, +43,74,69,45,214,204,69,113,51,249,172,166,52,227,126,196,209,114,200,71,103,107,124,189,28,161,210,228,51,165,147,252,170,64,95,109,113,218,120,141,70,140,251,134,182,44,189,205,137,210,205,145,106,138,166,70,35,200,74,232,180,36,89,43,169,131,183,132, +0,33,232,113,45,156,40,226,244,68,133,41,215,194,218,223,151,198,191,229,85,171,93,172,176,105,19,18,162,18,84,190,14,202,1,113,181,246,60,178,65,213,21,110,198,225,105,253,240,12,41,201,72,145,86,22,52,144,96,13,46,240,16,68,213,32,245,192,8,148,82, +148,203,101,130,32,192,117,93,115,114,141,160,27,12,134,245,89,218,9,65,172,24,11,98,46,249,49,190,210,104,173,41,69,73,242,217,131,165,128,143,207,214,25,245,227,230,228,235,134,64,91,8,86,234,76,234,74,35,218,107,65,205,219,16,69,77,171,59,57,222,67, +142,197,86,207,166,219,145,228,172,68,184,181,16,236,207,217,60,165,195,227,80,135,195,136,231,224,166,25,129,159,154,174,241,166,147,211,140,103,93,188,188,119,213,156,95,206,196,95,238,31,162,25,136,166,146,214,175,13,199,140,16,148,92,139,93,129,226, +213,3,30,79,201,228,120,228,66,133,32,214,243,246,133,26,237,14,32,133,187,224,34,12,43,126,242,1,109,129,109,219,140,141,141,97,89,22,7,15,30,52,174,119,35,232,6,131,97,129,112,95,67,180,181,210,140,250,33,135,171,17,167,235,33,90,65,172,53,115,145, +98,180,158,36,159,61,80,14,40,69,10,43,45,229,106,100,140,103,174,55,47,219,208,50,177,134,186,74,134,182,196,232,230,80,150,14,91,114,40,231,176,55,107,211,239,90,20,44,137,37,193,146,130,67,57,135,199,22,92,118,102,109,92,75,174,232,85,1,248,251,203, +69,126,225,196,12,97,12,25,41,104,217,163,173,21,212,190,145,238,38,174,62,115,89,107,158,62,224,241,154,130,203,99,11,14,129,128,222,78,135,209,153,224,234,149,167,35,164,187,59,105,74,195,213,218,254,168,30,38,22,122,67,108,108,155,11,23,46,176,117, +235,86,122,122,122,140,219,221,8,186,193,96,132,123,254,98,62,233,71,28,175,132,124,185,20,112,182,30,37,157,207,116,210,21,237,74,16,115,188,22,113,62,141,101,46,158,151,157,17,130,172,99,44,165,118,18,106,77,168,82,87,57,73,30,154,18,48,226,89,60,171, +211,227,64,222,101,200,179,200,91,18,4,228,45,201,93,89,155,157,25,135,130,35,184,86,45,190,94,114,93,36,194,253,187,103,103,120,243,233,89,178,50,113,193,175,77,38,21,84,191,150,184,222,83,89,46,42,120,237,112,150,215,184,54,222,209,18,85,149,60,243, +182,158,12,211,229,144,32,237,168,135,176,192,25,76,30,171,227,171,110,29,165,136,67,133,156,119,141,57,142,195,153,51,103,200,231,243,184,174,107,68,253,86,11,186,57,1,6,195,58,5,58,253,63,193,202,22,246,188,101,150,233,32,230,92,45,226,203,115,62,31, +43,250,148,67,149,36,41,41,77,85,41,102,66,197,120,160,40,198,42,9,125,138,100,94,182,45,146,36,169,254,107,148,122,153,187,249,58,235,29,44,177,118,245,114,127,3,216,150,224,241,121,151,167,118,123,220,149,115,25,244,44,50,169,167,35,111,9,70,92,139, +30,71,38,25,231,203,189,146,6,173,213,117,207,137,0,132,20,156,172,4,252,242,137,25,254,115,170,70,86,10,28,177,86,49,23,16,207,64,56,1,36,177,241,14,9,191,182,43,207,15,15,101,177,74,49,167,208,8,149,92,180,174,37,216,214,155,225,212,104,5,33,20,120, +131,32,179,203,30,168,184,30,226,228,156,5,155,144,169,169,41,42,149,10,142,227,24,61,89,180,65,51,22,186,193,176,65,69,91,44,84,238,5,214,86,164,160,162,20,169,54,227,171,249,45,75,107,124,174,20,18,70,42,49,116,210,56,107,61,109,91,154,26,74,205,28, +39,43,141,111,247,154,26,237,181,217,166,26,162,180,141,108,179,44,91,36,137,224,89,41,240,44,129,45,210,252,1,1,5,219,226,105,157,46,79,238,202,176,39,231,208,239,202,36,97,28,65,70,38,86,183,181,92,91,213,244,201,181,82,107,222,72,53,234,192,255,107, +170,206,143,29,158,164,22,198,120,50,41,249,91,179,52,10,11,170,95,39,86,17,117,5,247,231,45,126,115,123,158,111,233,241,64,64,77,106,108,71,18,133,137,69,174,129,222,188,195,149,156,67,169,82,70,186,59,150,23,116,32,174,5,64,110,137,112,29,59,118,140, +251,239,191,223,136,250,173,182,208,13,6,195,34,209,22,203,77,184,214,196,177,102,38,138,25,15,98,106,169,10,151,227,36,107,252,112,57,228,223,103,106,156,174,70,200,52,161,88,175,226,181,50,38,182,189,102,75,59,76,123,190,199,243,220,225,8,232,182,37, +219,28,155,78,39,201,222,182,69,34,232,187,178,54,79,237,244,120,84,135,199,246,140,77,167,147,244,124,191,238,107,233,196,147,217,110,157,146,82,224,71,138,119,140,149,248,249,227,179,72,209,174,100,68,139,160,250,32,74,69,188,168,55,203,111,238,44, +176,53,99,19,171,100,10,155,180,37,78,206,34,154,77,250,191,107,13,174,45,25,233,118,57,86,181,192,234,5,28,32,88,114,213,6,37,159,252,50,199,193,247,125,230,230,230,232,235,235,51,23,167,17,116,131,225,102,11,183,88,62,115,92,107,102,130,152,83,181, +136,51,245,136,56,205,86,46,71,138,75,245,152,195,229,128,207,151,2,38,195,36,107,124,225,4,175,198,188,108,115,140,219,105,109,215,149,38,208,201,220,242,70,201,87,198,18,236,206,216,236,202,36,201,103,121,75,96,35,192,18,28,200,218,60,177,211,99,111, +206,161,219,149,75,54,102,164,226,172,155,229,99,55,31,41,37,71,170,1,191,127,122,150,127,185,82,197,147,162,45,151,141,16,146,74,56,67,95,52,205,107,182,230,248,217,173,157,88,50,9,231,0,8,173,177,28,129,91,176,169,78,133,141,16,59,90,107,186,115,146, +222,222,33,166,40,96,175,112,100,162,122,184,204,107,10,234,245,58,167,79,159,166,167,167,7,203,178,140,149,126,211,5,221,28,112,195,109,142,92,224,34,95,184,168,151,3,197,217,90,200,3,149,128,83,181,24,116,98,237,53,146,207,142,84,67,142,85,67,226,121, +201,103,150,0,55,205,26,239,51,238,240,182,18,105,141,159,182,141,109,184,202,21,208,227,72,158,220,229,113,48,239,48,228,217,20,236,36,227,58,107,39,194,189,63,235,48,224,217,203,212,226,167,194,173,52,122,3,101,22,36,46,118,201,231,102,107,188,242, +240,20,199,42,33,3,109,106,200,35,128,217,200,230,81,28,225,141,59,225,249,125,29,73,248,65,47,92,246,165,37,177,51,86,122,92,68,243,247,174,21,177,165,255,110,202,229,33,162,40,88,182,189,129,138,98,116,172,16,139,178,244,45,203,162,86,171,49,62,62, +206,200,200,136,185,160,27,7,117,157,113,116,99,161,27,238,8,11,123,161,133,48,95,184,175,46,232,181,8,46,214,67,30,42,251,124,124,214,103,42,80,169,112,107,42,145,102,42,140,185,16,196,76,134,73,242,25,164,241,235,84,184,141,104,175,115,61,91,230,119, +113,234,34,111,36,158,105,157,36,132,29,200,217,60,181,51,195,193,66,34,220,89,153,156,207,188,20,236,240,108,134,60,11,219,90,41,249,172,33,220,155,96,131,41,224,31,46,149,120,211,233,25,46,251,49,131,142,108,203,251,214,192,108,172,120,206,96,23,191, +151,29,103,127,24,161,148,187,188,157,45,193,242,228,162,164,45,77,164,4,189,125,123,233,181,134,24,155,60,135,37,228,210,27,79,105,34,63,196,201,103,22,24,133,66,8,130,32,224,240,225,195,56,142,195,224,224,96,179,97,145,225,38,8,186,177,207,13,27,85, +172,23,52,82,17,11,119,188,58,77,40,139,82,151,105,132,102,194,87,156,170,36,125,198,63,89,244,169,134,73,242,89,156,90,125,229,88,49,27,169,230,140,109,65,50,181,171,57,47,219,8,247,154,69,36,214,73,191,179,198,136,211,134,112,57,105,248,193,18,87,93, +201,174,45,121,82,135,203,211,186,51,236,203,217,12,120,22,110,234,106,206,89,73,207,247,140,37,26,137,12,11,87,42,189,190,228,179,91,126,77,11,65,53,142,121,237,209,105,254,107,178,78,69,41,186,237,246,136,121,93,105,6,29,201,155,247,246,241,242,145, +28,29,151,125,226,90,140,190,198,101,109,217,2,203,22,168,134,17,169,99,132,211,139,240,118,176,165,191,159,217,226,40,65,24,46,201,212,214,26,194,90,128,91,200,44,113,242,90,150,69,16,4,204,204,204,208,223,223,127,199,183,132,213,172,63,250,102,44,116, +195,166,224,90,238,112,148,166,52,175,111,120,210,178,20,198,253,136,35,213,144,15,79,215,120,164,146,52,87,17,128,74,5,37,74,231,101,235,171,93,46,155,45,75,147,121,217,96,2,220,173,19,165,181,216,49,105,114,88,186,88,229,45,73,175,45,201,219,201,241, +181,16,104,9,195,158,197,51,58,92,30,215,229,177,51,231,208,99,203,230,56,84,91,36,227,62,86,234,49,223,72,64,187,93,76,14,153,230,106,156,173,132,188,236,225,9,142,86,194,228,90,92,115,125,249,66,113,45,41,205,163,11,14,127,118,176,143,71,117,101,32, +46,18,5,179,137,25,126,141,199,89,158,196,202,72,84,53,78,110,18,29,131,61,132,178,119,80,144,22,253,221,189,92,154,24,67,44,147,99,18,149,3,24,88,62,237,211,117,93,206,157,59,71,111,111,47,3,3,3,38,150,110,4,221,112,91,89,219,87,255,111,201,226,93,141, +20,23,235,17,23,210,150,165,74,67,41,82,140,250,49,143,148,3,62,61,87,231,162,175,176,244,85,203,189,97,85,167,30,217,5,187,96,153,90,222,43,244,108,49,92,71,28,124,157,116,62,139,210,100,49,173,53,150,20,140,120,22,59,115,54,61,142,36,103,39,201,103, +74,194,222,172,205,211,186,50,28,200,59,12,187,22,214,226,33,230,169,79,93,47,250,149,106,158,143,219,251,164,200,52,99,253,3,227,21,126,249,196,12,231,235,49,57,75,172,251,122,20,169,85,174,128,111,237,205,240,55,247,244,211,239,202,228,184,214,46,164, +237,94,173,107,154,142,182,103,227,100,44,130,74,156,238,173,36,216,125,104,153,3,85,101,219,224,8,147,115,211,132,97,184,232,58,209,73,98,220,53,246,197,66,8,38,39,39,233,234,234,194,182,141,36,25,65,55,108,174,133,235,170,41,188,68,184,163,88,113,177, +30,242,141,74,200,137,122,132,142,117,218,178,84,51,234,71,28,169,132,60,92,13,169,134,10,153,46,6,141,24,182,39,5,93,215,41,227,49,246,118,107,52,90,150,134,90,19,165,33,12,5,228,28,193,163,243,46,7,242,14,131,174,69,135,37,144,82,224,88,130,131,89, +155,71,21,92,70,60,27,219,18,75,61,42,169,112,43,101,118,77,243,197,188,170,52,191,116,124,154,119,141,150,9,84,210,140,102,189,71,72,144,148,74,246,216,130,215,237,236,228,231,118,118,33,165,72,142,189,4,234,23,32,156,5,86,22,116,173,52,182,39,177,61, +43,25,166,102,41,176,242,144,221,15,132,104,52,182,229,176,109,96,11,167,46,158,65,74,107,161,3,45,140,174,153,84,45,165,228,194,133,11,12,15,15,211,221,221,109,172,116,35,232,134,13,105,109,175,32,220,90,41,198,234,33,135,43,33,95,40,6,92,168,199,201, +78,94,37,67,66,38,194,100,94,246,69,63,134,101,90,150,230,133,160,224,154,150,165,237,36,74,91,198,198,122,158,155,92,194,86,207,226,5,157,25,14,21,92,134,60,155,188,149,56,85,51,182,96,111,198,102,135,103,147,117,36,203,143,92,221,120,89,227,27,85,204, +47,213,35,94,127,100,138,127,157,168,210,111,91,100,101,123,252,17,101,165,217,226,89,252,213,61,253,60,185,55,9,34,41,165,19,11,59,174,162,170,135,65,249,137,64,95,235,126,182,4,210,77,125,92,90,33,100,30,153,217,143,86,81,243,116,247,119,245,51,49, +51,197,92,181,156,132,14,26,30,150,88,17,215,35,172,140,141,94,97,19,39,165,228,236,217,179,28,60,120,144,76,38,99,68,221,8,186,225,166,136,180,88,108,235,94,189,241,230,215,233,6,74,51,19,41,206,85,35,190,56,231,243,241,98,157,185,64,33,211,216,117, +77,41,138,145,102,50,84,84,98,117,213,13,158,118,61,115,37,12,152,228,179,53,209,200,6,95,60,47,27,68,234,213,152,183,225,74,23,235,167,116,36,157,207,14,228,29,134,210,150,165,66,36,201,103,3,182,164,211,150,87,211,174,151,179,182,205,2,220,186,144, +167,55,212,135,39,106,252,239,83,51,60,88,10,24,114,44,218,145,17,208,168,191,127,66,151,203,95,221,221,207,142,156,11,90,53,187,12,34,64,135,211,224,143,130,116,87,117,77,217,174,164,49,36,77,59,125,104,145,7,237,167,255,174,113,28,155,145,193,17,138, +103,142,161,27,201,141,2,116,164,136,234,33,86,198,185,230,39,155,153,153,193,247,125,60,207,51,23,135,17,116,67,91,69,123,185,122,72,173,241,99,77,41,214,248,105,241,111,77,43,174,248,138,19,213,144,143,205,212,248,114,57,36,76,135,54,168,52,187,60, +80,154,250,188,206,89,13,89,104,88,221,221,70,184,215,68,188,100,94,118,178,92,186,18,58,44,153,244,247,110,180,5,21,208,237,36,45,75,159,216,237,177,59,155,182,44,21,137,112,55,66,22,242,154,45,75,141,181,221,78,171,220,87,240,191,79,205,240,231,231, +139,160,147,201,107,237,112,177,215,148,38,43,5,63,189,189,147,159,218,217,73,222,145,75,75,194,52,16,22,33,170,177,170,64,148,214,56,89,11,233,72,226,72,34,115,247,1,209,162,63,209,116,23,58,232,235,238,99,98,102,18,203,74,230,248,233,88,19,213,2,50, +61,185,21,63,95,99,102,250,209,163,71,185,239,190,251,200,231,243,166,140,205,8,186,161,117,209,94,186,122,135,177,98,50,140,185,236,199,212,226,100,9,47,71,138,49,63,226,145,82,200,199,230,234,156,170,69,216,122,254,13,153,36,152,45,54,224,27,63,123, +66,152,0,246,26,173,237,64,105,130,70,203,210,121,22,86,175,35,217,225,218,116,59,22,185,84,184,149,128,157,89,155,167,119,121,220,87,112,25,201,218,20,210,201,94,243,197,121,153,245,58,181,236,180,73,8,188,225,98,46,25,175,71,188,241,228,12,127,115, +185,76,143,35,105,195,92,14,52,48,19,41,250,29,139,63,58,216,199,139,134,115,160,150,203,85,144,160,2,40,125,41,25,200,98,229,174,111,241,43,112,114,54,182,43,18,65,207,28,64,107,181,68,208,93,219,101,184,119,128,185,210,44,97,28,35,165,68,197,42,77, +140,187,78,126,139,16,204,206,206,114,250,244,105,238,187,239,190,59,190,140,205,8,186,97,25,225,94,169,101,169,226,74,61,230,120,53,228,100,61,68,165,243,178,139,161,102,52,136,56,92,9,249,106,41,96,58,72,147,207,184,154,49,238,73,65,206,8,116,91,153, +223,178,52,74,227,216,138,100,178,213,193,172,205,190,156,195,128,107,165,131,63,146,129,93,251,115,14,223,220,225,178,43,235,144,119,150,107,89,202,85,119,184,89,23,55,140,152,255,231,68,133,63,56,91,228,19,179,117,250,218,212,40,70,105,168,42,197,147, +186,61,222,180,191,135,167,119,103,87,174,195,23,64,92,67,215,207,163,197,42,37,64,107,236,156,133,176,5,56,3,104,153,95,118,99,24,197,17,61,29,221,244,117,247,49,54,57,222,20,250,235,37,198,53,176,44,139,185,185,57,166,167,167,233,237,237,53,130,110, +4,253,14,92,36,26,38,242,50,53,218,115,65,204,137,106,200,87,203,1,103,106,81,34,220,74,83,140,21,227,190,226,120,53,228,148,31,161,226,229,91,150,246,59,198,29,222,78,34,173,9,22,181,44,213,34,105,89,250,204,46,143,67,5,151,97,207,34,111,75,4,224,165, +130,190,55,235,208,237,90,155,166,101,169,97,209,61,154,182,112,253,195,115,179,252,198,153,57,42,145,166,167,77,141,98,0,42,177,226,231,119,118,241,186,157,29,244,123,206,117,221,213,58,152,68,215,47,130,92,173,160,131,180,37,210,6,145,127,52,215,26, +39,36,132,96,164,127,136,217,210,44,245,48,25,216,162,34,69,28,37,22,187,190,78,198,123,177,88,228,202,149,43,244,246,246,26,43,221,8,250,109,100,93,47,99,88,55,255,85,92,221,154,207,197,138,75,181,152,175,22,125,62,62,231,51,233,199,205,206,103,213, +88,51,29,42,70,131,152,217,40,153,213,217,24,16,98,9,129,43,160,223,146,215,170,90,49,92,123,157,91,214,139,157,212,79,235,134,113,147,124,183,5,143,202,121,60,185,203,229,80,222,97,56,109,89,42,68,50,60,100,155,107,209,239,90,105,61,242,181,132,219, +176,185,172,114,65,45,138,121,243,169,25,254,240,66,9,87,180,167,36,173,97,153,87,208,252,201,61,189,252,240,112,103,226,77,191,166,152,39,77,97,116,249,107,16,151,64,102,86,127,173,11,141,229,89,8,117,32,53,35,226,101,255,46,86,49,29,185,2,253,221,125, +92,154,24,3,161,137,131,152,216,143,144,57,247,186,222,34,215,117,25,27,27,107,54,155,49,24,65,223,28,130,125,141,121,217,177,134,90,156,212,255,106,192,143,53,83,161,226,116,53,224,179,115,1,159,158,243,41,135,113,243,182,10,85,34,222,165,88,17,235, +133,175,97,145,184,202,123,109,113,13,89,50,92,107,209,140,73,226,203,122,222,17,179,4,100,132,192,149,11,231,101,187,182,197,83,58,92,158,218,157,73,92,229,158,196,75,235,227,179,82,144,183,146,199,172,148,120,104,172,237,219,201,42,23,60,48,231,243, +139,199,166,248,74,49,32,155,142,103,93,239,61,23,235,228,158,63,144,119,248,157,3,125,60,173,55,147,214,246,175,70,153,99,168,157,2,225,180,120,35,196,120,61,35,212,74,133,235,94,159,81,28,51,210,191,133,201,185,25,124,191,78,28,68,196,126,136,147,247, +174,251,217,27,211,216,74,165,82,115,26,155,193,8,250,198,185,169,87,104,89,170,148,102,46,138,153,8,21,245,88,161,53,84,149,102,180,30,113,180,18,242,95,51,117,142,84,195,102,45,182,190,186,230,167,89,205,233,136,195,244,121,205,188,236,245,17,54,90, +150,54,230,101,167,95,5,75,50,228,74,58,211,222,225,150,128,88,8,70,60,155,103,116,121,60,182,195,99,103,214,166,211,150,52,34,20,43,21,10,204,51,182,141,43,241,54,183,202,209,240,222,241,10,175,56,50,137,163,18,47,76,59,238,206,64,105,234,10,126,100, +36,207,175,239,239,165,215,181,90,240,220,8,8,167,209,149,35,215,238,14,183,220,101,27,213,240,134,158,14,149,108,178,203,189,206,135,113,29,135,109,253,91,56,121,233,12,58,140,81,65,156,116,141,93,197,107,57,142,195,233,211,167,233,234,234,162,175,175, +207,220,43,70,208,111,182,181,45,86,236,55,93,10,98,206,214,35,206,248,49,97,172,80,10,74,177,226,178,31,115,184,28,242,249,146,207,152,31,33,150,184,195,5,243,187,99,206,239,55,46,89,238,181,12,171,177,182,23,180,44,77,173,110,59,157,210,181,59,107, +211,231,72,10,182,196,18,2,45,96,119,214,225,105,93,46,251,115,14,3,174,221,72,90,152,167,206,201,46,75,45,242,121,152,53,232,78,21,115,73,41,140,120,219,133,50,255,251,244,76,210,190,85,180,103,157,41,199,154,140,37,248,229,93,157,252,202,222,158,214, +59,238,9,208,213,135,91,127,113,173,208,178,128,183,229,241,100,43,61,84,70,39,184,238,246,68,195,64,79,63,87,102,39,152,43,22,81,97,156,36,140,172,242,237,74,36,83,83,83,205,150,176,70,212,141,160,183,247,70,109,168,233,50,214,118,16,41,206,213,35,30, +44,167,89,227,177,38,34,233,53,62,86,143,57,82,9,56,92,139,240,35,181,68,180,61,41,232,182,76,242,89,59,153,63,47,187,217,253,76,64,193,182,120,108,193,77,231,101,91,116,218,22,66,128,99,9,14,100,108,238,206,187,140,100,44,132,148,203,152,213,204,115, +107,154,197,197,176,188,152,63,80,244,121,243,169,25,62,58,85,37,39,101,219,214,158,233,80,241,205,93,30,63,181,171,139,23,15,21,214,92,167,173,235,23,105,121,182,151,170,65,215,83,144,221,7,233,218,19,81,29,155,188,254,235,160,177,109,139,109,131,35, +204,206,205,17,5,17,42,142,208,66,172,106,183,43,132,224,236,153,179,0,220,117,215,93,230,226,50,130,222,218,238,151,121,22,240,114,177,237,32,86,140,214,34,30,41,7,124,124,206,103,52,181,170,163,52,126,61,25,198,156,247,99,198,131,164,149,233,252,177, +155,158,20,116,10,129,48,45,75,215,197,226,101,32,158,87,159,221,88,222,148,128,253,89,135,39,117,121,28,200,59,108,241,44,10,150,76,147,207,36,59,61,139,17,207,194,179,175,213,178,84,25,201,54,180,180,126,8,41,249,240,100,149,159,60,60,201,249,122,68, +175,35,219,230,67,155,8,21,223,55,148,231,215,247,247,176,51,231,174,77,204,133,64,199,69,116,229,68,107,122,174,99,176,58,144,133,251,17,194,69,104,255,90,73,238,139,30,171,233,46,116,49,208,219,79,169,90,71,133,10,153,118,195,91,205,134,0,9,99,99,99, +236,218,181,11,207,243,76,179,25,35,232,43,36,160,53,199,38,235,230,24,77,210,174,102,211,97,204,185,90,204,23,139,117,62,62,231,51,19,40,172,244,239,124,165,41,199,201,168,78,63,214,205,231,111,148,123,217,2,250,76,231,179,53,139,181,106,204,203,230, +234,38,94,164,245,239,86,163,121,77,122,14,165,37,248,166,130,203,51,186,51,220,181,160,101,169,32,39,69,50,237,107,201,188,236,121,214,182,210,24,217,54,172,219,122,22,130,80,105,222,118,110,150,223,58,51,199,92,164,232,111,83,125,121,168,53,161,134, +159,216,209,201,111,237,239,77,178,227,215,42,106,66,64,229,17,8,175,208,90,39,27,13,118,1,220,161,228,105,92,155,213,42,186,210,26,219,178,217,210,55,68,121,252,44,81,16,226,186,214,170,29,92,150,180,168,215,235,156,56,113,130,123,238,185,199,148,177, +221,41,130,126,205,121,217,105,249,214,108,20,39,99,4,53,212,211,58,236,99,85,159,143,205,248,60,80,14,80,169,64,235,244,66,12,231,181,214,92,24,191,78,93,229,182,137,97,175,133,168,177,137,106,136,183,78,66,107,153,52,244,80,176,45,220,70,231,51,160, +207,77,146,207,158,208,233,178,43,103,211,235,88,56,105,242,159,45,4,142,152,159,195,48,127,195,118,251,205,203,54,108,52,171,92,112,197,143,120,229,225,41,190,48,83,71,161,201,181,107,74,90,164,217,151,115,248,229,61,93,188,100,184,144,180,83,94,239, +132,186,218,57,208,81,139,59,237,8,225,244,33,220,193,164,186,195,145,104,165,87,189,39,80,74,209,221,217,69,111,169,147,122,16,225,10,209,242,253,88,42,149,168,84,42,228,243,121,115,225,221,46,130,126,189,150,165,126,148,212,91,159,247,35,130,56,17, +226,114,172,184,236,71,28,41,69,124,166,88,231,116,61,66,170,171,155,0,193,213,121,217,203,189,158,99,58,162,173,205,218,214,16,44,158,151,141,70,10,193,160,99,177,61,99,209,235,72,114,150,196,78,147,207,182,121,22,207,232,246,184,183,224,177,197,179, +112,23,123,58,230,137,244,226,95,107,211,13,205,112,51,13,136,116,193,120,168,232,243,67,223,152,224,76,53,34,111,9,214,235,100,23,36,37,146,211,145,226,153,61,25,254,248,80,63,251,242,14,106,221,253,7,36,196,1,170,114,56,105,251,42,91,27,128,34,50,59, +193,233,2,173,145,142,133,215,153,33,40,214,86,101,233,39,247,189,100,168,107,128,113,167,140,82,170,165,163,100,89,22,51,51,51,156,63,127,158,67,135,14,25,43,125,179,9,250,181,230,101,163,20,163,245,100,46,246,137,122,72,24,39,11,124,49,82,140,250,113, +210,178,180,226,83,13,85,250,92,98,94,203,82,40,52,10,179,13,109,97,225,188,236,171,163,55,61,75,112,40,231,112,32,151,184,194,27,89,227,150,132,187,178,14,143,237,112,217,145,177,201,216,43,180,44,197,204,203,54,108,108,49,127,219,249,34,191,115,118, +150,177,32,166,195,106,207,96,149,186,74,214,179,151,111,41,240,214,131,125,116,219,178,61,247,129,4,202,39,32,156,105,173,92,77,43,176,59,17,185,3,205,157,186,176,37,157,123,6,152,120,224,28,194,90,157,52,43,165,232,200,230,9,11,54,211,148,91,206,201, +179,109,155,217,217,217,102,75,88,195,6,19,116,33,146,88,231,114,251,57,52,76,250,33,39,170,17,159,154,243,57,95,143,17,169,96,148,35,197,100,16,115,186,22,113,214,143,136,151,153,151,157,21,130,156,99,84,187,157,92,157,151,173,155,141,107,148,16,12, +185,146,103,118,102,184,187,224,48,226,89,228,45,43,105,29,107,9,246,100,108,118,101,108,58,93,139,229,147,207,48,77,84,12,155,76,204,19,227,225,85,135,39,249,240,68,21,13,109,17,115,128,106,172,25,112,37,111,216,211,205,15,109,237,68,8,218,186,169,213, +225,12,168,122,50,232,126,213,15,138,17,178,0,217,189,243,60,96,233,218,221,98,36,43,86,138,145,238,65,170,149,144,74,173,130,109,217,45,28,119,201,204,204,12,179,179,179,116,119,119,175,160,29,6,251,230,223,16,201,197,228,215,235,140,94,25,231,252,196, +36,39,107,17,159,19,57,206,218,93,88,142,71,20,39,177,238,185,72,49,22,196,148,147,186,163,52,107,60,45,247,146,38,249,108,61,40,86,174,28,89,50,49,77,10,30,157,179,249,214,238,12,119,229,211,94,227,150,68,200,164,243,217,160,99,37,19,163,204,188,108, +195,237,42,228,233,255,157,40,135,188,230,200,36,159,153,245,233,74,7,229,172,247,202,214,36,201,182,59,114,14,239,188,111,128,187,59,220,212,170,109,211,61,35,36,168,16,93,121,4,162,74,11,238,118,13,88,80,184,15,220,129,196,90,39,237,62,233,218,45,127, +112,29,107,114,221,5,30,123,240,177,140,143,141,115,234,212,169,166,30,172,6,215,117,185,120,241,34,133,66,129,193,193,65,227,118,191,149,130,222,176,200,199,39,38,248,203,127,250,7,62,248,153,79,224,199,1,113,20,19,104,168,9,151,106,255,54,130,61,143, +71,111,217,141,204,100,145,217,28,150,155,161,199,146,201,214,88,52,190,207,19,141,102,163,108,115,114,151,136,118,35,169,47,253,239,198,45,106,167,189,164,179,86,210,217,76,10,129,2,186,28,201,83,58,61,190,165,203,99,111,206,161,207,181,240,228,213, +121,217,57,41,176,164,153,151,109,184,211,172,114,65,164,225,95,46,151,249,141,51,51,156,171,197,244,164,198,196,122,174,118,145,10,185,43,5,223,214,151,229,207,239,238,167,175,165,174,111,45,188,80,125,12,170,39,105,57,33,72,90,224,13,45,73,106,151, +174,133,82,186,181,232,165,72,92,239,93,249,2,126,183,223,146,152,55,52,196,247,125,14,31,62,76,103,103,39,153,76,198,136,250,173,20,244,175,62,244,117,222,248,214,223,227,240,249,211,105,178,89,242,37,0,143,10,222,133,89,244,216,73,42,247,62,131,104, +112,63,66,197,201,85,100,219,144,201,37,95,217,60,120,46,88,14,88,22,88,118,242,101,219,52,251,10,106,125,245,235,14,16,152,64,45,204,200,215,233,46,186,203,150,108,247,108,186,236,164,124,203,78,133,123,32,99,241,204,46,143,199,117,122,108,205,36,255, +190,208,133,181,252,49,107,100,140,155,123,200,112,39,137,121,41,210,252,242,201,41,222,118,177,68,167,76,75,33,219,160,177,197,72,209,235,88,252,202,158,46,94,181,173,253,46,246,5,247,110,56,137,14,103,91,108,247,170,1,27,145,191,103,201,146,96,185, +54,78,222,69,5,81,75,37,112,90,37,222,186,222,222,94,118,239,222,205,209,163,71,241,60,175,133,243,33,137,227,152,137,137,9,182,109,219,102,46,208,91,33,232,82,74,78,158,62,201,155,127,255,255,112,236,210,69,60,199,89,225,18,7,17,214,200,63,248,17,106, +135,2,130,237,247,32,148,134,48,130,176,8,197,185,84,85,84,34,230,158,7,94,6,188,92,242,221,182,193,118,192,113,193,245,192,113,146,1,4,130,228,49,11,132,126,243,89,219,190,210,248,105,12,187,209,178,212,146,73,172,122,95,214,102,208,181,232,176,37,150, +20,72,33,216,155,179,121,66,135,203,222,172,77,183,107,47,186,241,230,37,159,153,190,226,6,195,178,235,214,169,74,192,27,79,76,243,174,43,21,6,87,217,16,101,53,76,134,49,59,178,14,127,122,168,159,103,247,103,211,176,212,13,49,165,146,50,181,202,195,16, +77,131,213,177,122,35,71,107,240,134,16,222,246,5,107,166,214,96,231,92,58,118,245,49,115,120,20,185,202,124,37,33,5,245,169,50,42,140,176,93,135,158,158,30,114,185,28,65,16,180,52,128,69,107,205,169,83,167,24,26,26,194,117,93,179,118,221,76,65,23,66, +16,4,1,111,253,187,183,241,141,139,231,177,93,239,122,103,29,17,135,228,30,249,40,4,85,130,221,143,71,88,54,168,120,158,32,165,39,223,15,160,238,131,158,73,47,56,1,142,13,142,151,136,189,147,90,242,142,13,94,22,50,89,112,51,169,208,139,133,2,191,65,46, +138,70,203,210,104,94,247,179,164,22,91,242,205,29,30,247,228,29,182,100,146,206,103,150,20,216,82,176,47,99,55,179,201,89,161,101,105,98,89,155,11,223,96,88,173,152,191,115,180,196,159,156,43,242,229,146,207,144,99,209,174,30,101,149,88,241,221,131, +121,254,199,222,30,238,239,184,193,221,207,132,128,176,132,170,157,109,185,84,13,64,118,62,58,93,43,23,77,42,16,2,33,90,116,153,91,146,202,197,89,162,67,1,150,107,211,211,211,195,61,247,220,195,177,99,199,168,213,106,171,118,193,11,33,136,227,152,115, +231,206,177,119,239,222,235,206,88,55,130,222,102,65,63,118,242,4,159,127,248,65,132,101,175,46,130,35,37,66,197,228,142,125,22,194,26,193,190,111,65,88,78,34,234,139,47,86,209,72,149,155,103,202,214,107,80,171,38,34,157,116,127,184,106,189,219,13,23, +189,147,88,245,185,28,120,249,100,3,96,89,11,135,91,47,55,232,186,85,87,215,10,27,95,77,210,157,174,113,29,42,13,72,193,222,156,195,51,58,61,14,21,28,134,50,54,29,105,203,210,156,37,217,226,90,12,185,18,199,50,45,75,13,134,27,34,228,105,94,231,255,58, +53,205,31,159,43,18,40,77,143,45,219,34,230,154,164,44,237,215,247,246,240,99,219,58,232,112,236,27,223,202,84,128,14,198,161,114,172,245,113,169,104,40,220,189,236,175,133,4,203,181,154,101,170,171,87,28,137,138,85,115,97,236,237,237,37,155,205,82,169, +84,90,138,169,71,81,196,196,196,4,59,119,238,196,113,28,115,225,222,44,65,7,120,239,127,254,27,51,197,57,44,103,245,47,167,165,5,90,145,59,253,0,34,168,19,28,120,42,184,217,165,162,190,220,142,116,185,152,78,28,67,20,205,187,181,68,98,205,202,121,9,119, +182,157,88,241,217,52,86,159,201,38,194,207,213,120,255,194,166,54,186,233,2,74,70,154,234,121,237,75,147,197,193,19,2,71,10,172,244,103,5,100,108,201,19,58,92,158,222,149,97,127,222,102,192,179,201,166,45,75,61,9,93,150,196,179,150,127,45,51,47,219, +96,184,33,186,151,116,125,171,71,188,225,228,12,255,48,86,38,35,68,91,186,190,169,70,107,105,33,248,235,123,7,248,238,161,164,219,217,141,239,75,46,64,41,168,158,0,21,38,222,202,85,47,192,49,34,183,15,225,237,92,214,123,41,16,200,180,70,190,213,90,163, +216,143,82,91,73,35,132,96,239,222,189,84,42,21,124,127,245,137,114,182,109,83,169,84,56,121,242,36,7,15,30,52,86,250,205,20,244,137,82,137,48,86,216,78,139,201,36,66,130,37,200,94,62,130,21,250,212,239,126,6,42,219,137,136,195,53,222,177,98,222,15,169, +72,198,81,210,154,9,32,0,170,229,133,27,2,203,78,220,244,217,44,42,155,67,121,57,148,237,160,164,133,146,22,88,22,142,109,147,119,44,242,86,146,9,238,73,176,208,116,186,22,207,234,242,248,230,174,100,94,118,183,99,165,109,15,19,113,151,139,235,195,22, +108,18,76,203,82,131,225,230,89,229,130,143,78,213,248,31,199,167,56,85,141,200,91,146,118,20,197,70,90,19,40,120,82,151,199,111,30,232,229,49,157,153,155,232,69,19,160,124,116,237,56,200,22,173,88,29,130,183,5,132,187,226,159,88,25,59,45,95,211,171, +79,140,19,2,29,171,230,186,38,165,36,159,207,147,207,231,9,130,160,181,141,146,82,84,171,85,234,245,58,185,92,206,92,200,55,75,208,139,90,39,59,212,181,94,148,194,194,189,114,26,25,214,168,221,243,109,196,157,3,136,40,104,211,53,47,150,184,197,84,58, +193,43,6,226,40,64,249,62,162,56,71,78,66,151,37,232,112,44,58,50,30,185,124,14,39,95,160,183,80,96,159,155,101,127,87,150,253,93,57,246,118,230,233,206,103,23,221,32,122,137,123,234,106,18,140,17,109,131,225,150,136,185,76,114,105,254,230,98,145,215, +30,157,166,32,5,25,217,158,166,37,129,210,212,148,230,103,119,118,241,171,187,187,201,56,242,230,79,11,83,149,164,100,173,165,237,137,2,153,67,116,222,159,108,4,150,177,124,53,154,108,95,7,29,219,186,41,158,155,94,117,98,28,2,234,211,21,10,219,122,210, +101,81,227,56,14,119,221,117,23,95,250,210,151,90,19,47,219,102,114,114,146,35,71,142,112,239,189,247,226,121,222,29,111,165,223,20,65,191,119,207,94,190,248,249,164,102,112,205,29,126,164,133,51,117,9,241,181,15,82,121,212,115,80,61,219,16,145,191,246, +235,156,121,117,218,169,75,76,233,100,46,118,175,37,232,179,109,250,92,139,30,87,146,183,36,89,75,210,105,9,6,28,73,159,43,233,177,45,58,109,200,136,42,232,10,81,17,116,89,18,77,102,56,147,205,210,219,63,192,200,200,72,178,147,181,44,164,76,74,195,154, +190,1,173,23,124,55,24,12,55,91,204,37,147,126,196,239,159,153,225,173,23,74,205,124,149,54,216,197,84,98,77,193,17,252,218,238,94,126,114,71,39,183,164,149,177,0,93,121,24,237,95,108,45,33,78,197,144,221,142,200,236,90,217,224,208,160,133,64,183,88, +215,46,132,96,238,236,36,189,119,111,65,218,87,55,1,158,231,49,52,52,196,216,216,88,75,26,225,56,14,227,227,227,108,221,186,149,45,91,182,24,65,111,245,1,45,31,48,173,121,201,183,62,139,127,255,207,15,114,97,98,172,165,242,132,37,79,101,59,216,229,41, +10,15,252,27,149,71,61,155,168,127,39,34,142,175,105,225,54,44,110,197,213,26,109,128,130,37,24,246,36,195,158,205,128,107,209,239,88,116,56,146,172,37,40,72,73,167,45,232,176,36,5,91,146,73,179,201,27,194,159,148,141,37,155,129,146,158,119,243,40,77, +181,90,67,149,43,92,153,156,226,202,149,43,205,133,67,74,137,227,56,236,218,181,11,33,4,182,109,99,219,54,150,101,45,217,181,27,145,55,24,110,168,206,33,45,201,167,102,234,252,143,227,147,60,92,10,200,90,162,217,198,98,189,207,61,27,41,190,181,55,195, +47,238,234,226,233,125,185,102,237,245,77,71,235,100,246,121,203,201,112,49,194,233,69,139,12,11,230,24,47,254,172,150,72,102,155,183,248,217,164,37,81,97,140,176,101,179,2,199,117,93,182,111,223,206,229,203,151,91,214,8,215,117,57,123,246,44,29,29,29, +228,114,185,77,187,126,182,163,157,237,13,183,208,99,165,216,179,109,59,223,243,236,111,231,247,223,241,119,235,179,210,1,101,185,136,122,153,252,215,254,157,226,61,207,32,26,190,11,161,65,104,221,156,231,210,120,118,91,10,250,108,139,173,158,100,196, +179,24,201,216,244,186,201,160,144,76,154,128,150,145,18,55,141,123,219,34,185,169,155,229,98,233,70,160,166,146,68,180,213,156,16,33,68,51,177,99,122,122,122,129,64,11,33,152,153,153,105,254,119,67,232,247,237,219,215,20,252,249,66,223,150,13,149,193, +96,104,98,165,3,159,222,59,86,225,117,71,39,153,137,84,98,153,179,126,49,143,53,148,34,197,15,141,20,248,237,253,61,244,122,22,42,190,85,85,39,2,84,21,93,254,6,45,187,29,84,8,249,3,96,231,147,164,186,21,214,33,11,137,149,138,114,171,68,126,132,149,117, +155,71,93,41,69,62,159,103,247,238,221,156,57,115,166,37,81,23,66,48,55,55,71,169,84,34,155,205,26,11,125,181,187,189,53,111,20,149,226,229,47,124,41,159,248,252,39,249,234,233,83,32,37,182,180,86,28,184,163,105,140,219,36,205,30,79,111,198,244,134,116, +44,27,71,5,116,61,242,81,170,177,79,102,207,163,25,242,108,182,57,130,173,89,155,97,207,166,199,22,100,109,137,77,210,100,197,18,73,20,41,233,92,42,154,175,211,152,199,221,24,62,210,214,197,99,153,139,178,86,171,45,249,221,67,15,61,180,100,83,176,111, +223,62,44,203,194,178,172,166,200,219,150,133,151,201,52,255,166,177,49,154,111,225,27,193,55,24,86,186,31,5,179,126,204,31,157,47,241,135,23,138,68,90,211,37,101,91,90,80,212,149,38,107,73,126,122,79,23,255,103,111,15,150,134,56,190,133,247,162,144, +80,59,14,113,169,197,197,58,2,111,24,145,221,151,174,206,215,142,249,91,158,141,176,90,76,31,212,64,172,150,93,47,119,238,220,73,16,4,92,184,112,161,165,114,52,203,178,56,113,226,4,157,157,157,100,179,217,205,185,14,182,225,61,223,148,24,186,210,154, +238,158,30,254,236,183,254,144,223,253,163,223,227,253,159,250,40,115,65,136,235,122,144,182,35,77,190,146,18,8,7,200,10,65,86,10,114,2,60,1,46,130,14,1,221,18,6,44,201,128,148,244,74,40,92,254,18,249,97,7,235,192,83,192,118,208,97,136,22,44,59,51,251, +106,79,243,91,119,178,151,43,203,88,46,81,230,240,225,195,75,118,196,182,109,179,103,207,30,132,16,56,142,211,20,251,198,244,161,134,197,223,248,123,19,167,55,24,210,77,188,148,28,43,7,188,230,200,36,15,204,5,120,82,224,8,209,22,23,251,76,164,120,66, +151,199,27,119,119,243,172,193,28,42,86,196,183,250,67,11,160,126,118,81,67,152,213,44,214,17,56,189,224,244,173,98,93,87,20,182,246,80,190,60,71,109,170,140,92,165,176,107,173,241,103,171,100,250,11,75,214,105,219,182,41,20,10,184,174,155,204,77,111, +193,187,16,134,33,51,51,51,120,158,119,199,150,177,221,180,94,238,113,28,211,211,221,195,255,249,197,55,240,184,109,91,249,204,167,62,194,233,201,41,166,85,34,224,29,66,147,21,146,14,33,200,203,36,49,173,199,146,244,9,65,135,76,234,185,45,68,83,248,27, +110,113,173,20,213,47,127,26,187,86,197,249,150,103,39,93,226,194,96,243,47,66,203,8,191,214,154,99,199,142,45,16,105,33,4,219,183,111,111,198,229,45,219,198,150,146,161,225,225,166,192,219,182,189,224,49,70,232,13,119,140,85,46,18,215,220,39,38,170, +252,196,145,41,46,212,35,58,219,48,165,81,144,84,187,78,4,49,47,30,202,243,150,131,189,108,203,218,196,177,218,0,159,90,128,138,80,181,243,169,25,179,218,207,171,65,216,136,252,163,192,25,88,209,221,190,116,183,212,154,141,164,149,102,238,212,4,221,251, +7,23,60,172,17,142,221,182,109,27,83,83,83,140,143,143,227,186,238,234,62,177,16,68,81,196,153,51,103,232,239,239,95,245,227,238,88,65,111,199,210,31,199,49,150,155,225,37,63,250,147,188,240,190,123,57,246,225,247,82,60,119,138,140,180,200,10,141,80, +16,133,49,149,40,166,28,197,248,177,110,118,83,171,107,64,44,147,83,41,37,40,69,244,240,151,208,245,42,206,83,158,143,200,228,146,250,242,219,241,132,217,75,79,217,133,11,23,150,136,244,149,137,137,166,160,55,178,236,119,236,216,209,140,207,55,190,47, +110,9,107,68,222,112,59,137,185,210,154,95,63,57,203,95,94,40,51,21,198,116,217,178,45,86,121,93,105,108,33,248,249,221,93,188,105,95,47,5,235,22,187,216,23,173,137,186,114,12,170,71,19,11,125,181,45,90,117,12,118,1,145,221,147,138,180,190,142,165,13, +210,182,82,203,92,183,252,30,85,164,146,13,129,94,40,234,82,74,70,70,70,40,149,74,132,97,184,106,43,93,74,73,16,4,92,188,120,145,221,187,119,111,186,235,181,29,87,207,77,159,135,30,199,113,210,140,229,254,167,112,111,71,23,234,63,222,69,124,241,36,177, +180,146,56,182,82,68,74,19,41,77,172,20,190,210,84,162,152,74,16,81,14,21,126,20,47,141,234,72,9,194,38,58,241,8,186,90,193,249,214,23,34,11,221,215,239,42,119,27,139,252,244,244,244,18,161,158,157,157,109,186,230,27,55,201,158,61,123,240,60,175,233, +198,119,28,103,65,124,126,177,135,192,96,216,232,136,116,73,152,10,98,94,254,240,4,95,153,245,209,64,71,27,196,28,160,170,52,59,50,22,191,123,87,47,223,62,144,75,215,53,189,177,14,128,127,9,84,176,122,49,79,76,103,176,59,192,27,92,157,186,104,141,180, +45,132,108,61,49,78,107,77,236,199,216,89,103,217,174,151,131,131,131,156,63,127,30,223,247,87,157,32,215,232,241,126,234,212,41,92,215,101,199,142,29,137,222,24,11,253,134,171,58,177,144,176,255,209,40,55,131,255,190,191,69,157,59,10,182,131,45,5,78, +234,110,78,60,57,169,123,125,222,176,146,48,82,84,163,152,114,152,124,213,162,136,80,9,180,148,168,209,243,132,255,249,207,216,207,248,46,68,223,0,68,209,146,204,250,149,4,235,182,178,78,150,185,9,170,213,234,18,113,254,198,55,190,177,224,120,204,79, +202,107,100,221,55,226,245,174,235,46,249,59,147,144,103,216,104,86,57,192,3,179,62,175,57,58,197,35,229,144,188,37,214,157,197,46,128,48,109,56,117,168,224,240,174,251,6,216,153,75,154,174,196,27,234,178,151,105,185,218,35,16,149,193,106,37,235,91,35, +156,126,200,108,91,157,187,189,113,108,92,171,229,49,235,104,157,244,116,95,230,196,52,214,235,125,251,246,241,224,131,15,18,199,113,75,86,122,24,134,204,206,206,50,60,60,140,109,219,119,212,186,100,223,178,87,214,73,131,126,185,235,0,222,247,190,10, +255,221,111,71,157,250,6,218,113,209,203,236,42,173,52,83,29,192,115,45,10,174,197,224,252,61,130,210,212,162,152,114,168,40,251,115,212,63,243,94,120,198,119,33,182,223,133,80,49,90,169,166,248,248,190,191,236,116,159,249,73,101,183,35,203,125,182,149, +118,176,143,60,242,200,146,155,172,97,205,75,41,113,93,23,41,37,29,29,29,88,150,181,192,242,55,110,124,195,173,217,196,10,106,74,243,182,243,69,254,223,217,57,102,35,77,161,77,179,203,43,177,166,211,150,60,127,48,199,91,14,244,145,149,201,154,179,241, +220,19,2,234,23,193,191,220,250,236,115,153,133,252,61,172,38,187,253,234,189,173,232,222,59,64,125,162,68,84,11,17,171,233,178,39,64,199,154,176,92,199,237,88,185,225,77,71,103,39,249,124,158,153,153,153,101,189,144,43,225,56,14,151,46,93,162,183,183, +151,109,219,182,221,81,86,186,125,203,223,65,28,35,71,118,225,189,252,181,4,239,126,59,209,225,175,32,92,111,137,171,232,122,183,142,148,130,130,103,211,225,9,68,193,131,48,68,125,253,35,100,30,251,24,156,93,135,136,227,152,48,76,122,192,79,79,79,115, +229,202,149,166,139,166,145,77,89,42,149,150,76,253,105,196,159,111,87,86,187,243,21,66,112,234,212,169,5,2,173,148,98,251,246,237,77,145,183,109,27,41,229,130,164,148,70,12,191,241,56,147,144,103,184,81,98,62,21,196,252,252,241,105,254,230,114,153,1, +203,194,147,237,17,243,217,72,177,197,179,248,141,125,61,188,108,164,176,1,173,242,69,98,25,206,64,84,108,221,221,110,101,32,183,183,245,151,148,178,165,90,119,33,4,81,205,167,120,122,130,142,145,30,226,101,106,2,180,214,216,150,197,161,67,135,56,122, +244,40,115,115,115,45,121,85,45,203,98,106,106,138,158,158,158,205,91,198,182,41,5,61,21,117,171,127,11,222,203,94,11,239,253,75,194,175,127,54,153,129,110,181,246,246,244,252,146,52,199,129,169,49,252,15,252,3,226,101,175,67,14,12,227,202,196,29,53, +50,50,210,108,203,26,199,113,211,165,51,51,51,195,220,220,28,74,41,162,40,66,74,201,204,204,12,211,211,211,77,43,180,105,201,91,214,134,153,161,126,243,22,205,165,59,254,75,151,46,45,184,89,148,82,12,12,12,224,121,94,243,49,141,99,183,117,219,54,220, +212,125,111,217,118,154,119,99,172,121,195,122,175,75,201,215,103,234,188,241,244,44,31,154,168,178,197,109,223,236,242,169,72,177,55,231,240,215,247,246,243,196,238,100,176,138,218,176,98,158,212,235,234,218,25,116,84,106,205,66,23,64,102,55,50,187, +191,37,119,187,6,44,199,74,122,226,183,18,212,72,7,226,92,235,126,215,90,147,207,231,217,186,117,43,147,147,147,45,101,174,75,41,185,116,249,50,67,67,67,100,50,25,99,161,223,108,116,28,35,186,122,241,190,231,213,136,66,39,241,137,71,80,147,151,65,174, +241,45,106,13,217,14,226,51,71,169,191,239,175,113,159,251,82,172,237,251,65,171,5,46,152,70,185,23,36,137,24,131,131,131,104,173,155,238,249,106,181,74,185,92,38,142,99,162,116,252,234,244,244,52,99,163,163,11,220,64,119,66,92,126,217,11,104,177,200, +11,193,204,188,132,188,198,152,68,173,53,211,83,83,137,184,55,66,27,90,179,115,215,46,114,185,92,211,194,183,45,107,201,178,96,68,222,176,146,38,72,75,242,214,243,115,188,253,124,145,83,213,136,1,87,210,174,222,108,129,210,188,114,107,7,63,189,187,147, +253,57,119,131,148,164,93,83,198,32,156,130,202,215,210,113,169,118,75,143,149,217,221,32,236,36,219,125,181,40,141,116,45,90,30,77,151,78,93,83,97,140,112,228,138,157,56,133,16,116,117,117,49,50,50,194,248,88,107,173,195,29,219,230,220,217,179,228,114, +57,10,133,194,29,177,142,216,27,234,221,196,49,34,223,129,247,130,31,38,250,226,71,8,62,247,17,212,149,139,233,76,242,181,94,227,146,248,200,87,9,84,140,251,180,231,99,29,188,63,141,223,47,117,253,54,132,126,190,56,23,10,5,58,58,58,22,88,146,91,182,108, +97,223,222,189,68,13,55,190,214,76,207,204,112,241,194,133,5,238,101,65,154,204,151,110,14,196,188,139,249,182,21,127,173,87,188,233,202,229,242,18,107,188,92,46,39,226,46,146,142,126,113,28,179,103,207,30,242,133,66,51,243,190,145,152,183,56,177,113, +177,117,111,184,131,132,92,10,34,165,249,217,195,147,252,229,165,18,150,128,14,91,180,69,202,3,173,177,16,252,193,193,62,94,54,156,199,181,229,38,16,243,228,192,232,168,136,14,166,91,31,151,138,5,185,187,88,75,234,160,176,100,226,118,95,177,247,231,242, +231,80,41,133,138,21,150,35,175,107,165,119,117,117,49,54,58,218,242,117,82,42,149,168,215,235,100,179,217,219,58,116,186,49,5,61,21,117,188,44,246,147,158,11,185,14,130,255,122,119,34,234,142,75,235,169,148,36,113,36,41,136,79,60,76,16,250,216,51,147, +73,3,26,33,87,44,107,187,158,11,216,113,28,92,215,93,240,111,253,3,3,236,221,187,183,25,171,111,184,236,175,92,185,194,216,232,232,130,206,69,97,24,226,251,254,146,236,242,219,253,130,91,238,243,53,242,26,230,91,243,199,142,29,91,32,222,113,28,179,99, +231,78,58,59,59,155,199,223,182,109,114,185,92,179,61,228,252,99,105,98,245,183,241,53,212,232,250,86,10,248,95,167,166,249,215,43,85,10,150,164,29,19,79,99,157,136,121,183,107,241,23,247,244,243,220,190,44,40,189,177,74,210,174,169,230,58,153,125,238, +95,6,43,223,194,38,60,70,20,14,33,114,119,173,45,140,168,52,61,7,183,112,229,43,103,86,53,243,162,249,178,97,76,84,15,177,50,246,117,108,4,205,214,173,91,153,157,157,101,108,116,180,165,150,176,90,235,230,120,213,222,222,222,155,63,190,246,142,23,116, +72,132,214,118,176,31,255,116,68,38,143,255,129,191,69,141,95,2,215,91,227,181,158,220,237,241,169,195,196,231,79,65,189,138,251,140,23,162,45,43,217,64,180,108,132,46,111,25,54,226,197,141,248,49,64,103,103,39,123,247,238,37,12,195,102,172,126,122,102, +134,203,151,46,33,101,50,31,89,107,141,239,251,20,139,197,171,162,151,90,172,235,153,78,183,57,204,45,177,96,71,77,218,142,115,254,241,21,82,114,238,220,185,5,191,139,162,136,145,145,17,186,186,186,154,199,190,97,197,247,244,244,52,75,236,230,31,63,83, +98,183,185,177,210,2,243,119,141,150,120,227,137,25,198,131,246,52,138,129,100,114,98,61,214,188,120,48,207,155,246,245,176,183,224,110,14,171,124,254,221,163,106,80,57,154,184,205,91,125,180,221,9,194,91,251,171,183,216,125,79,88,146,250,76,133,210, +133,41,178,61,59,150,77,140,91,108,68,117,119,119,51,57,57,137,106,101,192,151,16,84,42,21,78,159,62,77,111,111,111,211,179,103,4,253,166,139,186,2,33,176,238,251,38,60,207,195,255,151,183,161,174,92,74,45,245,181,126,90,7,194,0,255,67,255,136,14,234, +184,207,126,105,18,103,106,115,89,195,114,23,204,252,132,142,109,91,183,178,109,235,214,102,66,30,36,238,232,177,177,49,4,16,197,49,90,107,106,181,26,87,174,92,89,208,8,102,126,204,255,142,178,204,22,89,247,150,101,37,222,143,177,177,69,14,158,152,225, +225,97,114,185,92,83,208,133,16,12,14,14,146,207,231,17,128,149,102,227,27,145,223,68,98,110,9,116,172,249,131,51,179,252,210,201,105,58,100,50,214,184,29,103,44,84,73,179,152,95,219,215,195,207,238,232,68,110,22,23,251,226,141,113,88,130,234,241,214, +221,237,58,128,220,221,32,173,214,123,191,167,158,53,203,181,215,246,158,245,245,157,252,141,186,244,157,59,119,50,62,62,206,244,244,116,75,86,186,109,219,84,210,245,117,104,104,200,88,232,183,12,173,65,41,236,187,30,133,248,254,215,83,255,231,63,71, +93,62,187,190,152,186,109,67,28,17,252,215,187,209,181,42,222,243,94,14,94,246,134,119,149,91,41,86,223,16,231,222,222,94,122,123,123,23,252,187,239,251,76,77,77,161,181,38,10,67,148,214,84,171,85,46,92,184,176,64,228,27,207,117,39,196,136,150,243,136, +44,222,201,79,77,77,49,49,49,177,224,120,143,143,143,55,71,43,54,194,31,13,11,191,217,7,63,21,127,147,117,191,209,206,179,228,108,37,228,215,79,205,240,143,99,101,58,173,171,61,41,214,105,211,82,83,154,1,215,226,143,247,247,243,178,45,249,77,228,98,95, +186,86,234,218,25,116,56,153,212,147,175,250,113,10,225,14,35,114,7,89,83,72,51,125,109,219,181,155,89,246,172,218,120,22,168,40,41,27,110,62,118,69,251,78,53,219,87,151,74,165,150,198,112,11,33,168,84,171,140,143,143,51,56,56,120,91,91,233,246,166,184, +80,99,133,220,117,23,153,31,248,239,248,239,254,115,162,83,135,17,182,219,250,156,223,230,10,97,131,138,9,63,243,31,16,134,184,223,254,125,136,142,238,155,222,42,118,57,145,159,159,48,151,205,102,217,190,125,251,2,75,50,138,34,182,109,219,134,214,186, +233,198,7,152,155,155,227,252,249,243,75,4,110,185,11,247,78,232,146,55,255,56,56,142,211,172,86,152,191,64,204,205,205,45,104,117,171,148,98,203,150,45,12,12,12,52,119,246,13,161,95,105,179,100,4,255,6,122,101,4,8,41,248,143,201,42,175,63,50,197,120, +61,34,111,201,182,136,185,2,42,145,226,59,250,179,188,113,95,15,247,118,110,240,146,180,235,18,163,43,223,0,209,162,7,83,71,144,217,154,204,62,95,207,230,200,150,13,131,187,197,151,87,232,72,33,157,235,143,177,85,58,41,137,109,212,166,183,114,239,57, +142,195,196,196,4,151,47,93,102,235,182,173,198,66,191,197,170,158,54,160,217,65,230,229,175,167,254,47,127,78,116,60,105,89,202,90,173,210,212,189,20,126,233,99,16,133,184,207,126,41,98,96,56,113,245,223,202,69,90,95,237,108,188,248,130,109,88,146,61, +61,61,75,254,125,104,104,136,93,59,119,17,197,17,97,24,54,51,200,79,159,62,221,28,194,210,16,178,70,66,222,124,113,191,19,18,242,22,127,198,40,138,22,38,229,105,205,153,51,103,56,127,254,124,211,2,136,227,152,161,161,33,134,135,135,155,131,35,26,93,242, +60,207,107,122,88,26,155,2,147,144,215,166,77,153,20,132,177,226,29,151,42,252,236,241,41,98,173,201,166,45,92,215,139,175,52,190,134,87,111,235,228,183,238,234,193,181,36,42,86,108,222,179,37,18,183,121,112,101,109,91,155,252,221,73,18,157,94,123,152, +65,88,130,158,131,91,152,124,232,98,11,241,109,136,195,24,21,39,130,190,26,25,176,44,139,142,142,14,28,199,33,8,86,63,85,83,8,65,24,134,20,75,69,6,130,129,150,92,246,70,208,111,216,38,52,70,244,15,147,249,190,215,18,126,238,63,137,190,248,49,84,105,118, +237,46,120,145,76,106,11,191,246,25,8,3,156,103,191,24,57,178,43,25,154,174,55,94,12,237,90,66,33,132,32,147,93,216,64,161,183,183,151,237,219,183,55,133,171,17,151,63,125,250,116,211,34,213,90,19,199,49,197,98,113,73,214,253,237,158,144,183,82,239,128, +197,173,34,199,198,198,24,93,84,50,211,72,202,235,235,235,107,90,0,82,74,10,133,194,2,215,126,227,249,77,172,190,21,15,139,228,92,53,228,15,207,206,242,87,163,101,28,33,176,69,123,186,190,149,98,205,86,207,226,71,183,117,242,63,247,116,161,99,189,49, +91,184,182,248,201,116,237,84,146,225,222,74,51,25,29,129,59,132,200,221,147,186,188,213,186,222,131,116,90,91,47,164,109,81,185,52,67,109,123,47,157,59,251,209,171,152,34,223,40,99,107,244,121,111,69,152,29,199,225,252,249,243,244,244,244,52,55,232, +70,208,55,130,168,247,244,227,60,253,133,136,108,158,224,227,31,64,87,102,193,90,163,168,203,164,124,45,60,252,21,212,236,4,206,179,94,140,115,207,55,161,149,216,116,157,224,86,186,64,27,83,212,32,169,171,31,28,28,108,54,202,81,74,17,4,1,23,46,92,104, +138,89,227,107,124,124,124,137,232,221,137,73,121,203,9,191,235,186,11,146,242,26,27,163,254,254,254,102,46,68,195,43,208,213,213,69,119,119,55,58,173,209,111,108,148,26,45,135,141,69,159,222,138,105,73,218,151,102,235,188,250,200,36,71,203,1,29,150, +108,139,85,46,129,137,80,241,220,190,44,111,220,219,205,19,122,178,155,47,241,109,229,11,20,42,71,214,224,239,86,96,119,182,86,226,118,173,99,236,172,45,49,78,183,120,30,164,148,228,243,121,122,122,122,22,86,6,173,242,177,147,147,147,116,119,119,147, +201,100,110,187,123,110,115,174,204,113,140,40,116,36,179,207,179,121,252,127,127,7,186,60,215,114,171,216,5,162,30,71,68,39,30,70,77,141,195,139,234,216,247,63,181,237,217,239,27,65,232,27,255,221,104,218,34,132,32,147,201,112,239,189,247,54,69,166, +209,250,118,112,112,16,165,20,113,20,53,51,239,27,226,191,56,243,254,182,47,175,91,97,113,152,191,152,56,142,67,177,88,100,102,102,102,129,181,223,209,209,65,87,87,23,90,41,172,116,51,212,211,211,195,208,208,16,74,169,5,243,233,23,215,201,222,41,34,111, +9,1,18,222,125,185,196,207,29,159,102,60,136,233,110,83,73,154,6,70,67,197,143,108,41,240,123,7,122,233,247,172,219,71,204,147,139,4,85,57,154,228,0,181,98,161,199,62,210,219,133,112,251,88,111,242,128,0,44,207,78,14,118,75,29,96,5,113,24,161,244,242, +147,215,86,90,207,186,187,187,25,25,25,97,106,106,106,65,153,240,106,238,217,75,151,46,161,148,226,158,123,238,89,16,142,52,130,126,139,69,29,199,197,126,226,179,16,110,134,250,191,254,245,250,68,93,8,68,182,128,46,206,226,191,231,47,161,94,195,126,210, +115,32,86,192,237,183,168,174,100,21,54,178,229,61,207,99,231,206,157,205,191,105,8,77,28,199,108,217,178,165,217,64,167,97,225,55,220,248,203,185,176,239,164,150,184,203,137,188,239,251,11,202,235,148,82,76,76,76,112,241,226,197,5,199,167,171,171,171, +57,195,185,33,242,246,188,18,187,219,85,232,45,1,213,88,241,139,71,167,121,223,120,133,185,72,183,77,204,3,173,41,88,146,223,221,223,203,107,119,118,146,181,196,230,204,98,95,113,221,178,208,245,179,73,51,153,86,173,115,167,19,242,7,147,124,162,54,24, +47,210,110,204,183,104,225,126,23,160,2,149,108,40,68,107,235,215,192,192,0,195,195,195,76,78,78,182,100,80,52,6,183,212,235,117,242,249,252,109,181,254,108,110,223,169,138,65,74,172,199,61,149,140,227,225,191,239,237,168,169,9,112,215,90,171,174,193, +113,208,213,34,245,15,252,45,110,181,130,251,204,239,106,219,5,191,217,133,30,146,204,239,70,191,251,249,127,187,101,203,150,166,184,43,165,8,195,144,227,199,143,47,113,41,55,250,225,47,39,132,119,138,200,55,68,189,84,42,45,56,214,165,82,137,43,87,174, +52,19,242,26,73,121,3,3,3,108,221,186,21,165,20,142,235,98,167,179,233,231,47,98,243,99,245,155,165,44,71,138,196,66,187,80,139,120,201,195,227,156,44,135,8,1,5,107,253,245,229,154,100,147,112,119,222,229,15,15,245,241,132,238,76,186,33,189,205,54,231, +2,168,158,4,21,180,54,93,141,8,97,247,33,188,145,182,216,43,26,141,147,115,232,218,55,200,236,137,241,68,220,87,187,140,7,17,90,105,132,37,87,109,60,41,165,200,229,114,244,244,244,44,233,213,113,125,219,77,16,69,17,71,143,30,229,177,143,125,236,130,46, +158,70,208,111,185,168,39,53,140,246,163,158,0,158,135,255,238,183,161,198,46,36,211,214,228,26,221,192,150,3,126,157,240,195,255,132,136,2,156,103,126,119,178,73,184,131,230,234,94,203,34,92,110,190,240,114,59,221,225,225,97,226,56,38,8,3,226,40,137, +203,159,56,113,162,105,241,55,172,254,70,70,254,226,204,251,219,217,141,191,146,55,99,185,204,221,209,209,209,5,22,126,28,199,244,246,246,94,21,249,116,130,93,38,147,33,159,207,55,55,4,27,185,121,142,149,246,106,253,232,100,141,255,126,116,138,139,245, +8,47,205,98,95,207,59,20,36,89,236,26,120,98,79,134,119,220,59,72,191,43,81,74,223,134,126,182,244,250,9,39,64,69,45,88,184,58,177,164,51,59,33,179,189,61,185,66,154,164,17,152,215,154,164,72,199,98,238,244,4,157,187,250,241,250,242,232,22,54,92,90,107, +182,109,219,70,165,82,97,116,116,180,101,79,96,173,86,163,84,42,53,187,77,26,65,223,56,106,131,142,99,236,3,143,134,151,191,14,255,61,111,71,79,141,163,235,213,181,187,224,45,27,29,135,248,31,127,31,58,142,112,158,246,2,68,71,215,29,45,234,171,21,252, +249,162,213,24,172,210,224,137,79,124,98,211,130,143,211,184,124,20,69,156,57,115,166,41,242,141,236,251,201,201,201,37,34,127,187,39,228,173,102,81,178,44,139,217,217,89,166,167,167,23,136,124,71,71,7,35,35,35,40,165,154,49,249,108,54,75,95,95,95,83, +228,55,66,43,92,203,18,148,34,197,239,158,158,227,237,23,75,212,149,34,99,181,43,139,93,209,239,72,94,62,92,224,215,246,247,97,139,13,60,187,124,221,31,88,130,63,142,46,61,0,218,79,91,183,174,230,195,42,176,178,136,252,61,201,52,203,118,245,223,16,2, +225,88,104,221,218,166,76,175,96,36,172,198,74,183,109,155,125,251,246,49,51,51,67,173,86,91,181,17,32,165,164,92,46,115,230,204,25,30,253,232,71,223,54,205,102,110,171,213,81,199,49,214,238,131,100,190,255,167,8,63,253,33,162,175,127,118,125,162,46, +45,8,3,130,79,255,27,58,240,113,158,242,60,228,192,22,35,234,109,176,238,27,153,247,13,1,123,204,99,30,147,36,224,197,113,83,212,47,93,186,180,32,235,94,107,221,140,59,223,73,34,191,146,240,207,95,188,44,203,162,94,175,115,252,248,241,5,11,94,38,147, +105,38,223,53,70,212,2,116,116,116,48,52,52,180,108,230,253,141,20,121,203,18,92,174,69,188,254,232,20,239,25,175,48,224,90,120,109,104,225,42,128,217,72,177,51,107,243,135,7,250,120,246,96,14,20,183,175,152,67,146,186,239,95,68,135,165,214,250,183,107, +13,86,6,50,131,109,222,95,8,108,215,105,253,186,17,2,21,196,107,74,204,107,220,7,91,182,108,225,252,249,243,205,144,211,234,174,69,139,82,169,196,248,248,56,67,67,67,183,133,168,223,126,43,97,28,35,183,236,192,125,214,75,144,153,28,193,23,254,107,221, +150,58,65,64,248,165,143,130,95,195,121,210,115,145,59,246,25,81,111,147,200,47,24,194,146,222,156,150,109,35,128,125,251,246,53,69,166,97,181,15,13,13,17,69,81,242,21,134,104,224,244,153,51,196,81,180,192,141,125,167,181,193,109,28,191,197,117,185,74, +41,46,92,184,176,96,177,106,8,253,229,203,151,155,205,114,0,58,58,59,217,177,125,123,211,141,223,72,200,107,87,43,92,203,146,124,114,162,194,155,78,207,242,249,89,159,97,215,106,53,41,122,69,202,74,115,95,151,199,223,222,211,207,161,130,183,201,187,190, +173,118,11,3,170,122,10,162,25,144,173,12,86,81,8,171,128,200,30,162,157,7,73,0,210,22,45,77,92,107,46,219,126,196,90,130,34,90,107,28,199,97,100,100,164,89,122,187,234,253,144,148,148,74,37,102,103,103,233,239,239,191,45,66,124,246,26,142,224,198,255, +84,81,140,232,29,192,249,182,23,131,227,225,127,242,3,16,212,214,33,234,86,34,234,95,253,36,209,217,99,120,47,121,21,206,254,123,209,113,188,233,106,213,55,139,37,175,231,237,222,5,32,133,0,33,146,225,10,105,66,94,227,107,190,200,55,230,211,159,60,121, +146,96,94,23,184,249,30,130,197,59,248,219,57,11,127,57,145,111,136,250,124,151,189,214,154,153,153,25,174,140,143,55,31,167,181,166,144,207,179,123,247,110,84,186,112,54,50,239,237,69,139,95,179,75,222,50,235,132,37,4,74,10,126,229,196,20,127,127,169, +204,76,168,232,117,100,91,172,242,48,157,93,254,51,219,58,120,221,174,46,6,61,155,56,186,3,54,219,194,2,127,38,25,198,130,162,181,204,114,43,233,14,39,221,36,246,222,174,251,55,86,120,221,57,58,119,244,81,190,60,179,234,196,56,33,72,170,137,90,245,213, +207,187,118,51,153,12,251,247,239,231,200,145,35,45,221,207,174,235,114,249,242,101,10,249,60,91,183,110,189,213,55,171,177,208,87,56,197,16,69,144,203,227,60,235,187,209,142,67,240,145,119,131,95,79,134,179,172,201,189,37,19,33,25,187,128,255,206,63, +66,188,228,149,216,119,63,14,173,84,146,152,103,184,81,42,191,224,30,143,151,201,146,47,228,243,205,89,234,13,250,7,6,154,177,250,40,138,18,151,189,82,156,56,121,178,233,190,111,108,32,106,181,218,146,97,15,119,66,151,188,229,62,99,189,94,95,176,185, +170,215,235,76,167,117,245,66,8,148,214,100,51,25,246,238,217,147,184,235,27,2,159,126,101,51,73,54,185,144,18,145,90,254,179,81,204,207,29,158,230,31,71,203,228,37,228,236,245,103,21,107,146,120,121,143,109,241,150,131,189,188,120,48,151,212,52,199, +119,200,189,40,64,7,87,208,254,229,22,251,183,107,16,22,34,119,224,134,84,227,10,91,38,243,205,91,124,238,200,15,91,222,151,44,88,158,133,160,171,171,11,215,117,87,172,164,89,233,62,80,74,113,236,248,113,186,186,186,232,232,236,76,214,244,59,197,66,223, +84,246,104,28,131,180,112,190,237,69,224,184,132,255,249,46,116,173,2,182,187,182,79,34,4,56,46,122,250,10,245,119,253,49,222,139,126,28,235,177,79,110,152,60,70,124,111,213,105,94,230,216,55,74,197,22,91,167,79,236,239,191,234,178,143,162,102,255,246, +70,77,125,35,134,60,55,55,215,180,230,231,103,221,223,238,53,245,139,147,16,231,139,123,227,123,181,90,229,161,135,31,94,98,241,231,114,57,118,236,216,1,64,214,117,112,108,155,175,21,67,254,224,220,44,31,157,139,232,204,184,96,219,104,219,73,188,101, +50,157,230,161,211,172,235,70,246,245,245,206,183,214,212,21,236,203,59,188,245,80,63,79,239,206,16,199,138,219,49,143,253,154,107,113,163,254,220,110,49,75,219,238,129,194,221,104,221,230,177,209,169,225,35,90,220,12,11,75,50,115,226,10,157,187,250, +177,114,206,154,173,244,66,161,192,222,189,123,121,248,225,135,23,140,171,94,205,53,175,181,230,202,196,4,185,124,254,150,221,227,237,120,213,219,63,155,72,107,136,193,125,250,11,16,153,60,193,7,255,14,93,156,1,47,179,118,119,185,237,160,139,179,212, +255,229,47,240,252,58,246,227,159,145,36,208,41,19,87,223,120,167,95,47,249,185,145,4,230,121,30,66,8,30,243,152,199,52,179,237,27,187,251,75,151,46,53,107,234,27,191,187,114,229,10,190,239,55,99,206,141,133,224,118,29,244,112,173,5,112,241,162,39,165, +196,247,125,142,28,57,130,39,37,165,40,230,61,227,101,254,117,188,10,2,186,28,7,237,184,224,122,224,229,192,115,147,242,80,199,73,126,231,102,146,210,80,203,78,205,79,181,80,232,155,98,14,181,88,243,19,219,58,248,133,221,221,108,201,218,68,209,157,182, +153,182,32,174,64,237,196,26,166,171,105,100,238,0,200,14,18,147,184,189,146,46,44,11,203,181,90,142,163,11,41,136,131,8,43,183,70,99,43,189,46,187,187,187,233,232,232,160,82,169,180,156,44,123,246,236,89,134,135,135,201,229,114,155,54,57,206,110,229, +66,216,196,203,122,82,214,246,205,223,138,200,100,241,223,251,118,244,212,21,200,100,215,113,228,28,168,149,241,63,248,119,232,160,134,243,132,111,75,54,9,38,89,110,83,137,252,252,46,120,141,73,106,176,48,33,175,145,153,63,60,60,140,239,251,77,87,126, +227,113,231,207,159,39,90,148,148,119,39,182,194,21,66,208,149,113,57,87,139,248,255,46,87,249,244,108,72,198,115,177,146,59,16,194,0,2,31,74,179,87,59,138,217,54,56,46,56,30,56,118,42,242,110,114,47,101,115,224,101,147,123,77,36,110,122,95,43,254,240, +96,31,175,216,90,0,41,238,64,49,39,241,20,70,181,196,58,151,45,218,100,58,130,236,110,214,93,240,191,130,137,46,105,204,121,89,67,98,92,176,190,181,83,41,69,161,80,224,222,123,239,229,200,145,35,148,74,165,85,223,135,141,251,246,236,217,179,236,223,191, +31,199,113,110,190,168,183,225,245,238,156,122,31,173,65,41,172,71,63,17,207,243,8,63,245,33,226,211,143,64,24,174,125,4,171,101,67,165,68,240,225,127,129,122,146,1,79,161,51,137,223,27,54,181,208,55,172,242,249,13,90,134,135,135,155,11,199,252,24,252, +224,224,96,51,86,223,16,246,211,167,79,175,106,188,227,237,226,194,151,128,45,224,11,51,117,254,246,114,137,115,245,152,220,130,113,167,34,17,17,33,210,191,158,119,95,250,117,240,107,87,69,94,202,36,17,213,178,82,215,188,69,36,109,10,133,60,111,186,123, +27,175,216,214,145,8,128,90,62,52,112,7,92,169,224,159,71,215,206,183,88,174,22,35,178,187,160,227,177,55,44,118,170,148,34,191,165,155,220,165,89,234,179,85,164,181,250,181,85,181,33,153,81,107,77,103,103,39,133,66,129,98,177,216,242,123,159,154,154, +98,215,174,93,155,182,20,214,110,225,18,218,252,164,179,206,173,131,143,69,118,116,19,124,252,3,68,15,125,14,226,104,237,93,229,108,7,170,37,194,207,252,59,186,84,196,121,250,119,32,250,135,141,168,223,198,34,223,16,226,134,152,116,119,119,47,249,219, +129,254,126,162,180,223,253,124,145,175,86,171,11,74,200,230,91,250,243,227,215,155,73,232,29,33,168,43,197,251,175,84,121,231,88,133,80,107,60,185,202,217,229,105,245,194,82,115,45,134,56,38,214,62,161,214,28,202,57,252,88,1,238,153,62,199,231,62,63, +206,222,125,251,22,52,46,106,132,80,22,159,159,219,111,108,173,0,21,162,75,95,7,34,160,149,114,53,13,78,23,200,27,219,191,92,122,54,210,107,45,49,78,107,205,244,145,81,10,35,221,235,210,154,70,114,235,158,61,123,40,22,139,84,42,149,150,154,205,248,190, +207,201,147,39,111,201,224,150,118,188,210,157,215,145,67,39,25,240,98,100,55,238,115,191,23,28,151,232,203,31,75,251,194,175,181,85,172,141,174,150,9,62,245,126,212,216,121,188,151,190,18,49,180,205,136,250,29,34,244,203,221,244,174,231,177,56,186,217, +211,221,141,210,122,129,200,159,59,119,142,114,185,220,180,16,132,16,84,42,21,130,32,88,82,75,191,209,146,242,4,224,73,193,184,31,243,206,209,18,31,155,241,177,69,34,240,235,127,114,65,168,147,40,239,51,122,179,252,200,72,129,126,207,166,166,20,186,82, +225,193,7,31,92,112,252,109,219,102,239,222,189,75,68,190,179,179,179,41,238,141,227,215,240,176,108,90,161,215,33,212,78,3,45,230,110,40,31,178,251,192,114,111,104,8,85,200,198,134,180,181,215,208,145,74,70,169,202,245,95,63,158,231,209,217,217,73,173, +86,107,249,177,181,90,141,74,165,66,103,103,231,237,107,161,223,118,196,17,162,111,24,247,59,190,31,225,184,132,159,249,80,98,21,172,53,246,41,4,194,205,18,159,120,144,250,63,190,21,239,37,63,129,220,177,215,136,186,17,252,5,215,136,76,199,213,54,104, +140,173,157,239,174,191,124,249,114,115,112,75,163,115,158,16,130,169,169,169,5,73,121,144,116,201,187,21,34,111,9,240,132,224,171,197,128,127,184,92,228,88,53,194,147,237,121,31,2,168,43,77,167,37,248,206,193,2,47,30,202,35,69,210,163,125,190,39,99, +190,53,174,148,226,200,145,35,75,126,191,99,199,142,166,200,55,26,229,12,13,13,53,135,121,52,18,36,231,207,21,216,216,34,47,192,191,140,174,157,105,205,221,142,2,43,135,200,29,2,225,36,177,244,27,100,47,73,219,66,58,214,154,76,206,56,140,215,84,246,182, +248,222,179,44,139,125,251,246,49,57,57,185,108,239,137,107,89,233,115,115,115,28,62,124,152,251,238,187,143,66,161,176,100,164,177,17,244,141,138,138,16,133,78,220,23,252,0,184,46,225,39,254,21,29,71,107,111,64,131,6,199,35,62,123,156,250,59,222,74, +230,37,175,68,238,187,215,136,186,97,69,177,111,36,220,205,79,200,219,179,103,79,242,119,74,39,109,111,85,178,32,77,76,76,80,171,213,154,117,245,82,74,70,71,71,169,86,171,11,166,77,221,104,75,222,78,173,175,15,92,169,240,247,99,21,230,34,69,174,141,98, +94,142,53,7,178,54,47,223,146,231,137,61,89,124,165,137,86,177,192,47,23,247,60,119,238,220,18,145,158,152,152,104,150,53,90,150,133,148,146,29,59,118,52,255,187,209,7,127,177,53,191,33,68,94,8,116,229,33,180,144,173,175,117,185,189,224,12,220,216,248, +169,214,72,43,77,131,108,38,198,233,85,156,119,157,116,247,11,98,236,236,250,19,210,180,214,184,174,203,214,173,91,57,127,254,124,107,215,183,109,51,61,61,205,212,212,20,133,66,193,88,232,155,138,40,2,215,195,123,222,203,16,153,28,254,127,253,83,146, +40,103,173,227,208,184,30,234,242,89,234,239,248,99,188,23,191,2,235,158,111,74,172,127,211,85,206,176,10,145,111,198,234,69,218,31,59,205,100,110,116,178,106,52,198,17,66,48,60,60,76,189,94,111,90,248,82,74,46,94,188,72,177,88,92,96,201,183,43,46,111, +11,40,71,138,119,140,22,249,240,84,157,72,211,54,49,215,64,85,105,158,220,237,241,35,91,11,236,200,58,212,227,245,85,151,47,39,242,19,19,19,75,142,251,236,236,108,243,24,53,196,94,74,201,222,189,123,155,34,239,56,206,242,179,233,27,166,233,205,185,82, +208,193,149,116,186,89,43,15,11,32,187,11,156,238,27,254,94,181,86,116,236,232,165,54,89,38,246,195,22,174,59,221,214,46,127,150,101,177,109,219,182,150,5,29,18,151,253,133,11,23,232,236,236,164,187,187,123,211,132,101,140,160,167,162,174,165,133,251, +204,23,129,231,226,127,232,157,73,121,13,98,237,237,248,28,15,53,57,74,253,221,127,133,23,248,216,143,122,162,169,85,55,180,172,112,243,229,108,126,230,253,114,9,121,141,69,103,96,112,144,48,8,136,211,164,60,72,234,234,167,38,39,151,36,250,52,54,7,11, +172,37,41,151,104,133,20,73,110,250,217,90,204,159,159,47,113,178,22,0,2,175,77,45,243,67,13,89,9,223,53,148,227,37,67,5,178,150,160,30,169,27,98,76,218,203,132,213,202,141,217,244,139,196,185,88,44,166,201,249,162,249,181,111,255,254,166,11,191,17,171, +159,63,104,168,113,142,218,110,217,11,137,246,199,208,149,195,45,94,71,49,216,189,136,252,99,218,222,238,117,69,235,184,144,193,114,44,226,122,216,210,198,67,183,177,211,95,99,102,193,254,253,251,57,113,252,120,75,27,90,1,84,202,101,202,229,114,51,15, +195,8,250,102,66,197,104,33,112,158,242,2,100,182,131,240,203,159,34,58,249,112,146,25,191,166,178,54,1,142,135,158,30,39,248,224,63,162,235,117,156,199,62,57,169,171,141,141,11,222,208,30,107,126,185,177,147,158,235,226,45,234,148,213,215,215,135,138, +227,5,153,247,150,101,113,238,220,57,230,230,230,154,2,36,72,218,189,134,97,216,20,176,172,99,19,43,248,236,108,141,183,95,46,83,138,52,150,16,109,233,108,165,73,226,229,219,60,139,31,24,206,243,212,222,44,161,214,4,55,121,178,202,74,195,124,194,101, +74,15,191,177,168,75,30,192,222,125,251,154,22,124,163,231,125,161,80,104,134,66,230,127,205,63,103,45,137,189,144,232,202,35,16,151,91,52,52,20,216,133,196,58,191,105,7,52,45,83,212,171,116,37,8,65,236,71,204,28,27,37,63,220,185,166,58,246,149,216,186, +117,43,190,239,115,234,228,201,150,58,200,217,182,205,137,70,75,216,142,142,77,97,165,27,65,95,184,82,66,28,97,61,238,233,136,142,110,176,36,209,145,7,146,84,219,181,214,170,219,14,106,122,156,240,163,239,129,106,25,231,91,158,5,185,130,137,171,27,110, +138,224,47,88,99,45,11,119,81,121,215,189,247,222,219,236,134,215,72,30,26,29,29,101,102,102,38,17,160,48,224,202,212,20,239,187,82,231,125,83,53,34,4,118,27,38,217,9,32,210,201,112,149,123,243,14,63,190,173,192,158,156,75,125,163,141,72,91,70,56,151, +123,135,199,143,31,95,112,220,149,82,236,220,185,179,217,141,176,97,197,75,41,233,235,235,107,198,232,27,147,5,87,157,121,95,59,155,88,216,173,8,186,10,17,238,32,194,27,185,41,161,1,173,193,114,108,132,181,134,235,36,214,196,161,66,72,218,22,235,183, +44,139,142,142,14,178,185,92,115,163,218,202,189,52,53,53,69,254,22,182,132,53,130,222,6,107,93,30,120,52,110,190,3,44,155,232,225,47,166,77,49,214,222,128,70,77,141,19,126,234,131,168,203,103,112,95,248,163,200,174,30,180,17,117,195,6,16,252,249,9,121, +112,181,75,30,104,70,103,139,252,212,71,31,228,97,229,224,22,92,236,160,14,65,112,117,118,65,163,142,92,172,62,60,37,0,95,107,92,4,207,27,200,242,125,195,5,58,108,217,204,98,223,140,44,87,98,120,254,252,249,37,34,173,181,102,235,214,173,205,140,123,203, +182,145,66,176,117,235,214,68,240,83,145,111,100,222,95,125,188,76,198,164,214,143,147,212,159,175,214,210,212,32,29,200,238,7,59,119,115,188,131,90,35,29,153,88,217,45,158,82,173,20,42,140,177,51,118,91,45,226,225,161,33,166,38,39,57,119,254,252,130, +13,237,106,238,149,227,169,187,126,215,174,93,27,62,227,221,8,250,138,150,122,140,220,182,7,239,69,63,134,144,146,240,161,47,130,212,107,143,169,91,54,106,110,26,245,165,143,163,171,21,50,47,125,21,244,13,26,75,221,176,225,4,62,138,34,108,75,112,186, +26,241,234,147,85,190,218,189,131,174,110,149,180,110,13,131,228,154,141,163,228,191,253,42,212,107,201,87,24,210,204,214,106,220,39,203,220,47,190,210,116,216,130,31,221,82,224,153,253,89,64,108,106,49,95,113,113,93,161,219,216,216,216,216,18,107,126, +114,114,178,89,130,104,201,100,180,236,238,221,187,241,60,47,113,227,123,57,162,226,49,226,234,12,158,180,16,150,72,115,44,26,27,133,21,21,18,236,46,100,118,207,77,237,14,166,53,116,238,234,103,186,114,41,137,139,139,213,185,221,149,210,168,40,106,171, +52,53,18,72,71,70,70,152,153,157,165,86,171,173,24,98,89,250,150,146,80,212,216,216,24,219,183,111,95,80,226,104,4,125,179,137,122,20,35,250,6,241,94,250,42,180,148,68,15,126,62,217,41,175,85,212,109,39,105,99,249,200,151,169,5,117,188,239,125,53,210, +52,160,49,108,32,44,145,44,98,239,27,171,240,230,83,179,28,171,134,116,91,2,45,68,50,64,197,203,94,13,137,42,149,36,121,198,113,242,93,169,196,122,247,171,80,173,64,181,156,252,156,14,88,137,83,225,217,149,115,248,201,109,29,236,203,217,68,74,19,165, +177,251,249,139,232,237,204,114,66,63,191,77,105,195,146,47,149,74,73,12,94,90,8,52,234,202,191,66,249,60,210,114,241,92,73,54,99,211,145,181,233,232,176,201,58,22,210,145,75,247,81,90,33,156,94,200,237,75,196,253,38,174,159,153,238,28,66,10,90,30,234, +118,131,222,102,79,95,31,133,66,129,74,165,178,106,65,111,156,175,98,177,200,233,211,167,185,235,174,187,22,36,60,26,65,223,92,170,158,136,109,190,147,204,247,190,134,32,91,32,248,226,71,215,215,85,78,202,164,86,253,212,97,252,191,127,11,222,75,127,2, +185,115,159,41,107,51,220,82,4,96,73,65,85,105,126,238,216,20,239,188,92,6,52,5,75,204,203,252,94,198,133,42,173,244,94,72,21,36,171,65,119,207,155,148,6,34,10,168,86,171,116,5,85,126,108,56,199,171,14,109,167,195,117,24,29,31,231,242,232,40,217,212, +234,17,66,16,134,225,146,56,231,252,126,250,183,237,70,106,153,204,251,32,8,18,225,144,30,186,126,6,61,119,18,17,105,32,162,82,3,230,194,36,247,44,109,179,107,91,130,76,198,162,51,107,83,40,216,228,50,54,142,21,226,120,25,178,110,39,104,141,214,242,230, +212,213,107,210,150,253,98,213,158,1,33,4,193,108,141,185,211,19,12,221,191,147,184,141,21,65,90,107,164,16,236,223,191,159,98,177,184,164,65,211,117,247,24,74,81,44,22,169,213,106,45,185,236,141,160,111,68,84,12,110,6,247,69,63,6,94,134,224,83,31,68, +7,117,132,235,177,166,41,182,66,128,237,16,95,60,141,255,207,127,134,251,162,31,195,218,115,40,137,209,155,178,54,195,205,22,115,1,150,37,185,88,9,249,197,227,211,252,243,120,133,30,71,178,170,60,118,189,66,243,144,52,166,174,129,105,233,177,173,63,207, +159,221,221,207,115,251,115,73,156,20,216,223,213,197,222,125,251,22,140,173,157,158,158,230,210,165,75,88,150,213,204,6,247,125,159,114,185,188,160,121,78,35,209,236,246,62,47,105,121,162,180,32,154,65,71,197,164,236,108,222,121,209,92,157,108,22,41, +77,61,80,204,22,67,244,120,178,249,18,58,162,107,107,157,221,61,179,160,234,116,117,117,53,75,236,26,137,121,243,39,14,182,75,232,53,96,185,107,27,43,172,194,8,165,116,219,39,194,105,173,201,229,114,116,117,117,49,54,54,214,178,149,62,62,62,78,111,111, +47,187,119,239,54,22,250,230,55,214,21,56,14,238,11,126,16,188,12,225,23,62,130,46,205,176,174,90,117,203,34,190,120,10,255,61,111,199,123,222,203,177,238,126,92,210,208,198,148,181,25,110,166,101,110,73,62,48,94,230,247,207,204,241,185,57,159,62,71, +182,101,29,77,102,151,43,158,222,155,225,55,239,234,227,155,186,60,162,69,141,67,132,16,184,174,219,76,202,43,20,10,236,220,185,147,40,142,137,210,26,250,82,169,196,216,216,88,242,156,105,221,124,173,86,99,114,114,114,129,200,39,14,48,121,155,9,189,4, +85,71,135,87,174,91,2,38,184,250,207,2,1,66,131,200,50,19,12,50,253,149,47,18,71,62,35,35,35,228,114,185,166,72,9,33,24,28,28,36,155,205,54,61,5,182,109,175,95,228,181,70,186,22,58,110,253,74,210,145,66,71,49,88,109,76,117,231,106,44,253,224,193,131, +64,210,96,168,149,240,142,109,219,76,78,78,210,219,219,75,103,103,231,134,20,117,35,232,45,173,80,73,175,119,247,57,223,131,181,101,7,193,199,222,71,124,254,68,178,131,94,115,92,221,70,93,62,67,240,111,255,128,83,171,96,223,255,148,84,212,141,165,110, +184,177,88,233,94,244,127,159,152,225,79,46,204,81,141,52,61,118,123,196,92,107,8,180,230,87,246,116,243,154,237,157,244,100,236,21,103,151,47,87,87,47,132,192,113,18,11,175,191,191,159,129,129,1,180,214,77,65,175,215,235,76,78,78,38,150,233,188,46,121, +179,179,179,140,143,143,47,136,83,55,186,190,109,206,29,151,132,112,42,41,87,147,173,90,188,26,164,139,157,223,7,66,224,216,25,38,38,38,22,8,117,28,199,140,143,143,55,231,11,52,26,15,141,140,140,208,213,213,213,236,139,222,56,23,139,69,236,90,162,38, +164,164,99,103,47,115,167,39,87,255,142,133,64,197,10,21,43,44,91,182,61,10,169,181,198,243,60,182,110,221,202,232,232,104,243,115,173,106,107,37,37,19,19,19,108,25,30,166,80,40,108,200,92,15,35,232,107,20,117,235,190,111,198,203,228,241,255,227,93,196, +103,143,174,125,168,11,2,44,135,248,202,37,212,123,222,70,124,233,44,238,243,191,63,113,231,27,75,221,112,163,172,114,41,152,9,98,126,249,196,52,127,117,185,76,78,10,114,141,120,249,122,22,76,64,233,164,176,234,175,239,25,224,37,67,57,16,98,69,49,191, +214,194,187,88,228,27,66,47,132,32,159,207,55,155,125,52,172,73,33,4,190,239,179,107,215,174,5,93,242,138,197,34,23,46,92,184,174,229,190,49,147,241,4,196,69,68,48,137,150,110,235,15,119,123,64,102,155,195,88,26,195,104,26,56,142,67,185,92,94,144,148, +167,148,98,118,118,182,233,53,105,184,229,71,70,70,232,239,239,71,41,213,20,249,149,134,3,53,206,95,118,160,131,185,211,83,45,89,218,73,186,198,141,181,126,59,58,58,216,185,115,231,170,174,139,249,56,142,195,217,115,231,200,23,10,27,178,37,172,17,244, +181,138,186,144,200,253,247,225,101,114,248,239,255,59,226,83,15,39,150,181,88,99,76,93,8,180,95,39,252,244,7,209,65,141,204,119,254,8,228,242,38,3,222,208,126,171,92,10,62,51,85,231,127,158,152,230,235,165,128,14,75,98,181,65,203,226,180,81,204,125, +5,151,223,63,216,203,19,186,51,73,25,146,106,175,219,180,241,125,190,165,217,16,149,76,38,67,54,155,93,208,10,87,41,181,64,228,181,210,20,75,69,206,158,61,219,180,220,27,127,223,216,4,44,78,202,187,53,98,47,64,135,232,250,104,26,44,111,253,241,34,115, +23,215,75,27,95,206,131,17,134,33,193,188,46,121,90,107,78,157,58,197,217,179,103,23,28,151,56,142,217,177,99,7,61,221,61,73,115,204,84,228,93,215,77,196,94,10,148,138,17,50,73,108,76,66,1,92,109,107,188,168,189,177,180,37,213,241,34,229,203,179,116, +239,27,66,223,128,156,34,173,53,153,76,134,238,238,110,46,94,188,216,226,82,157,140,55,126,228,145,71,248,230,111,254,230,102,120,194,8,250,102,71,171,196,163,181,99,31,222,247,188,18,255,221,111,35,62,246,96,90,154,182,246,6,52,104,77,244,133,143,226, +251,117,220,23,189,2,209,217,109,68,221,208,158,155,93,38,150,214,223,94,44,241,147,199,166,201,2,89,171,61,45,92,125,165,9,180,230,53,219,58,120,227,222,94,186,28,73,188,206,193,42,107,21,250,229,22,225,70,220,184,65,95,127,31,59,119,238,36,142,98,130, +48,64,41,69,181,90,229,204,153,51,75,166,172,69,81,180,164,212,233,230,36,229,9,80,117,168,157,0,177,134,215,18,2,149,221,141,92,131,224,44,183,137,153,191,225,153,207,153,51,103,56,195,153,230,207,81,20,177,109,219,54,122,251,250,152,60,59,198,153,51, +199,40,228,178,228,178,121,178,174,135,101,217,72,105,97,91,22,182,101,99,165,121,16,141,154,122,69,76,236,199,55,84,40,181,214,12,15,15,51,51,51,195,217,179,103,91,202,92,151,82,18,4,1,211,211,211,12,14,14,26,11,253,246,178,214,35,228,240,118,50,47, +123,29,254,123,222,78,244,208,23,192,113,215,46,234,66,128,148,132,15,124,26,229,215,201,188,228,149,136,222,1,35,234,134,245,221,232,182,100,186,30,242,71,231,138,252,214,217,57,58,219,20,43,111,140,59,205,88,130,55,237,234,230,103,246,116,163,149,38, +218,96,141,98,86,18,122,219,177,113,210,108,236,206,206,78,70,70,70,136,227,120,193,124,250,114,185,220,180,228,230,103,222,79,79,79,47,16,245,198,220,245,118,234,57,170,14,193,196,26,4,93,129,219,135,180,114,237,221,98,172,194,83,225,56,14,163,163,163, +92,186,124,153,234,216,44,149,90,153,98,181,132,38,233,67,96,91,18,199,118,201,121,25,114,153,44,158,235,225,216,54,150,180,113,29,23,91,11,116,172,16,90,32,164,92,224,109,105,231,245,32,165,164,167,167,135,241,241,241,150,102,166,55,202,43,79,157,58, +69,127,127,63,82,202,13,99,165,27,65,111,7,81,132,236,27,36,243,178,215,82,207,100,8,191,242,73,132,146,137,181,190,86,81,183,108,162,135,191,64,61,10,241,94,244,10,228,150,237,166,86,221,176,70,49,183,248,196,116,149,223,60,53,195,167,167,125,10,86, +251,196,124,54,82,60,169,43,195,79,239,234,226,133,195,249,150,99,229,27,73,236,155,110,252,84,152,109,199,73,26,164,100,179,12,14,14,38,179,233,227,24,13,248,245,122,179,227,91,20,69,104,173,241,125,159,203,151,47,55,45,249,134,64,172,89,228,53,80,63, +151,52,236,105,85,208,85,140,200,30,4,225,112,83,91,196,205,179,98,165,128,76,103,142,170,40,46,17,203,32,12,168,7,62,83,197,217,52,251,60,153,130,231,185,25,108,36,126,23,228,119,247,224,120,110,51,243,126,254,134,106,165,77,90,171,231,125,235,214,173, +140,143,143,51,58,58,218,210,224,22,41,37,245,122,157,139,23,47,178,125,251,246,13,211,108,198,94,195,81,48,43,228,114,135,37,12,17,29,93,120,47,121,21,34,215,65,124,252,97,212,149,75,107,79,150,19,2,225,184,196,71,31,160,254,30,133,247,237,223,135,181, +251,96,146,113,132,57,7,134,85,44,58,34,89,120,222,61,90,226,117,71,166,152,10,99,186,109,73,187,162,193,83,161,226,199,183,22,120,195,238,110,182,230,29,162,240,54,169,204,208,11,67,5,90,41,84,58,93,174,97,145,187,133,2,157,119,221,133,86,138,88,169, +36,84,22,69,108,217,178,101,193,176,27,223,247,57,123,246,236,18,23,246,234,178,238,21,186,122,120,77,51,36,180,208,136,236,46,16,118,51,33,238,86,176,82,45,186,16,2,107,25,151,126,173,94,67,41,197,145,175,31,102,150,42,249,254,78,100,26,2,25,30,26,162, +63,173,118,112,210,13,151,16,98,137,38,173,118,62,125,227,239,118,108,223,206,220,220,28,65,16,180,212,18,214,247,125,38,38,38,24,25,25,73,174,139,245,106,99,27,242,52,140,133,222,110,81,207,228,241,190,227,7,137,6,63,78,240,185,15,163,70,207,129,109, +179,182,6,52,18,108,23,117,226,225,100,152,197,211,159,143,125,232,155,146,231,210,202,28,112,195,202,55,182,16,84,98,197,159,156,157,229,119,207,206,81,87,154,222,54,185,217,67,173,9,53,252,252,158,46,222,180,167,135,140,96,83,90,230,107,18,249,116, +209,142,19,115,241,170,37,158,150,217,109,25,30,110,186,136,117,186,25,216,186,109,27,42,142,9,26,51,234,131,128,19,39,79,46,235,37,184,106,129,10,132,174,65,125,114,13,239,53,70,186,61,96,229,110,249,230,95,216,18,105,75,212,42,174,143,198,166,71,74, +73,232,135,76,95,190,66,32,163,230,241,41,149,74,156,61,119,174,249,183,74,41,6,6,6,24,217,178,5,165,117,51,33,207,113,28,172,69,194,220,176,160,23,88,209,105,25,100,79,79,15,247,220,125,55,223,120,228,145,102,152,101,117,158,47,155,233,233,105,206,159, +63,207,238,221,187,55,132,149,110,183,114,65,99,108,195,235,19,71,224,120,88,79,120,22,110,54,79,240,145,247,160,70,207,130,237,174,61,3,222,178,80,167,15,19,198,33,122,118,26,251,73,207,77,106,223,77,173,186,97,25,171,220,146,130,51,149,136,215,30,157, +228,139,179,73,166,114,70,10,218,17,214,46,199,154,187,243,14,191,186,167,147,239,26,238,64,43,69,120,135,239,45,23,12,90,89,116,79,10,41,41,228,243,75,22,250,225,225,97,84,154,100,22,69,17,74,41,234,245,58,167,78,157,74,19,196,4,193,220,57,194,56,106, +54,140,17,171,53,226,116,136,206,236,65,200,194,173,245,168,166,179,172,172,140,131,42,213,91,90,255,164,37,209,117,133,20,178,57,136,70,41,133,239,251,11,142,251,165,75,151,24,29,29,189,122,252,149,162,167,167,135,109,219,182,161,148,90,32,240,174,231, +45,40,197,147,243,226,243,249,66,161,217,157,112,181,194,220,200,242,47,149,74,248,190,143,231,121,235,210,71,209,134,115,101,44,244,27,129,74,107,213,239,127,42,94,182,64,253,253,127,139,190,124,14,60,151,53,183,138,21,130,248,204,49,226,11,167,208, +149,50,238,179,94,12,182,109,70,176,26,154,56,50,89,245,63,59,237,243,67,143,76,48,225,199,100,229,250,221,120,130,164,36,109,58,82,188,96,32,203,31,222,213,199,206,188,77,24,27,47,209,106,196,126,57,113,144,150,133,132,37,141,77,182,108,217,146,36,228, +41,152,56,53,202,120,213,33,8,34,194,72,19,132,154,40,86,104,221,88,18,68,210,203,125,177,80,106,133,112,135,193,202,128,10,110,237,1,16,2,167,224,17,20,107,45,149,254,9,1,97,205,71,43,133,72,195,28,139,31,223,248,121,254,241,21,66,48,51,51,195,212,212, +212,2,97,142,227,152,254,254,254,102,86,122,99,124,109,163,159,65,54,155,197,247,235,132,97,180,160,190,190,233,109,89,225,60,218,182,205,216,216,24,150,101,113,224,192,129,91,222,165,112,213,130,110,44,243,86,239,100,5,74,32,239,121,28,25,47,75,253, +159,255,12,61,122,14,220,117,52,246,183,147,182,176,193,127,190,11,252,26,206,243,95,158,88,254,81,104,142,183,17,115,148,130,63,58,63,199,111,159,45,50,23,41,242,109,104,20,35,128,154,210,72,1,175,218,94,224,255,29,232,35,43,5,161,50,43,66,187,173,251, +198,207,150,37,177,28,135,237,253,48,114,168,147,90,61,166,234,43,234,245,152,32,140,9,67,141,31,198,212,234,138,154,159,252,78,41,144,66,32,136,208,50,7,162,3,17,70,160,163,246,102,222,183,172,231,18,39,231,92,29,238,211,194,133,23,7,81,50,169,205,105, +173,169,251,114,37,133,150,101,49,59,59,203,212,212,84,243,119,113,28,211,217,217,73,127,127,63,66,8,166,167,103,152,156,156,36,147,201,52,235,232,109,219,33,227,185,184,158,151,204,171,159,215,183,64,164,83,2,109,215,229,210,197,139,108,219,186,149, +238,158,158,53,143,87,109,199,29,101,44,244,27,123,183,38,25,240,251,238,38,243,3,63,133,255,47,127,129,58,127,98,237,217,239,208,236,245,30,124,252,95,81,181,42,238,119,254,16,34,155,51,238,247,59,92,204,199,131,152,31,127,100,146,79,79,215,1,218,38, +230,229,88,179,51,99,241,198,189,221,188,108,75,1,192,136,249,141,94,54,144,232,176,132,46,29,65,160,200,229,28,242,249,68,176,1,148,210,132,145,194,15,146,175,40,86,132,161,162,86,143,168,249,10,167,255,89,120,91,158,134,210,130,40,12,56,119,238,220, +146,164,188,155,101,73,10,9,50,227,172,233,90,212,74,163,194,16,43,211,158,247,186,184,129,142,227,56,212,235,245,230,241,233,232,232,224,242,229,203,205,174,121,141,185,0,142,227,52,173,118,219,182,201,120,46,185,92,142,170,180,137,177,200,58,22,57, +199,230,236,217,51,220,157,203,225,184,238,45,139,165,27,65,191,25,162,30,134,200,29,251,200,252,192,127,199,255,231,63,35,62,241,112,34,234,107,30,234,98,131,138,137,190,248,95,16,6,184,223,241,3,136,174,158,164,188,197,112,199,32,5,88,192,67,197,128, +87,30,158,228,107,229,128,78,75,210,142,145,22,74,67,93,107,238,41,56,252,195,189,253,236,239,112,209,10,34,83,229,114,19,84,208,130,234,17,240,207,39,83,104,85,35,17,79,207,19,100,65,62,103,83,200,167,141,215,52,196,113,72,44,10,88,219,158,132,213,125, +0,29,135,104,173,217,50,188,133,40,142,8,195,176,89,122,119,114,81,82,222,114,222,130,134,181,187,94,44,219,74,6,173,92,123,182,204,178,68,181,0,167,35,115,227,238,161,121,34,47,132,96,100,203,8,103,207,205,239,32,152,196,237,253,122,29,173,21,213,32, +226,244,92,133,163,147,101,170,245,16,45,4,150,109,211,209,213,193,253,251,118,240,75,35,91,217,62,52,116,203,238,19,35,232,55,139,48,68,12,109,197,123,249,235,147,174,114,71,30,32,29,102,188,198,43,49,41,147,136,190,246,105,136,99,220,111,255,30,196, +208,54,83,171,126,7,89,229,190,214,252,237,165,50,191,117,102,142,81,63,166,219,90,255,0,18,1,212,149,38,43,5,223,209,159,227,47,14,246,209,229,74,162,155,216,245,205,8,58,80,31,5,21,173,184,233,79,198,205,235,69,15,139,177,51,189,200,220,14,80,87,179, +198,187,123,186,23,8,182,214,154,161,161,161,102,43,220,70,82,222,137,19,39,154,29,242,26,127,219,156,201,62,79,220,91,29,116,35,164,196,118,109,34,63,164,149,190,132,2,8,43,1,217,27,116,225,205,31,197,219,160,171,171,139,124,62,79,177,88,68,10,240,235, +62,149,90,141,114,221,231,114,165,206,225,169,26,165,106,64,24,70,141,186,55,52,2,113,105,156,19,39,47,240,208,249,49,222,246,51,175,226,208,174,237,203,118,213,51,130,126,187,137,122,239,32,222,247,190,154,232,115,31,38,252,226,71,81,115,83,235,107, +64,3,132,15,127,30,29,135,184,207,122,49,114,231,254,68,212,141,181,126,219,174,245,182,37,153,14,21,63,115,116,138,119,142,149,41,88,130,172,197,186,237,114,1,204,69,138,17,207,230,87,119,119,243,163,219,58,64,107,227,98,191,169,88,16,251,232,234,55, +208,170,154,12,86,89,37,90,131,112,70,208,206,64,178,25,96,229,118,184,203,181,58,109,12,94,105,136,188,214,154,211,167,79,39,253,239,231,245,206,47,22,139,205,97,56,11,196,100,185,88,189,78,74,215,156,188,75,84,11,104,109,104,128,32,172,180,39,169,175, +177,185,153,159,72,55,191,35,96,24,134,248,65,64,224,215,9,170,21,174,92,190,68,41,140,41,197,138,113,95,113,177,26,82,169,212,193,87,104,41,176,151,217,212,232,208,231,107,95,126,144,31,251,237,63,229,159,222,252,115,236,24,232,187,233,162,110,4,253, +102,19,133,136,174,62,156,167,127,7,34,87,192,255,216,191,162,231,166,192,89,135,168,43,69,116,228,1,244,236,36,206,51,95,132,243,216,39,167,57,40,70,212,111,55,108,91,114,100,206,231,127,156,152,225,3,19,21,6,93,171,61,227,78,129,137,48,230,64,222,229, +47,239,25,224,201,189,25,226,72,97,174,160,155,189,99,147,201,168,212,96,188,197,229,89,131,149,71,20,238,153,119,70,175,37,254,203,255,187,148,178,57,74,21,224,254,251,239,111,246,112,87,74,161,148,226,194,133,11,77,203,61,142,227,166,85,127,229,202, +149,36,89,108,158,177,225,56,54,82,10,172,140,187,22,143,59,113,16,94,157,3,223,194,131,147,10,0,209,236,17,223,104,242,227,251,62,97,24,38,2,238,7,212,106,85,106,181,58,113,20,226,73,65,12,92,174,199,156,142,44,206,205,148,153,140,52,74,131,168,133, +16,40,144,43,251,24,132,16,20,60,151,47,125,229,107,252,226,95,190,139,63,126,253,143,209,147,113,147,198,67,70,208,111,111,81,39,219,129,253,45,207,129,108,1,255,67,255,152,136,186,101,175,125,17,80,138,232,212,97,212,228,56,212,170,216,79,122,54,68, +218,184,223,111,35,28,91,242,182,11,69,254,252,92,145,135,42,1,67,174,213,22,193,85,26,124,173,249,254,225,2,191,178,175,135,187,59,92,194,208,72,249,173,114,193,232,168,136,142,235,173,133,227,116,12,86,7,34,119,215,186,55,242,243,197,62,138,22,142, +93,21,66,112,240,224,193,68,108,211,120,124,195,114,31,27,27,107,90,188,113,250,184,11,231,47,160,132,70,75,141,138,98,100,43,97,33,1,42,82,168,32,70,186,214,138,123,148,198,6,66,166,229,189,74,107,252,122,157,122,189,78,173,94,39,8,130,230,244,56,223, +247,155,33,6,33,4,150,148,120,150,160,36,36,71,203,1,231,234,17,99,129,102,58,116,16,177,192,70,163,235,33,42,136,86,149,243,164,129,190,92,134,247,126,248,147,188,226,57,79,227,57,247,223,107,4,253,142,32,142,192,118,176,31,255,116,132,231,81,127,239, +95,161,231,166,215,33,234,2,145,45,160,171,37,252,247,255,13,212,107,216,207,120,65,226,122,55,162,190,185,173,242,116,29,249,233,35,147,252,205,165,18,177,130,30,91,182,71,204,1,133,230,247,238,234,229,7,183,20,200,59,150,17,243,91,105,157,43,31,93, +126,4,162,34,72,167,165,199,138,220,65,240,182,221,144,86,175,203,141,173,109,52,103,145,233,180,180,157,59,119,54,255,189,241,247,131,67,67,40,29,83,154,46,241,72,253,171,76,142,77,38,73,114,243,212,248,154,113,117,13,97,61,196,243,236,171,235,216,124, +97,213,154,32,138,168,213,106,84,171,85,106,181,90,51,100,208,248,154,255,126,27,34,110,91,73,11,228,49,63,226,27,211,1,151,253,152,153,32,166,170,52,182,16,56,185,28,186,94,37,158,154,65,133,170,165,4,102,33,45,226,226,28,95,60,122,138,103,60,250,16, +242,38,118,144,51,130,126,43,81,201,92,117,235,209,79,34,227,102,146,178,182,137,81,112,215,216,128,6,13,182,131,174,215,168,255,251,59,112,253,42,238,179,94,146,244,147,55,101,109,155,142,70,215,183,243,213,136,95,58,62,205,187,39,42,228,165,192,109, +67,73,154,210,16,161,241,44,193,59,238,29,228,217,189,201,84,46,211,44,230,86,98,161,195,49,116,245,40,173,167,132,11,200,108,93,227,186,177,126,75,126,177,208,55,98,213,125,125,125,0,244,247,13,224,206,104,38,142,95,36,36,166,82,173,80,174,87,241,3, +159,48,142,81,90,45,219,188,69,107,77,88,169,227,116,122,168,88,165,29,245,124,170,213,10,149,114,153,186,239,55,67,1,141,175,171,54,142,104,214,164,55,66,247,145,134,106,172,56,83,9,249,70,57,96,42,82,248,177,70,161,145,66,144,105,52,98,82,154,88,185, +233,222,168,245,96,65,214,117,248,234,201,115,204,85,235,244,231,51,68,177,17,244,59,3,173,32,214,216,119,223,143,248,254,215,81,255,231,191,64,93,58,155,36,202,173,181,86,212,178,33,12,8,62,250,158,164,172,237,57,47,5,47,103,26,208,108,42,171,92,32, +36,188,127,188,194,175,158,156,230,76,45,166,211,106,207,96,149,80,107,98,5,79,237,245,248,221,3,125,220,157,119,137,148,201,98,191,245,22,58,137,101,30,206,36,75,243,170,79,72,35,126,126,31,105,151,249,91,187,164,205,19,229,70,111,122,233,88,120,25, +151,124,38,143,229,218,244,118,244,32,16,8,1,177,214,4,81,64,181,94,165,84,41,81,170,150,169,213,125,252,40,32,8,3,106,151,199,193,159,161,84,44,17,134,225,178,217,233,243,61,6,243,15,167,45,5,90,67,37,86,76,7,49,199,42,1,71,202,1,65,234,184,20,2,36, +32,17,243,116,91,16,151,234,232,0,112,179,224,87,214,176,25,23,204,149,43,132,113,220,82,102,191,17,244,219,66,212,53,58,12,177,246,221,75,230,7,94,135,255,207,111,71,77,92,70,215,171,107,119,193,167,86,121,240,201,15,66,20,226,60,243,187,17,221,189, +16,26,81,223,232,56,82,16,43,248,163,179,115,252,252,137,105,186,164,108,75,11,87,72,74,210,34,13,255,115,119,23,191,184,171,27,207,50,93,223,54,140,154,171,16,93,126,40,153,127,110,21,90,50,10,68,110,63,194,219,177,97,195,107,130,100,182,185,32,113, +121,55,134,171,132,81,136,31,6,4,81,64,28,43,28,219,37,227,100,8,163,152,122,232,19,69,49,248,138,156,215,129,236,20,68,105,220,190,145,216,22,199,113,58,126,85,204,115,169,11,92,41,240,99,205,165,90,200,168,31,115,162,28,112,161,30,161,27,155,101,150, +241,162,55,172,248,98,29,93,9,146,159,179,5,8,234,73,142,66,11,68,81,204,158,225,65,242,158,135,186,137,231,196,8,250,70,210,245,48,68,238,184,11,239,251,95,79,248,217,255,32,122,224,211,232,106,105,237,162,46,37,168,136,224,179,255,129,14,67,220,167, +63,31,49,188,195,136,250,70,22,115,71,114,161,28,242,187,103,102,249,179,75,37,122,108,217,150,231,109,116,125,235,117,37,191,182,183,135,31,221,222,129,142,77,73,218,198,81,60,153,88,231,213,147,32,221,214,31,239,246,164,51,211,55,214,249,108,214,174, +35,208,66,83,174,149,241,43,87,69,60,8,2,170,126,157,90,80,79,18,233,26,19,215,132,196,146,22,133,108,30,55,239,49,184,109,7,8,154,37,102,65,144,60,182,241,115,24,134,16,133,232,32,96,162,82,227,27,21,159,139,245,136,243,213,136,169,72,225,72,137,221, +220,20,175,124,140,162,98,112,85,204,211,119,78,182,0,149,153,85,39,41,10,173,169,42,197,19,14,236,166,35,227,161,110,162,103,212,8,250,70,35,12,145,91,182,227,62,243,69,200,76,142,224,115,255,185,78,81,79,44,245,240,43,31,135,160,134,243,228,111,71, +238,57,100,68,125,227,217,103,216,142,228,223,198,171,188,225,196,52,71,42,73,215,183,118,61,119,49,210,60,191,47,203,207,239,233,226,91,250,178,68,161,50,46,246,13,118,5,232,112,6,93,57,14,162,197,18,86,29,33,243,143,74,4,93,223,90,151,251,124,55,120, +99,26,89,24,134,132,42,226,226,196,40,71,206,31,71,9,65,20,71,105,137,219,85,203,218,94,166,31,135,70,19,71,49,126,165,134,157,115,17,66,224,186,46,158,231,53,75,211,164,214,132,81,196,225,217,42,159,154,40,113,92,250,92,113,124,124,21,144,17,1,153,200, +71,135,33,58,142,16,243,227,225,243,222,171,22,160,138,1,186,26,44,10,151,107,112,50,96,123,16,5,171,74,142,11,130,144,189,7,246,243,184,187,247,35,197,205,13,130,24,65,223,160,162,46,122,6,112,158,249,93,224,101,8,62,250,94,116,173,146,206,85,95,3,150, +5,81,68,248,245,207,17,157,61,142,247,146,255,134,115,247,227,146,73,109,38,3,254,214,91,229,105,173,236,223,158,47,242,51,199,166,169,43,69,161,77,241,242,72,107,202,177,230,117,219,58,121,211,190,110,186,60,203,136,249,70,68,199,80,59,6,113,45,153, +146,214,194,227,68,102,7,100,118,223,50,225,190,186,108,133,77,235,89,74,201,233,211,167,41,151,203,137,93,97,75,166,199,38,8,84,140,36,177,190,87,183,205,17,168,40,38,170,249,216,121,15,148,66,166,189,110,181,134,217,80,243,165,153,26,159,158,173,51, +22,40,138,177,36,178,114,216,133,28,94,65,131,82,73,217,152,86,201,49,142,98,44,191,134,14,234,232,32,64,198,33,66,41,226,57,63,17,243,249,119,70,227,35,74,9,153,142,196,74,191,206,157,163,226,152,57,97,241,223,191,227,217,60,102,231,182,102,249,158, +17,244,59,157,40,4,47,135,243,140,239,4,219,198,255,207,127,130,106,101,237,13,104,164,76,110,130,137,75,248,239,252,19,120,201,143,227,60,250,73,104,211,85,238,214,138,185,37,24,175,199,188,245,236,44,127,114,169,132,0,10,109,178,204,235,74,147,181, +4,111,216,221,205,175,236,233,70,42,8,35,35,229,27,210,63,163,99,116,229,4,200,22,151,100,21,38,217,237,50,67,187,221,237,34,109,230,146,196,191,23,142,18,141,227,152,114,185,76,24,69,68,105,211,153,249,173,99,27,214,121,35,65,78,90,18,203,179,112,60, +151,56,136,90,59,52,74,19,215,66,50,150,32,80,80,10,21,151,252,136,207,77,87,249,242,92,192,92,164,137,147,6,172,72,1,46,186,121,40,180,144,48,63,108,229,66,156,205,55,143,85,140,70,79,22,193,47,129,85,79,172,240,56,188,90,238,171,211,239,182,147,184, +222,235,165,116,189,20,205,4,186,100,88,123,82,103,95,180,28,94,243,3,47,226,13,223,247,29,8,173,136,111,178,193,212,186,160,155,245,224,230,17,39,101,109,206,211,190,19,108,151,224,223,255,17,93,46,130,227,174,241,14,21,224,120,232,185,41,234,255,244, +103,232,90,13,231,9,207,76,187,205,153,178,182,155,137,20,96,89,146,7,231,234,188,250,200,36,135,203,73,167,170,54,201,3,51,161,226,169,61,25,222,176,187,155,103,12,228,8,35,133,57,195,27,24,85,131,96,236,170,64,172,118,49,150,22,162,240,152,164,69,236, +58,54,230,98,94,39,54,41,37,66,138,102,153,88,16,5,204,206,206,54,227,213,90,107,124,223,231,204,153,51,11,166,182,205,207,48,159,159,168,214,176,232,237,140,131,116,44,98,63,90,117,21,152,45,4,182,214,248,181,136,147,149,144,195,179,117,62,63,93,227, +145,106,136,213,156,7,15,214,188,39,212,139,143,209,114,135,179,17,15,159,169,64,73,65,166,144,8,118,227,9,180,74,132,61,12,82,145,15,146,191,241,114,80,43,129,95,75,254,61,142,1,129,118,179,20,135,71,248,201,23,62,139,63,248,145,23,17,135,81,235,98, +222,134,219,223,88,232,27,222,21,151,148,181,57,79,125,30,34,151,199,255,215,191,65,207,78,130,155,89,187,187,220,118,160,82,194,127,207,219,193,175,227,60,233,57,105,2,93,204,205,172,99,189,35,79,39,26,87,10,144,130,127,27,175,240,170,35,147,204,132, +138,130,213,158,227,174,128,169,48,230,135,182,116,240,123,119,245,48,232,217,4,209,205,45,157,49,180,46,167,186,252,8,186,118,38,77,108,91,237,197,20,130,59,130,200,238,73,4,74,71,171,191,127,231,53,116,177,44,11,173,117,179,43,220,204,236,12,83,83, +83,40,165,136,85,76,189,86,103,116,116,180,217,64,166,33,208,78,11,222,66,173,52,150,235,32,109,121,181,149,235,53,116,205,73,179,213,199,131,136,51,85,159,179,65,196,131,245,164,17,140,147,102,177,175,155,233,42,204,214,151,23,254,212,248,193,241,26, +59,148,100,195,164,250,19,33,15,210,30,243,89,15,186,242,204,245,246,243,11,207,122,60,255,231,155,238,34,12,130,52,82,127,243,239,57,123,45,11,146,225,230,203,0,97,136,253,184,167,65,38,71,240,238,183,161,198,47,65,38,179,118,1,182,108,8,124,252,15, +253,3,132,245,164,13,109,198,204,85,191,209,184,82,80,141,53,111,62,62,205,95,95,46,83,138,147,120,121,59,102,151,215,149,198,21,130,95,221,219,195,27,118,119,227,74,8,210,70,49,230,190,221,200,122,46,208,181,19,173,143,83,214,10,225,246,161,173,252, +188,118,175,122,133,151,88,152,172,214,232,162,38,132,224,242,229,203,204,205,205,53,221,227,229,114,153,98,177,216,180,190,133,16,203,14,115,105,249,99,90,18,105,91,43,126,206,134,144,43,224,120,205,231,145,106,200,165,32,98,180,22,82,205,121,132,133, +2,57,219,66,172,215,141,45,4,122,166,10,115,181,229,45,99,221,104,153,173,147,141,146,227,37,150,185,147,77,146,227,108,23,250,58,160,191,11,10,57,166,61,155,55,220,213,199,255,218,209,65,148,138,249,90,238,185,118,108,0,140,133,190,105,52,93,163,195, +8,235,158,199,227,58,30,225,39,222,143,58,117,24,29,212,146,76,246,53,137,186,5,126,13,255,35,239,65,215,235,216,79,254,118,68,119,95,226,102,50,180,217,6,75,66,121,231,234,49,223,251,240,21,142,148,130,102,188,124,189,82,171,129,170,210,28,200,57,252, +206,254,110,158,213,159,3,13,65,108,68,124,83,92,25,186,142,174,60,146,118,58,105,197,29,19,65,118,119,82,178,150,110,196,23,39,171,53,44,239,70,59,84,1,156,56,121,178,57,92,69,8,65,181,90,93,208,176,101,241,128,150,118,26,38,150,103,35,230,89,215,98, +222,247,178,82,60,84,174,115,180,22,50,25,42,138,145,2,145,244,101,200,43,77,53,136,136,114,114,125,137,188,13,49,159,173,46,106,0,151,254,135,237,36,205,100,50,5,112,115,96,57,201,250,42,109,200,184,208,95,128,238,12,56,22,202,145,204,197,138,95,217, +85,224,77,219,178,196,97,112,203,135,25,25,65,223,84,162,174,32,12,177,246,223,135,44,116,18,124,226,3,68,95,251,76,18,227,145,235,232,42,87,175,18,166,229,113,206,211,94,128,24,222,150,148,181,153,12,248,182,224,72,1,90,243,217,25,159,87,29,153,226, +92,45,34,107,137,150,162,165,43,109,18,66,173,9,21,60,190,203,227,157,247,14,176,37,99,17,43,141,209,242,205,162,231,54,84,30,129,112,154,235,169,121,50,123,228,234,223,40,161,16,118,39,82,74,180,138,209,26,106,181,26,81,20,17,4,1,42,142,57,113,226,4, +81,42,246,13,11,124,241,72,207,86,221,231,235,176,73,176,114,110,146,96,23,107,132,0,45,4,151,253,128,47,204,213,57,237,71,248,74,19,166,229,108,77,183,186,6,17,198,200,48,2,225,209,82,142,129,230,234,70,73,10,244,92,29,230,252,68,160,165,5,118,6,178, +121,200,118,128,229,165,221,57,69,242,101,201,228,231,172,132,190,2,20,188,100,176,130,20,40,165,41,6,17,63,179,179,139,255,181,167,27,21,171,13,113,207,25,65,223,132,150,58,97,128,24,218,142,247,156,239,65,120,25,194,207,125,56,217,173,175,67,212,117, +189,74,248,233,127,35,190,116,6,239,165,175,194,218,190,23,29,24,75,125,189,184,150,160,24,43,254,244,92,137,183,158,155,163,172,52,57,41,214,157,92,218,104,20,211,231,72,94,48,156,227,15,14,244,98,11,8,76,163,152,77,38,232,2,93,191,148,196,191,23,184, +197,27,35,64,147,31,148,210,68,145,34,12,99,194,88,19,6,49,229,154,133,101,71,184,241,52,161,63,135,239,251,156,62,125,122,65,114,218,114,92,239,223,111,228,218,229,230,28,132,20,8,165,9,208,124,121,174,202,23,139,62,115,177,70,54,69,233,170,144,55,137, +99,68,20,95,127,109,76,51,211,5,2,164,68,219,78,82,25,228,216,80,140,65,103,97,48,7,153,124,98,125,139,121,247,162,78,178,213,113,36,120,54,116,184,208,151,79,254,187,241,126,52,232,88,51,23,43,126,122,87,39,191,123,87,15,97,180,113,202,64,141,160,111, +86,226,8,186,251,113,159,243,61,96,187,132,159,124,127,242,187,117,76,107,195,205,162,78,31,193,255,135,183,38,162,190,239,30,35,234,235,17,115,91,114,185,30,241,186,35,83,188,119,188,66,175,109,225,138,245,199,201,26,89,236,187,115,14,191,179,175,135, +23,109,201,17,25,171,124,51,170,121,34,228,193,69,36,201,104,81,153,246,30,15,66,69,221,143,168,249,49,65,160,8,2,69,181,30,81,174,68,84,234,49,97,224,35,50,91,19,79,218,133,47,3,81,115,16,201,70,182,69,44,207,65,74,73,168,99,30,40,215,249,204,108,157, +186,78,250,169,95,235,206,16,26,196,252,193,65,243,196,27,173,17,66,130,235,162,93,15,220,36,153,77,184,30,42,155,67,228,10,232,98,4,245,10,244,170,171,143,39,125,142,88,39,47,144,117,32,231,66,167,7,221,217,196,66,87,122,73,105,250,100,164,248,217,93, +93,252,222,93,189,4,209,198,42,249,181,91,58,27,134,141,133,138,33,87,192,125,222,247,129,227,18,126,228,95,214,39,234,104,112,61,212,165,51,212,223,241,71,120,47,254,111,88,247,60,238,106,70,167,97,181,71,17,207,146,124,126,178,198,47,159,154,225,19, +211,117,6,219,52,187,156,116,65,121,116,151,203,95,223,51,192,99,58,93,162,88,97,12,243,77,40,231,210,65,6,167,137,203,15,81,173,250,148,107,130,106,61,194,15,20,126,160,168,249,49,181,122,34,232,58,221,115,75,145,12,52,177,45,13,217,126,68,118,24,226, +250,230,176,205,180,70,218,22,194,22,156,47,134,124,110,174,70,89,105,156,85,237,113,21,50,8,17,65,144,88,223,182,131,202,102,19,119,185,235,37,201,106,158,139,246,50,224,102,208,150,147,220,137,2,244,149,18,92,44,66,172,146,122,209,198,77,170,210,159, +123,179,208,225,65,222,77,4,93,136,228,111,23,237,144,37,112,37,140,249,133,221,93,252,78,106,153,183,125,199,99,44,244,59,221,82,143,193,114,112,159,251,61,200,76,150,224,63,222,137,14,234,235,16,117,192,245,208,87,46,225,255,211,159,226,126,215,143, +97,63,246,73,96,186,202,173,218,122,118,45,193,111,157,153,229,175,47,148,56,87,143,24,104,147,152,43,64,105,205,235,183,119,240,115,187,187,216,145,117,54,156,133,96,88,201,1,38,150,44,222,97,164,184,114,250,65,198,190,113,30,223,15,9,66,146,126,1,170, +81,195,157,8,184,109,47,126,172,2,233,129,55,152,90,143,122,83,221,32,218,181,56,86,13,40,199,43,137,249,226,18,50,9,94,22,39,219,141,63,178,155,184,179,3,33,172,196,149,110,187,96,219,104,33,230,89,237,58,105,204,37,5,76,86,224,114,41,177,180,155,161, +46,13,174,132,190,174,36,46,158,117,192,177,174,186,220,87,56,158,87,162,152,95,220,221,197,111,223,213,155,244,157,217,128,135,119,213,171,190,89,202,55,178,168,71,96,89,56,223,250,66,180,231,18,124,240,31,161,82,188,26,35,90,11,142,135,158,190,66,240, +222,191,134,200,199,126,236,83,146,24,189,105,64,179,162,144,59,82,80,139,21,175,250,198,36,255,52,86,193,2,58,108,177,238,146,49,77,18,27,207,90,146,183,28,236,231,69,67,89,50,82,26,49,223,160,194,45,132,88,48,66,84,41,133,95,175,19,164,153,230,81,20, +113,226,228,105,136,230,8,70,63,72,88,44,35,164,147,142,255,76,190,174,123,69,216,29,73,187,87,189,57,188,103,141,14,115,18,65,221,145,156,171,135,196,58,141,155,139,249,189,213,5,194,73,50,205,45,47,15,94,22,145,26,39,194,203,32,186,6,208,157,133,171, +157,220,208,203,151,218,54,197,124,46,25,130,158,246,126,32,159,102,170,231,108,176,173,171,34,127,141,114,93,5,204,70,138,159,222,217,197,111,220,213,139,86,73,75,229,27,225,217,51,22,186,161,105,169,107,165,112,190,229,185,72,47,143,255,129,191,67, +151,230,82,183,210,26,147,96,28,15,61,55,73,240,193,127,68,215,107,56,143,123,122,226,226,50,115,213,23,96,9,176,164,228,161,98,157,95,57,49,195,135,167,106,20,44,201,122,123,95,52,179,216,53,12,120,54,127,119,95,63,79,237,202,16,105,109,146,223,54,136, +197,221,72,48,83,105,151,182,48,12,169,86,171,205,82,49,128,82,177,200,217,115,231,22,196,183,181,112,161,114,30,93,189,128,101,217,45,110,188,53,216,121,132,51,120,203,135,177,172,40,130,74,161,211,99,162,180,198,113,28,178,217,44,82,64,97,160,135,154, +24,67,58,22,194,178,17,110,6,225,228,144,153,44,194,241,208,11,214,171,171,19,210,100,148,38,198,233,107,180,171,110,204,69,157,40,195,165,185,228,191,115,14,116,101,19,215,186,231,92,149,78,13,215,139,85,41,13,115,177,226,117,219,59,249,127,7,250,136, +149,34,220,192,183,158,17,244,219,9,173,33,138,176,238,127,42,153,238,94,130,79,124,144,232,27,95,74,172,234,181,102,192,219,14,122,110,138,240,163,239,67,215,42,56,223,242,28,68,71,55,4,254,218,173,255,219,8,91,36,139,250,219,46,22,249,205,83,51,76, +4,138,46,91,182,101,183,29,40,77,164,53,47,29,206,243,230,189,189,236,200,57,205,70,49,134,155,47,222,112,181,171,90,28,199,8,33,152,157,153,161,84,42,53,187,172,205,206,206,50,58,58,186,64,188,147,25,221,11,235,167,133,208,16,207,36,45,95,101,174,197, +55,100,129,55,146,222,243,183,254,122,136,83,99,162,241,233,84,28,211,209,217,73,46,151,107,126,254,238,238,110,70,182,110,5,52,251,252,136,255,239,84,76,197,7,105,217,233,97,209,233,255,22,183,106,189,218,166,37,49,76,86,190,179,194,180,68,205,153,169, +192,76,45,17,241,158,108,242,93,138,52,193,173,181,59,115,54,82,188,118,123,7,111,57,212,71,24,111,252,161,70,70,208,111,75,107,61,66,238,189,23,55,91,64,88,54,225,215,62,11,196,235,42,107,83,179,147,132,159,254,119,212,197,211,120,47,122,5,178,111,16, +237,223,185,162,174,1,79,10,234,177,230,55,79,77,243,230,51,179,244,88,146,172,37,218,38,230,33,240,123,119,245,242,234,237,157,72,41,240,99,101,26,184,222,68,241,182,109,187,217,152,37,78,93,178,231,207,159,167,90,173,54,45,242,169,169,41,74,243,186, +170,73,41,113,221,235,204,90,16,18,226,18,186,118,97,13,75,176,6,225,66,238,224,45,11,127,69,81,148,134,162,147,141,205,192,192,0,249,124,30,210,44,123,1,12,12,14,210,217,217,185,160,198,61,142,227,164,28,220,214,12,14,245,115,236,252,20,98,149,253,231, +133,210,4,25,7,101,89,11,30,163,209,84,98,77,61,214,28,204,217,116,198,112,2,129,181,189,7,10,238,213,44,246,22,61,90,73,2,156,226,167,118,116,242,150,67,125,155,166,73,147,17,244,219,214,82,15,145,35,187,112,95,248,35,96,89,132,15,124,106,125,238,119, +203,70,23,103,136,190,250,25,116,181,66,246,123,127,2,49,180,237,142,45,107,243,108,201,145,98,192,155,79,207,240,238,241,10,125,150,92,80,210,186,102,65,33,105,225,58,236,89,252,223,3,125,124,231,80,142,56,214,248,177,54,98,126,131,5,188,49,33,44,72, +175,233,51,103,206,224,251,62,74,169,166,128,207,204,204,52,91,166,54,44,118,111,81,87,181,235,95,3,22,68,37,116,253,44,66,174,97,62,150,149,65,56,67,232,155,212,151,44,158,23,95,86,74,177,107,215,46,28,199,193,178,109,108,203,162,167,167,167,105,141, +75,41,177,44,107,193,49,139,230,141,16,213,36,101,222,79,220,51,192,71,207,77,97,183,112,81,199,249,12,177,231,44,16,114,91,192,15,12,231,121,193,96,158,135,230,124,222,57,90,65,244,23,146,27,105,141,57,38,2,152,8,21,63,179,189,147,255,123,176,111,83, +13,163,52,130,126,59,139,122,24,34,122,250,241,190,251,21,32,37,225,87,214,41,234,182,3,150,77,124,244,235,212,254,225,173,100,190,231,213,136,109,123,146,90,216,59,36,109,178,17,47,255,167,177,10,191,112,108,138,201,32,166,35,21,243,245,162,52,84,149, +226,165,131,121,126,121,79,55,135,58,93,194,72,115,237,81,22,134,86,133,59,185,61,52,113,218,81,45,76,227,221,39,79,158,68,107,221,20,162,74,165,210,76,110,155,31,51,191,174,5,190,10,43,91,71,179,16,215,208,50,211,242,99,201,108,75,109,72,213,134,101, +66,95,215,75,113,232,208,33,0,92,199,193,113,28,58,82,203,59,73,226,147,205,132,183,198,243,45,238,68,183,228,30,146,130,231,223,189,133,127,61,124,153,35,163,179,120,246,181,61,135,66,67,236,56,84,186,242,68,182,68,106,77,167,37,248,223,187,123,120, +122,127,142,189,89,155,82,172,249,237,51,69,46,197,26,119,29,45,24,53,48,29,198,188,118,123,39,191,125,176,23,244,141,73,128,51,130,110,88,219,229,25,133,144,45,224,189,228,149,136,76,158,224,115,255,145,150,186,89,107,93,25,193,245,136,207,30,163,246, +247,111,193,251,222,87,97,237,58,148,184,255,110,243,178,54,55,117,177,255,233,249,89,126,233,228,12,18,200,202,246,204,84,170,41,77,164,225,231,119,118,241,134,189,221,120,82,54,197,220,208,154,104,207,207,52,111,8,77,16,4,212,235,245,102,15,243,98, +177,200,217,179,103,155,73,109,141,184,248,2,225,185,33,77,90,4,40,31,81,59,137,22,246,154,110,105,114,135,214,164,88,243,55,43,90,107,44,203,106,110,78,132,16,40,165,232,236,236,100,207,158,61,104,173,113,93,23,219,182,23,108,96,230,103,240,47,119,204, +86,101,105,43,205,214,158,28,63,245,228,125,252,234,7,30,100,210,15,113,45,137,92,102,87,28,197,138,64,11,244,80,39,93,131,93,220,223,147,229,245,219,59,185,183,203,163,32,37,182,109,113,190,226,243,189,15,93,225,225,74,152,116,97,92,199,134,122,46,86, +252,196,182,78,222,114,176,31,33,52,225,38,75,62,53,130,126,39,160,98,176,29,220,23,254,48,34,147,197,255,216,251,32,168,39,83,132,214,98,90,10,1,182,139,26,59,143,255,174,63,195,251,238,87,96,237,191,47,137,13,222,166,101,109,174,45,57,86,246,249,131, +51,69,254,126,172,76,86,182,207,102,46,199,138,109,25,135,215,238,236,228,167,119,118,17,69,202,100,177,183,96,113,55,132,183,33,46,229,114,153,74,165,66,28,199,132,65,128,144,146,43,87,174,48,49,49,177,96,130,88,67,196,26,220,180,150,168,58,64,215,78, +181,54,42,181,249,38,221,36,187,125,21,147,0,226,56,110,138,111,28,199,228,243,249,230,208,149,70,162,218,182,109,219,208,90,99,219,54,182,109,47,217,196,204,223,20,173,100,209,175,101,79,18,41,205,115,238,222,130,103,75,254,224,147,199,249,218,165,153, +164,229,186,76,218,221,42,165,137,16,12,117,120,236,218,209,207,163,239,217,198,107,247,244,210,159,177,137,211,4,60,91,74,206,87,2,94,246,208,4,95,47,6,116,216,235,59,127,197,72,241,227,219,10,252,209,161,62,20,122,83,185,218,141,160,223,113,198,122, +146,37,234,60,239,229,144,201,18,126,250,67,168,226,76,146,37,43,214,26,87,183,80,99,23,240,223,243,151,120,207,123,57,214,189,223,148,184,229,111,163,178,54,75,128,101,75,62,62,81,229,39,143,78,114,166,26,209,97,181,103,225,151,192,68,24,243,221,3,121, +126,101,111,55,247,247,100,240,67,147,248,182,146,128,207,143,91,55,18,213,132,16,140,142,142,82,171,213,18,65,215,154,43,19,19,204,206,206,38,9,90,243,92,229,55,99,0,201,170,44,244,212,221,14,45,10,186,142,33,183,59,25,44,178,140,152,71,81,180,64,192, +7,7,7,241,60,175,121,236,134,135,135,233,234,234,2,192,113,146,22,172,243,55,52,139,197,251,198,46,71,201,80,161,103,28,24,98,103,95,129,247,63,116,145,35,227,69,38,107,1,42,140,233,204,186,236,26,238,226,9,187,250,121,222,254,1,132,36,217,232,166,85, +30,174,37,184,84,11,249,254,135,174,240,165,57,159,94,103,237,149,37,2,152,10,21,255,109,107,7,127,114,168,55,109,224,180,57,239,19,35,232,119,148,165,174,192,146,56,207,252,110,228,224,86,130,143,189,143,248,204,81,144,122,237,217,234,182,157,136,250, +135,254,1,183,86,198,122,220,211,17,142,155,52,187,217,228,56,105,183,174,191,61,95,228,231,143,79,83,138,85,219,196,92,147,100,209,190,110,123,23,191,190,175,135,46,87,26,49,95,198,250,110,252,220,24,255,169,181,230,236,217,179,132,97,216,20,244,201, +201,73,130,32,104,90,216,150,101,221,160,241,159,237,57,243,186,114,20,244,26,174,35,21,34,178,251,65,254,255,236,157,119,148,101,85,149,255,63,231,220,123,95,174,92,213,93,157,35,29,104,154,32,24,127,227,24,144,49,43,40,8,234,136,145,81,28,195,140,58, +58,166,209,25,195,40,51,42,102,5,196,52,70,84,212,65,49,225,128,98,68,164,105,82,3,29,160,115,229,240,242,187,247,158,243,251,227,190,42,170,233,6,234,213,123,85,93,97,127,214,122,139,94,172,238,23,238,61,247,124,207,222,103,159,239,142,19,60,168,110, +69,41,197,170,85,171,112,28,103,60,210,94,180,104,17,177,88,12,165,20,174,235,30,145,197,120,240,159,143,87,144,81,9,44,107,58,211,188,249,105,39,50,146,47,49,90,168,224,135,134,230,68,140,206,214,100,180,80,241,131,35,18,127,158,130,67,197,128,243,183, +247,242,135,145,50,157,158,158,114,53,129,2,250,125,195,107,151,103,248,212,166,14,20,204,233,158,8,34,232,11,141,48,234,202,230,108,121,52,177,68,146,202,207,175,34,220,121,251,212,247,212,199,68,189,255,48,229,31,94,137,179,127,23,241,231,92,136,74, +164,230,180,168,199,180,162,191,18,242,182,123,6,184,166,183,72,201,88,154,157,198,156,47,47,27,75,139,171,249,228,166,14,46,94,217,140,71,212,187,124,33,138,249,177,138,213,42,149,10,190,239,99,140,161,88,44,178,123,247,238,35,34,200,108,54,251,160, +68,145,67,60,30,159,43,191,24,138,123,106,78,174,69,231,176,93,172,219,129,171,61,54,111,94,87,125,244,220,241,189,238,230,230,102,148,142,246,162,199,162,239,177,136,123,98,165,249,108,163,18,24,20,134,166,132,71,75,50,114,183,180,198,226,251,193,81, +101,57,174,130,195,229,144,243,182,247,114,211,104,153,142,58,196,28,96,208,55,188,102,89,134,75,55,118,224,105,53,231,183,186,166,112,102,66,246,246,230,133,168,43,141,179,230,68,226,207,127,5,229,255,253,58,225,61,219,162,115,234,83,221,83,87,10,91, +41,19,252,238,231,216,114,137,196,217,175,66,165,155,231,92,250,221,81,10,7,216,145,171,112,206,109,125,28,42,250,40,32,213,128,243,229,99,85,236,167,55,197,185,116,99,59,103,180,196,49,198,82,153,231,207,212,196,98,181,49,97,6,8,170,71,196,198,236,80, +179,217,44,187,119,239,30,55,111,137,146,74,6,223,247,143,170,188,158,155,104,8,6,33,44,60,236,212,58,177,178,94,171,104,173,109,195,10,157,107,159,206,202,83,158,65,60,145,38,145,136,143,47,0,143,168,7,168,22,190,153,112,110,213,178,88,32,120,132,246, +168,49,173,232,173,132,188,104,123,47,55,143,148,105,174,195,192,201,88,200,134,134,151,45,205,240,201,77,237,196,181,58,254,166,77,13,56,42,35,17,250,66,197,70,221,5,244,210,85,196,207,189,136,242,213,95,34,188,227,166,200,255,189,142,179,234,88,75, +120,243,111,40,87,74,196,95,112,17,170,181,19,252,202,156,152,80,226,90,97,44,92,211,87,224,141,119,15,48,232,27,188,106,21,123,61,146,59,118,182,220,2,103,117,164,248,234,150,78,90,60,133,111,230,95,21,251,68,225,213,142,131,173,158,71,86,74,145,203, +229,41,148,138,81,161,154,82,244,246,246,114,248,240,225,163,10,177,102,166,218,252,120,92,28,7,138,59,192,250,81,15,17,236,216,99,136,2,28,71,225,185,10,215,117,240,92,77,60,166,105,78,187,52,103,20,153,166,149,196,214,60,7,149,233,6,19,85,234,91,142, +92,0,204,103,98,142,98,160,108,56,239,214,62,110,26,45,215,85,0,103,137,196,252,197,221,105,62,179,169,157,132,210,243,166,8,213,157,202,197,16,230,83,180,30,162,58,151,144,56,255,31,41,255,224,10,130,91,126,27,21,182,233,58,142,181,57,14,193,173,127, +194,150,138,196,207,125,29,186,123,89,228,42,55,139,137,187,154,254,138,225,195,123,134,248,202,254,28,1,150,88,181,146,189,94,49,31,14,13,203,99,46,47,91,146,225,253,235,90,9,137,10,130,230,83,228,237,58,46,198,26,194,48,196,132,145,74,29,60,116,136, +114,185,92,117,8,83,28,56,120,128,124,62,63,190,215,173,181,158,195,209,246,228,24,75,117,91,107,177,10,24,221,131,45,251,184,158,71,220,211,36,226,154,120,204,33,22,211,36,99,154,76,218,37,147,114,73,198,157,168,51,153,5,99,42,16,111,193,58,77,145,120, +47,176,44,105,220,81,244,85,12,47,186,173,151,27,71,74,180,187,245,21,192,13,7,134,11,22,167,249,204,166,142,40,50,159,37,215,179,17,91,110,18,161,11,16,248,168,214,14,226,23,188,30,18,73,130,63,254,170,154,70,215,83,31,154,174,75,184,227,22,74,223,254, +44,137,23,188,58,50,160,9,252,89,57,25,197,29,197,206,188,207,235,238,236,231,186,129,34,109,158,67,92,169,186,191,170,82,48,228,27,78,204,120,124,122,99,59,79,234,76,17,132,102,206,22,221,76,20,112,71,59,4,97,48,94,109,190,127,223,126,130,48,32,12,194, +241,8,251,208,225,67,227,209,57,112,212,153,230,121,151,244,154,112,46,123,44,106,94,190,124,121,117,225,226,129,178,24,157,192,13,82,36,146,9,18,113,135,84,210,33,17,115,112,93,85,237,222,105,163,35,91,19,35,198,176,140,138,45,141,252,219,77,176,160, +166,166,152,86,12,250,134,243,111,237,229,250,193,98,212,138,216,214,247,60,158,223,157,230,179,155,59,72,57,138,96,158,173,141,68,208,133,104,2,170,148,80,169,12,177,115,94,141,74,166,240,111,248,9,168,58,92,229,148,2,47,142,217,121,27,165,239,93,65, +252,89,47,70,175,219,60,54,243,205,42,49,191,182,183,192,123,118,14,115,107,182,66,167,231,96,27,240,21,45,48,26,88,30,211,22,231,127,182,116,177,54,237,225,135,102,206,28,135,121,176,37,170,53,118,60,218,46,149,74,236,217,179,7,133,34,52,209,89,231, +161,161,161,241,181,220,152,213,206,124,143,190,39,30,243,50,198,144,72,36,88,191,126,253,184,127,185,231,121,180,181,181,69,11,32,55,1,149,189,132,36,112,252,38,148,227,97,172,173,182,239,182,84,30,170,133,151,53,224,164,81,169,77,160,99,16,150,23,204, +156,164,85,244,12,189,240,150,94,126,51,84,162,203,115,234,122,126,134,252,40,205,254,201,141,237,180,184,154,242,60,244,122,16,65,23,198,163,106,91,169,160,98,9,98,207,124,9,186,185,19,255,230,223,96,14,236,142,250,6,51,197,98,57,47,134,185,239,78,42, +63,253,38,222,147,159,27,157,85,215,154,227,237,218,224,41,133,193,242,214,123,6,248,206,193,2,67,129,161,205,107,76,21,187,111,45,9,173,120,207,154,22,94,191,178,153,206,152,166,60,75,123,151,31,171,127,247,88,235,207,177,74,243,161,161,33,246,239,223, +63,110,243,105,140,161,84,42,29,33,250,179,227,140,119,99,197,122,226,159,181,214,71,100,40,194,48,164,163,163,131,229,203,151,163,120,64,192,147,169,228,17,215,117,220,153,13,48,249,61,16,140,18,24,85,67,151,52,3,110,59,36,87,46,168,253,78,79,41,114, +161,229,156,109,61,252,126,184,68,123,29,213,236,209,226,218,240,194,69,41,62,177,177,157,246,152,51,47,197,188,54,65,151,205,243,133,65,24,128,27,195,125,226,179,80,109,157,84,126,245,125,204,254,93,209,190,250,148,93,229,92,194,251,239,134,95,27,236, +80,31,238,223,60,19,92,23,142,195,81,26,173,192,211,138,254,114,200,235,238,28,224,199,125,5,210,142,38,169,235,175,98,31,43,182,233,142,57,124,225,196,14,254,174,35,137,66,81,62,222,57,246,9,81,243,131,251,119,23,139,197,241,74,115,223,247,209,90,179, +127,255,126,134,134,134,142,176,69,157,152,58,159,143,209,247,131,27,144,36,18,137,241,223,104,140,97,241,226,197,116,119,119,99,171,189,189,61,207,195,113,156,163,220,229,38,218,162,30,113,3,172,133,202,32,182,214,148,185,53,168,216,18,72,172,3,235, +47,136,41,40,174,21,195,161,225,5,219,122,249,221,80,84,0,103,235,121,38,3,195,243,186,82,124,102,83,7,157,179,89,204,27,240,181,36,66,23,142,17,20,132,209,177,182,147,31,71,60,153,166,252,191,95,35,220,123,47,42,54,69,171,88,162,66,185,112,223,61,4, +251,119,18,203,142,18,123,230,249,40,47,134,245,203,204,84,235,17,71,129,235,104,174,235,43,240,193,221,195,220,56,92,166,197,173,223,40,70,1,21,107,169,24,56,169,41,198,101,39,118,114,70,115,172,42,228,51,60,121,76,16,111,85,109,103,105,194,168,88,205, +98,233,239,239,143,162,239,138,15,10,246,237,219,71,46,151,27,143,64,39,70,163,19,69,105,198,108,81,103,136,35,138,213,172,165,173,173,45,18,104,165,177,88,86,172,88,65,115,115,51,0,177,88,108,146,194,253,80,247,196,133,74,47,54,119,83,181,255,249,100, +77,111,44,232,56,164,79,4,39,9,102,126,167,219,45,144,112,20,3,129,229,252,109,81,154,189,181,206,231,51,27,26,158,213,149,228,211,155,219,233,140,207,223,200,188,102,65,151,54,17,11,12,107,0,133,222,116,42,241,68,138,210,85,95,140,68,221,139,79,93,127, +181,11,38,164,114,221,247,177,229,60,241,231,189,28,226,201,105,63,214,102,137,220,165,28,173,248,208,238,97,62,125,255,40,163,190,161,213,213,13,235,93,30,90,120,227,202,38,254,101,117,11,93,9,151,82,48,51,174,111,15,222,235,214,74,227,7,145,139,90, +24,134,28,60,120,144,48,12,9,252,0,139,229,192,193,3,132,65,136,210,81,175,87,215,117,231,93,186,252,193,194,123,68,251,206,106,83,146,165,75,151,142,59,168,57,142,195,178,101,203,162,168,91,59,184,158,123,68,35,147,73,11,247,67,222,36,141,173,244,98, +43,131,181,249,183,91,64,107,84,98,25,11,33,69,26,215,138,145,192,112,193,173,125,92,55,80,140,246,204,235,88,100,143,4,134,103,116,36,249,236,166,14,150,196,93,202,102,118,155,55,53,66,99,37,66,23,30,110,54,4,191,130,94,179,145,196,75,222,72,229,251, +151,17,236,186,51,74,191,79,21,237,128,5,255,183,215,66,177,72,236,156,87,160,210,45,211,234,42,151,112,20,67,101,195,123,118,13,240,185,253,89,90,28,77,202,105,204,3,20,88,48,88,174,216,210,201,249,221,105,148,86,211,42,230,71,116,20,67,225,7,254,120, +187,202,92,54,199,190,125,251,162,36,139,49,132,38,100,112,96,48,250,55,213,200,221,117,93,28,207,57,90,56,230,3,10,172,153,208,81,204,88,98,241,24,171,215,175,142,38,187,106,3,18,207,243,232,236,236,28,207,96,140,121,195,79,171,171,90,233,62,240,7,65, +215,240,236,40,139,74,110,64,165,54,207,251,234,118,71,69,94,13,231,110,239,229,87,253,99,98,110,167,58,12,24,13,45,207,232,76,242,233,77,237,44,75,204,126,49,159,241,8,93,88,192,84,202,232,229,107,136,191,228,141,240,189,203,8,238,186,37,50,145,153, +170,179,145,19,57,210,249,55,223,128,13,125,226,207,189,16,213,214,217,240,66,57,5,196,28,205,77,195,37,222,179,115,144,235,7,75,180,57,154,70,52,74,179,128,111,44,107,82,30,159,218,212,206,147,218,147,4,198,18,54,200,194,245,152,253,187,195,144,114, +245,60,255,224,192,32,251,247,237,71,233,7,82,227,190,239,83,44,22,143,104,100,50,159,142,137,61,84,148,60,246,91,195,32,164,173,189,45,234,32,102,44,49,47,70,44,17,35,147,201,68,107,201,234,86,194,88,81,27,48,158,201,152,190,69,134,3,193,16,54,127,7, +216,0,136,213,54,130,227,75,192,105,154,215,251,231,142,138,90,170,62,111,123,31,215,247,151,170,222,236,118,202,207,101,54,48,60,181,61,201,165,27,219,89,149,244,230,125,154,93,4,93,152,146,168,171,142,37,196,47,120,3,92,125,5,193,246,63,1,186,154,126, +159,130,132,105,13,74,69,239,19,26,226,207,188,0,181,100,101,36,234,182,126,97,247,170,170,125,249,254,81,222,122,239,32,202,88,50,174,110,136,216,250,85,187,214,87,46,205,240,238,117,109,44,139,123,84,194,218,167,160,35,210,229,213,10,242,177,243,114, +165,82,137,74,185,60,110,123,186,111,255,126,6,250,251,199,93,211,140,49,4,65,112,84,202,221,243,92,230,75,248,253,64,239,238,232,119,120,158,135,30,107,127,10,152,48,100,197,202,149,180,119,116,140,47,94,198,124,205,39,94,223,137,71,203,102,62,107,224, +128,63,132,45,237,175,45,58,175,222,59,149,92,9,152,121,59,173,196,180,34,111,44,231,108,239,229,55,3,37,90,92,85,87,1,92,62,176,252,109,91,130,79,110,106,103,109,218,163,18,46,172,173,98,17,116,97,242,4,21,84,75,59,241,115,255,1,103,201,106,252,63,253, +26,51,216,51,245,20,124,117,194,13,238,184,9,66,159,216,89,231,162,215,157,24,85,191,79,177,175,122,84,88,163,25,174,4,124,118,111,150,255,216,61,76,198,85,71,69,188,83,37,23,90,28,5,239,95,215,198,59,86,71,174,111,229,73,8,197,17,166,44,142,19,249,109, +27,19,165,136,173,97,176,90,172,22,250,62,40,197,158,61,123,40,151,74,168,106,49,150,170,94,175,96,66,52,57,111,44,81,171,247,45,28,43,84,171,170,120,83,115,51,186,218,108,196,90,203,138,149,43,143,104,255,233,185,238,248,245,153,24,197,215,84,176,54, +19,191,173,184,23,202,251,162,72,187,150,43,162,211,144,222,50,47,157,225,198,10,224,134,66,184,96,123,47,215,15,20,105,169,179,147,97,33,52,60,190,37,206,167,54,117,176,33,19,59,254,167,75,68,208,133,217,47,234,62,42,211,138,247,183,207,70,165,155,168, +252,250,135,152,193,222,250,69,253,238,237,216,209,33,188,39,61,23,247,177,79,133,128,154,69,221,2,9,79,243,199,193,18,31,223,51,204,143,250,11,117,53,112,56,226,107,18,89,70,158,210,20,227,13,171,90,121,197,242,12,229,135,240,111,61,194,207,92,107,180, +214,132,65,64,88,141,170,15,31,62,28,21,170,5,65,84,129,110,66,246,238,221,123,196,191,115,28,103,60,26,125,184,223,59,103,39,244,9,197,106,99,149,245,139,22,45,26,95,240,104,173,89,189,122,117,180,231,175,53,238,49,10,247,102,178,127,247,148,71,77,88, +192,22,238,2,98,181,221,48,107,80,153,13,40,167,133,249,86,16,103,129,132,86,140,26,203,203,110,235,229,23,125,5,58,235,180,115,205,133,150,71,55,37,248,244,166,118,54,55,197,40,45,208,238,133,34,232,194,148,68,157,68,10,247,177,103,66,42,67,229,39,223, +136,68,221,153,226,112,82,81,251,147,96,207,221,152,190,67,216,82,142,216,19,159,131,181,102,210,209,137,86,224,185,154,239,31,204,241,230,187,7,56,92,14,27,86,197,174,128,1,223,240,202,37,77,188,99,109,51,27,154,227,148,38,244,46,127,176,128,143,117, +8,3,200,229,114,28,56,112,0,172,37,168,238,215,246,244,244,28,177,207,61,230,44,54,159,25,203,72,64,180,111,157,78,167,89,181,106,85,52,9,85,45,97,187,187,187,199,23,51,99,89,140,137,145,246,156,107,66,162,20,132,21,168,28,170,173,186,29,192,250,168, +228,218,232,200,219,60,19,244,152,82,20,141,229,194,219,250,248,73,79,129,78,175,62,49,207,27,203,233,77,113,62,189,185,157,147,90,226,11,86,204,69,208,133,169,19,6,224,184,184,167,61,1,21,75,80,190,250,75,81,250,221,241,166,252,104,170,84,26,91,46,82, +190,230,27,80,42,225,61,245,156,232,137,125,132,137,220,83,10,223,90,62,177,123,136,255,216,53,76,209,88,218,26,36,230,22,24,8,45,111,95,219,202,251,214,182,146,114,52,149,192,162,171,98,108,140,193,15,2,42,229,50,90,107,122,122,122,198,5,27,160,82,169, +144,203,229,80,58,218,191,87,74,205,161,222,221,83,143,190,39,138,111,24,134,44,94,188,152,174,174,46,180,214,120,158,71,34,145,160,169,169,105,124,17,52,177,80,13,102,119,255,238,154,174,69,121,63,182,120,127,141,199,213,66,84,124,9,170,233,81,81,63, +5,27,206,155,177,161,129,192,90,94,122,71,31,63,233,173,79,204,1,242,161,101,107,38,42,76,61,165,53,65,121,134,142,139,138,160,11,243,48,236,10,65,41,156,173,143,38,17,139,83,186,234,139,152,222,253,224,198,166,86,1,111,109,148,186,247,43,148,127,121, +21,182,84,36,246,244,243,193,115,225,24,149,200,138,168,168,230,254,82,192,63,237,24,224,250,193,34,161,133,38,103,138,147,132,82,84,207,119,129,181,84,66,75,90,91,62,184,170,137,183,173,106,66,155,128,145,210,3,182,168,90,107,246,236,217,67,54,155,29, +23,112,223,247,143,40,86,83,74,205,187,134,36,15,62,159,237,186,238,120,198,33,8,2,86,172,88,65,123,123,123,20,141,85,139,212,226,241,248,17,127,111,226,251,132,97,56,63,159,15,107,33,119,11,152,18,168,26,22,186,214,128,215,14,110,203,252,18,27,165,8, +177,92,120,71,63,63,235,45,212,93,0,87,12,45,155,210,30,159,220,220,201,163,218,226,84,130,249,91,60,40,130,46,204,220,164,21,4,56,155,78,37,241,210,55,83,186,234,11,152,189,247,64,44,49,245,99,109,90,67,224,83,185,254,71,80,41,225,61,243,197,168,84, +83,148,234,175,78,1,158,86,104,224,79,195,101,206,187,173,151,145,138,193,209,138,152,154,100,130,82,169,7,94,145,186,68,197,120,65,128,53,1,197,82,153,117,182,196,107,219,21,167,247,29,224,134,189,101,194,99,100,10,30,156,6,30,51,43,153,55,137,152,7, +117,15,3,72,103,50,168,106,100,109,173,101,253,250,245,36,19,9,148,214,196,98,49,60,207,59,102,17,226,236,223,243,110,248,213,195,22,246,84,151,158,53,252,110,83,130,228,106,112,82,243,166,32,46,166,21,5,11,111,184,179,159,107,122,242,36,235,60,59,90, +50,134,117,201,24,159,216,212,193,227,218,18,179,182,87,130,8,186,48,39,69,221,150,75,56,107,55,145,120,233,155,40,95,245,69,130,123,182,163,98,177,169,239,171,107,7,140,161,242,251,159,99,131,128,216,211,207,67,181,118,97,131,10,9,71,225,27,203,87,14, +230,120,247,189,67,228,67,51,222,187,252,225,197,59,58,42,135,9,163,197,65,185,28,185,212,249,209,127,85,33,71,144,203,225,151,203,156,209,236,240,170,101,45,44,55,30,67,121,30,178,74,190,81,213,243,179,227,54,86,11,213,198,44,96,149,162,163,122,36,76, +107,141,227,56,184,174,203,234,213,171,113,170,169,115,215,243,162,251,255,160,5,142,181,11,221,89,82,65,249,16,182,176,179,198,54,196,22,156,24,42,185,49,178,136,157,227,118,175,214,70,29,13,75,88,222,182,99,128,239,28,202,147,208,170,174,180,120,57, +180,44,79,184,124,114,83,59,79,234,72,70,197,169,10,97,74,130,110,197,2,86,120,136,161,81,42,226,44,95,75,252,197,111,68,93,243,117,194,61,59,176,217,225,168,17,203,84,35,117,19,226,255,233,87,16,6,196,158,244,92,18,43,215,178,63,87,228,45,119,15,112, +109,95,1,69,100,25,121,196,168,28,19,238,49,145,175,84,160,84,132,82,97,92,188,41,151,162,255,87,46,65,24,165,200,203,22,18,142,195,243,186,51,156,215,157,38,233,106,42,198,162,230,233,100,97,140,25,143,192,141,49,164,146,73,150,45,93,58,110,143,26,139, +199,89,190,108,25,192,184,152,107,199,137,142,151,85,69,220,204,215,116,121,221,122,238,96,242,183,18,157,33,175,97,0,153,0,149,88,129,138,47,173,122,50,204,237,249,54,166,20,129,177,188,243,222,65,190,114,32,75,210,137,50,107,83,92,34,81,177,176,40, +238,240,169,77,29,60,181,51,73,201,15,163,171,59,31,100,169,1,19,77,205,51,173,200,185,240,112,3,210,150,139,232,69,203,136,159,251,15,248,191,255,57,149,223,253,12,114,35,117,70,234,33,193,95,127,75,34,244,249,227,214,39,241,198,114,55,127,25,44,210, +230,41,180,82,145,237,198,88,20,110,2,40,228,160,152,131,66,190,26,129,251,15,8,121,224,71,131,120,98,202,221,245,40,25,75,71,76,243,138,165,77,60,169,35,137,177,145,71,251,124,19,240,177,200,57,12,67,58,59,59,233,234,234,138,38,2,215,37,157,74,209,218, +218,26,69,231,213,163,99,97,24,142,39,140,195,48,60,226,28,188,240,8,242,83,25,172,94,185,26,38,106,91,134,248,114,172,215,57,231,139,225,180,130,16,120,231,61,131,92,113,32,75,92,105,180,157,154,134,140,53,64,234,136,57,124,102,115,7,79,239,74,81,10, +204,188,210,164,70,196,13,146,114,23,26,62,44,173,95,134,166,22,188,191,125,14,42,158,164,114,221,15,176,185,145,41,157,85,87,128,235,184,148,194,144,143,253,254,183,252,240,250,27,217,181,230,177,180,63,254,220,40,74,44,21,161,144,141,68,188,144,139, +246,193,195,48,74,171,135,1,24,251,128,155,157,82,71,45,44,12,16,90,56,33,237,241,250,229,205,172,77,123,4,54,106,182,50,167,178,35,15,211,191,123,76,192,215,172,89,67,38,147,25,247,52,79,38,147,227,5,123,19,219,170,142,117,90,11,38,26,189,8,53,69,231, +248,125,216,220,157,81,129,219,100,43,220,173,1,183,5,213,116,26,56,153,104,47,125,14,139,185,70,241,174,123,7,185,252,64,14,23,133,163,166,62,150,74,198,210,234,105,62,185,169,157,103,118,165,100,207,92,4,93,152,81,130,0,226,73,220,39,62,11,235,197, +169,252,244,155,144,31,1,111,242,21,223,110,181,224,124,119,37,228,19,131,5,254,47,239,67,197,167,245,208,143,41,237,187,143,242,198,39,68,118,154,97,148,2,142,210,147,19,34,34,165,225,97,230,82,223,88,226,90,113,102,123,130,151,44,109,162,201,141,246, +230,103,187,128,61,184,19,24,64,34,145,24,23,102,99,12,235,214,173,35,153,76,162,171,133,106,99,34,62,177,250,126,98,145,90,40,145,119,3,5,221,195,22,119,64,208,95,99,220,101,192,77,67,172,125,110,139,138,86,88,44,239,223,57,196,229,7,114,209,58,186, +142,247,43,87,109,155,63,177,185,157,231,46,74,83,14,140,44,50,69,208,133,25,167,122,172,205,251,127,79,71,185,49,42,63,249,26,118,116,104,82,162,238,41,69,201,90,174,26,40,240,169,131,163,236,207,150,73,140,69,161,10,156,193,63,224,12,13,18,110,125, +10,52,183,70,105,245,177,99,103,147,160,16,90,58,60,205,249,221,105,158,222,149,138,138,245,103,233,44,49,209,148,197,24,131,235,186,180,182,182,142,11,184,235,186,172,93,187,118,252,207,94,44,54,126,78,254,193,17,188,20,173,205,72,146,10,138,251,34, +83,153,90,246,69,141,15,110,59,36,86,207,217,102,44,94,181,158,229,146,61,35,124,110,95,22,107,163,230,43,83,197,183,150,132,163,248,248,166,54,206,235,206,80,242,37,50,111,140,160,203,4,32,76,45,156,132,192,199,123,252,211,80,169,20,229,171,175,196, +14,30,142,142,181,61,196,152,114,20,140,26,195,135,246,143,240,205,131,163,216,74,72,106,98,225,155,5,163,60,216,117,39,228,139,112,202,83,160,107,113,180,128,176,143,24,3,81,10,45,235,83,46,175,94,214,196,41,205,113,42,214,206,154,246,23,19,11,213,198, +34,231,166,166,38,218,218,218,80,128,83,77,149,47,93,186,52,154,64,61,111,220,85,109,162,88,139,96,31,47,49,119,193,31,172,118,87,171,128,74,76,246,65,1,237,162,18,107,163,243,231,225,220,75,183,187,42,42,120,251,196,158,17,254,107,207,40,198,218,241, +38,73,83,157,58,172,82,92,186,169,131,151,44,205,80,244,231,185,105,140,149,126,232,194,92,25,171,149,18,238,169,79,128,120,146,242,247,191,136,61,184,23,226,71,159,85,87,68,197,104,31,217,63,194,87,246,15,147,12,45,90,63,132,1,69,44,129,234,189,31,110, +190,14,123,226,147,97,113,23,196,156,104,223,252,216,83,38,161,181,60,189,35,193,5,75,154,88,146,112,40,134,199,55,197,62,38,196,99,237,81,59,59,59,105,111,111,31,55,108,113,28,135,166,166,38,90,90,90,198,5,125,204,192,101,140,249,226,170,54,95,4,221, +22,247,130,63,92,181,109,157,236,3,98,162,125,243,244,166,57,89,180,160,170,219,99,159,190,127,148,15,221,55,66,96,45,9,61,117,227,24,44,20,177,124,126,83,39,127,191,180,137,226,88,53,187,208,24,65,151,245,190,80,191,168,151,113,54,159,70,226,130,55, +80,249,245,143,8,119,221,137,45,230,163,254,232,85,60,165,184,33,95,226,7,61,89,18,33,71,165,142,143,30,193,49,24,237,129,221,183,131,57,29,154,19,208,18,143,102,152,9,131,214,84,183,214,95,190,52,205,211,59,82,164,29,77,97,6,10,107,236,195,172,188,195, +48,100,213,234,213,100,50,153,241,116,121,38,147,33,153,76,142,23,182,141,153,183,140,165,220,69,188,103,181,172,129,2,91,188,27,235,247,128,78,213,54,82,156,12,42,181,33,74,189,207,173,95,141,3,92,182,111,148,15,237,25,162,98,198,196,124,106,170,97, +44,20,172,229,179,39,118,242,138,101,25,202,193,194,16,243,70,104,172,68,232,194,12,142,88,11,149,50,122,237,22,226,233,102,252,27,174,161,242,151,27,192,47,129,118,35,159,103,5,223,234,205,147,45,135,196,39,251,20,219,16,149,59,132,45,228,193,7,242, +21,104,79,66,194,195,170,168,232,125,81,76,243,154,229,25,78,107,142,124,212,75,211,112,36,237,193,150,168,19,109,95,199,138,209,78,56,225,132,168,245,167,231,225,197,98,196,227,241,241,10,243,177,66,181,177,63,79,220,59,23,230,130,178,105,8,70,161,180, +183,246,244,169,114,80,233,45,40,175,3,76,101,206,252,100,71,129,163,20,87,238,207,242,31,123,134,40,26,75,172,142,200,220,183,150,146,133,79,110,238,228,53,203,154,168,132,82,0,39,130,46,204,110,81,247,203,168,174,165,120,103,189,16,226,73,42,55,94, +11,65,5,215,113,57,224,135,236,47,250,209,223,155,116,65,145,130,74,22,242,125,208,222,12,37,31,14,230,176,205,49,84,115,130,39,116,37,185,112,73,134,174,184,219,176,42,246,137,98,59,102,196,146,201,100,198,197,88,41,69,34,145,24,47,86,139,197,98,56, +174,123,204,98,53,41,84,155,47,130,238,98,253,126,108,249,64,109,222,237,213,231,66,37,150,206,169,90,37,87,41,92,13,95,221,159,229,223,118,13,81,8,45,94,29,230,40,190,181,20,44,124,124,99,59,23,175,104,166,236,135,34,230,34,232,194,156,32,12,80,205, +237,120,103,189,0,21,139,81,249,213,213,56,38,228,112,16,50,236,135,53,186,73,41,8,125,240,11,15,44,2,172,197,140,148,200,196,93,54,165,60,58,98,14,142,82,84,166,56,69,132,97,120,68,51,145,76,38,67,75,75,203,120,106,60,149,74,177,106,213,170,113,113, +247,60,111,220,152,229,88,226,45,204,83,42,125,80,25,168,109,255,28,11,177,69,144,57,21,152,27,91,42,78,85,204,191,121,32,203,191,222,59,72,54,140,142,128,78,121,129,108,33,111,225,19,27,219,121,211,170,22,217,51,23,65,23,230,28,38,68,197,83,120,79,123, +33,120,113,248,197,119,113,138,101,52,42,10,84,106,122,162,245,3,158,217,214,130,171,113,58,50,100,211,49,190,122,48,207,45,217,10,207,91,148,226,244,230,56,69,99,121,164,140,123,24,134,71,20,171,45,94,188,152,166,166,38,148,82,56,142,67,75,75,203,17, +197,107,15,22,111,73,151,47,180,232,92,67,88,192,230,110,129,112,52,42,112,155,180,158,27,116,98,53,202,91,52,39,34,116,173,192,211,112,213,161,28,111,189,103,144,225,208,146,174,35,205,174,128,17,99,249,212,166,118,222,176,170,101,254,87,179,139,160, +11,243,89,212,113,92,188,51,207,65,37,18,44,251,201,255,208,66,127,141,147,131,141,28,224,226,153,200,255,58,233,65,71,10,226,30,110,245,72,218,31,134,203,236,41,6,60,190,53,206,11,23,165,105,141,105,198,142,180,62,88,120,141,49,172,93,179,134,68,50, +137,227,56,227,2,62,102,222,226,56,206,17,133,106,19,93,213,132,133,138,6,147,135,194,94,80,241,218,42,156,172,133,248,226,57,243,75,29,20,63,236,201,243,150,187,7,25,14,44,105,71,213,149,26,31,12,13,159,218,212,201,27,86,54,83,22,49,23,65,23,230,56, +97,16,121,182,255,205,179,89,153,76,177,97,239,127,179,125,116,31,150,216,164,31,110,27,111,129,68,43,180,120,81,149,187,227,140,71,59,26,200,56,154,161,138,225,167,61,5,110,27,41,243,130,238,20,79,104,75,226,41,205,218,19,79,140,142,136,105,141,87,117, +85,27,115,89,27,219,15,159,152,46,23,241,22,142,57,6,43,61,216,226,189,181,239,159,3,42,115,74,20,229,207,98,255,118,69,116,10,229,154,190,60,111,218,49,192,112,96,234,18,243,208,66,222,24,46,221,216,193,27,86,52,75,1,156,8,186,48,159,34,117,107,13,206, +163,159,194,27,94,91,225,15,31,254,8,7,251,7,137,121,143,52,57,86,187,61,180,46,131,238,78,104,73,70,66,62,222,169,202,142,55,99,241,28,7,235,184,28,80,154,143,247,195,95,220,4,111,220,188,140,181,203,151,18,162,142,114,138,147,61,111,97,242,106,30,64, +238,174,170,119,123,117,92,78,242,223,169,228,122,136,117,51,155,15,7,107,21,245,52,191,182,183,192,27,119,12,48,228,215,95,205,94,8,225,146,141,29,188,105,85,11,149,192,32,27,84,34,232,194,188,154,20,45,149,114,153,71,61,249,233,188,107,180,196,155, +62,250,17,202,185,81,18,137,228,177,39,14,107,163,232,126,241,26,216,114,6,100,226,85,11,88,162,8,61,158,0,55,14,158,27,217,205,38,83,168,84,6,39,145,196,113,61,110,52,176,189,15,254,179,57,207,139,186,83,36,60,71,246,239,132,169,197,174,54,192,150,238, +155,124,35,150,241,133,108,5,146,203,65,199,103,173,158,71,98,174,249,69,95,129,139,239,26,160,223,55,36,234,40,128,11,173,37,31,194,71,55,180,241,150,213,45,227,93,211,4,17,116,97,30,82,41,151,121,217,243,206,38,107,20,151,94,249,37,118,238,186,135, +246,68,28,165,199,138,222,76,244,210,113,88,186,30,123,218,83,161,189,29,98,241,72,196,99,241,168,179,91,50,5,241,36,196,98,213,116,166,121,160,137,139,49,196,128,156,15,175,190,163,143,159,15,164,185,96,105,19,207,93,148,34,8,12,190,97,222,246,65,23, +166,129,96,8,74,251,106,20,116,3,110,19,170,233,49,160,19,81,148,63,219,196,28,136,41,205,117,253,5,46,186,179,159,195,149,128,38,71,215,181,246,200,134,150,143,158,208,206,219,214,180,70,222,236,242,156,29,71,65,151,12,164,48,221,129,58,16,84,42,252, +227,57,207,231,9,91,182,112,197,207,126,193,87,175,253,25,12,247,19,39,4,47,5,75,86,193,134,83,96,221,86,104,106,143,28,46,188,88,244,26,115,158,51,54,18,241,48,36,234,204,124,140,7,64,65,147,171,249,230,161,60,191,28,44,241,15,75,154,248,167,53,205, +116,122,14,165,80,6,187,48,153,0,93,99,179,183,96,43,61,53,218,189,6,16,95,134,138,117,131,85,179,110,110,85,68,205,86,110,24,44,240,234,59,251,56,84,9,105,174,67,204,21,48,228,27,46,217,208,206,91,87,183,62,208,104,69,30,179,7,46,208,204,71,232,114, +245,133,233,39,52,33,166,84,226,180,13,235,249,232,138,229,252,195,243,158,195,187,111,217,195,239,122,115,132,201,20,110,50,133,106,105,7,237,62,16,117,91,19,13,79,63,168,249,57,234,112,53,5,223,112,233,222,17,126,216,151,231,63,215,183,241,119,93,73, +28,20,161,181,50,234,133,135,159,21,139,247,63,112,108,114,210,1,122,128,138,119,131,147,142,162,245,89,54,202,60,13,191,27,46,241,202,219,251,233,169,24,154,181,158,242,169,58,3,140,6,99,98,222,140,111,102,223,239,157,15,138,46,41,119,97,246,78,146, +214,82,42,22,137,107,205,201,203,151,242,157,37,221,252,106,176,196,91,238,25,98,160,228,19,132,134,120,131,124,175,45,16,175,22,249,220,87,12,120,197,29,253,156,216,18,227,203,155,58,89,147,114,112,80,211,98,23,43,204,131,73,56,28,173,118,87,179,181, +205,201,214,160,146,107,193,107,155,85,221,213,84,245,89,248,227,112,137,11,111,235,167,239,193,221,14,107,36,176,150,124,104,249,208,250,54,222,186,186,5,223,24,36,249,53,61,212,44,232,114,31,132,153,38,48,134,192,24,28,224,121,29,49,158,120,122,23, +159,184,127,132,203,14,228,232,45,135,180,122,186,161,219,112,49,173,48,192,95,135,202,60,233,47,135,120,243,202,102,46,92,218,68,119,194,161,18,202,100,36,76,84,63,15,242,119,66,88,168,173,232,194,6,209,217,243,196,186,106,212,59,59,6,149,2,226,174, +226,79,67,21,94,114,91,63,135,43,97,93,93,211,2,11,249,208,242,239,235,218,248,215,181,45,148,141,65,214,197,211,21,159,83,163,195,166,32,28,207,136,29,40,134,150,180,171,248,192,166,14,174,60,169,147,11,150,164,25,9,66,138,161,109,168,168,143,69,41, +249,192,240,142,29,131,188,236,182,94,190,114,32,75,76,43,18,117,26,105,8,243,8,237,96,203,61,213,130,182,26,70,160,241,81,94,39,196,151,128,157,61,221,213,18,174,230,47,195,101,94,178,189,135,253,229,128,100,61,253,204,129,124,104,120,255,186,54,222, +179,190,149,82,104,69,204,167,123,56,78,254,238,216,57,213,56,64,152,191,171,88,99,161,80,9,121,118,87,146,175,110,233,228,178,19,59,57,41,227,50,28,132,68,82,219,184,151,86,208,17,215,252,102,168,196,69,119,244,115,209,29,253,220,153,173,144,242,100, +45,44,131,81,99,195,81,108,113,103,85,148,39,41,126,214,130,138,97,51,39,71,30,238,179,164,186,61,233,40,182,13,151,185,224,214,94,238,43,5,52,57,99,45,80,107,127,41,44,163,65,200,251,215,181,242,222,117,45,148,196,52,102,114,227,98,166,4,125,236,86, +9,194,108,17,246,98,96,81,10,94,179,162,153,239,159,186,152,55,174,106,97,56,180,4,166,177,99,213,0,105,71,145,214,138,175,28,200,242,188,91,122,120,255,189,67,56,40,98,90,78,221,44,220,65,232,161,138,187,176,197,123,107,148,59,131,117,83,232,196,242, +168,186,125,22,16,83,138,91,71,43,156,183,189,151,251,75,1,173,238,212,171,217,45,48,28,24,222,183,174,141,119,173,105,165,98,172,196,130,147,188,110,51,23,161,11,194,44,36,176,80,10,12,43,18,46,31,61,161,141,63,63,102,41,143,110,137,17,88,75,185,193, +249,61,93,61,226,118,176,18,242,241,251,134,121,236,77,7,248,191,193,18,142,130,132,86,34,236,11,49,66,47,247,128,41,215,56,149,70,231,207,73,172,158,21,233,246,184,86,220,149,175,240,194,91,123,56,80,14,104,174,67,204,67,11,217,192,240,158,181,173,188, +107,77,43,22,43,53,39,51,136,8,186,48,47,86,182,37,19,89,188,110,109,242,248,217,233,221,124,104,125,59,235,82,30,67,129,193,183,141,221,95,79,106,133,163,20,187,243,1,231,108,235,225,157,247,12,114,123,190,66,194,209,227,149,242,194,124,199,129,176, +136,205,223,6,65,182,182,35,107,214,86,247,207,151,29,119,239,246,164,171,184,51,95,225,156,109,61,28,42,215,91,0,103,201,135,134,183,175,105,229,189,107,219,176,88,124,121,24,68,208,5,97,42,152,106,132,16,88,120,211,170,22,126,120,218,98,46,88,210,68, +139,163,25,244,27,107,47,169,168,122,217,40,197,165,123,71,57,235,230,195,92,177,111,148,1,63,36,229,57,18,173,207,251,232,220,197,86,14,96,75,7,107,108,198,98,35,87,184,204,169,19,150,163,199,73,204,61,205,93,57,159,23,110,235,101,111,41,168,175,159, +57,80,8,225,173,171,90,248,247,117,109,24,56,170,55,130,32,130,46,8,83,162,24,26,214,36,92,190,117,114,23,95,62,169,139,167,182,39,24,246,167,231,200,76,139,171,201,251,150,139,238,234,227,37,183,245,114,93,111,158,132,171,113,69,213,231,177,160,107, +40,238,135,210,129,200,29,110,210,27,232,22,148,131,74,111,4,115,252,138,225,146,142,226,174,209,10,103,223,114,152,157,5,159,140,51,117,41,80,64,46,48,188,109,85,11,31,56,161,173,154,102,23,53,23,65,23,132,6,82,50,150,82,96,56,107,81,138,175,109,93, +196,21,91,58,9,181,162,210,224,201,198,18,185,106,181,186,14,191,234,47,113,209,157,253,156,183,189,151,1,223,212,21,245,8,179,85,204,21,152,98,84,221,30,22,106,155,70,45,168,228,122,84,98,21,15,101,71,60,221,36,180,226,158,188,207,217,219,122,216,89, +168,175,0,14,96,52,176,252,243,170,22,222,183,190,21,5,178,103,46,130,46,8,211,131,5,10,190,97,73,220,225,85,203,155,248,227,163,151,240,170,37,77,148,141,165,210,96,75,87,5,180,123,154,94,63,228,234,67,121,206,250,203,33,62,187,119,4,87,69,133,71,162, +237,243,5,23,130,97,40,237,142,210,231,53,142,72,149,92,117,220,166,222,152,86,236,46,6,60,231,175,61,220,95,172,79,204,141,141,236,92,223,180,178,137,247,173,107,195,211,146,102,23,65,23,132,233,14,168,128,178,177,148,66,203,166,148,199,165,155,59,248, +246,41,139,217,146,137,81,50,150,98,3,243,240,150,232,8,80,179,171,184,175,20,240,182,123,7,121,225,182,30,254,60,82,70,43,85,151,81,135,48,139,8,242,216,202,80,141,254,237,22,116,12,50,91,57,30,123,231,73,71,113,95,209,231,89,127,141,76,99,82,117,24, +36,133,22,114,161,225,226,229,205,188,127,125,27,73,173,240,165,11,170,8,186,32,204,100,180,94,169,30,103,123,118,103,146,223,156,177,132,55,172,104,97,77,194,101,200,111,188,241,133,167,20,105,173,185,126,168,204,227,255,124,136,15,236,26,98,103,33, +32,233,105,180,18,95,135,57,172,230,216,252,118,40,31,172,182,75,157,228,6,186,13,171,233,246,213,51,110,210,149,116,53,187,10,33,207,190,165,151,251,139,126,93,253,204,163,2,56,203,69,203,155,248,208,134,54,146,142,110,248,54,150,32,130,46,8,147,166, +92,117,174,250,175,77,237,124,231,228,46,94,185,172,137,124,104,40,26,211,240,10,117,87,65,187,171,248,224,174,97,206,223,222,203,151,246,142,18,67,69,17,146,76,132,115,108,85,168,32,44,67,97,71,141,213,237,145,20,170,88,123,109,45,86,235,253,186,214, +146,116,20,247,230,125,158,123,203,97,238,205,87,72,59,245,141,240,124,104,120,213,210,12,31,89,223,78,74,43,42,161,132,230,179,133,41,244,67,151,9,72,152,39,115,179,181,20,253,144,173,77,113,190,176,217,227,89,157,73,254,251,190,17,254,52,82,162,181, +193,71,207,44,208,234,105,110,203,149,121,211,93,21,174,238,203,243,207,171,90,56,179,35,69,201,15,37,90,159,43,40,5,254,40,38,127,79,212,186,183,38,61,175,64,122,11,168,216,140,157,63,79,58,209,158,249,243,183,245,176,35,95,161,221,213,76,85,126,21, +144,11,45,175,88,210,196,127,158,208,74,218,81,84,76,213,227,65,116,161,49,99,75,34,116,65,168,143,98,24,69,229,231,118,167,249,193,169,139,248,232,250,118,146,74,81,49,52,252,152,91,147,163,113,181,226,39,125,69,94,118,91,31,239,187,103,144,162,177, +120,26,41,154,155,19,171,64,176,133,187,35,51,25,106,237,174,182,12,149,88,59,99,211,110,76,195,254,82,200,179,111,233,225,158,124,133,182,58,196,220,2,217,208,242,210,197,41,62,188,190,149,86,207,105,184,97,147,112,28,34,116,89,135,9,243,17,223,130, +31,24,22,197,28,222,188,170,153,231,44,74,243,154,29,253,236,204,250,12,7,134,148,211,24,107,87,91,157,206,219,28,205,168,111,184,116,239,40,223,56,148,231,211,155,219,121,92,107,156,54,87,83,12,173,60,103,179,153,194,61,181,167,205,173,143,74,44,195, +58,25,96,250,83,212,73,173,56,80,14,120,218,45,189,236,205,249,52,59,122,202,139,83,99,33,111,12,23,44,206,240,225,13,109,180,199,156,200,153,81,104,108,128,222,128,247,144,8,93,16,38,80,49,22,3,172,79,57,252,230,81,221,92,186,169,141,13,41,151,98,104, +169,52,184,26,222,83,209,34,161,183,18,242,252,109,189,92,120,71,63,119,229,124,146,142,170,171,104,73,152,70,76,9,91,233,155,218,50,46,125,50,184,205,96,167,79,208,45,144,114,53,251,202,33,127,183,173,135,189,121,191,174,118,191,134,104,207,252,133, +139,82,252,215,134,54,22,197,156,134,247,72,16,26,135,8,186,32,28,99,82,12,108,84,17,255,146,101,77,252,242,140,110,222,190,186,5,237,40,134,131,233,177,144,205,104,197,79,123,10,60,251,175,61,124,112,215,8,253,126,40,45,90,103,93,8,229,98,139,119,69, +41,247,90,246,59,109,8,177,46,84,106,93,53,178,183,211,54,110,211,174,102,79,41,224,217,219,122,184,59,235,215,221,207,188,24,90,158,223,149,226,99,27,218,233,78,56,13,61,226,41,28,79,65,151,126,232,194,2,36,239,27,186,98,14,31,216,208,198,215,183,118, +242,178,37,105,134,253,144,208,218,134,246,94,183,88,90,220,200,148,230,189,247,14,112,225,109,125,124,121,127,150,148,171,112,229,136,219,44,17,116,7,91,216,93,189,103,53,10,186,219,86,141,206,167,175,24,46,229,104,246,149,2,94,176,173,135,219,71,202, +180,56,186,174,126,230,197,208,242,204,142,36,31,223,212,206,178,164,75,33,148,61,243,233,141,36,102,176,31,186,32,44,200,57,156,40,13,95,8,12,103,119,165,249,236,230,78,190,186,181,147,101,9,135,124,131,247,186,45,22,79,65,91,204,225,87,3,69,254,105, +199,0,47,223,222,199,222,82,72,218,149,246,172,199,125,36,216,50,228,239,138,10,220,106,186,177,62,42,177,2,188,165,211,38,232,49,165,56,88,142,170,217,111,29,41,211,230,141,137,249,212,40,26,203,211,58,18,92,186,185,157,149,9,17,243,121,23,161,143,173, +221,4,97,161,82,8,12,9,173,248,251,165,77,252,223,25,75,120,241,178,38,194,170,224,55,50,19,105,137,250,174,27,107,185,170,39,207,19,254,124,144,143,238,25,193,55,145,15,183,108,175,31,15,61,247,176,197,93,88,191,135,154,114,51,54,196,186,45,144,218, +4,218,97,58,10,226,98,74,49,16,132,156,187,189,143,59,70,43,180,212,97,231,106,129,130,177,252,77,107,156,75,55,182,179,58,225,82,52,34,230,51,18,160,207,164,160,11,130,0,190,181,148,67,75,187,167,185,124,115,7,215,61,106,49,143,109,137,19,98,27,30,197, +184,74,17,211,138,98,104,248,192,174,33,206,188,249,16,215,15,150,128,40,189,42,204,164,160,187,80,58,8,97,137,218,211,237,45,168,228,138,218,35,251,73,8,64,210,81,12,4,134,11,110,239,99,251,72,153,148,83,223,158,121,62,52,60,174,37,206,167,54,117,114, +66,218,147,61,243,249,26,161,11,130,240,192,196,23,88,240,141,229,180,230,4,63,59,189,155,247,174,109,101,83,38,198,80,37,36,180,52,76,216,85,85,216,61,165,216,145,247,121,206,45,135,121,207,189,67,252,57,91,38,229,105,60,173,36,115,54,19,211,164,45, +69,86,175,166,18,221,149,73,135,232,42,178,122,141,175,2,235,55,116,12,166,93,77,143,111,120,217,237,125,252,97,176,68,76,215,247,126,197,208,112,70,83,140,79,111,234,96,115,83,140,188,180,77,19,65,23,132,133,22,177,27,11,239,88,215,206,55,78,238,226, +117,171,90,112,21,100,167,193,14,211,85,81,183,172,143,237,25,230,69,219,122,248,220,125,195,84,66,67,90,162,245,105,158,37,93,40,239,199,102,255,250,128,160,79,10,3,58,142,74,109,172,186,195,53,70,32,45,81,134,166,175,18,242,218,219,251,248,245,64,161, +238,99,142,101,99,217,146,137,241,249,45,93,156,220,28,39,31,24,73,179,139,160,11,194,194,195,0,121,63,228,164,116,140,207,109,234,224,170,83,22,241,152,150,248,180,68,56,138,168,104,238,112,41,228,173,247,12,241,188,91,122,248,237,80,177,97,198,55,194, +177,46,186,131,173,244,99,195,92,109,134,50,214,130,19,131,196,170,134,166,219,99,90,49,232,135,252,227,157,253,252,164,175,64,218,209,117,221,123,223,194,198,180,199,229,91,58,57,181,73,196,92,4,93,16,22,250,156,79,180,255,88,182,150,51,59,82,124,239, +148,197,124,118,83,7,33,81,171,201,176,193,69,115,73,71,17,83,138,27,134,74,188,120,123,47,231,108,239,37,23,26,60,29,157,107,23,26,56,69,154,0,155,191,27,252,161,218,4,93,105,84,250,36,84,114,109,195,4,221,85,144,11,12,255,120,87,63,215,84,197,188,158, +73,188,108,44,171,146,46,151,111,233,228,244,230,4,133,80,196,124,46,227,78,105,54,17,4,225,152,162,110,44,20,140,161,211,117,120,229,178,38,158,218,158,224,63,119,143,240,221,190,60,185,106,122,188,81,19,166,86,81,53,252,72,96,184,182,167,192,19,71, +43,252,235,218,86,206,93,148,34,227,56,148,140,65,106,154,26,16,157,251,253,216,226,221,83,152,0,45,120,237,160,18,117,239,159,91,32,174,21,185,208,242,198,187,250,185,166,175,72,76,215,151,149,41,24,195,202,184,203,229,155,59,121,116,83,156,66,32,93, +211,142,251,4,34,17,186,32,204,62,124,27,89,197,46,143,187,92,177,181,147,207,108,238,224,9,173,9,70,2,67,201,52,190,26,62,233,40,14,85,66,94,121,91,31,175,185,163,159,159,15,70,251,170,9,41,154,171,115,146,213,80,25,128,242,129,218,219,165,90,131,74, +111,0,234,59,123,62,150,145,41,134,134,127,185,103,128,31,246,21,112,85,125,243,127,33,180,116,199,29,190,120,82,23,79,104,75,80,144,2,184,5,26,161,203,244,32,8,147,38,4,242,129,229,194,238,52,103,119,36,249,200,253,163,252,160,39,207,221,121,191,106, +254,209,56,52,208,230,105,174,238,43,240,221,190,2,255,182,166,149,87,44,73,179,58,237,81,240,37,250,154,154,154,6,80,218,9,229,190,200,233,173,150,121,50,190,24,149,216,88,245,110,159,250,157,78,106,69,33,52,188,235,222,33,190,113,40,87,183,152,87,172, +165,45,174,249,242,137,93,60,181,61,65,222,15,37,205,62,79,66,116,233,182,38,8,51,64,62,180,36,28,197,135,55,180,241,162,197,41,62,122,255,8,223,62,152,35,227,56,184,186,113,174,202,22,72,42,69,194,194,191,239,28,226,154,158,60,23,173,104,226,181,203, +155,8,44,210,88,163,214,232,60,204,69,222,237,58,94,227,141,8,209,201,19,176,78,178,174,89,211,211,138,66,104,121,223,206,33,46,59,144,197,83,224,160,166,60,94,172,133,152,167,249,159,45,93,60,181,35,73,206,143,246,204,101,84,204,7,57,151,148,187,32, +204,24,190,133,130,111,56,181,57,206,231,54,117,242,163,211,22,179,58,233,146,15,109,195,247,186,149,130,102,87,243,215,108,133,119,220,51,196,89,55,247,176,45,91,33,161,149,20,205,213,50,197,154,10,84,250,65,57,53,42,167,129,244,198,218,154,184,60,8, +71,69,11,176,15,237,25,230,243,251,179,184,42,218,94,153,234,80,9,45,88,7,190,181,165,139,167,117,36,201,73,53,251,188,67,4,93,16,102,16,11,228,3,67,90,43,158,221,153,226,186,51,186,121,231,234,102,154,92,77,193,216,134,155,210,180,184,154,208,194,111, +135,74,60,231,175,61,92,178,103,132,1,63,178,176,117,149,76,231,143,116,183,108,105,39,182,184,167,198,227,106,1,36,86,67,234,164,41,79,177,142,130,192,192,37,187,135,249,204,222,81,156,170,185,208,84,199,65,217,88,140,99,249,246,214,46,158,209,153,160, +32,98,46,130,46,8,66,163,162,117,75,201,88,154,92,197,123,215,181,241,163,211,22,241,152,182,56,49,5,35,13,172,54,182,85,113,72,84,83,183,239,223,53,204,147,254,114,152,159,13,20,40,25,75,218,213,50,177,63,76,148,109,115,219,167,240,15,13,196,90,193, +137,79,233,126,141,185,255,125,226,190,17,62,185,111,20,165,166,158,85,81,68,222,236,174,163,248,198,214,69,60,171,51,69,62,176,146,98,23,65,23,4,161,209,152,234,190,246,169,77,49,110,124,84,55,31,223,212,206,73,153,24,35,126,136,105,112,187,98,173,32, +229,40,14,151,2,158,123,75,47,175,191,171,159,91,71,43,85,11,89,185,23,71,223,28,31,10,187,107,159,38,195,18,42,121,2,56,153,106,65,220,228,197,60,166,21,88,203,165,123,70,184,228,254,17,172,173,111,146,46,25,139,227,40,190,186,181,147,179,187,210,228, +228,104,154,8,250,248,104,147,101,157,32,76,11,101,99,41,24,203,203,87,52,241,157,83,186,120,223,250,86,114,214,82,48,166,225,125,215,93,5,205,142,226,155,7,179,188,120,123,15,111,187,103,128,98,104,73,59,114,196,237,129,208,86,99,75,187,177,229,125, +88,165,107,184,194,33,214,107,129,228,134,200,238,181,134,43,234,169,232,92,249,167,238,31,229,131,247,13,19,98,171,145,249,212,238,117,104,45,70,195,55,79,234,226,5,139,210,228,164,154,125,118,211,128,135,79,215,246,105,242,184,11,194,116,62,207,185, +138,97,99,218,227,125,107,219,184,246,81,221,156,187,40,205,112,96,152,142,184,170,213,115,216,93,12,248,216,238,17,158,119,75,15,95,63,152,35,227,104,41,154,3,192,193,22,238,160,230,138,6,19,160,226,203,81,177,174,154,162,115,71,69,203,173,207,238,29, +229,253,187,135,8,45,196,235,172,113,240,81,124,247,228,46,206,94,148,26,175,102,23,230,183,162,75,162,77,16,102,83,96,8,20,195,104,127,253,233,237,9,46,223,210,201,229,39,118,209,233,105,74,198,226,55,48,13,111,137,246,214,155,93,205,31,134,203,92,124, +87,63,175,188,173,143,253,165,144,152,158,122,17,214,252,32,132,202,208,20,46,106,0,201,181,16,235,156,180,221,171,174,222,140,43,247,103,249,183,93,67,24,27,157,61,159,234,157,14,172,165,100,225,219,91,187,120,126,87,90,188,217,23,16,186,150,135,95, +226,115,65,152,25,12,209,217,117,71,193,133,203,50,252,233,177,75,57,123,113,154,22,87,147,11,76,67,159,69,5,213,230,46,138,239,245,230,57,233,143,7,248,226,254,81,6,253,200,170,86,47,52,53,80,46,182,180,23,155,187,13,140,153,124,150,219,132,224,182, +161,210,39,69,118,175,147,200,171,56,42,122,125,245,96,150,119,237,28,2,27,237,163,219,41,222,199,146,177,128,226,27,91,163,200,92,236,92,23,82,124,46,17,186,32,204,238,56,177,218,119,61,237,104,190,125,114,23,223,60,105,17,103,118,36,201,135,134,98, +131,45,100,199,196,37,1,252,243,142,65,94,188,189,151,107,251,10,196,149,34,237,232,133,179,160,87,30,20,118,66,88,168,241,28,185,137,10,225,188,182,73,138,185,34,174,21,95,59,152,229,237,247,70,145,185,174,163,154,189,104,44,14,240,165,45,157,188,112, +113,154,124,104,36,8,147,8,93,16,132,217,184,122,207,7,150,39,119,36,249,222,41,139,184,100,67,27,43,147,14,195,149,112,90,38,237,180,163,248,237,112,145,23,109,239,229,13,59,6,248,107,182,76,198,115,22,192,132,161,34,49,46,238,1,83,174,109,138,52,62, +42,182,168,218,93,205,127,68,49,79,104,197,87,247,231,120,203,221,67,84,140,173,43,19,226,219,232,40,218,21,39,117,113,254,210,12,121,137,204,23,36,210,109,77,16,230,16,185,192,16,215,154,183,172,110,227,204,246,20,95,62,144,229,138,3,89,64,225,54,56, +53,222,228,104,2,11,159,191,127,132,235,6,139,188,97,121,51,23,173,104,194,3,230,173,53,188,118,161,124,32,178,123,181,193,228,29,226,172,5,29,71,165,54,130,74,65,152,127,232,37,131,2,15,248,250,129,44,111,190,103,128,178,177,164,234,60,97,16,88,248, +250,150,46,94,212,157,33,87,145,61,243,57,187,150,148,8,93,16,22,214,51,239,27,75,222,55,156,146,137,243,225,117,237,252,239,105,221,172,72,185,132,54,42,136,106,212,154,123,204,148,166,53,230,176,167,16,240,222,93,67,60,229,47,135,185,101,164,140,163, +34,167,185,249,39,28,30,148,246,66,48,90,155,59,28,6,220,12,164,214,63,108,49,156,38,234,105,254,221,195,57,222,112,119,253,98,30,90,40,133,150,175,158,20,137,185,20,192,45,108,68,208,5,97,142,146,15,13,74,195,223,180,38,248,221,233,75,248,224,186,86, +82,142,166,98,44,65,3,51,105,150,168,104,206,88,216,54,90,230,239,110,233,225,149,119,245,51,236,135,36,230,85,53,124,212,198,204,228,239,194,250,181,250,183,27,148,215,142,74,173,143,12,105,30,98,49,230,105,184,186,39,207,197,59,6,8,173,157,114,123, +91,5,84,76,116,214,252,202,147,58,57,127,113,154,98,40,105,246,133,142,180,79,21,132,57,140,177,81,59,204,132,134,55,175,106,230,153,157,73,254,243,190,17,190,217,147,39,31,88,90,220,198,173,217,181,138,206,70,91,224,123,135,114,220,54,82,230,173,171, +155,121,225,162,52,205,158,158,251,251,182,202,1,255,48,148,247,215,62,53,42,23,210,91,64,103,170,123,239,71,11,112,202,81,124,175,39,207,235,238,26,192,88,166,236,165,63,86,0,167,177,124,241,196,46,94,178,36,67,33,144,2,184,121,177,160,148,8,93,16,4, +11,228,66,203,234,164,203,151,79,234,226,191,55,182,113,86,71,130,145,74,216,240,253,110,69,84,52,119,95,41,224,85,219,251,120,253,93,3,92,211,151,39,237,233,186,186,129,29,255,249,212,197,86,134,176,149,222,26,163,115,91,61,212,191,2,108,120,204,240, +39,229,106,174,238,41,240,154,59,7,40,213,89,0,87,54,22,107,225,51,155,58,121,89,181,0,78,98,115,97,74,17,186,172,2,5,97,246,82,177,80,9,12,111,92,209,194,249,93,25,46,219,159,229,11,251,70,57,88,9,105,110,240,209,51,7,104,137,57,124,227,80,142,107,250, +11,92,188,188,204,155,86,54,179,36,225,206,81,207,112,131,45,237,131,74,95,84,28,55,233,73,209,162,18,235,80,233,147,177,15,218,63,87,42,90,252,252,168,39,207,171,239,232,39,63,102,177,91,71,63,243,192,194,23,55,119,240,202,229,77,71,92,103,153,155,23, +122,124,46,17,186,32,204,75,114,190,161,205,211,188,123,109,11,63,59,189,155,103,46,74,51,82,237,187,222,200,137,223,18,245,93,47,135,150,143,221,55,202,153,127,57,204,151,15,100,163,246,172,154,185,83,160,165,28,8,178,216,220,45,81,15,244,26,191,185, +77,46,1,167,233,168,9,58,161,21,215,244,22,121,229,237,253,228,234,244,203,183,64,217,90,62,191,185,131,151,47,147,163,105,130,8,186,32,44,24,202,198,82,12,45,155,51,30,255,115,82,39,255,123,74,23,203,19,14,129,177,84,26,108,74,19,211,138,132,163,184, +183,16,240,207,119,15,242,172,191,246,112,79,222,199,81,16,159,19,86,115,10,194,28,148,246,131,246,106,142,236,85,98,229,81,255,55,174,21,191,232,47,242,178,219,251,40,212,81,205,174,136,206,153,151,141,229,51,155,218,185,112,105,134,82,40,45,80,133, +122,4,221,90,176,50,132,4,97,46,97,136,188,225,227,10,158,214,153,228,198,71,47,225,226,229,25,58,227,154,145,32,36,180,182,97,221,220,20,150,148,3,161,181,220,56,92,226,41,55,29,230,211,247,143,114,127,57,32,227,106,92,53,187,211,194,182,180,15,91,190, +31,171,188,218,250,215,169,24,42,181,229,136,160,62,227,42,174,27,40,242,146,237,189,248,198,18,215,209,223,157,202,53,45,25,131,53,150,79,110,108,231,149,203,154,240,173,149,61,243,249,136,149,230,44,130,32,76,70,216,171,123,175,9,71,241,177,205,157, +124,109,107,23,207,232,74,97,176,100,195,6,247,93,7,60,21,157,137,127,251,61,3,156,179,173,135,31,28,142,140,86,154,156,217,56,229,40,176,21,40,220,73,205,101,69,38,64,165,78,0,175,125,130,152,107,126,217,95,228,197,183,245,82,54,182,174,238,117,101, +19,45,3,62,178,161,157,127,88,209,68,197,70,219,38,130,32,130,46,8,11,61,8,0,178,129,225,41,109,73,126,116,202,34,62,183,169,131,141,41,151,209,105,106,175,217,226,57,236,200,250,92,176,189,151,87,223,209,207,246,108,153,140,167,103,223,222,186,13,177, +165,67,128,83,91,16,109,42,81,119,53,157,0,107,201,120,154,95,245,23,120,241,246,94,178,161,37,86,199,118,67,88,21,239,75,78,104,231,141,43,155,41,25,68,204,5,17,116,65,16,142,136,71,201,6,134,16,120,197,138,102,174,58,101,17,239,63,161,141,145,144,134, +26,210,140,45,32,210,78,212,132,228,155,7,115,156,191,189,151,139,239,236,175,154,172,204,18,89,87,10,91,57,132,45,237,1,85,195,148,104,67,240,186,80,77,143,66,41,47,74,179,247,23,121,241,246,94,134,3,75,90,215,111,231,250,145,13,237,188,126,101,51,101, +107,49,178,229,41,52,74,208,165,125,170,32,204,47,81,15,109,84,13,191,41,19,227,95,87,183,114,227,163,187,57,179,45,65,193,24,42,13,238,187,174,21,52,123,154,93,197,128,203,247,143,114,230,205,135,248,69,127,129,132,86,196,244,241,183,144,181,217,91, +32,200,82,83,117,187,13,33,214,129,114,91,73,58,138,27,6,74,156,187,173,135,209,192,146,169,215,206,213,88,62,184,190,141,139,87,68,123,230,161,76,190,243,30,105,159,42,8,66,221,20,195,200,66,244,209,205,113,190,119,234,34,62,188,190,157,85,113,151,108, +96,26,94,13,159,212,138,148,214,220,154,173,240,194,109,189,188,121,199,0,59,242,21,226,142,170,43,61,93,255,69,184,191,246,233,208,250,232,228,42,50,137,86,126,55,148,231,236,91,15,71,174,125,78,125,118,174,190,181,252,251,186,54,94,191,178,57,202,234, +139,152,11,34,232,130,32,76,22,67,100,33,91,177,240,207,171,90,184,238,140,37,156,191,36,77,167,231,48,210,224,134,31,10,240,148,34,233,40,174,60,152,229,113,55,29,226,75,251,179,12,248,193,113,216,95,215,216,74,47,54,127,55,181,86,160,107,235,147,76, +44,225,255,70,92,206,190,229,48,21,99,167,108,231,10,81,1,92,104,225,61,107,90,121,243,170,22,20,74,34,115,65,4,93,16,132,169,83,10,45,29,158,230,91,91,23,113,229,150,78,158,210,145,28,183,144,109,180,216,198,148,194,49,240,186,59,250,121,197,246,62, +126,124,56,79,218,213,36,181,194,78,251,158,177,5,229,65,238,182,168,202,189,6,49,86,88,210,94,140,239,245,135,60,247,150,62,114,97,125,98,30,86,211,234,239,90,219,202,219,87,183,160,176,132,70,14,167,9,181,49,133,126,232,178,100,20,132,249,78,96,33, +31,88,206,234,74,177,165,57,198,213,135,243,124,100,247,8,251,203,1,205,110,99,227,0,77,228,54,247,139,254,18,127,29,245,57,171,39,207,123,215,180,178,57,227,77,191,133,172,178,88,127,232,40,15,246,135,253,39,10,146,132,124,127,180,157,139,71,91,40,187, +62,105,85,223,212,232,27,120,199,234,22,222,190,170,37,186,254,99,121,118,153,111,23,14,13,232,90,40,94,238,130,32,60,228,179,62,234,135,116,185,154,215,175,104,230,201,237,73,62,191,119,148,175,28,202,97,172,197,105,112,63,244,102,79,147,11,13,223,58, +152,227,47,35,101,254,105,69,19,23,46,107,194,81,209,62,114,195,165,93,57,224,247,99,115,183,71,61,204,39,209,255,92,1,49,5,63,233,207,113,81,207,42,10,109,43,73,169,96,202,223,205,18,237,155,191,109,85,51,111,91,211,140,82,52,180,32,81,152,67,122,222, +160,197,177,32,8,194,67,78,50,37,99,201,135,134,19,82,46,31,221,208,206,247,79,89,68,119,50,58,175,93,52,141,173,134,247,180,162,201,213,236,45,6,188,253,222,33,158,250,151,195,220,150,171,96,137,10,234,26,251,227,98,216,194,46,168,28,154,212,116,170, +128,184,134,95,14,150,121,213,238,60,101,189,136,132,215,196,84,125,219,2,107,41,25,203,155,86,52,243,182,53,45,196,180,34,16,49,23,68,208,5,65,152,238,104,61,114,45,179,60,185,61,193,246,199,46,227,95,215,180,176,36,230,144,13,76,195,43,177,99,90,161, +148,226,182,156,207,223,252,249,48,239,220,53,200,129,82,64,83,213,66,182,97,171,149,202,97,48,165,71,156,10,163,126,230,240,203,161,10,175,216,53,68,89,183,226,37,79,0,235,79,233,163,125,27,93,207,127,92,214,204,187,214,182,144,212,26,233,181,34,136, +160,11,130,48,163,194,94,169,218,145,190,123,125,27,223,59,165,139,87,45,111,34,111,44,249,208,78,67,53,124,212,177,236,51,123,178,156,119,107,31,159,222,59,138,1,154,220,122,91,193,58,16,12,99,115,183,66,88,124,196,253,203,102,71,241,203,161,10,175, +218,149,165,16,6,56,110,7,36,54,69,197,116,53,18,90,240,141,229,117,203,154,121,223,250,22,82,174,198,151,200,92,104,0,110,77,79,178,32,8,66,149,81,63,228,244,230,56,151,181,196,121,76,91,156,239,29,200,241,171,254,2,153,152,211,240,106,248,102,79,179, +45,87,230,166,59,75,220,56,84,226,229,75,51,60,107,81,154,188,31,78,45,225,173,61,108,254,0,182,210,251,176,221,213,20,208,228,40,126,54,84,230,21,187,70,25,12,66,210,218,193,122,93,160,51,96,242,53,47,136,124,107,121,245,178,38,62,112,66,43,25,87,83, +108,240,89,127,97,14,175,150,37,66,23,4,225,120,160,128,130,177,148,66,203,107,151,54,241,245,147,187,248,247,13,237,184,74,141,55,21,105,220,92,103,73,104,69,198,211,124,247,112,142,151,223,222,199,59,118,244,83,52,145,145,139,170,249,155,107,40,222, +7,229,67,15,89,12,167,128,132,82,252,122,184,204,107,118,101,233,247,77,100,231,170,18,144,60,105,74,233,118,223,192,75,187,211,124,224,132,54,17,115,161,225,212,98,92,44,97,186,32,8,71,97,136,188,225,219,61,135,127,89,221,194,31,30,179,132,199,180,39, +38,236,187,55,118,17,209,228,106,70,3,195,103,246,101,217,250,135,3,124,191,39,143,177,81,255,241,73,137,163,210,16,142,98,75,187,170,223,254,216,255,42,174,225,247,217,10,175,222,153,165,183,98,72,171,234,217,120,149,128,68,109,130,110,136,138,11,207, +93,156,226,63,79,104,167,217,209,148,69,204,133,6,135,232,18,161,11,130,208,16,198,156,206,86,37,93,126,118,234,98,190,186,165,147,13,41,143,82,104,27,46,94,113,173,208,10,70,252,144,87,223,222,207,139,111,235,229,142,108,133,184,142,28,232,236,35,77, +123,193,8,182,188,47,50,150,57,6,41,165,248,243,168,207,107,238,29,165,207,55,36,38,206,148,94,23,56,205,147,158,128,141,141,236,117,207,238,74,115,201,134,118,218,60,71,246,204,133,227,27,161,75,124,46,8,194,100,230,137,192,70,34,118,246,226,52,191, +56,189,155,139,87,52,209,230,106,70,43,97,195,163,117,87,41,28,5,63,239,47,242,119,55,31,226,99,247,141,112,95,41,160,217,211,15,59,185,89,127,16,202,3,28,171,93,106,179,19,137,249,69,59,179,28,244,205,209,85,245,233,211,39,47,230,68,71,251,158,213,153, +226,99,27,219,89,20,119,228,156,185,48,77,241,185,68,232,130,32,76,19,249,208,210,22,211,124,234,196,78,190,178,181,139,243,150,100,40,132,22,127,26,142,103,165,29,69,193,192,59,119,12,240,146,237,189,124,251,64,142,100,181,109,235,81,83,158,173,96,179, +55,131,63,16,153,203,76,80,243,102,71,241,199,145,10,175,217,53,194,238,114,136,167,142,49,101,38,78,1,251,200,63,194,2,165,208,112,102,123,146,207,110,238,96,121,194,165,32,230,236,194,108,136,208,5,65,16,106,141,160,125,3,89,223,240,140,206,20,151, +157,216,201,215,79,234,162,35,174,40,53,88,216,44,224,40,104,142,59,220,52,92,230,117,59,250,57,239,214,94,118,21,124,210,142,62,242,75,153,82,84,16,167,189,241,184,72,1,41,173,184,105,180,194,107,118,142,112,111,41,36,249,224,217,209,26,136,117,131, +211,52,169,239,228,27,120,98,91,146,47,108,233,96,69,194,37,27,26,217,51,23,166,21,241,114,23,4,97,218,201,250,33,113,173,184,160,59,197,25,45,30,95,62,144,231,99,247,141,224,42,208,74,53,44,178,176,64,147,163,169,132,150,171,123,242,252,105,164,204, +57,221,105,62,186,174,13,71,65,0,24,191,31,91,184,231,136,234,246,184,82,108,203,5,188,122,231,40,247,148,12,105,231,88,210,27,64,242,212,104,218,124,132,121,208,183,240,232,22,143,47,109,233,96,101,204,33,27,132,34,230,194,35,172,128,235,31,33,18,161, +11,130,48,35,4,214,82,8,45,171,18,30,239,95,215,202,245,103,116,243,196,214,56,101,99,27,158,138,118,149,34,227,104,250,203,33,159,191,111,148,179,254,114,136,95,15,20,81,22,82,165,29,104,235,51,86,221,158,212,138,219,243,62,23,237,26,102,103,217,144, +114,30,98,98,181,33,36,54,62,172,231,187,5,242,161,225,212,230,24,87,110,233,98,69,220,149,163,105,194,140,33,130,46,8,194,140,49,230,52,87,49,150,211,154,99,92,243,168,110,222,186,182,153,19,51,30,89,63,36,176,141,109,209,26,211,138,148,163,216,150, +245,121,214,95,123,121,239,189,61,252,110,255,77,104,229,144,212,138,140,86,220,93,8,120,237,174,81,238,41,89,98,15,57,35,134,224,45,2,167,141,135,250,134,22,200,133,134,83,155,227,92,185,165,131,181,73,151,146,145,140,166,48,115,72,183,53,65,16,142, +11,190,141,92,211,62,178,174,157,139,150,248,124,104,207,8,87,247,228,25,246,77,3,172,93,31,20,185,40,104,242,92,62,126,247,31,184,114,240,247,252,195,226,20,175,93,146,166,100,45,23,237,26,101,123,49,58,154,246,144,159,105,202,208,116,74,85,208,143, +221,106,53,23,90,54,55,197,248,218,214,78,54,165,99,140,6,178,103,46,76,158,70,140,21,87,46,163,32,8,199,147,209,192,176,50,233,114,197,137,29,188,120,113,154,119,239,30,226,166,129,18,233,152,110,168,32,90,229,146,41,221,76,193,24,46,57,92,228,119,125, +101,74,249,128,237,113,77,220,173,246,104,125,72,12,196,215,130,147,174,54,115,57,242,239,86,172,101,117,198,227,59,91,23,177,37,237,49,34,98,46,204,133,8,93,16,4,161,209,20,67,139,6,206,234,76,114,66,218,227,87,253,5,222,189,107,136,17,223,226,168,40, +194,174,59,254,177,37,240,15,16,211,22,207,183,252,126,79,22,93,182,36,51,46,116,197,56,210,61,102,226,74,32,0,119,17,184,93,213,98,184,35,197,60,176,208,25,119,248,225,214,69,156,36,98,46,28,71,38,191,135,46,206,50,130,32,76,35,166,26,173,119,199,29, +254,126,105,134,27,31,179,148,243,186,211,120,26,10,225,84,187,142,143,233,185,7,197,123,193,230,32,0,117,176,72,218,175,246,88,47,132,176,191,4,189,229,168,21,154,226,200,252,167,245,33,190,14,188,101,192,145,118,175,165,208,210,150,112,184,230,212, +110,182,100,60,70,229,104,154,48,85,164,57,139,32,8,243,141,138,177,248,22,150,197,29,174,220,210,201,101,39,117,113,98,83,140,208,88,138,83,45,50,83,49,168,220,9,165,97,56,88,129,210,4,225,86,68,233,246,161,0,238,47,66,54,56,114,114,181,22,98,75,193, +105,141,42,221,171,255,36,31,24,58,18,46,63,62,101,49,39,103,60,10,161,84,179,11,115,37,66,151,16,93,16,132,25,12,86,2,27,117,115,59,183,43,205,141,103,116,243,174,53,173,116,199,52,57,191,214,40,88,131,170,64,254,32,236,207,66,209,128,122,144,223,43, +54,250,127,190,129,131,101,24,242,171,255,59,140,132,60,182,156,137,38,52,185,208,208,157,112,185,250,212,69,156,209,20,35,39,14,112,194,44,8,209,197,203,93,16,132,89,139,2,178,161,193,213,138,127,219,208,198,55,182,118,241,154,21,205,100,43,134,202, +100,207,119,107,15,10,187,224,224,125,80,228,225,203,137,85,117,182,27,172,64,62,136,246,207,189,197,16,223,24,85,186,19,165,255,59,227,46,87,159,182,152,199,183,196,101,207,92,152,37,114,46,41,119,65,16,230,128,168,135,22,70,43,134,191,109,79,241,137, +141,237,124,235,180,69,156,222,20,35,27,152,71,158,8,149,7,3,247,192,240,126,208,147,172,3,14,44,140,248,81,42,62,86,45,136,35,58,39,223,18,119,184,230,212,197,60,182,57,206,136,47,98,46,204,30,68,208,5,65,152,51,100,3,131,86,138,243,22,167,249,209,163, +186,121,199,154,22,146,90,81,170,182,110,61,90,204,53,132,37,24,217,15,229,114,52,229,29,35,219,126,212,11,160,24,128,159,128,196,122,32,196,183,150,164,171,185,246,212,197,156,222,28,147,200,92,16,65,23,4,65,168,135,192,90,242,161,37,237,104,222,187, +174,141,235,207,232,230,177,45,113,146,90,145,127,176,170,43,13,149,126,40,28,0,199,171,237,131,140,1,147,70,37,78,166,24,148,200,56,154,159,156,186,136,71,53,199,200,75,1,156,32,130,46,8,130,208,56,97,15,45,172,78,122,252,250,140,110,62,177,177,157, +147,154,60,114,190,193,55,99,91,229,10,140,15,161,95,251,116,103,45,138,22,114,186,147,78,23,174,62,117,49,143,107,73,72,11,84,97,214,34,221,214,4,65,152,211,132,128,9,225,194,101,77,60,190,53,206,229,251,179,92,182,47,203,72,197,144,137,91,208,41,240, +50,213,35,103,147,143,210,149,118,201,39,55,211,233,40,174,58,117,17,79,108,141,51,26,132,114,193,133,233,161,1,221,214,196,203,93,16,132,57,143,5,134,253,144,213,9,151,75,54,180,115,86,71,146,203,246,101,249,94,111,137,180,151,130,116,87,148,126,183, +118,146,19,167,165,162,28,90,218,31,205,247,78,237,224,137,109,49,134,165,0,78,152,78,61,111,192,123,72,202,93,16,132,121,51,33,22,140,101,52,48,156,217,145,228,115,39,118,240,229,147,218,81,94,130,176,121,3,97,172,25,38,233,55,23,26,75,170,105,45,87, +63,241,52,254,95,171,136,185,48,55,16,65,23,4,97,222,69,235,217,192,144,114,52,23,116,167,184,243,177,139,121,245,201,79,66,117,61,134,98,16,96,109,248,176,139,130,74,80,66,199,218,248,198,249,111,225,113,29,25,114,82,205,46,136,160,11,130,32,28,63,2, +107,41,27,104,117,44,159,57,121,57,95,120,254,43,121,212,198,39,81,240,3,42,65,37,50,139,195,70,105,120,107,177,38,36,87,202,147,200,180,243,177,243,222,198,19,87,109,161,18,202,158,185,48,31,5,189,58,232,5,65,16,230,18,6,24,174,84,120,233,170,117,92, +125,225,127,112,241,89,23,209,185,104,37,57,127,136,124,49,75,190,82,36,95,201,82,112,60,30,127,242,83,185,252,239,63,204,171,79,121,10,152,16,35,115,158,48,83,52,96,172,73,251,84,65,16,230,61,10,200,5,62,29,94,156,207,60,251,98,206,222,250,255,216,118, +96,7,229,98,129,92,104,104,73,38,233,108,90,196,211,214,61,138,53,153,54,178,229,130,20,0,11,115,14,17,116,65,16,22,12,21,19,224,87,66,206,92,177,149,179,86,157,134,111,124,42,97,72,194,141,225,42,40,250,101,70,203,5,185,80,130,8,186,32,8,194,108,199, +90,75,174,82,140,10,221,148,138,170,227,203,190,68,228,194,194,17,116,25,236,130,32,204,43,97,143,212,93,230,54,97,246,140,199,58,145,42,119,65,16,4,65,88,72,17,186,132,234,130,32,8,130,48,77,52,192,236,96,10,123,232,162,232,130,32,8,130,48,219,20,93, +82,238,130,32,8,130,48,15,144,230,44,130,32,8,130,48,231,227,115,137,208,5,65,16,4,97,94,32,130,46,8,130,32,8,34,232,130,32,8,130,32,204,6,38,191,135,46,77,10,4,65,16,4,97,122,104,128,198,74,132,46,8,130,32,8,243,0,17,116,65,16,4,65,16,65,23,4,65,16, +4,97,54,80,123,115,22,217,75,23,4,65,16,132,134,98,213,204,58,197,41,26,115,246,93,16,4,65,16,132,163,53,118,102,34,116,224,32,16,200,53,23,4,65,16,132,134,115,112,198,4,221,90,123,8,8,229,154,11,130,32,8,66,131,177,118,230,4,29,56,44,87,92,16,4,65,16, +166,133,222,153,20,244,59,128,33,185,230,130,32,8,130,208,112,238,172,247,13,106,61,182,230,3,131,114,221,5,65,16,4,161,97,244,208,128,45,237,73,11,186,66,5,10,85,84,168,126,185,246,130,32,8,130,208,24,20,170,71,161,202,51,25,161,151,129,44,176,83,46, +191,32,8,130,32,52,140,187,129,226,204,69,232,10,95,41,178,40,238,144,107,47,8,130,32,8,13,11,209,111,87,170,126,65,159,116,81,156,138,92,108,12,214,222,41,94,113,130,32,8,130,208,32,61,87,234,54,53,193,144,117,218,5,221,24,51,246,199,125,88,27,80,91, +133,188,32,8,130,32,8,71,83,182,198,28,104,68,160,60,233,148,187,125,224,181,31,216,37,247,64,16,4,65,16,234,14,207,239,180,208,51,163,130,142,181,99,175,251,128,237,114,23,4,65,16,4,161,78,172,253,43,214,30,104,68,227,179,169,180,79,45,139,160,11,130, +32,8,66,67,184,133,6,245,73,169,97,31,252,136,70,48,183,89,108,1,72,201,189,16,4,65,16,132,41,49,162,80,119,53,234,205,38,29,161,107,173,39,190,110,80,74,221,41,247,66,16,4,65,16,166,134,82,106,155,214,250,166,49,109,157,49,65,31,239,134,30,189,134,129, +29,114,59,4,65,16,4,97,202,220,78,228,239,210,128,110,232,53,8,186,9,205,17,47,44,191,1,42,114,63,4,65,16,4,161,102,138,88,126,119,132,174,206,88,132,126,52,63,4,14,200,61,17,4,65,16,132,154,217,13,252,180,145,111,56,213,148,59,40,250,148,82,215,203, +61,17,4,65,16,132,154,176,74,169,255,67,49,114,132,174,206,148,160,91,107,143,245,250,98,35,206,206,9,130,32,8,194,194,145,115,235,91,107,47,127,176,166,214,203,84,172,95,39,242,39,173,245,159,176,246,177,114,135,4,65,16,4,97,18,40,117,163,49,166,225, +126,46,147,63,182,166,212,49,95,88,123,133,220,29,65,16,4,65,152,116,132,126,249,49,245,116,166,4,253,97,184,6,165,164,56,78,16,4,65,16,30,57,58,223,5,92,59,29,111,93,67,81,156,122,168,87,31,112,153,220,37,65,16,4,65,120,68,62,135,82,163,199,212,211, +58,105,68,11,212,16,248,134,133,215,1,75,228,94,9,130,32,8,194,49,185,95,193,183,104,64,239,243,250,34,244,135,103,143,82,234,139,114,175,4,65,16,4,225,216,40,165,62,1,28,158,174,247,111,148,160,27,224,59,72,159,116,65,16,4,65,56,22,119,16,25,178,77, +219,89,111,221,192,247,218,1,252,64,238,153,32,8,130,32,28,197,55,129,251,167,243,3,26,41,232,40,165,62,11,236,148,251,38,8,130,32,8,227,108,87,74,93,57,221,31,50,105,65,87,74,77,230,117,191,82,234,227,114,239,4,65,16,4,97,92,63,255,91,41,117,248,145, +52,180,238,207,153,172,221,220,200,200,200,164,223,52,12,130,235,44,60,85,110,163,32,8,130,176,160,197,28,254,215,113,221,231,77,230,239,182,180,180,212,245,89,147,62,182,230,251,126,45,239,251,78,5,55,0,9,185,157,130,32,8,194,2,37,107,224,93,166,54, +253,156,50,245,54,103,121,168,215,159,129,15,203,189,20,4,65,16,22,48,239,179,214,222,62,89,237,156,49,65,159,2,95,64,169,255,147,251,41,8,130,32,44,56,148,250,41,240,165,153,252,200,105,19,116,99,109,159,181,246,221,40,53,44,119,86,16,4,65,88,64,98, +126,216,90,251,110,99,237,232,76,126,172,59,205,239,255,7,224,63,44,252,23,224,200,93,22,4,65,16,230,57,21,5,239,1,182,205,244,7,235,233,254,0,165,212,231,149,82,255,35,247,88,16,4,65,152,255,193,185,186,66,41,245,245,227,241,217,147,143,208,167,176, +97,111,173,197,88,91,178,240,86,173,245,73,214,218,211,229,118,11,130,32,8,243,82,204,225,183,198,152,127,85,80,105,68,145,219,172,139,208,173,181,96,237,128,82,234,229,10,14,202,45,23,4,65,16,230,161,152,239,86,90,191,18,107,179,199,67,204,103,68,208, +39,112,7,112,190,130,172,220,122,65,16,4,97,30,137,249,0,240,34,142,115,131,50,61,195,159,119,35,240,70,96,84,134,128,32,8,130,48,15,232,7,46,6,110,62,222,95,196,61,14,159,249,85,21,101,226,63,9,180,202,88,16,4,65,16,230,40,195,74,171,55,97,237,85,179, +225,203,184,199,233,115,191,134,98,3,214,190,91,198,131,32,8,130,48,7,177,104,253,95,192,183,102,203,23,210,199,241,179,255,3,165,62,1,4,50,46,4,65,16,132,57,68,5,165,62,132,181,151,204,166,47,229,30,215,11,2,111,65,169,91,173,181,159,5,210,50,70,4,65, +16,132,89,206,168,82,234,34,224,187,179,237,139,233,89,240,29,190,170,148,250,71,96,68,198,137,32,8,130,48,139,25,80,74,189,102,54,138,249,108,17,244,49,81,127,41,176,87,198,139,32,8,130,48,11,185,87,41,117,62,112,213,108,253,130,122,22,125,151,159,104, +173,95,160,181,222,38,227,70,16,4,65,152,45,40,165,254,168,181,62,7,184,110,54,127,79,61,203,46,218,205,198,152,179,129,239,203,16,18,4,65,16,102,1,255,99,173,125,1,145,57,218,172,70,207,182,47,100,173,189,95,41,245,18,173,212,135,16,87,57,65,16,4,225, +248,48,162,149,122,55,240,10,224,208,92,248,194,238,44,253,94,21,224,61,10,126,103,45,31,5,182,202,216,18,4,65,16,102,2,165,184,25,120,27,112,253,92,250,222,122,54,127,57,107,237,181,22,251,28,133,253,2,96,192,202,72,19,4,65,16,166,67,113,0,202,74,113, +169,177,246,57,214,218,235,231,218,47,112,231,192,119,220,139,82,23,91,99,126,173,181,122,139,181,246,113,50,240,4,65,16,132,198,70,229,234,6,99,204,199,149,210,63,158,171,191,193,157,43,95,212,194,85,160,127,171,53,47,11,141,121,63,144,146,33,40,8,130, +32,212,201,136,163,245,123,173,181,223,177,208,59,151,127,136,158,99,223,247,48,168,255,82,74,157,161,148,250,1,144,151,177,40,8,130,32,76,129,156,82,234,155,74,169,211,65,125,154,57,46,230,115,81,208,199,184,11,120,161,82,234,153,192,143,129,33,25,155, +130,32,8,194,36,232,7,190,175,148,58,19,120,41,199,185,135,121,35,113,231,248,247,255,45,240,91,165,212,51,172,181,47,7,158,129,180,100,21,4,65,16,142,45,228,215,42,165,190,98,173,253,245,124,252,129,238,60,249,29,63,3,126,166,148,58,211,90,251,108,165, +212,179,173,181,27,100,252,10,130,32,44,108,148,82,119,90,107,175,81,74,253,212,90,123,195,124,254,173,238,60,251,61,215,85,95,159,199,218,199,41,173,255,222,90,123,22,160,100,88,11,130,32,44,20,21,39,84,168,107,173,49,223,68,169,63,51,143,210,234,11, +73,208,199,184,23,184,87,161,126,4,172,2,206,183,216,115,171,127,142,139,192,11,130,32,204,43,44,80,6,118,43,212,119,129,171,20,106,175,133,220,66,186,8,238,60,255,125,163,192,109,213,215,251,28,199,89,107,140,57,199,90,251,44,96,37,208,1,52,203,179, +32,8,130,48,231,24,1,6,128,61,90,169,159,40,173,127,20,134,225,253,64,184,80,47,136,187,128,126,107,88,141,220,47,1,46,193,218,102,165,212,147,173,181,143,81,74,157,0,44,179,214,118,3,221,64,90,158,21,65,16,132,89,67,14,56,172,148,58,4,28,176,214,222, +171,148,250,163,181,246,6,148,146,227,203,11,80,208,143,21,189,255,24,248,177,82,10,180,78,16,134,235,129,245,214,218,54,96,53,208,84,141,228,147,85,161,119,100,200,8,130,32,76,107,224,117,8,40,2,247,17,121,141,236,81,74,13,1,59,149,227,236,180,198,84, +176,98,3,46,130,254,240,148,136,206,183,239,169,10,119,28,104,7,78,68,169,102,96,93,245,122,201,72,18,4,65,104,60,10,240,129,157,88,155,37,218,42,29,37,218,27,15,170,255,13,229,50,61,204,5,180,178,210,17,4,65,16,132,57,143,150,75,32,8,130,32,8,34,232, +130,32,8,130,32,136,160,11,130,32,8,130,32,130,46,8,130,32,8,130,8,186,32,8,130,32,136,160,11,130,32,8,130,32,130,46,8,130,32,8,130,8,186,32,8,130,32,8,34,232,130,32,8,130,32,130,46,8,130,32,8,130,8,186,32,8,130,32,8,141,230,255,15,0,52,210,185,219,217, +94,61,140,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; + +const char* iconlarge_png = (const char*) temp_binary_data_0; + +//================== icon-small.png ================== +static const unsigned char temp_binary_data_1[] = +{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,50,0,0,0,50,8,6,0,0,0,30,63,136,177,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,10,79,105,67,67,80,80,104,111,116,111,115,104,111,112,32,73,67,67,32,112,114,111,102,105,108,101,0,0, +120,218,157,83,103,84,83,233,22,61,247,222,244,66,75,136,128,148,75,111,82,21,8,32,82,66,139,128,20,145,38,42,33,9,16,74,136,33,161,217,21,81,193,17,69,69,4,27,200,160,136,3,142,142,128,140,21,81,44,12,138,10,216,7,228,33,162,142,131,163,136,138,202, +251,225,123,163,107,214,188,247,230,205,254,181,215,62,231,172,243,157,179,207,7,192,8,12,150,72,51,81,53,128,12,169,66,30,17,224,131,199,196,198,225,228,46,64,129,10,36,112,0,16,8,179,100,33,115,253,35,1,0,248,126,60,60,43,34,192,7,190,0,1,120,211,11, +8,0,192,77,155,192,48,28,135,255,15,234,66,153,92,1,128,132,1,192,116,145,56,75,8,128,20,0,64,122,142,66,166,0,64,70,1,128,157,152,38,83,0,160,4,0,96,203,99,98,227,0,80,45,0,96,39,127,230,211,0,128,157,248,153,123,1,0,91,148,33,21,1,160,145,0,32,19,101, +136,68,0,104,59,0,172,207,86,138,69,0,88,48,0,20,102,75,196,57,0,216,45,0,48,73,87,102,72,0,176,183,0,192,206,16,11,178,0,8,12,0,48,81,136,133,41,0,4,123,0,96,200,35,35,120,0,132,153,0,20,70,242,87,60,241,43,174,16,231,42,0,0,120,153,178,60,185,36,57, +69,129,91,8,45,113,7,87,87,46,30,40,206,73,23,43,20,54,97,2,97,154,64,46,194,121,153,25,50,129,52,15,224,243,204,0,0,160,145,21,17,224,131,243,253,120,206,14,174,206,206,54,142,182,14,95,45,234,191,6,255,34,98,98,227,254,229,207,171,112,64,0,0,225,116, +126,209,254,44,47,179,26,128,59,6,128,109,254,162,37,238,4,104,94,11,160,117,247,139,102,178,15,64,181,0,160,233,218,87,243,112,248,126,60,60,69,161,144,185,217,217,229,228,228,216,74,196,66,91,97,202,87,125,254,103,194,95,192,87,253,108,249,126,60,252, +247,245,224,190,226,36,129,50,93,129,71,4,248,224,194,204,244,76,165,28,207,146,9,132,98,220,230,143,71,252,183,11,255,252,29,211,34,196,73,98,185,88,42,20,227,81,18,113,142,68,154,140,243,50,165,34,137,66,146,41,197,37,210,255,100,226,223,44,251,3,62, +223,53,0,176,106,62,1,123,145,45,168,93,99,3,246,75,39,16,88,116,192,226,247,0,0,242,187,111,193,212,40,8,3,128,104,131,225,207,119,255,239,63,253,71,160,37,0,128,102,73,146,113,0,0,94,68,36,46,84,202,179,63,199,8,0,0,68,160,129,42,176,65,27,244,193, +24,44,192,6,28,193,5,220,193,11,252,96,54,132,66,36,196,194,66,16,66,10,100,128,28,114,96,41,172,130,66,40,134,205,176,29,42,96,47,212,64,29,52,192,81,104,134,147,112,14,46,194,85,184,14,61,112,15,250,97,8,158,193,40,188,129,9,4,65,200,8,19,97,33,218, +136,1,98,138,88,35,142,8,23,153,133,248,33,193,72,4,18,139,36,32,201,136,20,81,34,75,145,53,72,49,82,138,84,32,85,72,29,242,61,114,2,57,135,92,70,186,145,59,200,0,50,130,252,134,188,71,49,148,129,178,81,61,212,12,181,67,185,168,55,26,132,70,162,11,208, +100,116,49,154,143,22,160,155,208,114,180,26,61,140,54,161,231,208,171,104,15,218,143,62,67,199,48,192,232,24,7,51,196,108,48,46,198,195,66,177,56,44,9,147,99,203,177,34,172,12,171,198,26,176,86,172,3,187,137,245,99,207,177,119,4,18,129,69,192,9,54,4, +119,66,32,97,30,65,72,88,76,88,78,216,72,168,32,28,36,52,17,218,9,55,9,3,132,81,194,39,34,147,168,75,180,38,186,17,249,196,24,98,50,49,135,88,72,44,35,214,18,143,19,47,16,123,136,67,196,55,36,18,137,67,50,39,185,144,2,73,177,164,84,210,18,210,70,210, +110,82,35,233,44,169,155,52,72,26,35,147,201,218,100,107,178,7,57,148,44,32,43,200,133,228,157,228,195,228,51,228,27,228,33,242,91,10,157,98,64,113,164,248,83,226,40,82,202,106,74,25,229,16,229,52,229,6,101,152,50,65,85,163,154,82,221,168,161,84,17,53, +143,90,66,173,161,182,82,175,81,135,168,19,52,117,154,57,205,131,22,73,75,165,173,162,149,211,26,104,23,104,247,105,175,232,116,186,17,221,149,30,78,151,208,87,210,203,233,71,232,151,232,3,244,119,12,13,134,21,131,199,136,103,40,25,155,24,7,24,103,25, +119,24,175,152,76,166,25,211,139,25,199,84,48,55,49,235,152,231,153,15,153,111,85,88,42,182,42,124,21,145,202,10,149,74,149,38,149,27,42,47,84,169,170,166,170,222,170,11,85,243,85,203,84,143,169,94,83,125,174,70,85,51,83,227,169,9,212,150,171,85,170, +157,80,235,83,27,83,103,169,59,168,135,170,103,168,111,84,63,164,126,89,253,137,6,89,195,76,195,79,67,164,81,160,177,95,227,188,198,32,11,99,25,179,120,44,33,107,13,171,134,117,129,53,196,38,177,205,217,124,118,42,187,152,253,29,187,139,61,170,169,161, +57,67,51,74,51,87,179,82,243,148,102,63,7,227,152,113,248,156,116,78,9,231,40,167,151,243,126,138,222,20,239,41,226,41,27,166,52,76,185,49,101,92,107,170,150,151,150,88,171,72,171,81,171,71,235,189,54,174,237,167,157,166,189,69,187,89,251,129,14,65,199, +74,39,92,39,71,103,143,206,5,157,231,83,217,83,221,167,10,167,22,77,61,58,245,174,46,170,107,165,27,161,187,68,119,191,110,167,238,152,158,190,94,128,158,76,111,167,222,121,189,231,250,28,125,47,253,84,253,109,250,167,245,71,12,88,6,179,12,36,6,219,12, +206,24,60,197,53,113,111,60,29,47,199,219,241,81,67,93,195,64,67,165,97,149,97,151,225,132,145,185,209,60,163,213,70,141,70,15,140,105,198,92,227,36,227,109,198,109,198,163,38,6,38,33,38,75,77,234,77,238,154,82,77,185,166,41,166,59,76,59,76,199,205,204, +205,162,205,214,153,53,155,61,49,215,50,231,155,231,155,215,155,223,183,96,90,120,90,44,182,168,182,184,101,73,178,228,90,166,89,238,182,188,110,133,90,57,89,165,88,85,90,93,179,70,173,157,173,37,214,187,173,187,167,17,167,185,78,147,78,171,158,214,103, +195,176,241,182,201,182,169,183,25,176,229,216,6,219,174,182,109,182,125,97,103,98,23,103,183,197,174,195,238,147,189,147,125,186,125,141,253,61,7,13,135,217,14,171,29,90,29,126,115,180,114,20,58,86,58,222,154,206,156,238,63,125,197,244,150,233,47,103, +88,207,16,207,216,51,227,182,19,203,41,196,105,157,83,155,211,71,103,23,103,185,115,131,243,136,139,137,75,130,203,46,151,62,46,155,27,198,221,200,189,228,74,116,245,113,93,225,122,210,245,157,155,179,155,194,237,168,219,175,238,54,238,105,238,135,220, +159,204,52,159,41,158,89,51,115,208,195,200,67,224,81,229,209,63,11,159,149,48,107,223,172,126,79,67,79,129,103,181,231,35,47,99,47,145,87,173,215,176,183,165,119,170,247,97,239,23,62,246,62,114,159,227,62,227,60,55,222,50,222,89,95,204,55,192,183,200, +183,203,79,195,111,158,95,133,223,67,127,35,255,100,255,122,255,209,0,167,128,37,1,103,3,137,129,65,129,91,2,251,248,122,124,33,191,142,63,58,219,101,246,178,217,237,65,140,160,185,65,21,65,143,130,173,130,229,193,173,33,104,200,236,144,173,33,247,231, +152,206,145,206,105,14,133,80,126,232,214,208,7,97,230,97,139,195,126,12,39,133,135,133,87,134,63,142,112,136,88,26,209,49,151,53,119,209,220,67,115,223,68,250,68,150,68,222,155,103,49,79,57,175,45,74,53,42,62,170,46,106,60,218,55,186,52,186,63,198,46, +102,89,204,213,88,157,88,73,108,75,28,57,46,42,174,54,110,108,190,223,252,237,243,135,226,157,226,11,227,123,23,152,47,200,93,112,121,161,206,194,244,133,167,22,169,46,18,44,58,150,64,76,136,78,56,148,240,65,16,42,168,22,140,37,242,19,119,37,142,10,121, +194,29,194,103,34,47,209,54,209,136,216,67,92,42,30,78,242,72,42,77,122,146,236,145,188,53,121,36,197,51,165,44,229,185,132,39,169,144,188,76,13,76,221,155,58,158,22,154,118,32,109,50,61,58,189,49,131,146,145,144,113,66,170,33,77,147,182,103,234,103, +230,102,118,203,172,101,133,178,254,197,110,139,183,47,30,149,7,201,107,179,144,172,5,89,45,10,182,66,166,232,84,90,40,215,42,7,178,103,101,87,102,191,205,137,202,57,150,171,158,43,205,237,204,179,202,219,144,55,156,239,159,255,237,18,194,18,225,146, +182,165,134,75,87,45,29,88,230,189,172,106,57,178,60,113,121,219,10,227,21,5,43,134,86,6,172,60,184,138,182,42,109,213,79,171,237,87,151,174,126,189,38,122,77,107,129,94,193,202,130,193,181,1,107,235,11,85,10,229,133,125,235,220,215,237,93,79,88,47,89, +223,181,97,250,134,157,27,62,21,137,138,174,20,219,23,151,21,127,216,40,220,120,229,27,135,111,202,191,153,220,148,180,169,171,196,185,100,207,102,210,102,233,230,222,45,158,91,14,150,170,151,230,151,14,110,13,217,218,180,13,223,86,180,237,245,246,69, +219,47,151,205,40,219,187,131,182,67,185,163,191,60,184,188,101,167,201,206,205,59,63,84,164,84,244,84,250,84,54,238,210,221,181,97,215,248,110,209,238,27,123,188,246,52,236,213,219,91,188,247,253,62,201,190,219,85,1,85,77,213,102,213,101,251,73,251, +179,247,63,174,137,170,233,248,150,251,109,93,173,78,109,113,237,199,3,210,3,253,7,35,14,182,215,185,212,213,29,210,61,84,82,143,214,43,235,71,14,199,31,190,254,157,239,119,45,13,54,13,85,141,156,198,226,35,112,68,121,228,233,247,9,223,247,30,13,58,218, +118,140,123,172,225,7,211,31,118,29,103,29,47,106,66,154,242,154,70,155,83,154,251,91,98,91,186,79,204,62,209,214,234,222,122,252,71,219,31,15,156,52,60,89,121,74,243,84,201,105,218,233,130,211,147,103,242,207,140,157,149,157,125,126,46,249,220,96,219, +162,182,123,231,99,206,223,106,15,111,239,186,16,116,225,210,69,255,139,231,59,188,59,206,92,242,184,116,242,178,219,229,19,87,184,87,154,175,58,95,109,234,116,234,60,254,147,211,79,199,187,156,187,154,174,185,92,107,185,238,122,189,181,123,102,247,233, +27,158,55,206,221,244,189,121,241,22,255,214,213,158,57,61,221,189,243,122,111,247,197,247,245,223,22,221,126,114,39,253,206,203,187,217,119,39,238,173,188,79,188,95,244,64,237,65,217,67,221,135,213,63,91,254,220,216,239,220,127,106,192,119,160,243,209, +220,71,247,6,133,131,207,254,145,245,143,15,67,5,143,153,143,203,134,13,134,235,158,56,62,57,57,226,63,114,253,233,252,167,67,207,100,207,38,158,23,254,162,254,203,174,23,22,47,126,248,213,235,215,206,209,152,209,161,151,242,151,147,191,109,124,165,253, +234,192,235,25,175,219,198,194,198,30,190,201,120,51,49,94,244,86,251,237,193,119,220,119,29,239,163,223,15,79,228,124,32,127,40,255,104,249,177,245,83,208,167,251,147,25,147,147,255,4,3,152,243,252,99,51,45,219,0,0,0,32,99,72,82,77,0,0,122,37,0,0,128, +131,0,0,249,255,0,0,128,233,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,111,146,95,197,70,0,0,11,160,73,68,65,84,120,218,220,154,121,144,28,213,125,199,63,175,143,233,158,233,222,217,221,89,237,37,237,161,221,149,37,173,140,132,36,196,101,34,97,76,165,48, +216,21,199,142,76,5,199,96,21,152,128,229,96,20,217,36,198,198,22,4,9,130,141,29,97,202,96,112,225,84,129,147,184,226,28,165,10,174,92,144,148,43,133,57,117,184,132,142,93,105,87,210,178,171,149,246,222,157,233,153,238,233,238,247,242,199,30,89,105,87, +7,32,163,172,95,213,111,166,170,103,94,247,239,251,222,239,251,187,94,11,165,20,191,13,195,56,195,245,106,224,163,192,106,192,2,46,54,90,13,56,9,252,18,120,29,136,102,252,67,41,53,93,44,165,212,86,165,212,9,245,255,119,188,161,148,186,241,52,189,79,1, +82,162,148,122,73,205,157,241,39,211,129,136,105,28,121,30,184,117,142,81,227,122,224,191,128,41,32,87,76,216,222,92,27,175,2,159,2,250,181,137,11,55,207,81,103,117,21,240,201,73,111,0,176,118,142,2,17,192,138,233,64,50,115,56,132,216,211,129,200,57, +12,68,77,5,196,185,30,221,133,16,103,140,236,23,89,177,233,20,56,191,133,54,46,22,67,167,125,204,24,145,84,12,75,232,239,63,78,173,155,162,204,45,189,56,64,196,76,141,103,140,162,84,140,69,49,221,126,68,183,31,113,60,136,57,234,71,180,121,33,125,69,73, +95,191,199,177,231,54,242,213,107,175,97,219,189,91,206,185,43,198,251,95,213,217,149,149,74,145,139,20,253,197,136,46,63,226,184,31,209,29,68,180,123,17,157,133,144,254,162,100,56,138,201,199,10,13,72,233,130,6,219,160,62,105,112,100,52,164,127,232, +29,174,93,56,74,227,112,129,177,49,143,116,218,57,43,152,51,146,93,76,217,170,152,93,97,165,200,71,146,209,72,210,19,196,188,227,71,244,248,49,71,10,17,237,249,34,61,65,204,112,40,201,70,146,72,129,165,9,202,77,141,70,219,160,37,105,178,174,92,167,37, +105,178,40,101,80,149,208,89,96,235,140,69,138,251,218,134,200,153,22,15,174,26,227,206,242,58,94,217,215,192,129,125,251,185,226,234,53,103,4,114,10,217,53,77,155,225,213,194,88,145,141,99,6,138,49,93,126,196,59,254,184,194,157,133,136,142,124,72,127, +49,102,36,146,4,82,161,11,129,163,11,106,45,131,133,182,193,199,50,9,234,45,157,37,142,73,157,109,144,49,52,202,77,141,164,161,157,182,131,10,16,188,49,226,115,219,222,62,198,34,197,223,173,88,192,141,81,23,133,220,66,22,44,88,78,239,137,94,250,250,250, +168,174,170,70,74,121,118,211,26,203,142,177,243,88,23,237,206,124,218,252,152,67,190,228,120,81,50,20,198,100,35,137,31,75,82,26,84,152,26,149,9,157,5,150,206,199,50,73,150,186,38,45,73,131,202,132,78,185,161,81,106,104,8,77,76,83,86,77,251,82,40,169, +80,19,215,52,33,64,8,158,235,30,101,227,254,65,174,41,179,248,143,203,171,105,176,67,226,131,111,67,213,245,204,27,172,33,52,21,135,59,58,168,156,87,137,16,98,214,157,49,38,119,227,149,93,111,178,225,235,155,208,215,220,68,114,249,90,42,108,157,249,78, +138,235,171,202,105,173,41,103,97,58,77,83,58,197,124,199,34,33,196,236,113,73,41,148,2,41,213,57,107,49,77,19,100,67,201,230,182,65,158,235,206,114,111,99,154,71,23,103,176,117,157,56,219,134,140,114,24,181,171,80,90,76,99,77,3,251,7,59,232,238,238, +166,161,161,225,204,64,164,148,92,119,245,90,94,218,252,167,168,127,121,1,51,40,65,95,183,158,208,203,18,228,71,8,142,247,19,247,40,142,27,6,3,118,18,203,182,113,74,74,112,29,7,219,182,177,108,27,211,52,209,52,13,49,65,169,83,138,158,211,184,167,233, +26,123,199,2,54,236,237,167,163,16,241,252,242,74,62,191,192,5,169,136,21,168,236,110,48,50,232,37,77,232,214,97,18,82,103,97,99,35,135,15,31,166,186,186,26,211,52,103,220,119,138,236,9,211,100,249,103,111,71,86,87,81,248,249,51,24,85,25,18,55,223,77, +164,32,240,60,10,190,79,33,159,103,44,155,197,243,60,134,71,71,9,130,0,41,37,134,97,144,76,38,177,109,27,215,117,41,41,41,33,153,76,98,89,22,150,101,205,224,223,207,122,115,220,189,175,159,197,41,131,95,93,57,159,101,37,9,100,44,81,8,80,49,42,251,107, +112,86,32,52,3,211,77,224,143,230,105,188,164,153,174,163,93,116,118,118,210,218,218,74,28,199,179,112,68,41,84,28,19,11,1,235,62,137,145,74,83,248,201,99,68,185,49,146,183,109,30,95,125,215,157,10,185,74,41,226,56,38,8,2,60,207,195,243,60,242,249,60, +158,231,209,211,211,67,20,69,72,41,209,52,141,100,50,137,235,186,84,148,184,8,59,201,15,79,22,121,172,167,192,231,234,51,60,187,162,154,148,54,126,79,161,77,56,129,160,23,21,244,160,85,173,31,87,208,177,200,247,101,49,52,131,230,150,102,14,30,56,72,125, +125,61,142,227,32,167,129,49,152,110,205,74,65,20,97,172,89,71,210,41,161,240,227,173,200,31,126,27,251,246,175,35,210,101,16,157,90,243,219,201,36,169,84,138,170,170,42,38,77,52,142,99,194,48,196,247,125,114,185,28,249,188,135,8,124,94,235,236,98,235, +193,62,246,231,2,238,170,75,243,133,210,12,237,187,187,177,82,14,169,84,10,199,113,72,58,105,244,209,93,232,154,133,145,94,6,64,170,194,101,244,208,73,138,121,159,186,186,122,186,142,30,227,208,161,67,172,92,185,242,20,22,206,26,16,85,20,97,180,174,34, +181,233,59,228,159,222,66,254,251,95,35,245,165,7,209,170,235,80,211,192,40,41,137,103,144,88,195,178,44,108,219,38,147,25,175,14,254,115,176,192,166,193,94,210,203,234,120,121,113,25,151,154,49,253,217,44,185,156,199,224,192,0,199,139,69,226,56,70,8, +3,113,242,31,176,44,157,114,186,113,220,36,166,210,240,10,121,10,163,30,101,110,146,75,150,47,103,247,174,157,228,179,99,56,233,82,162,9,125,132,82,138,48,12,219,128,197,51,2,141,105,34,251,123,41,252,120,27,106,100,144,228,221,91,208,155,151,162,194, +240,156,145,223,212,4,145,82,60,220,49,194,195,157,35,124,166,218,225,169,101,149,84,217,6,74,170,41,51,141,227,152,40,138,40,134,49,222,200,59,140,237,189,159,160,228,6,60,235,74,124,111,132,56,140,56,241,214,81,202,26,230,81,183,116,1,182,101,241,202, +238,95,51,22,10,190,120,203,122,28,43,241,180,166,235,27,207,154,162,168,48,68,84,214,146,186,247,47,41,60,243,23,228,183,255,57,201,141,15,98,44,93,133,10,163,51,186,88,83,23,244,23,99,238,124,123,128,29,125,30,91,90,202,217,178,168,28,1,132,225,204, +150,148,97,24,36,108,155,52,57,106,155,108,88,244,123,40,115,254,148,115,209,186,243,156,24,24,228,31,223,28,224,181,158,1,246,238,63,198,112,111,47,215,173,189,134,149,139,155,57,191,122,164,88,132,164,131,189,241,33,252,231,191,71,254,137,111,96,223, +186,25,243,35,191,59,190,51,211,230,106,2,12,67,227,181,33,159,219,246,246,51,22,73,126,177,186,134,155,170,82,68,177,100,124,35,196,41,162,148,66,74,137,95,8,25,59,242,63,120,125,6,94,177,143,156,119,140,66,33,143,46,20,175,15,14,240,55,61,30,199,91, +155,9,202,106,144,235,46,99,251,218,38,86,52,215,19,133,33,134,105,158,103,210,24,133,96,90,216,119,220,79,240,247,63,162,240,215,223,65,102,135,177,110,184,121,156,51,82,98,10,129,16,240,228,145,81,190,214,54,200,85,165,22,255,190,166,134,38,215,66, +198,10,77,55,16,74,17,71,17,133,73,111,151,203,49,50,58,74,62,95,192,47,228,40,30,125,153,68,233,135,113,156,16,39,149,164,182,182,134,76,89,41,249,242,38,122,187,70,121,171,178,146,183,70,2,182,175,168,228,75,117,165,132,197,226,148,77,156,127,133,24, +133,160,233,88,183,124,25,145,169,34,248,249,51,168,209,97,18,127,112,39,150,161,49,82,12,185,231,224,16,63,237,245,184,175,41,195,35,31,42,67,143,35,134,6,71,240,242,30,185,92,142,209,145,81,242,133,60,65,16,160,148,194,182,109,28,199,33,83,81,69,218, +84,88,73,3,183,245,115,88,153,75,17,147,110,68,41,110,90,85,198,238,146,33,246,28,26,102,123,107,134,141,181,41,138,65,112,110,175,117,198,33,99,84,81,146,184,225,179,96,167,240,95,248,43,236,98,129,253,159,184,131,219,247,246,179,167,111,152,199,234, +109,110,166,143,61,111,117,48,146,205,18,4,1,154,16,36,44,11,199,113,168,169,169,193,117,93,92,215,37,149,74,97,24,6,66,55,144,39,15,16,7,21,104,37,77,196,81,8,72,52,192,52,52,182,181,13,240,64,251,16,143,47,173,96,99,67,154,98,36,103,176,243,221,215, +236,74,161,130,0,243,218,79,96,167,75,121,241,241,111,243,133,159,190,68,234,218,245,60,219,90,193,210,156,197,209,188,137,235,186,52,52,52,224,186,46,142,227,144,72,36,198,149,158,224,197,164,68,81,4,177,64,14,191,14,246,98,208,210,32,253,113,16,186, +198,214,67,67,124,171,125,136,173,75,42,248,106,83,41,197,40,70,170,11,85,88,73,133,242,125,196,170,223,161,242,158,135,105,248,217,139,28,174,172,99,119,77,61,31,111,173,165,202,177,137,212,120,6,172,148,66,42,57,149,13,76,45,229,84,222,169,67,177,15, +85,56,138,54,255,142,169,159,18,186,96,91,199,48,223,106,31,228,161,15,101,248,102,115,41,197,104,220,97,204,86,116,190,247,46,138,130,98,161,192,71,174,184,154,95,93,126,13,79,116,14,240,104,199,16,59,118,246,177,181,165,156,63,172,113,16,128,47,213, +89,154,56,128,102,160,188,131,40,21,67,106,9,200,16,75,23,60,218,49,204,3,109,67,60,178,36,195,253,45,101,4,19,94,239,148,185,167,157,59,140,187,208,247,40,5,223,199,42,22,120,160,209,229,213,53,53,180,216,6,127,180,231,4,159,217,115,146,118,175,72,210, +16,232,147,139,53,171,128,26,219,5,86,61,34,81,141,173,75,158,56,58,194,55,14,14,241,205,69,229,220,223,92,134,31,73,98,121,22,61,38,129,156,126,214,240,110,4,165,136,164,196,11,99,46,113,77,254,109,117,53,127,123,105,53,187,70,125,86,190,218,195,182, +195,195,20,98,73,74,23,40,20,114,250,124,4,42,206,33,189,3,8,119,5,182,145,224,201,35,35,108,218,55,192,230,230,82,182,182,156,10,226,140,58,76,1,185,0,2,80,136,37,65,44,185,165,214,97,231,85,243,217,88,87,194,3,135,134,184,252,181,30,118,156,244,72, +105,2,75,19,255,55,79,152,72,175,13,138,253,56,165,171,121,242,232,16,95,217,215,207,61,11,211,124,119,113,57,190,148,196,19,138,158,235,217,239,219,180,78,23,169,20,185,48,38,173,107,124,111,73,134,55,174,156,79,163,109,240,251,59,79,176,126,207,73, +58,243,33,142,33,208,80,40,165,65,118,23,37,246,60,158,234,43,231,43,123,79,112,111,83,41,219,151,100,8,98,69,36,207,243,185,23,194,180,102,51,53,148,34,148,146,92,24,179,186,36,193,47,86,85,241,163,75,230,241,223,67,62,171,95,237,225,241,206,17,98,5, +142,240,113,11,111,243,147,225,26,190,124,160,192,93,13,14,223,95,60,9,66,158,213,156,78,55,45,131,223,240,73,103,62,150,8,224,174,58,151,27,43,108,182,118,142,112,223,193,65,94,232,245,249,65,115,158,246,174,118,254,120,224,211,108,88,86,194,147,75, +221,9,115,58,163,115,122,247,125,173,11,221,46,31,11,21,85,166,206,179,203,230,113,107,173,203,159,117,20,248,232,142,29,208,221,197,231,63,125,25,79,183,150,18,202,144,232,61,170,242,129,118,227,3,165,8,36,92,85,106,241,242,101,14,79,197,31,230,120, +205,23,121,104,121,43,50,14,9,223,135,30,147,64,196,7,217,196,246,162,24,141,152,77,87,220,0,154,78,190,88,160,248,222,65,136,233,64,252,15,186,35,31,3,217,162,127,161,110,53,213,69,217,9,44,159,163,167,60,71,166,123,173,127,70,169,13,115,16,70,39,240, +226,244,56,242,175,10,222,188,16,17,254,3,150,239,42,165,218,166,167,241,33,74,109,80,74,189,140,16,53,115,100,55,94,16,66,60,115,74,246,59,158,192,177,31,33,174,83,74,253,82,74,137,148,242,130,70,252,11,33,19,58,229,149,82,143,0,27,38,222,73,153,181, +176,58,8,92,39,132,184,94,41,245,41,37,229,34,32,193,197,127,205,73,0,195,66,104,111,2,255,36,224,208,140,63,252,182,188,120,246,191,3,0,81,236,211,213,117,182,178,199,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; + +const char* iconsmall_png = (const char*) temp_binary_data_1; + +//================== cpmono-black-serialized ================== +static const unsigned char temp_binary_data_2[] = { 120,156,237,157,127,156,149,85,181,255,71,65,64,12,10,47,132,9,130,81,152,63,80,233,226,197,66,158,103,176,240,66,23,47,136,93,12,186,24,196,211,65,177,51,228,185,151,210,11,134,66,141,97,160,32,40,5,57,6,130,130,160,99,16,36,8,231,57,6,66,98,160,24, 212,24,228,143,33,212,41,16,20,196,194,160,190,251,253,89,207,179,103,200,31,13,126,49,61,190,248,99,102,125,94,103,255,90,251,199,179,247,218,107,175,189,246,231,47,249,207,111,140,252,198,144,111,117,62,191,164,164,100,240,228,207,149,158,90,242,55, 135,142,41,89,184,160,105,233,200,50,7,75,102,111,106,20,102,1,35,103,117,41,100,245,123,10,8,138,202,58,116,184,43,56,99,112,251,66,22,16,54,253,82,144,221,176,126,103,232,1,65,81,217,105,133,167,2,151,199,13,217,19,170,162,176,124,199,173,113,150,95, @@ -229,10 +1100,10 @@ static const unsigned char temp_binary_data_0[] = 33,16,98,208,66,64,165,133,0,168,139,0,116,17,81,213,69,164,165,35,200,236,208,187,111,169,2,12,170,46,2,72,31,2,160,188,148,147,168,140,108,213,204,0,29,214,114,202,236,65,226,103,102,120,232,129,212,29,171,247,93,105,234,14,91,227,94,138,253,11,117, 39,245,137,109,181,198,15,39,160,102,201,43,166,238,224,78,3,234,14,168,158,218,3,104,152,0,24,38,68,213,48,33,173,29,159,199,233,48,177,155,126,42,15,0,3,176,29,101,254,118,116,116,191,107,163,251,200,205,65,174,242,37,255,15,41,157,224,99,0,0 }; -const char* cpmonoblackserialized = (const char*) temp_binary_data_0; +const char* cpmonoblackserialized = (const char*) temp_binary_data_2; //================== cpmono-bold-serialized ================== -static const unsigned char temp_binary_data_1[] = +static const unsigned char temp_binary_data_3[] = { 120,156,237,157,15,156,87,69,185,255,65,8,20,47,36,94,76,19,83,219,46,94,52,77,10,131,90,247,28,212,48,45,188,24,118,53,236,210,213,56,125,81,185,223,37,206,109,11,46,118,81,40,188,32,38,136,134,129,173,173,130,65,144,171,16,40,202,126,207,33,8,10,131, 194,160,182,32,44,8,107,11,68,3,177,48,200,223,188,63,207,57,243,101,213,250,129,47,42,191,190,120,189,246,181,207,231,245,157,63,231,153,153,103,102,158,153,121,230,153,15,124,228,223,62,61,226,211,215,124,174,87,223,54,109,218,12,153,114,81,191,211, 219,188,228,80,219,54,243,231,117,234,55,162,214,193,54,247,173,239,16,22,1,35,26,122,167,69,253,158,3,130,162,218,150,69,227,130,117,55,188,35,45,2,174,222,53,57,40,158,210,242,124,232,1,65,81,237,236,145,165,192,229,113,115,241,198,110,35,194,9,219, @@ -466,10 +1337,10 @@ static const unsigned char temp_binary_data_1[] = 51,181,25,217,171,205,216,211,1,112,175,76,109,134,99,37,218,12,170,54,3,48,217,40,132,199,124,136,58,145,7,18,72,11,71,57,175,81,45,31,86,203,0,116,100,204,109,66,15,50,39,17,131,66,15,180,131,130,86,170,29,20,118,124,144,10,58,153,164,3,85,87,26,1, 62,84,1,80,61,172,2,144,220,0,108,87,189,201,228,134,196,146,27,228,18,64,246,48,21,21,94,58,34,238,127,63,113,63,124,163,148,171,141,54,255,15,230,92,172,169,0,0 }; -const char* cpmonoboldserialized = (const char*) temp_binary_data_1; +const char* cpmonoboldserialized = (const char*) temp_binary_data_3; //================== cpmono-extralight-serialized ================== -static const unsigned char temp_binary_data_2[] = +static const unsigned char temp_binary_data_4[] = { 120,156,237,157,127,188,149,69,181,255,81,16,232,24,24,10,65,129,98,20,132,133,129,97,218,69,246,3,26,126,177,139,23,193,210,176,75,87,227,113,195,133,246,38,118,151,130,164,48,40,16,195,4,81,143,74,29,5,193,32,240,158,194,64,65,206,126,54,129,160,32, 40,4,122,8,130,4,33,143,65,160,32,42,134,117,231,253,89,207,51,251,80,118,191,71,47,254,216,190,248,99,191,230,243,218,243,107,61,107,214,172,89,51,179,102,230,11,253,254,237,155,195,191,121,245,119,186,156,95,175,94,189,129,83,46,234,113,102,189,191, 57,116,66,189,249,243,202,122,12,207,58,88,111,230,198,134,65,6,48,124,70,215,66,70,255,39,128,168,48,123,227,164,73,221,207,26,216,185,144,1,180,157,176,39,149,25,50,184,97,15,15,136,10,179,77,71,126,53,229,202,248,65,230,236,195,19,130,9,123,110,137, @@ -713,10 +1584,10 @@ static const unsigned char temp_binary_data_2[] = 120,66,120,32,139,155,40,15,180,126,150,157,113,154,128,107,216,179,37,108,220,194,47,233,224,13,93,89,4,92,176,15,24,56,101,167,173,159,113,105,17,195,62,33,235,103,186,197,72,130,4,64,144,72,42,65,34,47,226,66,97,18,36,138,143,5,233,108,1,8,128,236, 48,253,183,227,242,255,46,202,255,177,211,99,142,61,245,254,7,170,167,234,165,0,0 }; -const char* cpmonoextralightserialized = (const char*) temp_binary_data_2; +const char* cpmonoextralightserialized = (const char*) temp_binary_data_4; //================== cpmono-light-serialized ================== -static const unsigned char temp_binary_data_3[] = +static const unsigned char temp_binary_data_5[] = { 120,156,237,157,127,160,149,69,181,247,81,16,12,195,196,32,40,8,184,167,80,41,20,13,195,222,19,207,6,12,47,118,233,98,120,47,132,69,65,60,110,12,218,155,216,93,186,16,118,17,168,99,7,161,32,48,76,13,131,192,32,168,83,120,161,64,206,126,54,129,135,4,65, 65,168,99,32,40,4,117,18,2,130,208,11,65,189,243,249,174,231,153,125,200,122,47,250,226,143,109,252,115,230,123,246,252,90,207,204,154,53,107,102,214,172,249,208,71,255,245,115,163,62,55,228,63,175,190,174,65,131,6,131,167,95,223,163,67,131,191,56,116, 94,131,37,139,155,246,24,149,117,176,193,188,173,141,83,25,192,168,185,93,11,25,253,158,0,162,194,236,202,118,23,4,147,251,189,183,144,1,236,107,245,88,144,41,12,58,191,135,7,68,133,217,41,149,149,129,43,99,98,102,204,246,137,169,138,253,223,136,50,252, @@ -973,10 +1844,10 @@ static const unsigned char temp_binary_data_3[] = 195,60,113,76,68,82,189,98,69,94,234,75,40,9,179,212,163,142,0,200,180,129,55,79,61,208,165,32,162,60,208,222,215,218,99,87,216,222,23,55,12,225,138,77,27,99,207,194,67,59,175,52,141,128,61,47,211,39,127,99,123,95,139,154,253,81,123,95,132,58,191,0,136, 145,0,48,18,73,197,72,228,133,93,40,76,140,68,241,98,164,228,70,35,4,64,118,152,254,203,57,254,127,13,249,255,236,201,49,215,60,13,254,47,224,111,82,132,0,0 }; -const char* cpmonolightserialized = (const char*) temp_binary_data_3; +const char* cpmonolightserialized = (const char*) temp_binary_data_5; //================== cpmono-plain-serialized ================== -static const unsigned char temp_binary_data_4[] = +static const unsigned char temp_binary_data_6[] = { 120,156,237,157,127,188,86,69,181,255,143,130,96,40,36,6,98,65,104,39,33,44,8,10,67,67,246,62,80,120,177,240,106,88,16,118,241,66,108,31,20,122,14,185,187,20,132,93,68,12,67,161,48,48,76,234,212,65,84,16,244,24,4,10,194,179,31,2,193,64,240,30,131,194, 32,44,8,12,131,192,48,72,184,144,119,222,159,181,247,28,200,238,247,162,95,127,61,198,31,231,181,62,231,153,31,123,205,204,154,153,53,51,107,214,124,242,51,255,250,229,225,95,30,248,181,78,23,150,149,149,13,152,252,137,138,115,203,94,114,232,164,178, 185,115,26,85,12,175,116,176,108,198,250,6,97,30,48,188,186,115,49,175,223,51,64,80,84,233,146,5,155,187,127,160,152,7,76,29,248,64,144,239,52,237,112,232,1,65,81,101,121,249,221,129,203,99,108,126,212,200,145,225,248,93,223,77,242,252,50,126,87,211, @@ -1230,10 +2101,10 @@ static const unsigned char temp_binary_data_4[] = 0,27,91,68,213,198,22,105,225,40,227,53,170,180,27,162,231,22,196,138,108,12,220,164,29,120,160,235,41,4,121,160,125,43,154,68,251,86,204,159,72,5,47,118,73,58,120,227,78,42,194,244,187,14,10,64,101,123,97,160,204,66,144,14,162,74,110,72,156,118,156, 171,5,200,30,166,162,220,75,39,196,253,141,19,247,215,110,148,114,252,151,253,15,5,44,29,103,0,0 }; -const char* cpmonoplainserialized = (const char*) temp_binary_data_4; +const char* cpmonoplainserialized = (const char*) temp_binary_data_6; //================== BebasNeue.otf ================== -static const unsigned char temp_binary_data_5[] = +static const unsigned char temp_binary_data_7[] = { 79,84,84,79,0,11,0,128,0,3,0,48,67,70,70,32,57,136,64,140,0,0,39,76,0,0,70,154,71,80,79,83,223,12,110,56,0,0,116,248,0,0,73,16,71,83,85,66,114,203,114,178,0,0,116,0,0,0,0,246,79,83,47,50,102,169,27,20,0,0,1,32,0,0,0,96,99,109,97,112,211,17,247,228,0, 0,35,232,0,0,3,68,104,101,97,100,243,84,238,113,0,0,0,188,0,0,0,54,104,104,101,97,6,215,3,186,0,0,0,244,0,0,0,36,104,109,116,120,67,128,39,22,0,0,109,232,0,0,6,24,109,97,120,112,1,134,80,0,0,0,1,24,0,0,0,6,110,97,109,101,230,56,31,140,0,0,1,128,0,0,34, 101,112,111,115,116,255,184,0,50,0,0,39,44,0,0,0,32,0,1,0,0,0,1,0,131,131,184,68,27,95,15,60,245,0,3,3,232,0,0,0,0,200,111,85,40,0,0,0,0,200,111,85,40,255,119,255,60,3,232,3,130,0,0,0,3,0,2,0,0,0,0,0,0,0,1,0,0,2,188,254,212,0,185,3,232,255,119,255,119, @@ -1843,10 +2714,10 @@ static const unsigned char temp_binary_data_5[] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,10,0,3,0,10,0,3,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,0,24,0,22,0,24,0,22,0,24,0,22,0,24,0,4,0,11,0,4,0,11,0,4,0,11,0,23,0,25,0,23,0,25,0,23,0,25,0,23,0,25,0,23,0,25,0,23,0,25,0,5,0,12,0,6,0,13,0,6,0,19, 0,21,0,19,0,21,0,19,0,21,0,15,0,17,0,3,0,10,0,22,0,24,0,4,0,11,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,0,24,0,4,0,11,0,5,0,12,0,5,0,12,0,5,0,12,0,6,0,13,0,0 }; -const char* BebasNeue_otf = (const char*) temp_binary_data_5; +const char* BebasNeue_otf = (const char*) temp_binary_data_7; //================== cpmono_bold.otf ================== -static const unsigned char temp_binary_data_6[] = +static const unsigned char temp_binary_data_8[] = { 79,84,84,79,0,10,0,128,0,3,0,32,67,70,70,32,35,187,57,254,0,0,10,112,0,0,84,205,71,83,85,66,106,18,122,98,0,0,98,20,0,0,5,216,79,83,47,50,104,215,98,101,0,0,1,16,0,0,0,96,99,109,97,112,38,198,129,33,0,0,5,56,0,0,5,24,104,101,97,100,237,187,124,213,0, 0,0,172,0,0,0,54,104,104,101,97,6,229,0,115,0,0,0,228,0,0,0,36,104,109,116,120,58,11,56,208,0,0,95,64,0,0,2,212,109,97,120,112,1,105,80,0,0,0,1,8,0,0,0,6,110,97,109,101,226,66,147,104,0,0,1,112,0,0,3,198,112,111,115,116,255,181,0,161,0,0,10,80,0,0,0, 32,0,1,0,0,0,1,0,0,64,149,238,152,95,15,60,245,0,3,3,232,0,0,0,0,198,13,28,168,0,0,0,0,198,13,28,168,255,7,255,16,3,131,3,149,0,0,0,3,0,2,0,0,0,0,0,0,0,1,0,0,3,144,254,224,0,200,2,138,255,7,255,7,3,131,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,80,0,1,105, @@ -2190,10 +3061,10 @@ static const unsigned char temp_binary_data_6[] = 0,2,0,21,0,4,0,12,0,0,0,14,0,19,0,9,0,21,0,23,0,15,0,28,0,28,0,18,0,36,0,51,0,19,0,53,0,54,0,35,0,57,0,60,0,37,0,63,0,66,0,41,0,71,0,72,0,45,0,82,0,82,0,47,0,92,0,92,0,48,0,99,0,99,0,49,0,103,0,106,0,50,0,140,0,162,0,54,0,165,0,168,0,77,0,179,0,184,0, 81,0,208,0,209,0,87,0,214,0,214,0,89,0,224,1,6,0,90,1,8,1,8,0,129,1,13,1,13,0,130,0,1,0,26,0,3,0,13,0,20,0,24,0,25,0,26,0,27,0,52,0,55,0,56,0,61,0,62,0,67,0,68,0,69,0,70,0,134,0,135,0,136,0,137,0,138,0,139,0,163,0,164,0,169,1,7,0,0 }; -const char* cpmono_bold_otf = (const char*) temp_binary_data_6; +const char* cpmono_bold_otf = (const char*) temp_binary_data_8; //================== cpmono_extra_light.otf ================== -static const unsigned char temp_binary_data_7[] = +static const unsigned char temp_binary_data_9[] = { 79,84,84,79,0,10,0,128,0,3,0,32,67,70,70,32,248,217,201,134,0,0,10,164,0,0,78,103,71,83,85,66,106,18,122,98,0,0,91,224,0,0,5,216,79,83,47,50,104,210,98,59,0,0,1,16,0,0,0,96,99,109,97,112,38,198,129,33,0,0,5,108,0,0,5,24,104,101,97,100,237,187,115,86, 0,0,0,172,0,0,0,54,104,104,101,97,6,229,0,179,0,0,0,228,0,0,0,36,104,109,116,120,81,57,79,54,0,0,89,12,0,0,2,212,109,97,120,112,1,105,80,0,0,0,1,8,0,0,0,6,110,97,109,101,101,109,217,12,0,0,1,112,0,0,3,252,112,111,115,116,255,181,0,161,0,0,10,132,0,0, 0,32,0,1,0,0,0,1,0,0,97,176,60,66,95,15,60,245,0,3,3,232,0,0,0,0,198,13,23,248,0,0,0,0,198,13,23,248,255,71,255,16,3,67,3,118,0,0,0,3,0,2,0,0,0,0,0,0,0,1,0,0,3,144,254,224,0,200,2,138,255,71,255,71,3,67,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,80,0,1, @@ -2518,10 +3389,10 @@ static const unsigned char temp_binary_data_7[] = 0,55,0,61,0,62,0,70,0,2,0,21,0,4,0,12,0,0,0,14,0,19,0,9,0,21,0,23,0,15,0,28,0,28,0,18,0,36,0,51,0,19,0,53,0,54,0,35,0,57,0,60,0,37,0,63,0,66,0,41,0,71,0,72,0,45,0,82,0,82,0,47,0,92,0,92,0,48,0,99,0,99,0,49,0,103,0,106,0,50,0,140,0,162,0,54,0,165,0,168, 0,77,0,179,0,184,0,81,0,208,0,209,0,87,0,214,0,214,0,89,0,224,1,6,0,90,1,8,1,8,0,129,1,13,1,13,0,130,0,1,0,26,0,3,0,13,0,20,0,24,0,25,0,26,0,27,0,52,0,55,0,56,0,61,0,62,0,67,0,68,0,69,0,70,0,134,0,135,0,136,0,137,0,138,0,139,0,163,0,164,0,169,1,7,0,0 }; -const char* cpmono_extra_light_otf = (const char*) temp_binary_data_7; +const char* cpmono_extra_light_otf = (const char*) temp_binary_data_9; //================== cpmono_light.otf ================== -static const unsigned char temp_binary_data_8[] = +static const unsigned char temp_binary_data_10[] = { 79,84,84,79,0,10,0,128,0,3,0,32,67,70,70,32,64,226,171,159,0,0,10,124,0,0,81,133,71,83,85,66,106,18,122,98,0,0,94,216,0,0,5,216,79,83,47,50,104,211,98,73,0,0,1,16,0,0,0,96,99,109,97,112,38,198,129,33,0,0,5,68,0,0,5,24,104,101,97,100,237,187,127,116,0, 0,0,172,0,0,0,54,104,104,101,97,6,229,0,158,0,0,0,228,0,0,0,36,104,109,116,120,73,105,71,167,0,0,92,4,0,0,2,212,109,97,120,112,1,105,80,0,0,0,1,8,0,0,0,6,110,97,109,101,106,76,91,179,0,0,1,112,0,0,3,209,112,111,115,116,255,181,0,161,0,0,10,92,0,0,0,32, 0,1,0,0,0,1,0,0,215,127,97,71,95,15,60,245,0,3,3,232,0,0,0,0,198,13,30,2,0,0,0,0,198,13,30,2,255,50,255,16,3,88,3,128,0,0,0,3,0,2,0,0,0,0,0,0,0,1,0,0,3,144,254,224,0,200,2,138,255,50,255,50,3,88,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,80,0,1,105,0,0, @@ -2856,10 +3727,10 @@ static const unsigned char temp_binary_data_8[] = 0,4,0,12,0,0,0,14,0,19,0,9,0,21,0,23,0,15,0,28,0,28,0,18,0,36,0,51,0,19,0,53,0,54,0,35,0,57,0,60,0,37,0,63,0,66,0,41,0,71,0,72,0,45,0,82,0,82,0,47,0,92,0,92,0,48,0,99,0,99,0,49,0,103,0,106,0,50,0,140,0,162,0,54,0,165,0,168,0,77,0,179,0,184,0,81,0,208, 0,209,0,87,0,214,0,214,0,89,0,224,1,6,0,90,1,8,1,8,0,129,1,13,1,13,0,130,0,1,0,26,0,3,0,13,0,20,0,24,0,25,0,26,0,27,0,52,0,55,0,56,0,61,0,62,0,67,0,68,0,69,0,70,0,134,0,135,0,136,0,137,0,138,0,139,0,163,0,164,0,169,1,7,0,0 }; -const char* cpmono_light_otf = (const char*) temp_binary_data_8; +const char* cpmono_light_otf = (const char*) temp_binary_data_10; //================== cpmono_plain.otf ================== -static const unsigned char temp_binary_data_9[] = +static const unsigned char temp_binary_data_11[] = { 79,84,84,79,0,10,0,128,0,3,0,32,67,70,70,32,153,52,71,27,0,0,10,124,0,0,81,49,71,83,85,66,106,18,122,98,0,0,94,132,0,0,5,216,79,83,47,50,104,213,98,87,0,0,1,16,0,0,0,96,99,109,97,112,38,198,129,33,0,0,5,68,0,0,5,24,104,101,97,100,237,186,121,35,0,0,0, 172,0,0,0,54,104,104,101,97,6,228,0,137,0,0,0,228,0,0,0,36,104,109,116,120,65,179,64,52,0,0,91,176,0,0,2,212,109,97,120,112,1,105,80,0,0,0,1,8,0,0,0,6,110,97,109,101,95,80,74,175,0,0,1,112,0,0,3,209,112,111,115,116,255,181,0,161,0,0,10,92,0,0,0,32,0, 1,0,0,0,1,0,0,76,64,104,233,95,15,60,245,0,3,3,232,0,0,0,0,198,13,26,212,0,0,0,0,198,13,26,212,255,28,255,16,3,109,3,139,0,0,0,3,0,2,0,0,0,0,0,0,0,1,0,0,3,144,254,224,0,200,2,138,255,28,255,29,3,109,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,80,0,1,105, @@ -3193,10 +4064,10 @@ static const unsigned char temp_binary_data_9[] = 0,50,0,140,0,162,0,54,0,165,0,168,0,77,0,179,0,184,0,81,0,208,0,209,0,87,0,214,0,214,0,89,0,224,1,6,0,90,1,8,1,8,0,129,1,13,1,13,0,130,0,1,0,26,0,3,0,13,0,20,0,24,0,25,0,26,0,27,0,52,0,55,0,56,0,61,0,62,0,67,0,68,0,69,0,70,0,134,0,135,0,136,0,137,0,138, 0,139,0,163,0,164,0,169,1,7,0,0 }; -const char* cpmono_plain_otf = (const char*) temp_binary_data_9; +const char* cpmono_plain_otf = (const char*) temp_binary_data_11; //================== miso-bold.ttf ================== -static const unsigned char temp_binary_data_10[] = +static const unsigned char temp_binary_data_12[] = { 0,1,0,0,0,17,1,0,0,4,0,16,76,84,83,72,237,157,221,60,0,0,5,108,0,0,0,227,79,83,47,50,81,16,250,27,0,0,1,152,0,0,0,86,86,68,77,88,108,156,116,37,0,0,231,220,0,0,5,224,99,109,97,112,117,108,128,122,0,0,26,212,0,0,6,164,99,118,116,32,0,20,0,0,0,0,34,224, 0,0,0,2,102,112,103,109,50,77,115,102,0,0,33,120,0,0,1,98,103,108,121,102,122,237,74,59,0,0,34,228,0,0,184,220,104,100,109,120,139,147,218,195,0,0,6,80,0,0,20,132,104,101,97,100,230,15,38,231,0,0,1,28,0,0,0,54,104,104,101,97,6,202,7,163,0,0,1,84,0,0, 0,36,104,109,116,120,82,131,27,122,0,0,1,240,0,0,3,124,107,101,114,110,23,5,21,255,0,0,221,128,0,0,4,68,108,111,99,97,100,35,145,228,0,0,219,192,0,0,1,192,109,97,120,112,2,241,2,157,0,0,1,120,0,0,0,32,110,97,109,101,215,203,101,65,0,0,225,196,0,0,3,225, @@ -3880,10 +4751,10 @@ static const unsigned char temp_binary_data_10[] = 255,203,0,239,0,212,255,203,0,240,0,213,255,203,0,241,0,214,255,202,0,242,0,215,255,202,0,243,0,216,255,202,0,244,0,217,255,202,0,245,0,218,255,202,0,246,0,218,255,201,0,247,0,219,255,201,0,248,0,220,255,201,0,249,0,221,255,201,0,250,0,222,255,201,0, 251,0,223,255,200,0,252,0,224,255,200,0,253,0,225,255,200,0,254,0,226,255,200,0,255,0,226,255,199,0,0 }; -const char* misobold_ttf = (const char*) temp_binary_data_10; +const char* misobold_ttf = (const char*) temp_binary_data_12; //================== miso-light.ttf ================== -static const unsigned char temp_binary_data_11[] = +static const unsigned char temp_binary_data_13[] = { 0,1,0,0,0,17,1,0,0,4,0,16,76,84,83,72,109,206,108,252,0,0,5,108,0,0,0,227,79,83,47,50,79,98,250,86,0,0,1,152,0,0,0,86,86,68,77,88,108,201,116,87,0,0,229,68,0,0,5,224,99,109,97,112,117,108,128,122,0,0,26,212,0,0,6,164,99,118,116,32,0,20,0,0,0,0,34,224, 0,0,0,2,102,112,103,109,50,77,115,102,0,0,33,120,0,0,1,98,103,108,121,102,9,54,37,173,0,0,34,228,0,0,182,56,104,100,109,120,120,118,213,147,0,0,6,80,0,0,20,132,104,101,97,100,230,13,38,194,0,0,1,28,0,0,0,54,104,104,101,97,6,201,7,195,0,0,1,84,0,0,0,36, 104,109,116,120,82,124,51,141,0,0,1,240,0,0,3,124,107,101,114,110,23,5,21,255,0,0,218,220,0,0,4,68,108,111,99,97,249,219,39,62,0,0,217,28,0,0,1,192,109,97,120,112,2,241,2,188,0,0,1,120,0,0,0,32,110,97,109,101,174,204,29,32,0,0,223,32,0,0,3,240,112,111, @@ -4549,10 +5420,10 @@ static const unsigned char temp_binary_data_11[] = 203,0,243,0,216,255,203,0,244,0,217,255,203,0,245,0,218,255,202,0,246,0,218,255,202,0,247,0,219,255,202,0,248,0,220,255,202,0,249,0,221,255,201,0,250,0,222,255,201,0,251,0,223,255,201,0,252,0,224,255,201,0,253,0,225,255,201,0,254,0,226,255,200,0,255, 0,226,255,200,0,0 }; -const char* misolight_ttf = (const char*) temp_binary_data_11; +const char* misolight_ttf = (const char*) temp_binary_data_13; //================== miso-regular.ttf ================== -static const unsigned char temp_binary_data_12[] = +static const unsigned char temp_binary_data_14[] = { 0,1,0,0,0,17,1,0,0,4,0,16,76,84,83,72,96,206,125,196,0,0,5,108,0,0,0,227,79,83,47,50,79,197,250,61,0,0,1,152,0,0,0,86,86,68,77,88,108,201,116,86,0,0,225,224,0,0,5,224,99,109,97,112,117,108,128,122,0,0,26,212,0,0,6,164,99,118,116,32,0,20,0,0,0,0,34,224, 0,0,0,2,102,112,103,109,50,77,115,102,0,0,33,120,0,0,1,98,103,108,121,102,144,118,127,194,0,0,34,228,0,0,179,20,104,100,109,120,123,104,215,146,0,0,6,80,0,0,20,132,104,101,97,100,230,14,38,213,0,0,1,28,0,0,0,54,104,104,101,97,6,189,7,195,0,0,1,84,0,0, 0,36,104,109,116,120,82,124,40,229,0,0,1,240,0,0,3,124,107,101,114,110,23,5,21,255,0,0,215,184,0,0,4,68,108,111,99,97,156,38,200,236,0,0,213,248,0,0,1,192,109,97,120,112,2,241,2,186,0,0,1,120,0,0,0,32,110,97,109,101,65,189,188,90,0,0,219,252,0,0,3,174, @@ -5216,10 +6087,10 @@ static const unsigned char temp_binary_data_12[] = 0,206,255,208,0,236,0,207,255,207,0,237,0,207,255,207,0,238,0,208,255,207,0,239,0,209,255,207,0,240,0,210,255,207,0,241,0,211,255,206,0,242,0,212,255,206,0,243,0,213,255,206,0,244,0,214,255,206,0,245,0,214,255,206,0,246,0,215,255,205,0,247,0,216,255, 205,0,248,0,217,255,205,0,249,0,218,255,205,0,250,0,219,255,205,0,251,0,220,255,204,0,252,0,220,255,204,0,253,0,221,255,204,0,254,0,222,255,204,0,255,0,223,255,203,0,0 }; -const char* misoregular_ttf = (const char*) temp_binary_data_12; +const char* misoregular_ttf = (const char*) temp_binary_data_14; //================== miso-serialized ================== -static const unsigned char temp_binary_data_13[] = +static const unsigned char temp_binary_data_15[] = { 120,156,236,221,11,252,253,197,180,63,254,79,244,237,170,139,164,123,73,55,116,165,146,240,221,239,175,168,148,75,95,145,144,16,187,143,67,246,231,155,173,155,131,82,169,164,72,233,34,149,110,18,37,183,82,74,159,253,222,137,238,36,33,169,164,66,116,145, 20,161,19,254,243,124,205,222,31,250,31,231,156,56,156,195,227,119,122,60,62,205,250,238,247,204,154,153,53,51,107,214,90,179,102,205,139,223,188,219,174,19,19,19,231,156,250,226,57,171,78,252,161,64,243,77,28,59,103,195,102,222,228,163,70,233,163,71, 233,252,163,116,214,40,93,96,148,46,56,74,23,26,165,11,143,210,69,70,233,162,163,244,49,163,116,177,81,186,248,40,93,98,148,46,57,74,31,59,74,151,26,165,143,27,165,75,143,210,199,143,210,101,70,233,178,163,116,185,81,186,252,40,93,97,148,174,56,74,87, @@ -6270,10 +7141,10 @@ static const unsigned char temp_binary_data_13[] = 219,114,86,91,239,25,109,89,219,189,161,215,207,60,247,238,205,109,203,166,45,119,111,203,250,157,123,151,118,230,189,119,251,157,251,182,245,247,109,219,239,219,214,223,183,212,95,163,80,149,125,75,61,229,188,222,155,243,251,188,182,254,188,182,254, 188,182,254,188,82,223,122,206,43,245,149,251,181,245,246,107,235,237,215,214,219,175,212,91,173,244,183,95,169,167,124,91,91,239,109,109,189,203,123,251,166,252,89,91,222,212,150,255,15,63,201,76,247,0,0 }; -const char* misoserialized = (const char*) temp_binary_data_13; +const char* misoserialized = (const char*) temp_binary_data_15; //================== nordic.ttf ================== -static const unsigned char temp_binary_data_14[] = +static const unsigned char temp_binary_data_16[] = { 0,1,0,0,0,14,0,128,0,3,0,96,79,83,47,50,123,137,164,77,0,0,1,136,0,0,0,86,99,109,97,112,54,197,178,209,0,0,31,240,0,0,1,202,99,118,116,32,15,192,16,0,0,0,26,184,0,0,2,0,102,112,103,109,1,82,156,24,0,0,28,184,0,0,0,179,103,97,115,112,0,23,0,6,0,0,26,168, 0,0,0,16,103,108,121,102,108,103,13,174,0,0,40,168,0,0,51,44,104,101,97,100,98,133,67,155,0,0,0,236,0,0,0,54,104,104,101,97,6,68,3,192,0,0,1,36,0,0,0,36,104,109,116,120,180,81,19,127,0,0,37,52,0,0,3,116,108,111,99,97,0,33,207,92,0,0,33,188,0,0,3,120, 109,97,120,112,24,248,0,170,0,0,1,72,0,0,0,32,110,97,109,101,185,229,179,231,0,0,1,224,0,0,24,198,112,111,115,116,255,163,0,48,0,0,1,104,0,0,0,32,112,114,101,112,15,37,62,165,0,0,29,108,0,0,2,130,0,1,0,0,0,5,0,0,166,84,57,97,95,15,60,245,0,1,4,0,0,0, @@ -6514,10 +7385,10 @@ static const unsigned char temp_binary_data_14[] = 6,7,6,39,53,54,55,51,22,23,185,30,74,27,4,1,23,86,22,3,204,31,74,27,4,2,22,86,22,4,2,126,88,56,12,28,214,22,3,3,22,86,88,56,12,28,214,22,3,3,22,0,0,0,2,0,50,1,226,1,133,2,237,0,10,0,21,0,3,0,48,49,19,6,7,6,39,53,54,55,51,22,31,1,6,7,6,39,53,54,55,51, 22,23,185,30,74,27,4,1,23,86,22,3,204,31,74,27,4,2,22,86,22,4,2,126,88,56,12,28,214,22,3,3,22,86,88,56,12,28,214,22,3,3,22,0,0,0,0 }; -const char* nordic_ttf = (const char*) temp_binary_data_14; +const char* nordic_ttf = (const char*) temp_binary_data_16; //================== ostrich.ttf ================== -static const unsigned char temp_binary_data_15[] = +static const unsigned char temp_binary_data_17[] = { 0,1,0,0,0,16,1,0,0,4,0,0,70,70,84,77,91,245,3,49,0,0,1,12,0,0,0,28,71,68,69,70,0,172,0,3,0,0,1,40,0,0,0,32,79,83,47,50,147,188,109,12,0,0,1,72,0,0,0,96,99,109,97,112,43,226,86,187,0,0,1,168,0,0,1,162,99,118,116,32,13,119,11,140,0,0,3,76,0,0,0,34,102, 112,103,109,15,180,47,167,0,0,3,112,0,0,2,101,103,97,115,112,0,0,0,16,0,0,5,216,0,0,0,8,103,108,121,102,143,7,37,77,0,0,5,224,0,0,69,164,104,101,97,100,248,105,156,174,0,0,75,132,0,0,0,54,104,104,101,97,11,58,5,41,0,0,75,188,0,0,0,36,104,109,116,120, 102,145,6,220,0,0,75,224,0,0,1,252,108,111,99,97,36,35,54,72,0,0,77,220,0,0,1,0,109,97,120,112,1,156,1,252,0,0,78,220,0,0,0,32,110,97,109,101,44,100,71,147,0,0,78,252,0,0,2,6,112,111,115,116,68,107,181,125,0,0,81,4,0,0,1,187,112,114,101,112,2,242,181, @@ -6769,10 +7640,10 @@ static const unsigned char temp_binary_data_15[] = 32,69,176,3,43,68,176,12,32,69,186,0,11,127,255,0,2,43,177,3,70,118,43,68,176,13,32,69,178,12,9,2,43,177,3,70,118,43,68,176,14,32,69,178,13,8,2,43,177,3,70,118,43,68,176,15,32,69,186,0,14,1,56,0,2,43,177,3,70,118,43,68,176,16,32,69,178,15,7,2,43,177, 3,70,118,43,68,89,176,20,43,0,0,0,0 }; -const char* ostrich_ttf = (const char*) temp_binary_data_15; +const char* ostrich_ttf = (const char*) temp_binary_data_17; //================== silkscreen-serialized ================== -static const unsigned char temp_binary_data_16[] = +static const unsigned char temp_binary_data_18[] = { 120,156,237,155,7,148,20,69,16,134,215,156,48,39,80,84,204,57,160,120,162,48,123,42,98,206,120,230,132,99,171,200,238,170,140,162,24,49,97,206,57,231,128,57,158,1,238,206,132,1,195,153,21,207,128,17,179,232,138,138,9,39,117,119,245,116,207,78,47,252, 199,221,170,188,199,123,205,78,239,215,213,85,213,85,93,53,203,128,65,133,193,158,59,132,177,82,46,151,235,217,165,95,125,143,220,20,127,52,131,255,55,87,95,42,246,26,57,185,175,63,26,94,8,6,254,227,150,66,145,77,204,139,65,240,200,45,142,27,59,62,239, 63,31,93,8,6,19,242,125,90,252,217,195,28,49,8,30,185,108,70,56,113,38,56,113,102,56,113,22,56,113,86,56,113,54,56,113,118,56,113,14,56,113,78,56,113,46,56,177,11,156,56,55,156,56,15,156,56,47,156,56,31,156,56,63,156,184,0,156,184,32,156,184,16,156,184, @@ -6807,10 +7678,10 @@ static const unsigned char temp_binary_data_16[] = 2,78,156,0,39,126,9,39,126,5,39,126,13,39,126,3,39,126,11,39,126,7,39,126,15,39,254,0,39,78,132,19,127,132,19,127,130,19,203,112,226,207,112,226,36,56,241,23,56,241,87,56,241,55,56,113,50,156,248,59,156,248,7,156,248,39,156,248,23,156,248,55,156,56,5, 78,12,128,255,0,255,66,227,172,0,0 }; -const char* silkscreenserialized = (const char*) temp_binary_data_16; +const char* silkscreenserialized = (const char*) temp_binary_data_18; //================== silkscreen.ttf ================== -static const unsigned char temp_binary_data_17[] = +static const unsigned char temp_binary_data_19[] = { 0,1,0,0,0,15,0,48,0,3,0,192,79,83,47,50,121,166,129,146,0,0,64,208,0,0,0,78,80,67,76,84,173,52,110,22,0,0,65,32,0,0,0,54,99,109,97,112,198,58,142,190,0,0,61,32,0,0,2,4,99,118,116,32,7,83,8,77,0,0,64,172,0,0,0,36,102,112,103,109,152,92,220,162,0,0,3,224, 0,0,0,100,103,108,121,102,48,157,174,66,0,0,4,152,0,0,54,18,104,100,109,120,137,166,202,30,0,0,65,88,0,0,6,72,104,101,97,100,213,88,95,61,0,0,0,252,0,0,0,54,104,104,101,97,2,213,6,14,0,0,1,52,0,0,0,36,104,109,116,120,44,25,4,90,0,0,63,36,0,0,1,136,108, 111,99,97,0,10,37,204,0,0,58,172,0,0,1,140,109,97,120,112,1,9,0,219,0,0,1,88,0,0,0,32,110,97,109,101,63,98,60,192,0,0,1,120,0,0,2,103,112,111,115,116,9,71,9,62,0,0,60,56,0,0,0,230,112,114,101,112,5,176,112,7,0,0,4,68,0,0,0,83,0,1,0,0,0,1,0,0,124,56,31, @@ -7017,10 +7888,10 @@ static const unsigned char temp_binary_data_17[] = 14,16,19,16,16,16,16,14,14,16,16,8,16,16,14,19,19,16,16,16,16,16,14,16,19,19,19,19,14,11,14,11,14,16,11,16,16,16,16,14,14,16,16,8,16,16,14,19,19,16,16,16,16,16,14,16,19,19,19,19,14,14,8,14,16,24,20,12,0,11,11,9,14,20,17,20,17,9,11,11,20,20,9,14,6,14, 17,14,17,17,17,17,17,17,17,17,6,9,14,14,14,17,20,17,17,17,17,14,14,17,17,9,17,17,14,20,20,17,17,17,17,17,14,17,20,20,20,20,14,11,14,11,14,17,11,17,17,17,17,14,14,17,17,9,17,17,14,20,20,17,17,17,17,17,14,17,20,20,20,20,14,14,9,14,17,0,0 }; -const char* silkscreen_ttf = (const char*) temp_binary_data_17; +const char* silkscreen_ttf = (const char*) temp_binary_data_19; //================== floppy5.png ================== -static const unsigned char temp_binary_data_18[] = +static const unsigned char temp_binary_data_20[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,64,0,0,0,64,8,6,0,0,0,170,105,113,222,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119, 119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,3,13,73,68,65,84,120,156,237,155,59,104,84,65,20,134,191,63,49,74,16,37,17,148,40,8,66,132,8,134,20,90,88,88,8,6,162,101,42,43,107,77,99,103,163,24,176,80,172,44,13,248,168,148, 96,107,229,163,16,17,37,18,196,66,48,160,4,19,27,45,20,68,124,129,143,229,88,236,10,203,238,206,102,247,206,185,153,13,123,63,152,102,103,231,156,127,254,157,217,189,59,15,153,25,221,76,79,106,1,169,41,12,72,45,32,53,133,1,169,5,164,38,104,128,164,62, @@ -7035,10 +7906,10 @@ static const unsigned char temp_binary_data_18[] = 128,164,9,224,25,112,56,38,86,236,151,224,32,112,181,34,42,50,84,26,66,35,32,243,34,99,135,18,236,79,200,128,218,163,106,107,157,112,127,34,111,140,172,133,210,244,198,72,179,109,167,62,202,55,53,22,168,191,198,178,22,202,18,48,3,12,54,219,94,83,113, 117,182,203,41,12,72,45,32,53,93,111,192,63,131,88,78,60,241,11,118,138,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* floppy5_png = (const char*) temp_binary_data_18; +const char* floppy5_png = (const char*) temp_binary_data_20; //================== upload2.png ================== -static const unsigned char temp_binary_data_19[] = +static const unsigned char temp_binary_data_21[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,64,0,0,0,54,8,6,0,0,0,119,18,159,2,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,8,220,0,0,8,220,1,159,232,95,60,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119, 119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,3,121,73,68,65,84,104,129,237,154,207,75,20,97,24,199,63,207,160,32,146,150,73,97,102,217,33,36,131,32,2,15,66,116,48,45,162,14,97,183,144,58,21,20,20,70,16,65,29,138,46,25,69,81,7, 17,253,3,10,36,8,66,147,78,218,143,75,135,220,234,102,135,172,67,73,84,27,5,9,229,62,29,118,214,86,155,217,221,217,125,223,153,17,247,11,207,97,153,247,249,190,223,231,59,239,190,243,206,251,142,168,42,81,65,68,174,2,168,234,249,168,52,84,68,209,169, @@ -7054,10 +7925,10 @@ static const unsigned char temp_binary_data_19[] = 138,204,229,234,54,197,151,133,201,10,32,97,129,184,26,184,36,34,47,12,241,181,185,156,166,145,16,85,69,68,190,1,171,44,116,16,103,36,85,181,46,51,91,219,24,5,113,71,2,254,237,9,218,152,7,226,142,73,40,27,192,178,255,11,100,214,216,14,48,142,217,117, 118,156,99,28,112,230,95,135,93,19,154,129,100,12,196,217,142,36,208,188,96,67,36,203,132,22,224,10,48,21,3,161,166,99,202,173,173,37,187,230,191,60,246,55,101,129,175,33,100,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* upload2_png = (const char*) temp_binary_data_19; +const char* upload2_png = (const char*) temp_binary_data_21; //================== ArduinoIcon.png ================== -static const unsigned char temp_binary_data_20[] = +static const unsigned char temp_binary_data_22[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,6,47,0,0,4,111,8,6,0,0,0,96,133,119,144,0,0,0,9,112,72,89,115,0,0,46,35,0,0,46,35,1,120,165,63,118,0,0,10,79,105,67,67,80,80,104,111,116,111,115,104,111,112,32,73,67,67,32,112,114,111,102,105,108,101, 0,0,120,218,157,83,103,84,83,233,22,61,247,222,244,66,75,136,128,148,75,111,82,21,8,32,82,66,139,128,20,145,38,42,33,9,16,74,136,33,161,217,21,81,193,17,69,69,4,27,200,160,136,3,142,142,128,140,21,81,44,12,138,10,216,7,228,33,162,142,131,163,136,138, 202,251,225,123,163,107,214,188,247,230,205,254,181,215,62,231,172,243,157,179,207,7,192,8,12,150,72,51,81,53,128,12,169,66,30,17,224,131,199,196,198,225,228,46,64,129,10,36,112,0,16,8,179,100,33,115,253,35,1,0,248,126,60,60,43,34,192,7,190,0,1,120,211, @@ -7846,10 +8717,10 @@ static const unsigned char temp_binary_data_20[] = 223,255,212,213,121,32,27,7,166,188,232,223,182,138,0,0,0,0,0,32,99,109,205,214,129,253,183,63,255,249,207,94,222,126,236,75,57,185,187,67,8,23,75,2,0,0,0,0,32,163,252,123,8,225,191,255,169,171,243,68,54,14,206,157,23,76,13,33,108,19,3,0,0,0,0,64,198, 248,117,8,97,92,182,22,23,33,184,243,130,147,190,148,147,59,46,132,48,51,132,240,223,165,1,0,0,0,0,16,73,39,66,8,91,255,212,213,249,84,182,15,244,255,63,0,215,70,173,194,31,62,235,52,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* ArduinoIcon_png = (const char*) temp_binary_data_20; +const char* ArduinoIcon_png = (const char*) temp_binary_data_22; //================== OpenEphysBoardLogoBlack.png ================== -static const unsigned char temp_binary_data_21[] = +static const unsigned char temp_binary_data_23[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,7,115,0,0,5,27,8,6,0,0,0,52,231,138,245,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, 97,100,121,113,201,101,60,0,0,140,165,73,68,65,84,120,218,236,221,209,149,19,71,162,199,225,54,231,30,29,233,9,54,2,228,8,152,141,96,180,17,120,110,4,200,17,236,108,4,30,71,176,16,129,69,4,59,68,176,34,2,102,34,176,136,224,194,147,116,244,194,173,178, 122,188,44,6,3,51,211,221,127,73,223,119,78,185,13,6,117,119,169,103,95,126,91,213,223,189,127,255,190,33,195,104,60,121,84,14,39,237,47,103,31,252,167,217,71,127,116,90,198,99,51,6,0,0,0,0,0,192,87,122,83,198,234,163,223,91,126,226,223,175,182,155,245, @@ -8323,10 +9194,10 @@ static const unsigned char temp_binary_data_21[] = 38,188,253,43,192,21,222,214,75,152,155,65,10,120,183,225,238,40,149,248,181,93,188,0,0,0,0,0,0,228,118,87,109,194,218,69,42,243,248,20,220,54,79,152,91,152,116,76,115,188,135,119,148,74,245,197,215,187,226,247,220,209,11,0,0,0,0,0,192,215,196,99,144, 23,247,124,127,177,243,253,237,215,183,235,213,242,218,144,149,227,255,1,23,88,237,144,160,48,169,201,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* OpenEphysBoardLogoBlack_png = (const char*) temp_binary_data_21; +const char* OpenEphysBoardLogoBlack_png = (const char*) temp_binary_data_23; //================== OpenEphysBoardLogoGray.png ================== -static const unsigned char temp_binary_data_22[] = +static const unsigned char temp_binary_data_24[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,7,115,0,0,5,27,8,6,0,0,0,52,231,138,245,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, 97,100,121,113,201,101,60,0,0,139,144,73,68,65,84,120,218,236,221,223,117,220,198,193,198,97,68,39,247,100,7,98,42,16,115,133,75,174,43,16,191,10,180,174,192,76,5,166,43,8,85,129,86,21,132,170,32,171,203,185,50,89,65,168,14,168,10,242,13,188,160,163, 40,148,197,63,11,224,197,238,243,156,51,134,100,75,11,96,22,204,205,47,51,248,211,191,255,253,239,134,12,165,148,195,122,56,238,127,187,248,226,63,45,190,250,163,71,117,188,52,99,0,0,0,0,0,0,60,208,167,58,110,190,250,119,235,123,126,125,213,182,237,173, @@ -8797,10 +9668,10 @@ static const unsigned char temp_binary_data_22[] = 194,221,105,190,210,239,85,241,2,0,0,0,0,0,80,218,125,179,13,107,55,249,90,167,187,224,182,127,194,220,202,228,109,154,211,57,188,211,124,53,127,249,253,190,244,103,206,232,5,0,0,0,0,0,224,107,210,54,200,155,7,254,124,179,247,231,187,223,223,133,16,110, 12,89,61,254,7,181,146,230,16,82,63,166,171,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* OpenEphysBoardLogoGray_png = (const char*) temp_binary_data_22; +const char* OpenEphysBoardLogoGray_png = (const char*) temp_binary_data_24; //================== RadioButtons-01.png ================== -static const unsigned char temp_binary_data_23[] = +static const unsigned char temp_binary_data_25[] = { 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, @@ -8814,10 +9685,10 @@ static const unsigned char temp_binary_data_23[] = 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* RadioButtons01_png = (const char*) temp_binary_data_23; +const char* RadioButtons01_png = (const char*) temp_binary_data_25; //================== RadioButtons-02.png ================== -static const unsigned char temp_binary_data_24[] = +static const unsigned char temp_binary_data_26[] = { 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, @@ -8831,10 +9702,10 @@ static const unsigned char temp_binary_data_24[] = 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* RadioButtons02_png = (const char*) temp_binary_data_24; +const char* RadioButtons02_png = (const char*) temp_binary_data_26; //================== RadioButtons-03.png ================== -static const unsigned char temp_binary_data_25[] = +static const unsigned char temp_binary_data_27[] = { 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, @@ -8846,10 +9717,10 @@ static const unsigned char temp_binary_data_25[] = 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* RadioButtons03_png = (const char*) temp_binary_data_25; +const char* RadioButtons03_png = (const char*) temp_binary_data_27; //================== RadioButtons-04.png ================== -static const unsigned char temp_binary_data_26[] = +static const unsigned char temp_binary_data_28[] = { 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, @@ -8862,10 +9733,10 @@ static const unsigned char temp_binary_data_26[] = 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* RadioButtons04_png = (const char*) temp_binary_data_26; +const char* RadioButtons04_png = (const char*) temp_binary_data_28; //================== RadioButtons-05.png ================== -static const unsigned char temp_binary_data_27[] = +static const unsigned char temp_binary_data_29[] = { 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,10,79,105,67,67,80,80,104,111,116,111,115,104,111,112,32,73,67,67,32,112,114,111,102,105,108,101,0, 0,120,218,157,83,103,84,83,233,22,61,247,222,244,66,75,136,128,148,75,111,82,21,8,32,82,66,139,128,20,145,38,42,33,9,16,74,136,33,161,217,21,81,193,17,69,69,4,27,200,160,136,3,142,142,128,140,21,81,44,12,138,10,216,7,228,33,162,142,131,163,136,138,202, 251,225,123,163,107,214,188,247,230,205,254,181,215,62,231,172,243,157,179,207,7,192,8,12,150,72,51,81,53,128,12,169,66,30,17,224,131,199,196,198,225,228,46,64,129,10,36,112,0,16,8,179,100,33,115,253,35,1,0,248,126,60,60,43,34,192,7,190,0,1,120,211,11, @@ -8917,10 +9788,10 @@ static const unsigned char temp_binary_data_27[] = 162,63,207,207,191,252,78,47,76,49,6,14,15,19,62,191,243,5,198,88,140,57,95,51,207,205,73,170,147,228,66,176,16,240,240,225,99,176,159,49,24,68,52,91,17,113,60,230,203,175,118,209,74,32,4,164,153,37,207,237,84,135,186,200,254,53,213,207,44,73,224,94, 237,224,164,117,254,119,192,197,96,131,206,243,127,62,241,255,97,121,158,163,163,104,72,171,217,188,84,112,20,13,17,213,106,245,211,23,241,3,249,115,0,245,214,95,36,216,96,243,208,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* RadioButtons05_png = (const char*) temp_binary_data_27; +const char* RadioButtons05_png = (const char*) temp_binary_data_29; //================== RadioButtons_neutral-01.png ================== -static const unsigned char temp_binary_data_28[] = +static const unsigned char temp_binary_data_30[] = { 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, @@ -8933,10 +9804,10 @@ static const unsigned char temp_binary_data_28[] = 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* RadioButtons_neutral01_png = (const char*) temp_binary_data_28; +const char* RadioButtons_neutral01_png = (const char*) temp_binary_data_30; //================== RadioButtons_neutral-02.png ================== -static const unsigned char temp_binary_data_29[] = +static const unsigned char temp_binary_data_31[] = { 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, @@ -8948,10 +9819,10 @@ static const unsigned char temp_binary_data_29[] = 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* RadioButtons_neutral02_png = (const char*) temp_binary_data_29; +const char* RadioButtons_neutral02_png = (const char*) temp_binary_data_31; //================== RadioButtons_neutral-03.png ================== -static const unsigned char temp_binary_data_30[] = +static const unsigned char temp_binary_data_32[] = { 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, @@ -8961,10 +9832,10 @@ static const unsigned char temp_binary_data_30[] = 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* RadioButtons_neutral03_png = (const char*) temp_binary_data_30; +const char* RadioButtons_neutral03_png = (const char*) temp_binary_data_32; //================== RadioButtons_neutral-04.png ================== -static const unsigned char temp_binary_data_31[] = +static const unsigned char temp_binary_data_33[] = { 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, @@ -8976,10 +9847,10 @@ static const unsigned char temp_binary_data_31[] = 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* RadioButtons_neutral04_png = (const char*) temp_binary_data_31; +const char* RadioButtons_neutral04_png = (const char*) temp_binary_data_33; //================== RadioButtons_neutral-05.png ================== -static const unsigned char temp_binary_data_32[] = +static const unsigned char temp_binary_data_34[] = { 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,10,79,105,67,67,80,80,104,111,116,111,115,104,111,112,32,73,67,67,32,112,114,111,102,105,108,101,0, 0,120,218,157,83,103,84,83,233,22,61,247,222,244,66,75,136,128,148,75,111,82,21,8,32,82,66,139,128,20,145,38,42,33,9,16,74,136,33,161,217,21,81,193,17,69,69,4,27,200,160,136,3,142,142,128,140,21,81,44,12,138,10,216,7,228,33,162,142,131,163,136,138,202, 251,225,123,163,107,214,188,247,230,205,254,181,215,62,231,172,243,157,179,207,7,192,8,12,150,72,51,81,53,128,12,169,66,30,17,224,131,199,196,198,225,228,46,64,129,10,36,112,0,16,8,179,100,33,115,253,35,1,0,248,126,60,60,43,34,192,7,190,0,1,120,211,11, @@ -9030,10 +9901,10 @@ static const unsigned char temp_binary_data_32[] = 229,42,213,143,142,62,250,227,151,203,24,65,139,24,130,192,255,173,248,237,236,204,95,123,50,69,12,90,68,234,14,193,191,10,17,65,135,229,50,139,153,249,134,130,195,114,25,157,207,187,183,242,121,183,225,63,144,239,3,0,218,200,55,245,184,64,106,163,0, 0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* RadioButtons_neutral05_png = (const char*) temp_binary_data_32; +const char* RadioButtons_neutral05_png = (const char*) temp_binary_data_34; //================== RadioButtons_selected-01.png ================== -static const unsigned char temp_binary_data_33[] = +static const unsigned char temp_binary_data_35[] = { 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, @@ -9046,10 +9917,10 @@ static const unsigned char temp_binary_data_33[] = 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* RadioButtons_selected01_png = (const char*) temp_binary_data_33; +const char* RadioButtons_selected01_png = (const char*) temp_binary_data_35; //================== RadioButtons_selected-02.png ================== -static const unsigned char temp_binary_data_34[] = +static const unsigned char temp_binary_data_36[] = { 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, @@ -9062,10 +9933,10 @@ static const unsigned char temp_binary_data_34[] = 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* RadioButtons_selected02_png = (const char*) temp_binary_data_34; +const char* RadioButtons_selected02_png = (const char*) temp_binary_data_36; //================== RadioButtons_selected-03.png ================== -static const unsigned char temp_binary_data_35[] = +static const unsigned char temp_binary_data_37[] = { 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, @@ -9075,10 +9946,10 @@ static const unsigned char temp_binary_data_35[] = 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* RadioButtons_selected03_png = (const char*) temp_binary_data_35; +const char* RadioButtons_selected03_png = (const char*) temp_binary_data_37; //================== RadioButtons_selected-04.png ================== -static const unsigned char temp_binary_data_36[] = +static const unsigned char temp_binary_data_38[] = { 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, @@ -9091,10 +9962,10 @@ static const unsigned char temp_binary_data_36[] = 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* RadioButtons_selected04_png = (const char*) temp_binary_data_36; +const char* RadioButtons_selected04_png = (const char*) temp_binary_data_38; //================== RadioButtons_selected-05.png ================== -static const unsigned char temp_binary_data_37[] = +static const unsigned char temp_binary_data_39[] = { 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,10,79,105,67,67,80,80,104,111,116,111,115,104,111,112,32,73,67,67,32,112,114,111,102,105,108,101,0, 0,120,218,157,83,103,84,83,233,22,61,247,222,244,66,75,136,128,148,75,111,82,21,8,32,82,66,139,128,20,145,38,42,33,9,16,74,136,33,161,217,21,81,193,17,69,69,4,27,200,160,136,3,142,142,128,140,21,81,44,12,138,10,216,7,228,33,162,142,131,163,136,138,202, 251,225,123,163,107,214,188,247,230,205,254,181,215,62,231,172,243,157,179,207,7,192,8,12,150,72,51,81,53,128,12,169,66,30,17,224,131,199,196,198,225,228,46,64,129,10,36,112,0,16,8,179,100,33,115,253,35,1,0,248,126,60,60,43,34,192,7,190,0,1,120,211,11, @@ -9145,10 +10016,10 @@ static const unsigned char temp_binary_data_37[] = 67,47,42,109,196,133,131,158,216,185,173,106,221,105,147,89,82,137,21,26,39,18,154,254,235,201,213,60,226,64,151,202,198,52,99,235,6,155,222,129,127,54,50,165,90,172,177,249,59,150,208,89,45,165,141,110,69,109,250,195,137,253,157,172,168,141,30,48,99, 15,3,166,34,209,235,207,0,161,143,20,90,35,156,236,45,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* RadioButtons_selected05_png = (const char*) temp_binary_data_37; +const char* RadioButtons_selected05_png = (const char*) temp_binary_data_39; //================== RadioButtons_selected_over-01.png ================== -static const unsigned char temp_binary_data_38[] = +static const unsigned char temp_binary_data_40[] = { 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, @@ -9162,10 +10033,10 @@ static const unsigned char temp_binary_data_38[] = 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* RadioButtons_selected_over01_png = (const char*) temp_binary_data_38; +const char* RadioButtons_selected_over01_png = (const char*) temp_binary_data_40; //================== RadioButtons_selected_over-02.png ================== -static const unsigned char temp_binary_data_39[] = +static const unsigned char temp_binary_data_41[] = { 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, @@ -9179,10 +10050,10 @@ static const unsigned char temp_binary_data_39[] = 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* RadioButtons_selected_over02_png = (const char*) temp_binary_data_39; +const char* RadioButtons_selected_over02_png = (const char*) temp_binary_data_41; //================== RadioButtons_selected_over-03.png ================== -static const unsigned char temp_binary_data_40[] = +static const unsigned char temp_binary_data_42[] = { 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, @@ -9195,10 +10066,10 @@ static const unsigned char temp_binary_data_40[] = 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* RadioButtons_selected_over03_png = (const char*) temp_binary_data_40; +const char* RadioButtons_selected_over03_png = (const char*) temp_binary_data_42; //================== RadioButtons_selected_over-04.png ================== -static const unsigned char temp_binary_data_41[] = +static const unsigned char temp_binary_data_43[] = { 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, @@ -9212,10 +10083,10 @@ static const unsigned char temp_binary_data_41[] = 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* RadioButtons_selected_over04_png = (const char*) temp_binary_data_41; +const char* RadioButtons_selected_over04_png = (const char*) temp_binary_data_43; //================== RadioButtons_selected_over-05.png ================== -static const unsigned char temp_binary_data_42[] = +static const unsigned char temp_binary_data_44[] = { 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,10,79,105,67,67,80,80,104,111,116,111,115,104,111,112,32,73,67,67,32,112,114,111,102,105,108,101,0, 0,120,218,157,83,103,84,83,233,22,61,247,222,244,66,75,136,128,148,75,111,82,21,8,32,82,66,139,128,20,145,38,42,33,9,16,74,136,33,161,217,21,81,193,17,69,69,4,27,200,160,136,3,142,142,128,140,21,81,44,12,138,10,216,7,228,33,162,142,131,163,136,138,202, 251,225,123,163,107,214,188,247,230,205,254,181,215,62,231,172,243,157,179,207,7,192,8,12,150,72,51,81,53,128,12,169,66,30,17,224,131,199,196,198,225,228,46,64,129,10,36,112,0,16,8,179,100,33,115,253,35,1,0,248,126,60,60,43,34,192,7,190,0,1,120,211,11, @@ -9268,10 +10139,10 @@ static const unsigned char temp_binary_data_42[] = 210,38,160,217,252,135,89,141,144,218,222,213,127,69,126,47,211,166,159,227,102,123,180,167,147,214,1,202,239,5,92,241,228,72,133,253,94,128,218,110,134,159,111,55,205,200,111,32,127,13,0,111,180,58,50,205,148,146,75,0,0,0,0,73,69,78,68,174,66,96,130, 0,0 }; -const char* RadioButtons_selected_over05_png = (const char*) temp_binary_data_42; +const char* RadioButtons_selected_over05_png = (const char*) temp_binary_data_44; //================== noise_wave.png ================== -static const unsigned char temp_binary_data_43[] = +static const unsigned char temp_binary_data_45[] = { 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, @@ -9553,10 +10424,10 @@ static const unsigned char temp_binary_data_43[] = 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* noise_wave_png = (const char*) temp_binary_data_43; +const char* noise_wave_png = (const char*) temp_binary_data_45; //================== saw_wave.png ================== -static const unsigned char temp_binary_data_44[] = +static const unsigned char temp_binary_data_46[] = { 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, @@ -9698,10 +10569,10 @@ static const unsigned char temp_binary_data_44[] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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* saw_wave_png = (const char*) temp_binary_data_44; +const char* saw_wave_png = (const char*) temp_binary_data_46; //================== sine_wave.png ================== -static const unsigned char temp_binary_data_45[] = +static const unsigned char temp_binary_data_47[] = { 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, @@ -9874,10 +10745,10 @@ static const unsigned char temp_binary_data_45[] = 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* sine_wave_png = (const char*) temp_binary_data_45; +const char* sine_wave_png = (const char*) temp_binary_data_47; //================== square_wave.png ================== -static const unsigned char temp_binary_data_46[] = +static const unsigned char temp_binary_data_48[] = { 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, @@ -9948,10 +10819,10 @@ static const unsigned char temp_binary_data_46[] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,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* square_wave_png = (const char*) temp_binary_data_46; +const char* square_wave_png = (const char*) temp_binary_data_48; //================== triangle_wave.png ================== -static const unsigned char temp_binary_data_47[] = +static const unsigned char temp_binary_data_49[] = { 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, @@ -10060,10 +10931,10 @@ static const unsigned char temp_binary_data_47[] = 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* triangle_wave_png = (const char*) temp_binary_data_47; +const char* triangle_wave_png = (const char*) temp_binary_data_49; //================== wifi.png ================== -static const unsigned char temp_binary_data_48[] = +static const unsigned char temp_binary_data_50[] = { 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, 97,100,121,113,201,101,60,0,0,12,225,73,68,65,84,120,218,236,221,139,117,27,199,21,128,225,81,5,102,7,70,7,70,7,130,43,8,58,8,84,65,144,10,12,87,0,167,2,56,21,192,169,128,84,5,164,42,32,93,1,169,10,28,236,209,64,130,104,62,0,98,95,51,247,251,207,185, 135,142,148,248,132,187,51,255,222,59,51,187,55,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,109,242,206,37,64,75,92,236,98,250,196,159,79,243,223,157,202,205,46,30,30,253,217,67,254,115,128,0,209,57,123,121,77,114,52, @@ -10113,10 +10984,10 @@ static const unsigned char temp_binary_data_48[] = 242,3,16,82,130,228,7,32,164,4,201,15,64,72,9,146,31,128,144,18,36,63,0,33,37,72,126,0,66,74,144,252,0,132,148,32,249,1,8,41,65,242,3,16,82,130,228,7,32,164,4,201,15,64,72,9,146,31,128,144,18,36,63,0,33,37,72,126,0,66,74,144,252,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,45,252,95,128,1,0,166,155,18,218,219,72,225,153,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* wifi_png = (const char*) temp_binary_data_48; +const char* wifi_png = (const char*) temp_binary_data_50; //================== SourceDrop.png ================== -static const unsigned char temp_binary_data_49[] = +static const unsigned char temp_binary_data_51[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,154,0,0,2,209,8,6,0,0,0,163,255,186,145,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, 97,100,121,113,201,101,60,0,0,24,15,73,68,65,84,120,218,236,157,49,118,219,58,155,64,225,252,234,199,59,120,76,55,93,244,78,154,233,66,173,192,206,10,34,55,108,99,175,64,210,10,226,180,106,44,175,32,206,10,68,151,83,228,68,89,65,152,106,202,167,233,166, 203,224,139,32,255,50,4,82,36,69,144,50,113,239,57,140,98,218,164,36,232,234,3,64,2,31,206,212,137,144,36,201,185,126,24,234,45,214,219,95,122,139,244,38,251,190,206,231,243,105,195,207,181,52,207,211,36,35,253,58,211,6,95,163,188,190,101,133,67,178, @@ -10206,10 +11077,10 @@ static const unsigned char temp_binary_data_49[] = 26,164,75,209,72,34,211,28,63,74,138,38,66,201,96,214,123,31,215,202,78,82,52,153,53,99,58,3,113,133,118,4,84,67,196,90,153,246,239,131,61,5,46,8,209,140,108,43,83,16,183,166,173,177,173,50,183,237,162,119,53,170,131,166,73,95,128,80,217,182,35,165,183, 255,53,143,89,151,98,217,252,191,0,3,0,92,224,0,25,78,103,130,40,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* SourceDrop_png = (const char*) temp_binary_data_49; +const char* SourceDrop_png = (const char*) temp_binary_data_51; //================== DefaultDataSource.png ================== -static const unsigned char temp_binary_data_50[] = +static const unsigned char temp_binary_data_52[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,14,0,0,2,14,8,6,0,0,0,208,187,133,57,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,97, 100,121,113,201,101,60,0,0,54,204,73,68,65,84,120,218,236,221,219,113,27,71,211,198,241,33,234,187,55,51,240,58,2,193,55,46,251,74,171,8,76,69,32,40,2,137,17,144,140,64,100,4,130,34,16,20,129,86,87,118,249,198,80,4,239,58,3,58,131,15,35,244,90,16,5,146, 56,236,244,116,207,252,127,85,44,218,239,129,0,22,187,179,207,246,156,78,2,0,247,254,248,243,175,118,227,95,167,171,159,211,141,127,255,65,254,179,109,78,31,248,239,182,185,93,253,44,31,248,239,63,221,249,247,165,252,127,190,252,127,127,251,245,151,37, @@ -10408,10 +11279,10 @@ static const unsigned char temp_binary_data_50[] = 124,222,248,247,158,65,139,0,193,1,192,126,193,98,168,90,68,177,106,209,200,63,55,193,126,229,98,168,20,12,255,252,175,252,243,80,45,88,50,72,17,32,56,0,200,27,52,54,181,59,252,95,159,110,249,207,134,39,255,135,220,74,24,248,166,114,64,133,0,40,207,255, 11,48,0,82,9,189,51,228,54,205,183,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* DefaultDataSource_png = (const char*) temp_binary_data_50; +const char* DefaultDataSource_png = (const char*) temp_binary_data_52; //================== FileReaderIcon.png ================== -static const unsigned char temp_binary_data_51[] = +static const unsigned char temp_binary_data_53[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,43,0,0,2,165,8,6,0,0,0,10,20,172,128,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,97, 100,121,113,201,101,60,0,0,13,207,73,68,65,84,120,218,236,221,193,109,219,102,24,199,97,167,224,189,217,160,26,33,39,130,60,69,222,32,27,68,217,160,157,64,244,6,217,32,242,4,237,6,97,78,36,120,202,8,234,6,206,4,233,171,194,45,138,130,110,42,231,179,244, 138,126,30,224,3,115,50,132,191,232,234,87,17,65,94,12,227,244,245,234,219,250,171,60,62,37,122,45,159,227,220,101,121,45,109,83,223,93,1,192,194,188,248,159,177,2,23,27,113,113,190,216,69,220,2,98,5,96,9,17,183,143,243,123,162,215,178,207,242,90,34, @@ -10457,10 +11328,10 @@ static const unsigned char temp_binary_data_51[] = 127,254,79,195,56,173,205,12,0,100,141,149,205,253,1,0,120,20,143,129,0,0,177,2,0,32,86,0,0,177,2,0,32,86,0,0,196,10,0,32,86,0,0,196,10,0,32,86,0,0,196,10,0,128,88,1,0,196,10,0,128,88,1,0,196,10,0,128,88,1,0,16,43,0,128,88,1,0,16,43,0,128,88,1,0,16,43, 0,0,98,5,0,16,43,0,0,167,240,135,0,3,0,22,72,102,252,69,115,49,232,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* FileReaderIcon_png = (const char*) temp_binary_data_51; +const char* FileReaderIcon_png = (const char*) temp_binary_data_53; //================== IntanIcon.png ================== -static const unsigned char temp_binary_data_52[] = +static const unsigned char temp_binary_data_54[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,88,0,0,2,88,8,6,0,0,0,190,102,152,220,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, 97,100,121,113,201,101,60,0,0,63,109,73,68,65,84,120,218,236,221,219,117,219,198,162,6,96,56,43,239,155,187,130,208,21,88,126,201,74,158,76,87,96,185,2,83,21,88,170,64,82,5,146,43,16,93,129,229,10,68,63,37,43,47,86,42,48,83,193,81,42,216,7,99,13,19,154, 230,5,131,27,1,242,251,214,194,102,182,197,203,112,0,2,63,102,6,131,39,89,71,252,246,251,31,71,249,67,88,134,249,242,44,95,6,241,79,71,11,255,13,0,240,144,47,247,11,255,253,103,190,204,194,191,253,250,203,207,247,93,40,224,147,29,7,170,227,124,121,145, @@ -10691,72 +11562,37 @@ static const unsigned char temp_binary_data_52[] = 105,213,2,0,154,55,203,151,219,124,121,95,245,202,192,206,6,172,21,97,107,148,47,175,178,199,150,45,115,105,1,0,85,133,57,172,66,144,250,152,47,211,54,67,85,39,2,214,154,192,53,140,97,235,167,236,223,22,174,97,166,181,11,0,248,215,44,46,243,255,254,43, 134,170,217,174,2,213,178,255,23,96,0,208,173,232,3,246,227,153,225,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* IntanIcon_png = (const char*) temp_binary_data_52; +const char* IntanIcon_png = (const char*) temp_binary_data_54; //================== muteoff.png ================== -static const unsigned char temp_binary_data_53[] = -{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,165,0,0,0,119,8,6,0,0,0,98,221,128,254,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, -97,100,121,113,201,101,60,0,0,7,127,73,68,65,84,120,218,236,93,237,141,219,56,16,157,13,238,255,169,131,232,42,136,58,136,174,130,115,42,136,182,3,167,130,213,85,160,77,5,74,7,218,171,64,238,64,78,5,187,169,192,123,21,236,217,128,140,91,24,182,197,33, -135,228,144,126,15,32,2,36,182,98,146,79,111,190,248,65,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,23,119,24,2,49,52,251,246,215,190,21,251,182,221,183,239,251,246,130,97,1,98,224,64,194,105,223,222,78,218,110,223,86,24,30,64,11,33,223,183,10,195,4,132,194,106, -86,195,183,133,182,155,201,11,0,94,213,113,48,32,227,251,214,99,216,128,216,234,120,174,149,24,62,32,182,58,66,45,1,111,168,29,212,49,85,181,172,230,62,227,69,82,168,142,157,16,25,143,173,77,136,144,80,120,133,234,248,44,76,200,183,249,153,41,17,18,196, -204,84,29,83,201,91,86,11,110,74,11,122,228,163,142,167,173,75,144,144,199,214,128,38,249,168,163,102,19,110,74,200,99,33,0,21,170,76,212,81,179,9,31,45,94,42,175,21,170,15,55,76,200,110,158,144,50,210,203,160,5,91,230,231,75,4,62,126,204,213,68,225, -213,241,125,27,148,141,73,111,209,7,172,128,18,66,27,153,140,239,125,51,74,156,152,88,104,146,129,58,106,79,13,21,22,99,52,128,90,105,171,99,10,233,149,130,248,37,213,26,20,75,91,29,99,85,73,142,105,31,147,148,78,77,121,85,169,160,142,140,54,6,38,36, -39,215,200,29,191,53,40,151,174,58,158,182,208,132,228,228,26,57,227,136,160,231,2,214,9,145,49,68,176,179,84,169,153,12,190,31,101,5,84,236,45,182,197,220,249,202,241,77,251,156,168,195,253,101,223,158,60,17,114,52,24,211,199,125,251,182,96,198,31,12, -255,207,215,125,251,99,254,51,73,19,219,37,102,102,125,181,54,130,66,114,146,224,5,241,202,176,73,249,150,197,60,1,207,32,162,247,8,156,187,109,99,201,31,108,114,139,196,143,100,220,129,128,193,34,240,202,98,188,151,94,142,137,50,41,63,174,160,140,209, -202,141,181,197,111,169,23,230,50,249,42,79,7,194,69,79,11,53,194,170,205,17,152,82,155,185,70,0,163,39,45,196,93,100,209,8,145,92,77,192,83,129,144,86,173,118,24,239,221,60,230,133,144,72,44,5,42,166,190,234,164,69,33,17,204,132,91,152,113,26,204,92, -35,38,55,9,190,18,114,203,202,91,48,217,166,57,61,142,83,110,90,30,171,72,79,174,242,82,116,61,8,145,105,20,26,135,168,38,124,80,104,234,6,146,77,95,76,74,72,185,148,238,89,11,89,178,82,32,224,137,22,133,135,174,55,155,110,90,50,153,4,211,65,243,157, -73,24,133,8,121,84,254,242,74,201,80,98,27,112,71,113,211,93,87,81,70,242,35,77,247,77,175,4,204,118,77,58,18,232,156,132,248,40,160,150,207,66,38,60,248,234,250,129,226,5,7,166,102,183,119,248,62,183,238,235,147,148,220,109,176,181,128,234,87,2,81,120, -80,191,178,166,248,149,144,194,146,88,131,178,151,206,164,94,44,149,8,47,133,124,93,211,177,233,111,69,37,185,228,170,45,200,188,34,125,85,157,86,72,45,39,1,5,55,141,37,130,229,43,75,74,47,199,215,49,204,118,12,95,217,20,28,51,222,11,4,167,18,150,50, -8,90,69,164,220,25,38,105,11,70,234,101,140,208,15,31,193,229,37,171,80,146,76,10,78,85,176,163,109,229,143,228,242,175,88,91,42,124,137,194,202,113,14,215,2,60,96,151,81,185,103,9,149,164,239,136,228,90,40,202,171,40,222,49,125,28,53,121,100,124,246, -243,133,191,223,24,126,255,227,149,127,123,241,208,55,43,82,214,164,19,157,163,153,40,40,238,161,77,156,253,73,135,61,48,63,28,231,235,151,0,161,182,30,250,102,69,202,79,164,23,46,164,122,160,180,206,93,252,199,145,84,27,1,66,253,107,248,140,223,125, -147,82,243,196,217,154,95,41,243,31,18,27,199,57,123,21,152,239,87,95,156,177,241,41,53,99,205,116,49,10,74,243,144,166,87,71,243,185,21,248,13,91,95,157,203,141,148,92,51,222,81,186,39,59,188,102,52,103,78,164,76,1,47,140,207,126,191,129,126,130,148, -10,212,227,158,105,130,254,78,180,175,191,40,83,228,70,202,123,166,82,30,208,250,244,143,60,226,19,72,169,31,79,100,127,46,207,61,165,119,6,142,169,47,188,201,157,148,90,59,200,53,219,57,152,241,108,239,179,249,96,49,249,90,205,182,235,111,123,76,72, -85,74,134,82,158,115,103,106,129,249,174,125,113,134,75,202,159,10,39,232,135,161,217,54,137,66,191,36,98,198,87,12,66,188,56,152,126,9,95,251,167,111,82,106,83,146,195,128,127,51,248,220,225,173,30,12,39,241,62,1,82,126,117,36,85,197,32,245,37,124,212, -52,32,169,157,46,241,126,75,68,107,216,199,208,43,235,57,9,252,154,220,183,52,140,228,190,37,194,244,25,77,8,82,14,74,8,105,90,231,62,221,44,85,49,137,172,109,61,37,103,17,114,229,40,44,215,220,132,29,121,90,79,105,131,70,1,33,77,247,127,159,83,149,201, -131,34,133,34,229,138,220,55,164,113,250,85,94,241,207,125,88,1,39,196,62,55,168,118,84,187,214,82,101,99,146,146,123,202,69,235,216,167,157,192,203,17,244,64,130,54,34,33,165,8,85,26,18,97,82,64,74,155,223,113,73,161,76,221,146,94,96,254,199,144,164, -140,117,202,154,164,233,229,28,151,18,187,79,92,63,190,23,48,255,215,2,20,211,23,36,248,246,146,24,155,172,164,131,148,181,2,203,48,10,168,190,233,14,207,81,64,105,11,161,64,201,27,66,30,146,234,195,15,52,221,162,203,157,80,31,187,49,123,199,113,226, -4,39,131,80,176,85,198,32,165,205,77,4,177,205,182,45,41,74,79,125,229,44,74,238,29,198,137,115,212,116,35,240,28,235,235,75,126,115,36,229,118,174,168,248,222,9,184,53,84,202,175,22,207,174,231,223,111,178,62,241,133,228,23,66,112,214,69,222,191,75, -203,113,170,81,53,35,137,125,120,206,211,130,82,154,224,137,34,3,183,65,132,189,117,172,247,20,152,44,5,39,156,28,181,138,251,116,122,16,204,235,177,134,215,198,187,21,12,72,75,129,44,192,142,20,1,196,12,119,59,196,209,66,181,130,233,172,126,193,167, -142,121,189,159,19,26,16,77,76,153,92,115,201,147,224,111,233,40,49,211,125,238,13,197,21,120,113,143,202,227,38,220,59,161,98,201,142,20,163,32,93,199,6,106,108,190,110,125,229,186,81,75,135,201,182,66,228,86,131,18,190,102,208,218,176,141,16,172,132, -84,82,221,189,140,38,228,92,195,172,123,87,21,110,122,110,16,124,222,72,9,227,72,208,129,110,251,62,71,95,7,107,153,90,166,37,179,205,141,222,107,137,31,127,167,204,7,181,173,150,28,190,247,64,233,157,11,244,39,249,219,247,212,27,84,113,150,254,255,145, -65,180,205,252,60,224,68,125,99,156,87,30,106,111,142,180,98,46,169,52,55,233,94,131,130,215,7,51,133,27,117,67,165,78,122,139,228,118,201,28,195,17,180,203,67,53,67,78,100,79,188,106,203,4,149,188,77,213,108,3,143,69,103,24,237,115,163,247,30,52,203, -71,53,53,150,226,26,146,77,186,3,137,169,166,182,201,180,89,176,189,6,173,100,84,83,67,94,244,57,3,66,34,184,17,70,27,153,148,154,252,48,155,157,169,156,189,77,0,83,29,98,169,166,38,127,210,230,24,158,6,244,201,79,53,53,249,147,136,182,161,154,42,125, -49,211,90,249,4,170,228,169,154,90,35,214,37,98,34,253,147,177,106,106,14,16,250,43,132,172,64,141,60,85,51,133,52,202,57,98,214,160,131,46,213,148,92,148,156,74,212,218,35,210,214,141,130,100,14,91,120,78,172,223,107,82,186,43,17,248,31,181,163,106, -182,24,66,64,147,106,154,30,135,13,0,193,84,19,102,16,80,165,154,3,134,10,8,141,134,174,87,64,96,182,129,104,196,220,157,81,72,16,210,2,119,24,2,81,172,102,34,110,136,127,239,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,153,224,63,1,6,0,199,74,112, -188,78,34,32,245,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; - -const char* muteoff_png = (const char*) temp_binary_data_53; +static const unsigned char temp_binary_data_55[] = +{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,36,0,0,0,36,8,6,0,0,0,225,0,152,152,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,0,72,0,0,0,72,0,70,201,107,62,0,0,0,9,118,112,65,103,0,0,0,36,0,0,0,36,0,120,7,27,143,0,0, +1,159,73,68,65,84,88,195,237,151,191,43,70,81,24,199,191,143,228,205,46,165,68,249,49,25,12,36,155,178,40,131,50,51,26,109,12,54,202,36,254,16,98,80,76,98,80,72,202,106,144,196,138,209,207,197,199,224,190,117,122,58,247,250,121,239,85,222,239,116,190, +223,158,115,206,231,158,247,237,222,231,72,53,213,244,7,5,52,150,205,224,129,30,128,13,96,180,44,128,121,231,67,29,2,253,133,194,0,184,236,213,65,61,3,211,133,193,68,128,58,129,37,224,209,129,45,22,2,227,129,130,154,54,224,192,65,205,228,14,147,6,148, +212,86,128,213,160,244,5,232,205,21,38,11,40,153,211,0,236,7,229,39,128,229,6,19,249,15,109,3,45,46,235,0,238,131,41,35,177,61,44,178,233,160,164,161,72,109,151,164,169,52,88,51,179,96,13,36,93,73,26,48,179,219,32,95,150,52,155,216,45,51,27,251,204,41, +204,241,13,185,53,170,218,115,121,123,240,74,120,4,42,126,255,186,31,255,142,217,26,78,78,188,122,138,215,146,206,18,219,40,105,160,104,32,73,26,119,254,52,24,119,148,1,212,237,252,77,48,110,42,3,232,75,42,2,232,220,249,230,96,124,87,6,208,166,243,125, +193,248,178,104,160,29,51,59,174,26,160,93,82,79,98,159,36,157,248,9,245,145,69,142,37,45,69,242,86,73,19,95,128,185,144,52,233,178,176,5,217,53,179,151,31,61,46,176,240,201,23,227,58,208,236,178,78,222,59,201,204,79,199,175,65,125,48,39,159,143,107, +22,84,70,109,5,88,203,173,253,72,131,74,169,233,2,142,28,251,239,55,104,49,40,151,119,3,43,20,217,194,122,40,151,149,211,228,135,80,206,135,42,246,26,148,2,88,238,69,49,2,244,183,174,210,53,253,43,189,1,81,184,172,245,143,151,83,182,0,0,0,0,73,69,78, +68,174,66,96,130,0,0 }; -//================== muteon.png ================== -static const unsigned char temp_binary_data_54[] = -{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,165,0,0,0,119,8,6,0,0,0,98,221,128,254,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, -97,100,121,113,201,101,60,0,0,5,175,73,68,65,84,120,218,236,157,225,113,219,54,20,128,41,95,7,144,39,40,51,65,153,9,66,79,80,101,130,72,19,84,158,32,242,4,106,38,176,55,80,58,129,212,9,228,78,32,101,2,187,19,176,192,9,185,178,172,34,63,146,32,240,32, -126,223,29,207,254,33,203,226,227,167,247,0,16,0,179,12,0,0,0,0,0,0,0,0,0,32,46,19,66,224,135,170,170,230,230,199,175,230,152,154,227,217,28,95,38,147,201,145,200,64,12,25,167,230,216,87,255,231,197,28,51,34,4,90,132,172,83,16,41,8,37,228,204,101,195, -183,176,175,153,18,49,24,58,59,110,170,118,60,18,57,136,157,29,207,145,19,65,136,157,29,201,150,48,152,144,101,143,236,72,182,236,192,13,33,184,152,29,215,230,215,109,118,26,123,244,193,156,200,66,159,236,120,168,252,115,32,186,208,41,59,86,195,194,184, -37,68,207,142,77,214,68,27,52,100,71,74,56,168,203,142,148,112,122,223,34,33,191,247,172,99,12,211,148,168,135,148,117,25,11,59,137,194,252,186,140,248,49,62,160,30,124,23,114,85,233,224,133,171,129,140,133,96,138,25,237,74,202,119,184,236,104,126,216, -114,173,77,2,164,28,155,148,181,182,227,103,165,31,145,118,229,152,164,84,156,29,235,228,232,119,158,201,149,201,104,37,124,76,165,52,78,12,40,120,197,153,210,8,185,76,32,59,158,251,18,65,131,159,34,95,148,169,147,200,30,125,166,135,217,246,89,153,96, -252,109,9,127,70,195,200,82,186,236,240,201,73,52,246,76,97,207,255,43,26,70,144,210,101,196,165,147,145,6,254,191,252,76,8,2,75,89,147,241,183,204,223,236,237,107,130,47,104,200,222,183,219,29,98,77,224,47,242,106,58,224,183,132,33,128,148,110,6,206, -146,240,10,46,0,195,66,195,74,233,202,245,150,14,76,43,222,27,47,233,129,215,184,241,40,100,129,144,157,160,173,61,68,71,167,150,33,9,48,157,157,248,153,50,160,144,15,19,1,230,117,31,219,116,52,204,113,43,120,207,247,72,153,86,249,14,117,175,249,179, -93,83,35,232,56,216,193,104,233,128,244,194,188,254,85,120,142,144,2,246,126,115,224,137,177,7,201,182,122,110,133,226,91,91,173,108,164,35,9,3,159,211,22,147,252,9,153,123,220,99,199,251,186,105,183,67,90,175,61,35,221,106,199,10,41,211,145,114,19,113, -41,193,76,248,25,31,187,254,189,203,182,7,164,76,71,200,50,246,194,171,22,101,252,208,177,108,135,250,210,177,57,193,21,100,201,182,114,149,29,100,158,133,60,17,140,242,211,150,212,194,188,101,103,101,38,60,191,23,164,140,71,151,193,243,185,162,207,111, -101,219,9,158,87,243,96,142,191,221,112,145,100,248,135,155,0,17,153,116,200,148,7,101,3,190,86,202,59,95,67,92,217,105,102,83,216,139,192,164,140,255,112,211,242,162,229,153,190,59,16,165,147,169,175,144,69,12,33,107,255,27,186,72,153,233,93,7,179,238, -115,97,93,231,39,230,93,27,154,11,61,164,252,69,241,185,244,145,202,110,88,64,182,74,84,74,205,23,174,232,178,75,174,187,159,206,132,228,132,165,204,149,159,207,82,50,105,163,81,182,55,104,128,148,154,202,248,154,246,92,250,82,166,192,177,197,107,191, -160,0,82,14,141,157,27,185,144,190,216,173,141,121,64,3,164,28,146,133,224,238,78,83,204,85,198,214,41,72,57,16,95,133,183,17,207,202,236,178,44,36,40,229,238,26,202,54,101,252,186,164,212,154,77,164,107,109,46,137,249,187,226,47,29,82,94,224,47,133, -231,240,36,41,219,194,199,26,127,164,140,83,190,251,98,59,53,247,2,33,203,76,48,72,238,178,237,2,45,18,67,217,99,63,74,193,231,173,47,137,88,9,207,49,244,204,122,6,240,123,74,185,81,34,164,116,85,227,186,237,243,107,2,46,26,99,230,185,39,41,231,10,132, -148,174,255,62,183,192,109,47,60,207,18,41,211,18,243,37,177,178,221,100,213,49,203,34,165,98,41,99,62,227,208,151,80,185,80,236,61,82,166,33,229,52,82,182,244,89,122,183,194,247,42,52,156,19,67,66,178,161,147,24,119,64,22,146,47,76,38,155,190,38,90, -219,19,224,110,15,227,162,158,51,230,62,193,178,221,220,105,35,23,190,239,150,109,91,210,144,178,8,84,198,135,236,49,75,203,248,80,155,20,176,205,96,131,94,59,249,218,210,102,130,122,159,13,191,18,240,89,152,41,63,117,120,239,210,137,241,77,240,218,99, -230,127,157,210,55,52,244,40,165,19,243,201,92,84,187,202,113,200,197,87,243,129,227,48,71,133,196,59,58,103,196,180,217,242,137,112,118,171,2,132,96,0,41,157,152,11,196,164,247,173,74,202,154,152,204,178,105,199,145,16,52,60,26,170,87,158,157,166,138, -229,132,248,205,47,50,155,91,13,153,41,235,189,242,236,244,152,15,150,24,144,37,117,72,233,196,124,117,43,5,223,209,214,68,74,21,82,214,228,60,186,182,166,149,243,158,11,65,207,59,74,155,82,208,230,180,109,77,187,213,243,7,215,238,28,235,142,103,247, -110,193,26,196,150,242,7,162,78,123,200,105,255,206,110,231,151,218,178,130,59,35,229,14,13,149,74,233,41,251,218,219,133,101,66,31,251,182,239,210,96,218,148,154,191,93,167,182,235,157,107,183,166,112,161,95,17,242,202,165,172,201,105,219,104,118,56, -74,123,89,164,147,51,22,41,19,202,154,127,162,223,136,164,76,36,107,146,41,199,142,123,12,116,236,85,152,108,64,48,166,222,119,139,30,186,189,39,31,123,92,212,54,47,222,161,223,8,203,247,15,218,154,26,238,201,239,80,15,206,101,205,34,240,194,183,214, -207,43,135,241,202,185,162,61,9,99,207,154,44,169,165,77,41,106,107,62,7,108,107,254,65,196,65,91,214,204,137,50,104,106,107,82,186,193,75,214,244,185,121,234,156,168,130,15,49,167,158,246,169,60,16,77,240,45,103,217,51,107,174,136,34,104,202,154,7,198, -38,65,91,214,228,14,14,168,202,154,60,228,30,130,203,121,233,105,25,123,202,54,196,20,179,57,87,115,131,144,221,96,31,27,191,114,218,182,163,21,113,215,246,185,227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,112,61,252,35,192,0,171,7,136,102,133,179,227,147,0,0,0, -0,73,69,78,68,174,66,96,130,0,0 }; +const char* muteoff_png = (const char*) temp_binary_data_55; -const char* muteon_png = (const char*) temp_binary_data_54; +//================== muteon.png ================== +static const unsigned char temp_binary_data_56[] = +{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,36,0,0,0,36,8,6,0,0,0,225,0,152,152,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,0,72,0,0,0,72,0,70,201,107,62,0,0,0,9,118,112,65,103,0,0,0,36,0,0,0,36,0,120,7,27,143,0,0, +2,8,73,68,65,84,88,195,237,214,177,107,20,65,20,199,241,223,211,144,144,216,218,40,162,16,17,68,11,49,136,216,152,84,18,180,16,173,44,252,7,98,146,78,11,187,8,86,65,16,4,241,252,11,196,194,74,173,34,22,66,68,17,236,44,44,3,118,10,86,230,162,22,249,90, +100,23,30,207,185,157,59,111,39,141,247,170,217,183,111,118,62,59,187,179,179,210,40,70,81,32,0,3,230,134,232,63,217,54,166,3,108,3,11,255,120,141,77,224,25,112,169,13,208,108,133,161,95,20,176,18,142,125,188,5,206,12,139,90,232,23,5,172,0,132,220,118, +64,253,4,150,139,163,106,76,2,116,20,88,5,186,1,118,183,24,10,24,7,214,82,32,87,115,24,88,15,168,155,37,81,83,53,170,161,255,4,240,212,129,126,1,167,138,163,50,253,199,129,55,14,245,1,176,162,168,80,251,18,56,16,114,211,192,15,135,154,79,141,99,137,129, +207,73,234,245,81,188,38,233,116,93,42,105,209,204,30,39,174,129,164,13,73,103,205,236,155,203,223,147,116,171,58,124,97,102,151,251,153,137,219,244,31,189,86,95,29,175,67,254,136,155,229,46,48,209,54,40,137,242,171,175,154,113,127,238,147,59,119,62, +142,191,39,43,204,135,73,122,20,80,87,36,189,170,218,87,67,253,71,215,158,46,1,250,11,101,102,93,135,58,22,106,191,186,246,254,82,160,38,212,122,168,219,235,218,99,37,65,164,80,102,118,63,212,29,116,237,239,37,65,75,41,84,34,102,92,251,115,254,54,7,95, +101,212,91,7,112,131,134,13,25,56,225,186,108,1,251,226,248,99,9,211,123,73,171,137,252,33,73,215,155,110,198,204,58,213,150,240,208,205,148,220,199,115,67,59,47,250,5,73,107,102,182,57,212,51,1,238,52,205,144,171,91,34,191,33,207,15,46,24,0,149,168, +107,66,77,50,236,230,154,67,245,168,91,102,192,223,225,214,80,61,106,78,2,95,154,182,153,98,168,144,63,14,60,96,231,103,44,187,247,21,65,133,92,252,201,255,13,60,217,213,199,23,142,125,188,3,102,170,252,98,64,205,22,67,5,208,22,240,28,184,24,87,147,67, +117,104,115,165,101,64,83,153,243,115,187,134,25,197,127,23,127,0,12,214,29,49,254,250,119,179,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; + +const char* muteon_png = (const char*) temp_binary_data_56; //================== MergerA-01.png ================== -static const unsigned char temp_binary_data_55[] = +static const unsigned char temp_binary_data_57[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,69,0,0,1,169,8,6,0,0,0,131,16,66,165,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,97, 100,121,113,201,101,60,0,0,21,118,73,68,65,84,120,218,236,221,189,111,93,71,122,7,224,33,205,133,100,55,75,195,69,108,96,131,28,117,74,82,136,238,210,36,190,238,220,45,221,109,170,92,117,73,181,218,46,157,168,191,64,18,130,0,219,241,170,76,37,186,220, 138,87,221,22,73,72,45,16,239,166,226,81,103,87,146,58,17,145,172,204,240,156,107,82,50,181,226,199,189,119,230,156,243,60,192,64,194,98,23,246,190,188,31,63,190,243,158,153,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -10834,10 +11670,10 @@ static const unsigned char temp_binary_data_55[] = 248,195,31,30,43,12,66,17,148,105,26,154,109,180,127,89,116,32,18,138,24,98,32,26,159,252,207,126,241,139,191,60,90,127,252,246,219,240,242,229,255,41,18,66,17,148,97,18,215,111,98,24,186,179,204,71,246,189,163,25,108,32,154,249,139,79,63,13,127,253, 55,127,27,254,251,191,254,83,48,66,40,130,124,82,39,232,183,113,253,99,12,67,15,114,28,238,248,255,2,12,0,160,41,104,168,212,59,220,159,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* MergerA01_png = (const char*) temp_binary_data_55; +const char* MergerA01_png = (const char*) temp_binary_data_57; //================== MergerA-02.png ================== -static const unsigned char temp_binary_data_56[] = +static const unsigned char temp_binary_data_58[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,69,0,0,1,169,8,6,0,0,0,131,16,66,165,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,97, 100,121,113,201,101,60,0,0,21,221,73,68,65,84,120,218,236,221,207,143,220,229,125,192,241,199,6,20,145,3,24,113,104,14,84,76,14,68,42,145,98,71,109,165,68,106,203,112,171,0,41,246,49,39,236,219,70,171,85,234,191,0,175,170,168,205,41,187,26,141,58,55, 102,149,246,18,21,177,72,148,156,130,191,62,1,39,198,28,210,10,34,49,78,140,212,139,221,129,74,56,17,152,246,251,236,124,7,111,28,227,95,187,51,207,243,253,62,175,151,52,26,43,34,96,127,118,215,251,222,231,121,190,223,239,145,0,29,55,24,142,94,174,223, @@ -10917,10 +11753,10 @@ static const unsigned char temp_binary_data_56[] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,7,243,255,2,12,0,244,180,87,201,128,90,137,162,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* MergerA02_png = (const char*) temp_binary_data_56; +const char* MergerA02_png = (const char*) temp_binary_data_58; //================== MergerB-01.png ================== -static const unsigned char temp_binary_data_57[] = +static const unsigned char temp_binary_data_59[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,69,0,0,1,169,8,6,0,0,0,131,16,66,165,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,97, 100,121,113,201,101,60,0,0,22,71,73,68,65,84,120,218,236,221,193,110,92,215,125,192,225,35,195,64,150,97,158,160,147,39,16,253,4,30,111,219,2,161,159,32,163,29,1,130,144,252,4,146,94,160,148,58,24,100,18,47,56,68,187,106,211,74,6,28,103,149,112,180,106, 187,210,72,221,217,5,60,130,232,165,108,102,99,67,128,1,245,156,185,119,68,202,162,109,82,26,206,57,247,222,239,67,47,168,4,110,98,255,69,101,126,60,231,220,123,67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -11001,10 +11837,10 @@ static const unsigned char temp_binary_data_57[] = 90,156,33,18,68,136,34,40,194,36,100,60,119,36,138,232,108,24,185,195,12,81,4,197,154,214,113,52,21,69,112,201,254,254,31,254,241,240,179,63,125,218,55,9,68,17,20,109,30,214,248,42,17,81,68,23,221,138,215,77,99,64,20,65,99,164,67,217,31,94,246,182,218, 187,230,76,199,92,248,185,69,0,100,51,13,107,124,50,182,40,66,16,1,80,154,73,200,240,14,53,81,132,32,2,160,4,199,117,12,221,205,117,247,217,255,11,48,0,4,145,141,135,126,85,212,174,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* MergerB01_png = (const char*) temp_binary_data_57; +const char* MergerB01_png = (const char*) temp_binary_data_59; //================== MergerB-02.png ================== -static const unsigned char temp_binary_data_58[] = +static const unsigned char temp_binary_data_60[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,69,0,0,1,169,8,6,0,0,0,131,16,66,165,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,97, 100,121,113,201,101,60,0,0,18,109,73,68,65,84,120,218,236,221,253,109,28,199,25,192,225,161,97,88,127,90,174,192,231,10,76,87,224,77,5,145,42,48,85,129,237,10,44,86,16,177,2,31,43,200,165,2,175,42,200,169,2,173,42,200,249,207,0,1,156,27,237,94,72,43, 148,248,117,119,243,238,204,243,0,7,25,65,128,216,175,201,240,199,249,216,253,60,65,253,126,221,126,206,140,129,154,125,254,228,137,33,48,87,203,237,231,242,63,255,254,119,95,252,251,200,191,11,4,17,0,71,182,153,98,232,98,27,67,67,152,95,46,252,123,65, @@ -11071,10 +11907,10 @@ static const unsigned char temp_binary_data_58[] = 0,0,68,17,0,128,40,2,0,16,69,0,0,162,8,0,64,20,1,0,136,34,0,0,81,4,0,32,138,0,0,68,17,0,128,40,2,0,16,69,0,0,162,8,0,64,20,1,0,136,34,0,0,81,4,0,32,138,0,0,68,17,0,128,40,2,0,16,69,0,0,162,8,0,64,20,1,0,136,34,0,0,81,4,0,32,138,0,0,68,17,0,128,40,2,0, 16,69,0,0,162,8,0,64,20,1,0,136,34,0,0,81,4,0,32,138,0,0,68,17,0,128,40,2,0,16,69,0,0,181,248,175,0,3,0,94,88,236,111,126,120,246,51,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* MergerB02_png = (const char*) temp_binary_data_58; +const char* MergerB02_png = (const char*) temp_binary_data_60; //================== PipelineA-01.png ================== -static const unsigned char temp_binary_data_59[] = +static const unsigned char temp_binary_data_61[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,49,0,0,1,169,8,6,0,0,0,124,178,103,71,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, 97,100,121,113,201,101,60,0,0,20,161,73,68,65,84,120,218,236,221,77,118,220,198,213,6,224,82,236,121,232,89,102,129,87,96,122,5,106,175,192,202,10,212,90,129,153,21,136,90,1,165,21,176,51,250,134,162,71,223,80,240,10,68,205,50,19,178,2,209,179,204,148, 174,3,180,217,110,145,84,55,8,116,85,1,207,115,78,29,57,63,199,150,47,33,246,203,91,183,80,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,22,190,81,2,128,193,124,92,175,39,235,245,239,245,250,175,114,0,0,165,248,220,173,79,235, @@ -11149,10 +11985,10 @@ static const unsigned char temp_binary_data_59[] = 0,132,24,40,73,28,224,125,17,12,242,2,8,49,80,88,128,137,91,72,6,121,1,132,24,40,138,147,72,0,66,12,20,25,96,174,148,1,64,136,129,210,2,204,74,25,0,132,24,40,201,107,1,6,96,222,188,39,134,18,197,240,242,66,25,0,230,77,39,6,1,6,0,33,6,4,24,0,132,24,16, 96,0,16,98,16,96,0,152,154,111,149,128,204,57,70,13,192,157,116,98,16,96,0,40,210,255,4,24,0,27,12,93,110,21,245,184,159,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* PipelineA01_png = (const char*) temp_binary_data_59; +const char* PipelineA01_png = (const char*) temp_binary_data_61; //================== PipelineA-02.png ================== -static const unsigned char temp_binary_data_60[] = +static const unsigned char temp_binary_data_62[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,49,0,0,1,169,8,6,0,0,0,124,178,103,71,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, 97,100,121,113,201,101,60,0,0,25,18,73,68,65,84,120,218,236,221,191,114,28,199,157,192,241,214,149,67,178,12,101,167,75,52,10,200,84,36,93,133,2,18,97,121,14,233,42,83,145,228,72,96,157,157,185,78,160,99,203,36,66,251,2,146,137,47,228,224,94,64,240,19, 104,20,1,133,132,208,19,104,239,9,4,63,1,111,154,59,123,128,36,252,217,157,253,51,221,51,159,79,213,214,74,182,69,139,63,146,139,47,122,122,166,67,8,225,173,151,87,74,175,91,183,111,191,125,93,254,207,15,71,199,39,247,2,0,92,225,189,230,11,7,36,225,206, @@ -11244,10 +12080,10 @@ static const unsigned char temp_binary_data_60[] = 25,5,136,24,128,212,157,133,243,243,140,198,198,1,34,6,32,117,49,88,28,9,0,34,6,32,27,85,152,172,186,28,26,5,136,24,128,28,148,77,188,156,26,5,136,24,128,212,77,143,4,40,237,119,1,17,3,144,131,24,44,251,110,145,6,17,3,144,139,170,137,151,202,40,64,196, 0,228,160,12,142,4,0,17,3,144,137,24,44,142,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,210,240,127,2,12,0,195,72,32,13,219,83,201,41,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* PipelineA02_png = (const char*) temp_binary_data_60; +const char* PipelineA02_png = (const char*) temp_binary_data_62; //================== PipelineB-01.png ================== -static const unsigned char temp_binary_data_61[] = +static const unsigned char temp_binary_data_63[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,49,0,0,1,169,8,6,0,0,0,124,178,103,71,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, 97,100,121,113,201,101,60,0,0,23,202,73,68,65,84,120,218,236,221,191,111,164,199,125,192,225,177,99,56,141,4,159,75,167,241,186,184,107,69,157,1,130,108,196,85,107,5,208,165,58,5,72,34,30,98,215,186,75,109,231,142,165,227,66,199,198,46,245,242,47,16, 13,196,85,18,248,149,155,93,108,99,10,112,106,189,174,148,146,130,221,43,239,104,223,21,87,247,131,183,187,220,221,153,217,247,121,128,5,37,69,145,229,239,209,224,231,102,230,125,39,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,200, @@ -11334,10 +12170,10 @@ static const unsigned char temp_binary_data_61[] = 175,127,249,203,162,231,100,4,12,0,223,240,55,237,231,137,49,144,218,31,254,240,73,248,235,95,255,18,14,14,14,5,12,0,34,134,178,252,239,159,254,20,254,239,243,207,195,221,31,223,13,223,253,238,223,206,254,114,124,140,250,196,116,0,120,145,47,125,124, 114,250,220,190,115,231,203,255,250,239,255,249,114,52,158,28,251,159,39,0,47,243,255,2,12,0,38,140,193,224,172,166,247,238,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* PipelineB01_png = (const char*) temp_binary_data_61; +const char* PipelineB01_png = (const char*) temp_binary_data_63; //================== PipelineB-02.png ================== -static const unsigned char temp_binary_data_62[] = +static const unsigned char temp_binary_data_64[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,49,0,0,1,169,8,6,0,0,0,124,178,103,71,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, 97,100,121,113,201,101,60,0,0,20,155,73,68,65,84,120,218,236,221,189,122,28,71,118,6,224,162,54,217,141,4,101,155,169,121,5,132,50,103,28,101,206,22,190,130,29,101,206,12,103,206,22,186,2,72,87,192,209,21,16,190,2,54,51,103,4,51,109,132,118,182,142,72, 101,206,184,93,238,30,99,22,4,64,204,95,119,157,238,247,125,158,122,160,213,15,151,60,232,25,124,83,117,170,234,89,74,233,83,130,242,124,108,199,247,237,184,86,10,0,238,243,76,136,161,240,32,243,67,59,174,148,2,0,33,134,136,114,144,89,41,3,0,66,12,130, @@ -11412,7 +12248,7 @@ static const unsigned char temp_binary_data_62[] = 228,45,210,23,73,191,11,0,16,36,196,184,18,0,0,8,21,98,242,146,209,66,105,1,128,8,33,38,247,187,92,38,253,46,0,64,144,16,227,74,0,0,32,84,136,201,253,46,103,202,7,0,68,9,49,185,223,229,84,217,0,128,8,33,102,125,37,64,165,92,0,64,132,16,179,238,119,1, 0,8,17,98,114,191,203,66,105,0,128,40,33,198,149,0,0,64,24,174,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,202,241,119,1,6,0,159,157,76,71,98,187,78,10,0,0,0,0,73,69,78,68,174,66,96,130,0,0 }; -const char* PipelineB02_png = (const char*) temp_binary_data_62; +const char* PipelineB02_png = (const char*) temp_binary_data_64; const char* getNamedResource (const char*, int&) throw(); @@ -11425,6 +12261,8 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw switch (hash) { + case 0x815f42cc: numBytes = 54744; return iconlarge_png; + case 0xf36d5698: numBytes = 5749; return iconsmall_png; case 0x9ad84ff3: numBytes = 15547; return cpmonoblackserialized; case 0x430faa99: numBytes = 16442; return cpmonoboldserialized; case 0x804451da: numBytes = 17136; return cpmonoextralightserialized; @@ -11478,8 +12316,8 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw case 0x6189efd0: numBytes = 14143; return DefaultDataSource_png; case 0x3862b802: numBytes = 3650; return FileReaderIcon_png; case 0xe67215bf: numBytes = 16352; return IntanIcon_png; - case 0xd9760f20: numBytes = 2034; return muteoff_png; - case 0x7b0e8322: numBytes = 1570; return muteon_png; + case 0xd9760f20: numBytes = 532; return muteoff_png; + case 0x7b0e8322: numBytes = 637; return muteon_png; case 0xe26621d2: numBytes = 5609; return MergerA01_png; case 0xe2743953: numBytes = 5712; return MergerA02_png; case 0x174c5d13: numBytes = 5818; return MergerB01_png; @@ -11497,6 +12335,8 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw const char* namedResourceList[] = { + "iconlarge_png", + "iconsmall_png", "cpmonoblackserialized", "cpmonoboldserialized", "cpmonoextralightserialized", diff --git a/JuceLibraryCode/BinaryData.h b/JuceLibraryCode/BinaryData.h index d04b5f37515d246f4567fdb31d1485dbafd0c97a..c63ebb106b7d83cbb03933049e0c19998766607c 100644 --- a/JuceLibraryCode/BinaryData.h +++ b/JuceLibraryCode/BinaryData.h @@ -9,6 +9,12 @@ namespace BinaryData { + extern const char* iconlarge_png; + const int iconlarge_pngSize = 54744; + + extern const char* iconsmall_png; + const int iconsmall_pngSize = 5749; + extern const char* cpmonoblackserialized; const int cpmonoblackserializedSize = 15547; @@ -169,10 +175,10 @@ namespace BinaryData const int IntanIcon_pngSize = 16352; extern const char* muteoff_png; - const int muteoff_pngSize = 2034; + const int muteoff_pngSize = 532; extern const char* muteon_png; - const int muteon_pngSize = 1570; + const int muteon_pngSize = 637; extern const char* MergerA01_png; const int MergerA01_pngSize = 5609; @@ -202,7 +208,7 @@ namespace BinaryData extern const char* namedResourceList[]; // Number of elements in the namedResourceList array. - const int namedResourceListSize = 63; + const int namedResourceListSize = 65; // If you provide the name of one of the binary resource variables above, this function will // return the corresponding data and its size (or a null pointer if the name isn't found). diff --git a/JuceLibraryCode/modules/juce_graphics/image_formats/jpglib/jinclude.h b/JuceLibraryCode/modules/juce_graphics/image_formats/jpglib/jinclude.h index ab660087df5cc8abdad13da2de8c96290c432910..bccfd54422eb5139048dd22ec837d755f5b7e71e 100755 --- a/JuceLibraryCode/modules/juce_graphics/image_formats/jpglib/jinclude.h +++ b/JuceLibraryCode/modules/juce_graphics/image_formats/jpglib/jinclude.h @@ -180,11 +180,16 @@ static const int extend_test[16] = /* entry n is 2**(n-1) */ { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; +#define SHIFTED_BITS_PLUS_ONE(n) (int) (((unsigned int) -1) << n) + 1 + static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ - { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, - ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, - ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, - ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + { 0, + SHIFTED_BITS_PLUS_ONE (1), SHIFTED_BITS_PLUS_ONE (2), SHIFTED_BITS_PLUS_ONE (3), SHIFTED_BITS_PLUS_ONE (4), + SHIFTED_BITS_PLUS_ONE (5), SHIFTED_BITS_PLUS_ONE (6), SHIFTED_BITS_PLUS_ONE (7), SHIFTED_BITS_PLUS_ONE (8), + SHIFTED_BITS_PLUS_ONE (9), SHIFTED_BITS_PLUS_ONE (10), SHIFTED_BITS_PLUS_ONE (11), SHIFTED_BITS_PLUS_ONE (12), + SHIFTED_BITS_PLUS_ONE (13), SHIFTED_BITS_PLUS_ONE (14), SHIFTED_BITS_PLUS_ONE (15) }; + +#undef SHIFTED_BITS_PLUS_ONE #endif /* AVOID_TABLES */ diff --git a/Resources/Icons/icon-large.png b/Resources/Icons/icon-large.png new file mode 100644 index 0000000000000000000000000000000000000000..55e918f72609efd780296abed7f6e527f105676a Binary files /dev/null and b/Resources/Icons/icon-large.png differ diff --git a/Resources/Icons/icon-small.png b/Resources/Icons/icon-small.png new file mode 100644 index 0000000000000000000000000000000000000000..6b8c718906f085ceab439a86d0e68404a832bf19 Binary files /dev/null and b/Resources/Icons/icon-small.png differ diff --git a/Resources/Images/Buttons/muteoff.png b/Resources/Images/Buttons/muteoff.png old mode 100644 new mode 100755 index 826a6321999859a51f78996588d9f93edf0e17f3..05e9dbeedb488ae30eb2139e2a8eca2e2a6e4068 Binary files a/Resources/Images/Buttons/muteoff.png and b/Resources/Images/Buttons/muteoff.png differ diff --git a/Resources/Images/Buttons/muteon.png b/Resources/Images/Buttons/muteon.png old mode 100644 new mode 100755 index 014e5af738bd92f68470619681a8a6619ed08158..9e0e0284d1b0e21c35499b362e99856f75359ce8 Binary files a/Resources/Images/Buttons/muteon.png and b/Resources/Images/Buttons/muteon.png differ diff --git a/Source/CoreServices.cpp b/Source/CoreServices.cpp index 84a668fd697378d7d4e042cf2d1ea5aef302b787..f17620830644cc9276486889f22a137a99c862ed 100644 --- a/Source/CoreServices.cpp +++ b/Source/CoreServices.cpp @@ -107,6 +107,16 @@ void setAppendTextToRecordingDir(String text) getControlPanel()->setAppendText(text); } +String getSelectedRecordEngineId() +{ + return getControlPanel()->getSelectedRecordEngineId(); +} + +bool setSelectedRecordEngineId(String id) +{ + return getControlPanel()->setSelectedRecordEngineId(id); +} + namespace RecordNode { void createNewrecordingDir() @@ -145,7 +155,7 @@ int addSpikeElectrode(SpikeRecordInfo* elec) } }; -PLUGIN_API const char* getApplicationResource(const char* name, int& size) +const char* getApplicationResource(const char* name, int& size) { return BinaryData::getNamedResource(name, size); } diff --git a/Source/CoreServices.h b/Source/CoreServices.h index 4b46d403afc7ba1d76aefeeecc221147d6487962..b8e254d4a6bdcd85e5e3001b685077b25d145614 100644 --- a/Source/CoreServices.h +++ b/Source/CoreServices.h @@ -78,6 +78,14 @@ PLUGIN_API void setPrependTextToRecordingDir(String text); /** Manually set the text to be appended to the recording directory */ PLUGIN_API void setAppendTextToRecordingDir(String text); +/** Gets the ID fo the selected Record Engine*/ +PLUGIN_API String getSelectedRecordEngineId(); + +/** Sets a specific RecordEngine to be used based on its id. +Return true if there is an engine with the specified ID and it's possible to +change the current engine or false otherwise. */ +PLUGIN_API bool setSelectedRecordEngineId(String id); + namespace RecordNode { /** Forces creation of new directory on recording */ diff --git a/Source/Main.cpp b/Source/Main.cpp index f718d2ce77ebd09d9c76ae123dcdcaaf4af3ad4d..9dc3a1df8b90280e8162ff6bde0489ac8b471465 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -26,7 +26,7 @@ #endif #include "../JuceLibraryCode/JuceHeader.h" #include "MainWindow.h" -#include "UI/CustomLookAndFeel.h" +#include "UI/LookAndFeel/CustomLookAndFeel.h" #include <stdio.h> #include <fstream> diff --git a/Source/Plugins/ArduinoOutput/ArduinoOutput.cpp b/Source/Plugins/ArduinoOutput/ArduinoOutput.cpp index 0c2317d04e4418cecb8f6b737c46b535e7f5aedc..95c911543d6ca4e382de159e80980e5de3beffd9 100644 --- a/Source/Plugins/ArduinoOutput/ArduinoOutput.cpp +++ b/Source/Plugins/ArduinoOutput/ArduinoOutput.cpp @@ -27,7 +27,7 @@ #include <stdio.h> ArduinoOutput::ArduinoOutput() - : GenericProcessor("Arduino Output"), outputChannel(13), inputChannel(-1), state(true), deviceSelected(false), acquisitionIsActive(false) + : GenericProcessor("Arduino Output"), outputChannel(13), inputChannel(-1), state(true), acquisitionIsActive(false), deviceSelected(false) { } diff --git a/Source/Plugins/BasicSpikeDisplay/SpikeDetector/SpikeDetectorEditor.cpp b/Source/Plugins/BasicSpikeDisplay/SpikeDetector/SpikeDetectorEditor.cpp index 34723c468a78725da659ebe889e6fe440da1a06b..50100748ae1862ae74ec306f33bd89d059ee7d2f 100644 --- a/Source/Plugins/BasicSpikeDisplay/SpikeDetector/SpikeDetectorEditor.cpp +++ b/Source/Plugins/BasicSpikeDisplay/SpikeDetector/SpikeDetectorEditor.cpp @@ -383,7 +383,7 @@ void SpikeDetectorEditor::buttonEvent(Button* button) } -void SpikeDetectorEditor::channelChanged(int chan) +void SpikeDetectorEditor::channelChanged (int channel, bool /*newState*/) { if (electrodeEditorButtons[0]->getToggleState()) // editing is active @@ -394,13 +394,13 @@ void SpikeDetectorEditor::channelChanged(int chan) { if (electrodeButtons[i]->getToggleState()) { - electrodeButtons[i]->setChannelNum(chan); + electrodeButtons[i]->setChannelNum (channel); electrodeButtons[i]->repaint(); SpikeDetector* processor = (SpikeDetector*) getProcessor(); processor->setChannel(electrodeList->getSelectedItemIndex(), i, - chan-1); + channel - 1); } } } diff --git a/Source/Plugins/BasicSpikeDisplay/SpikeDetector/SpikeDetectorEditor.h b/Source/Plugins/BasicSpikeDisplay/SpikeDetector/SpikeDetectorEditor.h index 086129d380ae20853eae9a694ae3ab31ea1d631b..07162cd7787d7a516038b5b1a9130f9e0f480cf0 100644 --- a/Source/Plugins/BasicSpikeDisplay/SpikeDetector/SpikeDetectorEditor.h +++ b/Source/Plugins/BasicSpikeDisplay/SpikeDetector/SpikeDetectorEditor.h @@ -58,7 +58,7 @@ public: void comboBoxChanged(ComboBox* comboBox); void sliderEvent(Slider* slider); - void channelChanged(int chan); + void channelChanged (int channel, bool newState) override; bool addElectrode(int nChans, int electrodeID = 0); void removeElectrode(int index); diff --git a/Source/Plugins/BasicSpikeDisplay/SpikeDisplayNode/SpikeDisplayCanvas.cpp b/Source/Plugins/BasicSpikeDisplay/SpikeDisplayNode/SpikeDisplayCanvas.cpp index 6b254dcc5875da4809af8991719bb12b4c5562f6..4fea4b839d22aa3e0a9abc33b5ac11853d4cca8e 100644 --- a/Source/Plugins/BasicSpikeDisplay/SpikeDisplayNode/SpikeDisplayCanvas.cpp +++ b/Source/Plugins/BasicSpikeDisplay/SpikeDisplayNode/SpikeDisplayCanvas.cpp @@ -347,7 +347,8 @@ void SpikeDisplay::resized() int tetrodePlotIndex = -1; int index = -1; - float width, height; + float width = 0; + float height = 0; float maxHeight = 0; @@ -648,11 +649,13 @@ void SpikePlot::resized() float width = getWidth()-10; float height = getHeight()-25; - float axesWidth, axesHeight; + float axesWidth = 0; + float axesHeight = 0; // to compute the axes positions we need to know how many columns of proj and wave axes should exist // using these two values we can calculate the positions of all of the sub axes - int nProjCols, nWaveCols; + int nProjCols = 0; + int nWaveCols = 0; switch (plotType) { diff --git a/Source/Plugins/CAR/CAR.cpp b/Source/Plugins/CAR/CAR.cpp index d4f55305ef326f557eb923900797fb45ef6556af..a57b7ca8c0c72ad03275519d4b0e5d34b761f2bc 100644 --- a/Source/Plugins/CAR/CAR.cpp +++ b/Source/Plugins/CAR/CAR.cpp @@ -1,9 +1,8 @@ - /* ------------------------------------------------------------------ This file is part of the Open Ephys GUI - Copyright (C) 2014 Open Ephys + Copyright (C) 2016 Open Ephys ------------------------------------------------------------------ @@ -22,73 +21,118 @@ */ +#include <stdio.h> +#include "CAR.h" +#include "CAREditor.h" -#include <stdio.h> -#include "CAR.h" - CAR::CAR() - : GenericProcessor("Common Avg Ref") //, threshold(200.0), state(true) - + : GenericProcessor ("Common Avg Ref") //, threshold(200.0), state(true) { + m_avgBuffer = AudioSampleBuffer (1, 10000); // 1-dimensional buffer to hold the avg +} - parameters.add(Parameter("Gain (%)", 0.0, 100.0, 100.0, 0)); - - avgBuffer = AudioSampleBuffer(1,10000); // 1-dimensional buffer to hold the avg +CAR::~CAR() +{ } -CAR::~CAR() + +AudioProcessorEditor* CAR::createEditor() { + editor = new CAREditor (this, true); + return editor; +} + +float CAR::getGainLevel() +{ + m_gainLevel.updateTarget(); + return m_gainLevel.getNextValue(); } +void CAR::setGainLevel (float newGain) +{ + m_gainLevel.setValue (newGain); +} + -void CAR::setParameter(int parameterIndex, float newValue) +void CAR::process (AudioSampleBuffer& buffer, MidiBuffer& events) { - editor->updateParameterButtons(parameterIndex); - // std::cout << "Setting CAR Gain" << std::endl; + const int numSamples = buffer.getNumSamples(); + const int numReferenceChannels = m_referenceChannels.size(); + const int numAffectedChannels = m_affectedChannels.size(); - if (currentChannel >= 0) + // There are no sense to do any processing if either number of reference or affected channels is zero. + if (! numReferenceChannels + || ! numAffectedChannels) { - Parameter& p = parameters.getReference(parameterIndex); - p.setValue(newValue, currentChannel); + return; + } + + m_avgBuffer.clear(); + + for (int i = 0; i < numReferenceChannels; ++i) + { + m_avgBuffer.addFrom (0, // destChannel + 0, // destStartSample + buffer, // source + m_referenceChannels[i], // sourceChannel + 0, // sourceStartSample + numSamples, // numSamples + 1.0f); // gain to apply + } + + m_avgBuffer.applyGain (1.0f / float (numReferenceChannels)); + + m_gainLevel.updateTarget(); + const float gain = -1.0f * m_gainLevel.getNextValue() / 100.f; + + for (int i = 0; i < numAffectedChannels; ++i) + { + buffer.addFrom (m_affectedChannels[i], // destChannel + 0, // destStartSample + m_avgBuffer, // source + 0, // sourceChannel + 0, // sourceStartSample + numSamples, // numSamples + gain); // gain to apply } } -void CAR::process(AudioSampleBuffer& buffer, - MidiBuffer& events) + +void CAR::setReferenceChannels (const Array<int>& newReferenceChannels) { - int nChannels = buffer.getNumChannels(); + const ScopedLock myScopedLock (objectLock); - float gain = -1.0f * float(getParameterVar(0, 0)) / 100.0f; // just use channel 0, since we can't have individual channel settings at the moment + m_referenceChannels = Array<int> (newReferenceChannels); +} - avgBuffer.clear(); - for (int j = 0; j < nChannels; j++) - { - avgBuffer.addFrom(0, // destChannel - 0, // destStartSample - buffer, // source - j, // sourceChannel - 0, // sourceStartSample - buffer.getNumSamples(), // numSamples - 1.0f); // gain to apply - } +void CAR::setAffectedChannels (const Array<int>& newAffectedChannels) +{ + const ScopedLock myScopedLock (objectLock); - avgBuffer.applyGain(1.0f/float(nChannels)); + m_affectedChannels = Array<int> (newAffectedChannels); +} - for (int j = 0; j < nChannels; j++) - { - buffer.addFrom(j, // destChannel - 0, // destStartSample - avgBuffer, // source - 0, // sourceChannel - 0, // sourceStartSample - buffer.getNumSamples(), // numSamples - gain); // gain to apply - } +void CAR::setReferenceChannelState (int channel, bool newState) +{ + if (! newState) + m_referenceChannels.removeFirstMatchingValue (channel); + else + m_referenceChannels.addIfNotAlreadyThere (channel); } + + +void CAR::setAffectedChannelState (int channel, bool newState) +{ + if (! newState) + m_affectedChannels.removeFirstMatchingValue (channel); + else + m_affectedChannels.add (channel); +} + diff --git a/Source/Plugins/CAR/CAR.h b/Source/Plugins/CAR/CAR.h index 99d75f457bf506c4e55818f42b07be9a69e0542d..8f86eb0ce9076e47ae9f7085d2ac6e2ae0d89502 100644 --- a/Source/Plugins/CAR/CAR.h +++ b/Source/Plugins/CAR/CAR.h @@ -2,7 +2,7 @@ ------------------------------------------------------------------ This file is part of the Open Ephys GUI - Copyright (C) 2014 Open Ephys + Copyright (C) 2016 Open Ephys ------------------------------------------------------------------ @@ -36,18 +36,16 @@ This is a simple filter that subtracts the average of all other channels from each channel. The gain parameter allows you to subtract a percentage of the total avg. - See Ludwig et al. 2009 Using a common average reference to improve cortical - neuron recordings from microelectrode arrays. J. Neurophys, 2009 for a detailed - discussion + See Ludwig et al. 2009 Using a common average reference to improve cortical + neuron recordings from microelectrode arrays. J. Neurophys, 2009 for a detailed + discussion + - */ class CAR : public GenericProcessor - { public: - /** The class constructor, used to initialize any members. */ CAR(); @@ -55,16 +53,10 @@ public: ~CAR(); /** Determines whether the processor is treated as a source. */ - bool isSource() - { - return false; - } + bool isSource() override { return false; } /** Determines whether the processor is treated as a sink. */ - bool isSink() - { - return false; - } + bool isSink() override { return false; } /** Defines the functionality of the processor. @@ -78,21 +70,50 @@ public: number of continous samples in the current buffer (which may differ from the size of the buffer). */ - void process(AudioSampleBuffer& buffer, MidiBuffer& events); + void process (AudioSampleBuffer& buffer, MidiBuffer& events) override; + + /** Returns the current gain level that is set in the processor */ + float getGainLevel(); + + /** Sets the new gain level that will be used in the processor */ + void setGainLevel (float newGain); + + /** Creates the CAREditor. */ + AudioProcessorEditor* createEditor() override; - /** Any variables used by the "process" function _must_ be modified only through - this method while data acquisition is active. If they are modified in any - other way, the application will crash. */ - void setParameter(int parameterIndex, float newValue); + Array<int> getReferenceChannels() const { return m_referenceChannels; } + Array<int> getAffectedChannels() const { return m_affectedChannels; } + + void setReferenceChannels (const Array<int>& newReferenceChannels); + void setAffectedChannels (const Array<int>& newAffectedChannels); + + void setReferenceChannelState (int channel, bool newState); + void setAffectedChannelState (int channel, bool newState); - AudioSampleBuffer avgBuffer; private: + LinearSmoothedValueAtomic<float> m_gainLevel; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CAR); + AudioSampleBuffer m_avgBuffer; -}; + /** We should add this for safety to prevent any app crashes or invalid data processing. + Since we use m_referenceChannels and m_affectedChannels arrays in the process() function, + which works in audioThread, we may stumble upon the situation when we start changing + either reference or affected channels by copying array and in the middle of copying process + we will be interrupted by audioThread. So it most probably will lead to app crash or + processing incorrect channels. + */ + CriticalSection objectLock; + /** Array of channels which will be used to calculate mean signal. */ + Array<int> m_referenceChannels; + + /** Array of channels that will be affected by adding/substracting of mean signal of reference channels */ + Array<int> m_affectedChannels; + + // ================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CAR); +}; diff --git a/Source/Plugins/CAR/CAREditor.cpp b/Source/Plugins/CAR/CAREditor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f9f2ed96a1b98a49393b5d320aa0f52aed51255c --- /dev/null +++ b/Source/Plugins/CAR/CAREditor.cpp @@ -0,0 +1,149 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 "CAREditor.h" +#include "CAR.h" +#include "../../UI/LookAndFeel/MaterialButtonLookAndFeel.h" +#include "../../Processors/Parameter/ParameterEditor.h" + + +static const Colour COLOUR_PRIMARY (Colours::black.withAlpha (0.87f)); +static const Colour COLOUR_ACCENT (Colour::fromRGB (3, 169, 244)); + +static const Font FONT_LABELS ("Default", 13.f, Font::plain); + + +CAREditor::CAREditor (GenericProcessor* parentProcessor, bool useDefaultParameterEditors) + : GenericEditor (parentProcessor, useDefaultParameterEditors) + , m_currentChannelsView (REFERENCE_CHANNELS) + , m_channelSelectorButtonManager (new LinearButtonGroupManager) + , m_gainSlider (new ParameterSlider (0.0, 100.0, 100.0, FONT_LABELS)) +{ + TextButton* referenceChannelsButton = new TextButton ("Reference", "Switch to reference channels"); + referenceChannelsButton->setClickingTogglesState (true); + referenceChannelsButton->setToggleState (true, dontSendNotification); + referenceChannelsButton->setColour (TextButton::buttonColourId, Colour (0x0)); + referenceChannelsButton->setColour (TextButton::buttonOnColourId, Colour (0x0)); + referenceChannelsButton->setColour (TextButton::textColourOffId, COLOUR_PRIMARY); + referenceChannelsButton->setColour (TextButton::textColourOnId, COLOUR_ACCENT); + + TextButton* affectedChannelsButton = new TextButton ("Affected", "Switch to affected channels"); + affectedChannelsButton->setClickingTogglesState (true); + affectedChannelsButton->setColour (TextButton::buttonColourId, Colour (0x0)); + affectedChannelsButton->setColour (TextButton::buttonOnColourId, Colour (0x0)); + affectedChannelsButton->setColour (TextButton::textColourOffId, COLOUR_PRIMARY); + affectedChannelsButton->setColour (TextButton::textColourOnId, COLOUR_ACCENT); + + m_channelSelectorButtonManager->addButton (referenceChannelsButton); + m_channelSelectorButtonManager->addButton (affectedChannelsButton); + m_channelSelectorButtonManager->setRadioButtonMode (true); + m_channelSelectorButtonManager->setButtonListener (this); + m_channelSelectorButtonManager->setButtonsLookAndFeel (m_materialButtonLookAndFeel); + m_channelSelectorButtonManager->setColour (ButtonGroupManager::backgroundColourId, Colours::white); + m_channelSelectorButtonManager->setColour (ButtonGroupManager::outlineColourId, Colour (0x0)); + m_channelSelectorButtonManager->setColour (LinearButtonGroupManager::accentColourId, COLOUR_ACCENT); + addAndMakeVisible (m_channelSelectorButtonManager); + + m_gainSlider->setColour (Slider::rotarySliderFillColourId, Colour::fromRGB (255, 193, 7)); + m_gainSlider->setName ("Gain (%)"); + m_gainSlider->addListener (this); + addAndMakeVisible (m_gainSlider); + + channelSelector->paramButtonsToggledByDefault (false); + + setDesiredWidth (280); +} + + +void CAREditor::paint (Graphics& g) +{ + GenericEditor::paint (g); + + // Draw slider's label + // ======================================================================== + g.setColour (Colours::darkgrey); + g.setFont (FONT_LABELS); + + auto gainSliderBounds = m_gainSlider->getBounds(); + g.drawText (m_gainSlider->getName().toUpperCase(), + gainSliderBounds.getX(), gainSliderBounds.getBottom() - 15, + gainSliderBounds.getWidth(), 30, + Justification::centred, + false); + // ======================================================================== +} + + +void CAREditor::resized() +{ + m_channelSelectorButtonManager->setBounds (110, 50, 150, 36); + + m_gainSlider->setBounds (15, 30, 80, 80); + + GenericEditor::resized(); +} + + +void CAREditor::buttonClicked (Button* buttonThatWasClicked) +{ + const String buttonName = buttonThatWasClicked->getName().toLowerCase(); + + // "Reference channels" button clicked + if (buttonName.startsWith ("reference")) + { + channelSelector->setActiveChannels (static_cast<CAR*> (getProcessor())->getReferenceChannels()); + + m_currentChannelsView = REFERENCE_CHANNELS; + } + // "Affected channels" button clicked + else if (buttonName.startsWith ("affected")) + { + channelSelector->setActiveChannels (static_cast<CAR*> (getProcessor())->getAffectedChannels()); + + m_currentChannelsView = AFFECTED_CHANNELS; + } + + GenericEditor::buttonClicked (buttonThatWasClicked); +} + + +void CAREditor::channelChanged (int channel, bool newState) +{ + auto processor = static_cast<CAR*> (getProcessor()); + if (m_currentChannelsView == REFERENCE_CHANNELS) + { + processor->setReferenceChannelState (channel, newState); + } + else + { + processor->setAffectedChannelState (channel, newState); + } +} + + +void CAREditor::sliderEvent (Slider* sliderWhichValueHasChanged) +{ + auto processor = static_cast<CAR*> (getProcessor()); + + processor->setGainLevel ( (float)sliderWhichValueHasChanged->getValue()); +} diff --git a/Source/Plugins/CAR/CAREditor.h b/Source/Plugins/CAR/CAREditor.h new file mode 100644 index 0000000000000000000000000000000000000000..1ba414709264aa15e30c603581cf8839f2f1f490 --- /dev/null +++ b/Source/Plugins/CAR/CAREditor.h @@ -0,0 +1,75 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 <EditorHeaders.h> +#include <UIUtilitiesHeaders.h> + + +class MaterialButtonLookAndFeel; +class ParameterSlider; + + +/** + User interface for CAR Processor. + + @see CAR +*/ +class CAREditor : public GenericEditor +{ +public: + CAREditor (GenericProcessor* parentProcessor, bool useDefaultParameterEditors); + + // Component methods + // ========================================================= + void paint (Graphics& g) override; + void resized() override; + + // Button::Listener methods + // ========================================================== + void buttonClicked (Button* buttonThatWasClicked) override; + + // GenericEditor methods + // ========================================================= + /** This methods is called when any sliders that we are listen for change their values */ + void sliderEvent (Slider* sliderWhichValueHasChanged) override; + void channelChanged (int channel, bool newState) override; + + +private: + enum ChannelsType + { + REFERENCE_CHANNELS = 0, + AFFECTED_CHANNELS + }; + + ChannelsType m_currentChannelsView; + + ScopedPointer<LinearButtonGroupManager> m_channelSelectorButtonManager; + ScopedPointer<ParameterSlider> m_gainSlider; + + // LookAndFeel + SharedResourcePointer<MaterialButtonLookAndFeel> m_materialButtonLookAndFeel; + + // ========================================================= + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CAREditor) +}; diff --git a/Source/Plugins/ChannelMappingNode/ChannelMappingEditor.cpp b/Source/Plugins/ChannelMappingNode/ChannelMappingEditor.cpp index c32b683841d0e6a8b2cfd762e37bba04d1f82b52..9835bb378167da213e81dfa802f6dbf7023586de 100644 --- a/Source/Plugins/ChannelMappingNode/ChannelMappingEditor.cpp +++ b/Source/Plugins/ChannelMappingNode/ChannelMappingEditor.cpp @@ -400,7 +400,10 @@ void ChannelMappingEditor::buttonEvent(Button* button) if (ModifierKeys::getCurrentModifiers().isShiftDown() && (previousClickedChan >= 0)) { - int toChanA,toChanD,fromChanA,fromChanD; + int toChanA = 0; + int toChanD = 0; + int fromChanA = 0; + int fromChanD = 0; if (previousShiftClickedChan < 0) { @@ -609,14 +612,14 @@ void ChannelMappingEditor::setChannelReference(ElectrodeButton* button) } -void ChannelMappingEditor::channelChanged(int chan) +void ChannelMappingEditor::channelChanged (int channel, bool /*newState*/) { - if (!reorderActive) + if (! reorderActive) { - setConfigured(true); - getProcessor()->setCurrentChannel(chan-1); - getProcessor()->setParameter(2,selectedReference); - referenceChannels.set(selectedReference,chan-1); + setConfigured (true); + getProcessor()->setCurrentChannel (channel - 1); + getProcessor()->setParameter (2, selectedReference); + referenceChannels.set (selectedReference, channel - 1); } } diff --git a/Source/Plugins/ChannelMappingNode/ChannelMappingEditor.h b/Source/Plugins/ChannelMappingNode/ChannelMappingEditor.h index be25bf7c68afd02b3f4d7ada4a06e521296ad890..e2b2408b451440d8902ea021f4d17a499b279338 100644 --- a/Source/Plugins/ChannelMappingNode/ChannelMappingEditor.h +++ b/Source/Plugins/ChannelMappingNode/ChannelMappingEditor.h @@ -55,7 +55,7 @@ public: void saveCustomParameters(XmlElement* xml); void loadCustomParameters(XmlElement* xml); - void channelChanged(int chan); + void channelChanged (int channel, bool newState) override; void mouseDrag(const MouseEvent& e); diff --git a/Source/Plugins/EventBroadcaster/Makefile b/Source/Plugins/EventBroadcaster/Makefile index 64235b796ccf7b7bc9e99faa788a2fbb979d61f9..c916381bcc66174e176da18f4d1f0898da744914 100644 --- a/Source/Plugins/EventBroadcaster/Makefile +++ b/Source/Plugins/EventBroadcaster/Makefile @@ -2,7 +2,6 @@ LIBNAME := $(notdir $(CURDIR)) OBJDIR := $(OBJDIR)/$(LIBNAME) TARGET := $(LIBNAME).so -OS := $(shell uname) SRC_DIR := ${shell find ./ -type d -print} VPATH := $(SOURCE_DIRS) @@ -10,10 +9,6 @@ VPATH := $(SOURCE_DIRS) SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cpp)) OBJ := $(addprefix $(OBJDIR)/,$(notdir $(SRC:.cpp=.o))) -ifeq ($(OS),Darwin) -CXXFLAGS := $(CXXFLAGS) -I/opt/local/include -LDFLAGS := $(LDFLAGS) -L/opt/local/lib -endif CXXFLAGS := $(CXXFLAGS) -D "ZEROMQ" LDFLAGS := $(LDFLAGS) -lzmq diff --git a/Source/Plugins/FilterNode/FilterEditor.cpp b/Source/Plugins/FilterNode/FilterEditor.cpp index 29a777f869a680ba7eb6a2825669f34da3f0af63..4983f530ce402900b133799b83b893cee6c21fa5 100644 --- a/Source/Plugins/FilterNode/FilterEditor.cpp +++ b/Source/Plugins/FilterNode/FilterEditor.cpp @@ -162,13 +162,13 @@ void FilterEditor::labelTextChanged(Label* label) } -void FilterEditor::channelChanged(int chan) +void FilterEditor::channelChanged (int channel, bool /*newState*/) { FilterNode* fn = (FilterNode*) getProcessor(); - highCutValue->setText(String(fn->getHighCutValueForChannel(chan)), dontSendNotification); - lowCutValue->setText(String(fn->getLowCutValueForChannel(chan)), dontSendNotification); - applyFilterOnChan->setToggleState(fn->getBypassStatusForChannel(chan), dontSendNotification); + highCutValue->setText (String (fn->getHighCutValueForChannel (channel)), dontSendNotification); + lowCutValue->setText (String (fn->getLowCutValueForChannel (channel)), dontSendNotification); + applyFilterOnChan->setToggleState (fn->getBypassStatusForChannel (channel), dontSendNotification); } diff --git a/Source/Plugins/FilterNode/FilterEditor.h b/Source/Plugins/FilterNode/FilterEditor.h index 2ab56711c588adecabb9acb835709300871ca3d6..79f5df09581ca4773b55429440a03b714201eac4 100644 --- a/Source/Plugins/FilterNode/FilterEditor.h +++ b/Source/Plugins/FilterNode/FilterEditor.h @@ -52,7 +52,7 @@ public: void setDefaults(double lowCut, double highCut); - void channelChanged(int chan); + void channelChanged (int chan, bool newState); private: diff --git a/Source/Plugins/Headers/CoreServicesHeader.h b/Source/Plugins/Headers/CoreServicesHeader.h new file mode 100644 index 0000000000000000000000000000000000000000..49871820b0fb990c587922671f3c341c6b0a977a --- /dev/null +++ b/Source/Plugins/Headers/CoreServicesHeader.h @@ -0,0 +1,29 @@ +/* +------------------------------------------------------------------ + +This file is part of the Open Ephys GUI +Copyright (C) 2013 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/>. + +*/ + +/* +This file references the CoreServices namespace header, in case a plugin type that usually doesn't +access this namespace (FileSource, for example) needs, as a particular case, use its functionality +*/ + +#include "../../CoreServices.h" diff --git a/Source/Plugins/Headers/EditorHeaders.h b/Source/Plugins/Headers/EditorHeaders.h index fda3e9f061dff66e4f106b2718bccefbd387bb17..93565b46bcd66c3ae532ee910e693fdb460f9127 100644 --- a/Source/Plugins/Headers/EditorHeaders.h +++ b/Source/Plugins/Headers/EditorHeaders.h @@ -32,3 +32,6 @@ which should use VisualizerEditorHeaders. #include "../../Processors/Editors/ImageIcon.h" #include "../../Processors/Editors/ElectrodeButtons.h" #include "../../Processors/Editors/ChannelSelector.h" + + + diff --git a/Source/Plugins/Headers/UIUtilitiesHeaders.h b/Source/Plugins/Headers/UIUtilitiesHeaders.h new file mode 100644 index 0000000000000000000000000000000000000000..b22147f43e0b9a2cd6e9cba5ddc7cceb226148cd --- /dev/null +++ b/Source/Plugins/Headers/UIUtilitiesHeaders.h @@ -0,0 +1,28 @@ +/* +------------------------------------------------------------------ + +This file is part of the Open Ephys GUI +Copyright (C) 2016 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/>. + +*/ + +/** + This header contains all needed UI utuility components for plugins. +*/ + +#include "../../UI/Utils/LinearButtonGroupManager.h" diff --git a/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.cpp b/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.cpp index af9c7951489da38569facb3e9714fe33f05eef15..7a626fc82a617e2f2f48ceeb5898e987f07f5a23 100644 --- a/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.cpp +++ b/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.cpp @@ -22,14 +22,14 @@ */ #include <H5Cpp.h> #include "KwikFileSource.h" - +#include <CoreServicesHeader.h> using namespace H5; #define PROCESS_ERROR std::cerr << "KwikFilesource exception: " << error.getCDetailMsg() << std::endl -KWIKFileSource::KWIKFileSource() : samplePos(0) +KWIKFileSource::KWIKFileSource() : samplePos(0), skipRecordEngineCheck(false) { } @@ -247,4 +247,32 @@ void KWIKFileSource::processChannelData(int16* inBuffer, float* outBuffer, int c *(outBuffer+i) = *(inBuffer+(n*i)+channel) * bitVolts; } +} + +bool KWIKFileSource::isReady() +{ + //HDF5 is by default not thread-safe, so we must warn the user. + if ((!skipRecordEngineCheck) && (CoreServices::getSelectedRecordEngineId() == "KWIK")) + { + int res = AlertWindow::showYesNoCancelBox(AlertWindow::WarningIcon, "Record format conflict", + "Both the selected input file for the File Reader and the output file format for recording use the HDF5 library.\n" + "This library is, by default, not thread safe, so running both at the same time might cause unexpected crashes (chances increase with signal complexity and number of recorded channels).\n\n" + "If you have a custom-built hdf5 library with the thread safe features turned on, you can safely continue, but performance will be reduced.\n" + "More information on:\n" + "https://www.hdfgroup.org/HDF5/doc/TechNotes/ThreadSafeLibrary.html\n" + "https://www.hdfgroup.org/hdf5-quest.html\n\n" + "Do you want to continue acquisition?", "Yes", "Yes and don't ask again", "No"); + switch (res) + { + case 2: + skipRecordEngineCheck = true; + case 1: + return true; + break; + default: + return false; + } + } + else + return true; } \ No newline at end of file diff --git a/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.h b/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.h index ba92857e831e7ccb2c86d0b6f1461311b1e665f1..7bacf4964b506f484270b414252f1be35bb6cb1e 100644 --- a/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.h +++ b/Source/Plugins/KWIKFormat/FileSource/KwikFileSource.h @@ -43,20 +43,23 @@ public: KWIKFileSource(); ~KWIKFileSource(); - int readData(int16* buffer, int nSamples); + int readData(int16* buffer, int nSamples) override; - void seekTo(int64 sample); + void seekTo(int64 sample) override; - void processChannelData(int16* inBuffer, float* outBuffer, int channel, int64 numSamples); + void processChannelData(int16* inBuffer, float* outBuffer, int channel, int64 numSamples) override; + + bool isReady() override; private: ScopedPointer<H5::H5File> sourceFile; ScopedPointer<H5::DataSet> dataSet; - bool Open(File file); - void fillRecordInfo(); - void updateActiveRecord(); + bool Open(File file) override; + void fillRecordInfo() override; + void updateActiveRecord() override; int64 samplePos; Array<int> availableDataSets; + bool skipRecordEngineCheck; }; diff --git a/Source/Plugins/KWIKFormat/Makefile b/Source/Plugins/KWIKFormat/Makefile index 7ef684226bf1ce1ca4141d351a7ef481ac19e408..78241817a672f9c25c7105b6f2312a42c2afe75f 100644 --- a/Source/Plugins/KWIKFormat/Makefile +++ b/Source/Plugins/KWIKFormat/Makefile @@ -3,15 +3,8 @@ LIBNAME := $(notdir $(CURDIR)) OBJDIR := $(OBJDIR)/$(LIBNAME) TARGET := $(LIBNAME).so -OS := $(shell uname) - -ifeq ($(OS),Darwin) -CXXFLAGS := $(CXXFLAGS) -I/opt/local/include -LDFLAGS := $(LDFLAGS) -L/opt/local/lib -lhdf5 -lhdf5_cpp -else CXXFLAGS := $(CXXFLAGS) -I/usr/include/hdf5/serial -I/usr/local/hdf5/include LDFLAGS := $(LDFLAGS) -L/usr/lib/x86_64-linux-gnu/hdf5/serial -L/usr/local/hdf5/lib -lhdf5 -lhdf5_cpp -endif SRC_DIR := ${shell find ./ -type d -print} VPATH := $(SOURCE_DIRS) diff --git a/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.cpp b/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.cpp index 46ac97f76d04f2eaeeb361938bbab2939d72830a..76e3387e8fb66972cc1d723b2dd090660195c5ef 100644 --- a/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.cpp +++ b/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.cpp @@ -25,7 +25,7 @@ #include "HDF5FileFormat.h" #ifndef CHUNK_XSIZE -#define CHUNK_XSIZE 640 +#define CHUNK_XSIZE 2048 #endif #ifndef EVENT_CHUNK_SIZE @@ -40,6 +40,10 @@ #define SPIKE_CHUNK_YSIZE 40 #endif +#ifndef TIMESTAMP_CHUNK_SIZE +#define TIMESTAMP_CHUNK_SIZE 16 +#endif + #define MAX_TRANSFORM_SIZE 512 #define MAX_STR_SIZE 256 @@ -97,7 +101,7 @@ int HDF5FileBase::open(bool newfile, int nChans) FileAccPropList props = FileAccPropList::DEFAULT; if (nChans > 0) { - props.setCache(0, 809, 8 * 2 * 640 * nChans, 1); + props.setCache(0, 1667, 2 * 8 * 2 * CHUNK_XSIZE * nChans, 1); //std::cout << "opening HDF5 " << getFileName() << " with nchans: " << nChans << std::endl; } @@ -498,7 +502,7 @@ HDF5RecordingData::HDF5RecordingData(DataSet* data) this->size[2] = 1; this->xChunkSize = chunk[0]; - this->xPos = dims[0]; + this->xPos = 0; this->dSet = dataSet; this->rowXPos.clear(); this->rowXPos.insertMultiple(0,0,this->size[1]); @@ -506,6 +510,8 @@ HDF5RecordingData::HDF5RecordingData(DataSet* data) HDF5RecordingData::~HDF5RecordingData() { + //Safety + dSet->flush(H5F_SCOPE_GLOBAL); } int HDF5RecordingData::writeDataBlock(int xDataSize, HDF5FileBase::DataTypes type, void* data) { @@ -661,6 +667,9 @@ void KWDFile::startNewRecording(int recordingNumber, int nChannels, HDF5Recordin this->multiSample = info->multiSample; uint8 mSample = info->multiSample ? 1 : 0; + ScopedPointer<HDF5RecordingData> bitVoltsSet; + ScopedPointer<HDF5RecordingData> sampleRateSet; + String recordPath = String("/recordings/")+String(recordingNumber); CHECK_ERROR(createGroup(recordPath)); CHECK_ERROR(setAttributeStr(info->name,recordPath,String("name"))); @@ -669,12 +678,29 @@ void KWDFile::startNewRecording(int recordingNumber, int nChannels, HDF5Recordin CHECK_ERROR(setAttribute(F32,&(info->sample_rate),recordPath,String("sample_rate"))); CHECK_ERROR(setAttribute(U32,&(info->bit_depth),recordPath,String("bit_depth"))); CHECK_ERROR(createGroup(recordPath+"/application_data")); - CHECK_ERROR(setAttributeArray(F32,info->bitVolts.getRawDataPointer(),info->bitVolts.size(),recordPath+"/application_data",String("channel_bit_volts"))); + // CHECK_ERROR(setAttributeArray(F32,info->bitVolts.getRawDataPointer(),info->bitVolts.size(),recordPath+"/application_data",String("channel_bit_volts"))); + bitVoltsSet = createDataSet(F32, info->bitVolts.size(), 0, recordPath + "/application_data/channel_bit_volts"); + if (bitVoltsSet.get()) + bitVoltsSet->writeDataBlock(info->bitVolts.size(), F32, info->bitVolts.getRawDataPointer()); + else + std::cerr << "Error creating bitvolts data set" << std::endl; + CHECK_ERROR(setAttribute(U8,&mSample,recordPath+"/application_data",String("is_multiSampleRate_data"))); - CHECK_ERROR(setAttributeArray(F32,info->channelSampleRates.getRawDataPointer(),info->channelSampleRates.size(),recordPath+"/application_data",String("channel_sample_rates"))); + //CHECK_ERROR(setAttributeArray(F32,info->channelSampleRates.getRawDataPointer(),info->channelSampleRates.size(),recordPath+"/application_data",String("channel_sample_rates"))); + sampleRateSet = createDataSet(F32, info->channelSampleRates.size(), 0, recordPath + "/application_data/channel_sample_rates"); + if (sampleRateSet.get()) + sampleRateSet->writeDataBlock(info->channelSampleRates.size(), F32, info->channelSampleRates.getRawDataPointer()); + else + std::cerr << "Error creating sample rates data set" << std::endl; + recdata = createDataSet(I16,0,nChannels,CHUNK_XSIZE,recordPath+"/data"); if (!recdata.get()) std::cerr << "Error creating data set" << std::endl; + + tsData = createDataSet(I64, 0, nChannels, TIMESTAMP_CHUNK_SIZE, recordPath + "/application_data/timestamps"); + if (!tsData.get()) + std::cerr << "Error creating timestamps data set" << std::endl; + curChan = nChannels; } @@ -687,6 +713,7 @@ void KWDFile::stopRecording() CHECK_ERROR(setAttributeArray(U32,samples.getRawDataPointer(),samples.size(),path,"valid_samples")); //ScopedPointer does the deletion and destructors the closings recdata = nullptr; + tsData = nullptr; } int KWDFile::createFileStructure() @@ -712,6 +739,23 @@ void KWDFile::writeRowData(int16* data, int nSamples) curChan++; } +void KWDFile::writeRowData(int16* data, int nSamples, int channel) +{ + if (channel >= 0 && channel < nChannels) + { + CHECK_ERROR(recdata->writeDataRow(channel, nSamples, I16, data)); + curChan = channel; + } +} + +void KWDFile::writeTimestamps(int64* ts, int nTs, int channel) +{ + if (channel >= 0 && channel < nChannels) + { + CHECK_ERROR(tsData->writeDataRow(channel, nTs, I64, ts)); + } +} + //KWE File KWEFile::KWEFile(String basename) : HDF5FileBase() @@ -856,18 +900,17 @@ KWXFile::KWXFile(String basename) : HDF5FileBase() { initFile(basename); numElectrodes=0; - transformVector = new int16[MAX_TRANSFORM_SIZE]; + transformVector.malloc(MAX_TRANSFORM_SIZE); } KWXFile::KWXFile() : HDF5FileBase() { numElectrodes=0; - transformVector = new int16[MAX_TRANSFORM_SIZE]; + transformVector.malloc(MAX_TRANSFORM_SIZE); } KWXFile::~KWXFile() { - delete transformVector; } String KWXFile::getFileName() diff --git a/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.h b/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.h index 1be0343c6c3307ad7567a11c7555cbef9656a5d7..a9ab171d8a715abb1acf231a7d9edb09e2e14dc5 100644 --- a/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.h +++ b/Source/Plugins/KWIKFormat/RecordEngine/HDF5FileFormat.h @@ -127,6 +127,8 @@ public: void stopRecording(); void writeBlockData(int16* data, int nSamples); void writeRowData(int16* data, int nSamples); + void writeRowData(int16* data, int nSamples, int channel); + void writeTimestamps(int64* ts, int nTs, int channel); String getFileName(); protected: @@ -139,6 +141,7 @@ private: String filename; bool multiSample; ScopedPointer<HDF5RecordingData> recdata; + ScopedPointer<HDF5RecordingData> tsData; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWDFile); }; @@ -202,7 +205,8 @@ private: OwnedArray<HDF5RecordingData> timeStamps; Array<int> channelArray; int numElectrodes; - int16* transformVector; + HeapBlock<int16> transformVector; + //int16* transformVector; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWXFile); }; diff --git a/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.cpp b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.cpp index e3b415a5697b9ba7528ae1a0b35b0e951cece675..8ec088422e6d0a87b60a565bf584527e026a1777 100644 --- a/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.cpp +++ b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.cpp @@ -22,22 +22,23 @@ */ #include "HDF5Recording.h" -#define MAX_BUFFER_SIZE 10000 +#define MAX_BUFFER_SIZE 40960 +#define CHANNEL_TIMESTAMP_PREALLOC_SIZE 128 +#define CHANNEL_TIMESTAMP_MIN_WRITE 32 +#define TIMESTAMP_EACH_NSAMPLES 1024 -HDF5Recording::HDF5Recording() : processorIndex(-1), hasAcquired(false) +HDF5Recording::HDF5Recording() : processorIndex(-1), hasAcquired(false), bufferSize(MAX_BUFFER_SIZE) { //timestamp = 0; - scaledBuffer = new float[MAX_BUFFER_SIZE]; - intBuffer = new int16[MAX_BUFFER_SIZE]; + scaledBuffer.malloc(MAX_BUFFER_SIZE); + intBuffer.malloc(MAX_BUFFER_SIZE); } HDF5Recording::~HDF5Recording() -{ - delete scaledBuffer; - delete intBuffer; +{ } -String HDF5Recording::getEngineID() +String HDF5Recording::getEngineID() const { return "KWIK"; } @@ -47,10 +48,12 @@ String HDF5Recording::getEngineID() // this->timestamp = timestamp; // } -void HDF5Recording::registerProcessor(GenericProcessor* proc) +void HDF5Recording::registerProcessor(const GenericProcessor* proc) { HDF5RecordingInfo* info = new HDF5RecordingInfo(); - info->sample_rate = proc->getSampleRate(); + //This is a VERY BAD thig to do. temporary only until we fix const-correctness on GenericEditor methods + //(which implies modifying all the plugins and processors) + info->sample_rate = const_cast<GenericProcessor*>(proc)->getSampleRate(); info->bit_depth = 16; info->multiSample = false; infoArray.add(info); @@ -63,6 +66,9 @@ void HDF5Recording::registerProcessor(GenericProcessor* proc) void HDF5Recording::resetChannels() { + scaledBuffer.malloc(MAX_BUFFER_SIZE); + intBuffer.malloc(MAX_BUFFER_SIZE); + bufferSize = MAX_BUFFER_SIZE; processorIndex = -1; fileArray.clear(); channelsPerProcessor.clear(); @@ -70,11 +76,14 @@ void HDF5Recording::resetChannels() sampleRatesArray.clear(); processorMap.clear(); infoArray.clear(); + recordedChanToKWDChan.clear(); + channelLeftOverSamples.clear(); + channelTimestampArray.clear(); if (spikesFile) spikesFile->resetChannels(); } -void HDF5Recording::addChannel(int index, Channel* chan) +void HDF5Recording::addChannel(int index,const Channel* chan) { processorMap.add(processorIndex); } @@ -94,37 +103,43 @@ void HDF5Recording::openFiles(File rootFolder, int experimentNumber, int recordi //Let's just put the first processor (usually the source node) on the KWIK for now infoArray[0]->name = String("Open Ephys Recording #") + String(recordingNumber); - if (hasAcquired) + /* if (hasAcquired) infoArray[0]->start_time = (*timestamps)[getChannel(0)->sourceNodeId]; //(*timestamps).begin()->first; else - infoArray[0]->start_time = 0; + infoArray[0]->start_time = 0;*/ + infoArray[0]->start_time = getTimestamp(0); infoArray[0]->start_sample = 0; eventFile->startNewRecording(recordingNumber,infoArray[0]); //KWD files - for (int i = 0; i < processorMap.size(); i++) - { - int index = processorMap[i]; - if (getChannel(i)->getRecordState()) - { - if (!fileArray[index]->isOpen()) - { - fileArray[index]->initFile(getChannel(i)->nodeId,basepath); - if (hasAcquired) - infoArray[index]->start_time = (*timestamps)[getChannel(i)->sourceNodeId]; //the timestamps of the first channel - else - infoArray[index]->start_time = 0; - } - channelsPerProcessor.set(index, channelsPerProcessor[index] + 1); - bitVoltsArray[index]->add(getChannel(i)->bitVolts); - sampleRatesArray[index]->add(getChannel(i)->sampleRate); - if (getChannel(i)->sampleRate != infoArray[index]->sample_rate) - { - infoArray[index]->multiSample = true; - } - } - } + recordedChanToKWDChan.clear(); + Array<int> processorRecPos; + processorRecPos.insertMultiple(0, 0, fileArray.size()); + for (int i = 0; i < getNumRecordedChannels(); i++) + { + int index = processorMap[getRealChannel(i)]; + if (!fileArray[index]->isOpen()) + { + fileArray[index]->initFile(getChannel(getRealChannel(i))->nodeId, basepath); + infoArray[index]->start_time = getTimestamp(i); + } + + channelsPerProcessor.set(index, channelsPerProcessor[index] + 1); + bitVoltsArray[index]->add(getChannel(getRealChannel(i))->bitVolts); + sampleRatesArray[index]->add(getChannel(getRealChannel(i))->sampleRate); + if (getChannel(getRealChannel(i))->sampleRate != infoArray[index]->sample_rate) + { + infoArray[index]->multiSample = true; + } + int procPos = processorRecPos[index]; + recordedChanToKWDChan.add(procPos); + processorRecPos.set(index, procPos+1); + channelTimestampArray.add(new Array<int64>); + channelTimestampArray.getLast()->ensureStorageAllocated(CHANNEL_TIMESTAMP_PREALLOC_SIZE); + channelLeftOverSamples.add(0); + } + for (int i = 0; i < fileArray.size(); i++) { if ((!fileArray[i]->isOpen()) && (fileArray[i]->isReadyToOpen())) @@ -160,6 +175,7 @@ void HDF5Recording::closeFiles() { if (fileArray[i]->isOpen()) { + std::cout << "Closed file " << i << std::endl; fileArray[i]->stopRecording(); fileArray[i]->close(); bitVoltsArray[i]->clear(); @@ -167,44 +183,80 @@ void HDF5Recording::closeFiles() } channelsPerProcessor.set(i, 0); } + recordedChanToKWDChan.clear(); + channelTimestampArray.clear(); + channelLeftOverSamples.clear(); + scaledBuffer.malloc(MAX_BUFFER_SIZE); + intBuffer.malloc(MAX_BUFFER_SIZE); + bufferSize = MAX_BUFFER_SIZE; } -void HDF5Recording::writeData(AudioSampleBuffer& buffer) +void HDF5Recording::writeData(int writeChannel, int realChannel, const float* buffer, int size) { -// int64 t1 = Time::getHighResolutionTicks(); - for (int i = 0; i < buffer.getNumChannels(); i++) - { - if (getChannel(i)->getRecordState()) - { + if (size > bufferSize) //Shouldn't happen, and if it happens it'll be slow, but better this than crashing. Will be reset on flie close and reset. + { + std::cerr << "Write buffer overrun, resizing to" << size << std::endl; + bufferSize = size; + scaledBuffer.malloc(size); + intBuffer.malloc(size); + } + double multFactor = 1 / (float(0x7fff) * getChannel(realChannel)->bitVolts); + int index = processorMap[getChannel(realChannel)->recordIndex]; + FloatVectorOperations::copyWithMultiply(scaledBuffer.getData(), buffer, multFactor, size); + AudioDataConverters::convertFloatToInt16LE(scaledBuffer.getData(), intBuffer.getData(), size); + fileArray[index]->writeRowData(intBuffer.getData(), size, recordedChanToKWDChan[writeChannel]); - int sourceNodeId = getChannel(i)->sourceNodeId; - int nSamples = (*numSamples)[sourceNodeId]; + int sampleOffset = channelLeftOverSamples[writeChannel]; + int blockStart = sampleOffset; + int64 currentTS = getTimestamp(realChannel); - double multFactor = 1/(float(0x7fff) * getChannel(i)->bitVolts); - int index = processorMap[getChannel(i)->recordIndex]; - FloatVectorOperations::copyWithMultiply(scaledBuffer,buffer.getReadPointer(i,0),multFactor,nSamples); - AudioDataConverters::convertFloatToInt16LE(scaledBuffer,intBuffer,nSamples); - fileArray[index]->writeRowData(intBuffer,nSamples); - } - } -// int64 t2 = Time::getHighResolutionTicks(); -// std::cout << "record time: " << float(t2 - t1) / float(Time::getHighResolutionTicksPerSecond()) << std::endl; + if (sampleOffset > 0) + { + currentTS += TIMESTAMP_EACH_NSAMPLES - sampleOffset; + blockStart += TIMESTAMP_EACH_NSAMPLES - sampleOffset; + } + + for (int i = 0; i < size; i += TIMESTAMP_EACH_NSAMPLES) + { + if ((blockStart + i) < (sampleOffset + size)) + { + channelTimestampArray[writeChannel]->add(currentTS); + currentTS += TIMESTAMP_EACH_NSAMPLES; + } + } + channelLeftOverSamples.set(writeChannel, (size + sampleOffset) % TIMESTAMP_EACH_NSAMPLES); +} + +void HDF5Recording::endChannelBlock(bool lastBlock) +{ + int nCh = channelTimestampArray.size(); + for (int ch = 0; ch < nCh; ++ch) + { + int tsSize = channelTimestampArray[ch]->size(); + if ((tsSize > 0) && ((tsSize > CHANNEL_TIMESTAMP_MIN_WRITE) || lastBlock)) + { + int realChan = getRealChannel(ch); + int index = processorMap[getChannel(realChan)->recordIndex]; + fileArray[index]->writeTimestamps(channelTimestampArray[ch]->getRawDataPointer(), tsSize, recordedChanToKWDChan[ch]); + channelTimestampArray[ch]->clearQuick(); + } + } } -void HDF5Recording::writeEvent(int eventType, MidiMessage& event, int samplePosition) +void HDF5Recording::writeEvent(int eventType, const MidiMessage& event, int64 timestamp) { const uint8* dataptr = event.getRawData(); if (eventType == GenericProcessor::TTL) - eventFile->writeEvent(0,*(dataptr+2),*(dataptr+1),(void*)(dataptr+3),(*timestamps)[*(dataptr+1)]+samplePosition); + eventFile->writeEvent(0,*(dataptr+2),*(dataptr+1),(void*)(dataptr+3),timestamp); else if (eventType == GenericProcessor::MESSAGE) - eventFile->writeEvent(1,*(dataptr+2),*(dataptr+1),(void*)(dataptr+6),(*timestamps)[*(dataptr+1)]+samplePosition); + eventFile->writeEvent(1,*(dataptr+2),*(dataptr+1),(void*)(dataptr+6),timestamp); } -void HDF5Recording::addSpikeElectrode(int index, SpikeRecordInfo* elec) +void HDF5Recording::addSpikeElectrode(int index, const SpikeRecordInfo* elec) { spikesFile->addChannelGroup(elec->numChannels); } -void HDF5Recording::writeSpike(const SpikeObject& spike, int electrodeIndex) +void HDF5Recording::writeSpike(int electrodeIndex, const SpikeObject& spike, int64 /*timestamp*/) { spikesFile->writeSpike(electrodeIndex,spike.nSamples,spike.data,spike.timestamp); } diff --git a/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h index dc27f26ff37934a868f8f37b0ea677da827410ea..2ffcecae9eb7c3db6a39a6f918b8906da6fa15b7 100644 --- a/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h +++ b/Source/Plugins/KWIKFormat/RecordEngine/HDF5Recording.h @@ -32,18 +32,18 @@ class HDF5Recording : public RecordEngine public: HDF5Recording(); ~HDF5Recording(); - String getEngineID(); - void openFiles(File rootFolder, int experimentNumber, int recordingNumber); - void closeFiles(); - void writeData(AudioSampleBuffer& buffer); - void writeEvent(int eventType, MidiMessage& event, int samplePosition); - void addChannel(int index, Channel* chan); - void addSpikeElectrode(int index, SpikeRecordInfo* elec); - void writeSpike(const SpikeObject& spike, int electrodeIndex); - void registerProcessor(GenericProcessor* processor); - void resetChannels(); - //oid updateTimeStamp(int64 timestamp); - void startAcquisition(); + String getEngineID() const override; + void openFiles(File rootFolder, int experimentNumber, int recordingNumber) override; + void closeFiles() override; + void writeData(int writeChannel, int realChannel, const float* buffer, int size) override; + void writeEvent(int eventType, const MidiMessage& event, int64 timestamp) override; + void addChannel(int index, const Channel* chan) override; + void addSpikeElectrode(int index,const SpikeRecordInfo* elec) override; + void writeSpike(int electrodeIndex, const SpikeObject& spike, int64 timestamp) override; + void registerProcessor(const GenericProcessor* processor) override; + void resetChannels() override; + void startAcquisition() override; + void endChannelBlock(bool lastBlock) override; static RecordEngineManager* getEngineManager(); private: @@ -52,14 +52,20 @@ private: Array<int> processorMap; Array<int> channelsPerProcessor; + Array<int> recordedChanToKWDChan; OwnedArray<Array<float>> bitVoltsArray; OwnedArray<Array<float>> sampleRatesArray; + OwnedArray<Array<int64>> channelTimestampArray; + Array<int> channelLeftOverSamples; OwnedArray<KWDFile> fileArray; OwnedArray<HDF5RecordingInfo> infoArray; ScopedPointer<KWEFile> eventFile; ScopedPointer<KWXFile> spikesFile; - float* scaledBuffer; - int16* intBuffer; + HeapBlock<float> scaledBuffer; + HeapBlock<int16> intBuffer; + int bufferSize; + //float* scaledBuffer; + //int16* intBuffer; bool hasAcquired; diff --git a/Source/Plugins/LfpDisplayNode/OpenEphysLib.cpp b/Source/Plugins/LfpDisplayNode/OpenEphysLib.cpp index d15aa896e714a3f65fa6e2ea0b5152cdf7482ddc..1b1841c81184b5e7f32bee81b8fcea3a51856b24 100644 --- a/Source/Plugins/LfpDisplayNode/OpenEphysLib.cpp +++ b/Source/Plugins/LfpDisplayNode/OpenEphysLib.cpp @@ -48,7 +48,7 @@ extern "C" EXPORT int getPluginInfo(int index, Plugin::PluginInfo* info) { case 0: info->type = Plugin::ProcessorPlugin; - info->processor.name = "LFP viewer"; + info->processor.name = "LFP Viewer"; info->processor.type = Plugin::SinkProcessor; info->processor.creator = &(Plugin::createProcessor<LfpDisplayNode>); break; diff --git a/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayCanvas.cpp b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayCanvas.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f484e2c93c81a54c0aaab5b164201d6c5ab91a1c --- /dev/null +++ b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayCanvas.cpp @@ -0,0 +1,2672 @@ +/* +------------------------------------------------------------------ + +This file is part of the Open Ephys GUI +Copyright (C) 2013 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 "LfpDisplayCanvas.h" + +#include <math.h> + +using namespace LfpDisplayNodeBeta; + +LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) : + timebase(1.0f), displayGain(1.0f), timeOffset(0.0f), + processor(processor_), selectedChannelType(HEADSTAGE_CHANNEL) +{ + + nChans = processor->getNumInputs(); + 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; + + screenBuffer = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP); + screenBuffer->clear(); + + screenBufferMin = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP); + screenBufferMin->clear(); + screenBufferMean = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP); + screenBufferMean->clear(); + screenBufferMax = new AudioSampleBuffer(MAX_N_CHAN, MAX_N_SAMP); + screenBufferMax->clear(); + + viewport = new LfpViewport(this); + lfpDisplay = new LfpDisplay(this, viewport); + timescale = new LfpTimescale(this); + + timescale->setTimebase(timebase); + + viewport->setViewedComponent(lfpDisplay, false); + viewport->setScrollBarsShown(true, false); + + scrollBarThickness = viewport->getScrollBarThickness(); + + isChannelEnabled.insertMultiple(0,true,10000); // max 10k channels + + //viewport->getVerticalScrollBar()->addListener(this->scrollBarMoved(viewport->getVerticalScrollBar(), 1.0)); + + UtilityButton* tbut; + + addAndMakeVisible(viewport); + addAndMakeVisible(timescale); + + //Ranges for neural data + voltageRanges[HEADSTAGE_CHANNEL].add("25"); + voltageRanges[HEADSTAGE_CHANNEL].add("50"); + voltageRanges[HEADSTAGE_CHANNEL].add("100"); + voltageRanges[HEADSTAGE_CHANNEL].add("250"); + voltageRanges[HEADSTAGE_CHANNEL].add("400"); + voltageRanges[HEADSTAGE_CHANNEL].add("500"); + voltageRanges[HEADSTAGE_CHANNEL].add("750"); + voltageRanges[HEADSTAGE_CHANNEL].add("1000"); + voltageRanges[HEADSTAGE_CHANNEL].add("2000"); + voltageRanges[HEADSTAGE_CHANNEL].add("5000"); + voltageRanges[HEADSTAGE_CHANNEL].add("10000"); + voltageRanges[HEADSTAGE_CHANNEL].add("15000"); + selectedVoltageRange[HEADSTAGE_CHANNEL] = 8; + rangeGain[HEADSTAGE_CHANNEL] = 1; //uV + rangeSteps[HEADSTAGE_CHANNEL] = 10; + rangeUnits.add("uV"); + typeNames.add("DATA"); + + tbut = new UtilityButton("DATA",Font("Small Text", 9, Font::plain)); + tbut->setEnabledState(true); + tbut->setCorners(false,false,false,false); + tbut->addListener(this); + tbut->setClickingTogglesState(true); + tbut->setRadioGroupId(100,dontSendNotification); + tbut->setToggleState(true,dontSendNotification); + addAndMakeVisible(tbut); + typeButtons.add(tbut); + + //Ranges for AUX/accelerometer data + voltageRanges[AUX_CHANNEL].add("25"); + voltageRanges[AUX_CHANNEL].add("50"); + voltageRanges[AUX_CHANNEL].add("100"); + voltageRanges[AUX_CHANNEL].add("250"); + voltageRanges[AUX_CHANNEL].add("400"); + voltageRanges[AUX_CHANNEL].add("500"); + voltageRanges[AUX_CHANNEL].add("750"); + voltageRanges[AUX_CHANNEL].add("1000"); + voltageRanges[AUX_CHANNEL].add("2000"); + //voltageRanges[AUX_CHANNEL].add("5000"); + selectedVoltageRange[AUX_CHANNEL] = 9; + rangeGain[AUX_CHANNEL] = 0.001; //mV + rangeSteps[AUX_CHANNEL] = 10; + rangeUnits.add("mV"); + typeNames.add("AUX"); + + + + tbut = new UtilityButton("AUX",Font("Small Text", 9, Font::plain)); + tbut->setEnabledState(true); + tbut->setCorners(false,false,false,false); + tbut->addListener(this); + tbut->setClickingTogglesState(true); + tbut->setRadioGroupId(100,dontSendNotification); + tbut->setToggleState(false,dontSendNotification); + addAndMakeVisible(tbut); + typeButtons.add(tbut); + + //Ranges for ADC data + voltageRanges[ADC_CHANNEL].add("0.01"); + voltageRanges[ADC_CHANNEL].add("0.05"); + voltageRanges[ADC_CHANNEL].add("0.1"); + voltageRanges[ADC_CHANNEL].add("0.5"); + voltageRanges[ADC_CHANNEL].add("1.0"); + voltageRanges[ADC_CHANNEL].add("2.0"); + voltageRanges[ADC_CHANNEL].add("5.0"); + voltageRanges[ADC_CHANNEL].add("10.0"); + selectedVoltageRange[ADC_CHANNEL] = 8; + rangeGain[ADC_CHANNEL] = 1; //V + rangeSteps[ADC_CHANNEL] = 0.1; //in V + rangeUnits.add("V"); + typeNames.add("ADC"); + + tbut = new UtilityButton("ADC",Font("Small Text", 9, Font::plain)); + tbut->setEnabledState(true); + tbut->setCorners(false,false,false,false); + tbut->addListener(this); + tbut->setClickingTogglesState(true); + tbut->setRadioGroupId(100,dontSendNotification); + tbut->setToggleState(false,dontSendNotification); + addAndMakeVisible(tbut); + typeButtons.add(tbut); + + selectedVoltageRangeValues[HEADSTAGE_CHANNEL] = voltageRanges[HEADSTAGE_CHANNEL][selectedVoltageRange[HEADSTAGE_CHANNEL]-1]; + selectedVoltageRangeValues[AUX_CHANNEL] = voltageRanges[AUX_CHANNEL][selectedVoltageRange[AUX_CHANNEL]-1]; + selectedVoltageRangeValues[ADC_CHANNEL] = voltageRanges[ADC_CHANNEL][selectedVoltageRange[ADC_CHANNEL]-1]; + + timebases.add("0.25"); + timebases.add("0.5"); + timebases.add("1.0"); + timebases.add("2.0"); + timebases.add("3.0"); + timebases.add("4.0"); + timebases.add("5.0"); + timebases.add("10.0"); + timebases.add("20.0"); + selectedTimebase = 4; + selectedTimebaseValue = timebases[selectedTimebase-1]; + + spreads.add("10"); + spreads.add("20"); + spreads.add("30"); + spreads.add("40"); + spreads.add("50"); + spreads.add("60"); + spreads.add("70"); + spreads.add("80"); + spreads.add("90"); + spreads.add("100"); + selectedSpread = 5; + selectedSpreadValue = spreads[selectedSpread-1]; + + + overlaps.add("0.5"); + overlaps.add("0.75"); + overlaps.add("1"); + overlaps.add("2"); + overlaps.add("3"); + overlaps.add("4"); + overlaps.add("5"); + selectedOverlap = 4; + selectedOverlapValue = overlaps[selectedOverlap-1]; + + saturationThresholds.add("0.5"); + saturationThresholds.add("100"); + saturationThresholds.add("1000"); + saturationThresholds.add("5000"); + saturationThresholds.add("6389"); + + selectedSaturation = 5; + selectedSaturationValue = saturationThresholds[selectedSaturation-1]; + + + colorGroupings.add("1"); + colorGroupings.add("2"); + colorGroupings.add("4"); + colorGroupings.add("8"); + colorGroupings.add("16"); + + + rangeSelection = new ComboBox("Voltage range"); + rangeSelection->addItemList(voltageRanges[HEADSTAGE_CHANNEL], 1); + rangeSelection->setSelectedId(selectedVoltageRange[HEADSTAGE_CHANNEL], sendNotification); + rangeSelection->setEditableText(true); + rangeSelection->addListener(this); + addAndMakeVisible(rangeSelection); + + + timebaseSelection = new ComboBox("Timebase"); + timebaseSelection->addItemList(timebases, 1); + timebaseSelection->setSelectedId(selectedTimebase, sendNotification); + timebaseSelection->setEditableText(true); + timebaseSelection->addListener(this); + addAndMakeVisible(timebaseSelection); + + + spreadSelection = new ComboBox("Spread"); + spreadSelection->addItemList(spreads, 1); + spreadSelection->setSelectedId(selectedSpread,sendNotification); + spreadSelection->addListener(this); + spreadSelection->setEditableText(true); + addAndMakeVisible(spreadSelection); + + overlapSelection = new ComboBox("Overlap"); + overlapSelection->addItemList(overlaps, 1); + overlapSelection->setSelectedId(selectedOverlap,sendNotification); + overlapSelection->addListener(this); + overlapSelection->setEditableText(true); + addAndMakeVisible(overlapSelection); + + saturationWarningSelection = new ComboBox("Sat.Warn"); + saturationWarningSelection->addItemList(saturationThresholds, 1); + saturationWarningSelection->setSelectedId(selectedSaturation,sendNotification); + saturationWarningSelection->addListener(this); + saturationWarningSelection->setEditableText(true); + addAndMakeVisible(saturationWarningSelection); + + + colorGroupingSelection = new ComboBox("Color Grouping"); + colorGroupingSelection->addItemList(colorGroupings, 1); + colorGroupingSelection->setSelectedId(1,sendNotification); + colorGroupingSelection->addListener(this); + addAndMakeVisible(colorGroupingSelection); + + invertInputButton = new UtilityButton("Invert", Font("Small Text", 13, Font::plain)); + invertInputButton->setRadius(5.0f); + invertInputButton->setEnabledState(true); + invertInputButton->setCorners(true, true, true, true); + invertInputButton->addListener(this); + invertInputButton->setClickingTogglesState(true); + invertInputButton->setToggleState(false, sendNotification); + addAndMakeVisible(invertInputButton); + + //button for controlling drawing algorithm - old line-style or new per-pixel style + drawMethodButton = new UtilityButton("DrawMethod", Font("Small Text", 13, Font::plain)); + drawMethodButton->setRadius(5.0f); + drawMethodButton->setEnabledState(true); + drawMethodButton->setCorners(true, true, true, true); + drawMethodButton->addListener(this); + drawMethodButton->setClickingTogglesState(true); + drawMethodButton->setToggleState(false, sendNotification); + addAndMakeVisible(drawMethodButton); + + // two sliders for the two histogram components of the supersampled plotting mode + // todo: rename these + brightnessSliderA = new Slider; + brightnessSliderA->setRange (0, 1); + brightnessSliderA->setTextBoxStyle(Slider::NoTextBox, false, 50,30); + brightnessSliderA->addListener(this); + addAndMakeVisible (brightnessSliderA); + + brightnessSliderB = new Slider; + brightnessSliderB->setRange (0, 1); + brightnessSliderB->setTextBoxStyle(Slider::NoTextBox, false, 50,30); + brightnessSliderB->addListener(this); + addAndMakeVisible (brightnessSliderB); + + sliderALabel = new Label("Brightness","Brightness"); + sliderALabel->setFont(Font("Small Text", 13, Font::plain)); + sliderALabel->setColour(Label::textColourId,Colour(150,150,150)); + addAndMakeVisible(sliderALabel); + + sliderBLabel = new Label("Min. brightness","Min. brightness"); + sliderBLabel->setFont(Font("Small Text", 13, Font::plain)); + sliderBLabel->setColour(Label::textColourId,Colour(150,150,150)); + addAndMakeVisible(sliderBLabel); + + + //ScopedPointer<UtilityButton> drawClipWarningButton; // optinally draw (subtle) warning if data is clipped in display + drawClipWarningButton = new UtilityButton("0", Font("Small Text", 13, Font::plain)); + drawClipWarningButton->setRadius(5.0f); + drawClipWarningButton->setEnabledState(true); + drawClipWarningButton->setCorners(true, true, true, true); + drawClipWarningButton->addListener(this); + drawClipWarningButton->setClickingTogglesState(true); + drawClipWarningButton->setToggleState(false, sendNotification); + addAndMakeVisible(drawClipWarningButton); + + + //ScopedPointer<UtilityButton> drawSaturateWarningButton; // optionally raise hell if the actual data is saturating + drawSaturateWarningButton = new UtilityButton("0", Font("Small Text", 13, Font::plain)); + drawSaturateWarningButton->setRadius(5.0f); + drawSaturateWarningButton->setEnabledState(true); + drawSaturateWarningButton->setCorners(true, true, true, true); + drawSaturateWarningButton->addListener(this); + drawSaturateWarningButton->setClickingTogglesState(true); + drawSaturateWarningButton->setToggleState(false, sendNotification); + addAndMakeVisible(drawSaturateWarningButton); + + + //button for pausing the display - works by skipping buffer updates. This way scrolling etc still works + pauseButton = new UtilityButton("Pause", Font("Small Text", 13, Font::plain)); + pauseButton->setRadius(5.0f); + pauseButton->setEnabledState(true); + pauseButton->setCorners(true, true, true, true); + pauseButton->addListener(this); + pauseButton->setClickingTogglesState(true); + pauseButton->setToggleState(false, sendNotification); + addAndMakeVisible(pauseButton); + + + lfpDisplay->setNumChannels(nChans); + lfpDisplay->setRange(voltageRanges[HEADSTAGE_CHANNEL][selectedVoltageRange[HEADSTAGE_CHANNEL]-1].getFloatValue()*rangeGain[HEADSTAGE_CHANNEL] + ,HEADSTAGE_CHANNEL); + lfpDisplay->setRange(voltageRanges[ADC_CHANNEL][selectedVoltageRange[ADC_CHANNEL] - 1].getFloatValue()*rangeGain[ADC_CHANNEL] + , ADC_CHANNEL); + lfpDisplay->setRange(voltageRanges[AUX_CHANNEL][selectedVoltageRange[AUX_CHANNEL] - 1].getFloatValue()*rangeGain[AUX_CHANNEL] + , AUX_CHANNEL); + + // add event display-specific controls (currently just an enable/disable button) + for (int i = 0; i < 8; i++) + { + + EventDisplayInterface* eventOptions = new EventDisplayInterface(lfpDisplay, this, i); + eventDisplayInterfaces.add(eventOptions); + addAndMakeVisible(eventOptions); + eventOptions->setBounds(500+(floor(i/2)*20), getHeight()-20-(i%2)*20, 40, 20); + + lfpDisplay->setEventDisplayState(i,true); + + } + + // allocate samplesPerPixel, behaves like float samplesPerPixel[nChans][MAX_N_SAMP][MAX_N_SAMP_PER_PIXEL] + samplesPerPixel = (float***)malloc(nChans * sizeof(float **)); + for(int i=0;i<nChans;i++) + { + samplesPerPixel[i] = (float**)malloc(MAX_N_SAMP * sizeof(float*)); + for(int j=0;j<MAX_N_SAMP;j++) + { + samplesPerPixel[i][j] = (float*)malloc(MAX_N_SAMP_PER_PIXEL*sizeof(float)); + } + } + + TopLevelWindow::getTopLevelWindow(0)->addKeyListener(this); +} + +LfpDisplayCanvas::~LfpDisplayCanvas() +{ + + deleteAndZero(screenBuffer); + deleteAndZero(screenBufferMin); + deleteAndZero(screenBufferMean); + deleteAndZero(screenBufferMax); + + // de-allocate 3d-array samplesPerPixel [nChans][MAX_N_SAMP][MAX_N_SAMP_PER_PIXEL]; + + for(int i=0;i<nChans;i++) + { + for(int j=0;j<MAX_N_SAMP;j++) + { + free(samplesPerPixel[i][j]); + } + free(samplesPerPixel[i]); + } + free(samplesPerPixel); + + + TopLevelWindow::getTopLevelWindow(0)->removeKeyListener(this); +} + +void LfpDisplayCanvas::resized() +{ + + timescale->setBounds(leftmargin,0,getWidth()-scrollBarThickness-leftmargin,30); + viewport->setBounds(0,30,getWidth(),getHeight()-90); + + if (lfpDisplay->getSingleChannelState()) + lfpDisplay->setChannelHeight(viewport->getHeight(),false); + + lfpDisplay->setBounds(0,0,getWidth()-scrollBarThickness, lfpDisplay->getChannelHeight()*nChans); + + rangeSelection->setBounds(5,getHeight()-30,80,25); + timebaseSelection->setBounds(175,getHeight()-30,60,25); + + spreadSelection->setBounds(245,getHeight()-30,60,25); + + overlapSelection->setBounds(315,getHeight()-30,60,25); + drawClipWarningButton->setBounds(410-30,getHeight()-29,20,20); + + colorGroupingSelection->setBounds(620,getHeight()-30,60,25); + + invertInputButton->setBounds(750,getHeight()-50,100,22); + drawMethodButton->setBounds(750,getHeight()-25,100,22); + pauseButton->setBounds(860,getHeight()-50,50,44); + + saturationWarningSelection->setBounds(315+90,getHeight()-30,60,25); + drawSaturateWarningButton->setBounds(410-30+90,getHeight()-29,20,20); + + for (int i = 0; i < 8; i++) + { + eventDisplayInterfaces[i]->setBounds(500+(floor(i/2)*20), getHeight()-40+(i%2)*20, 40, 20); // arrange event channel buttons in two rows + eventDisplayInterfaces[i]->repaint(); + } + + brightnessSliderA->setBounds(920,getHeight()-50,100,22); + sliderALabel->setBounds(1020, getHeight()-50, 180, 22); + brightnessSliderA->setValue(0.9); //set default value + + brightnessSliderB->setBounds(920,getHeight()-25,100,22); + sliderBLabel->setBounds(1020, getHeight()-25, 180, 22); + brightnessSliderB->setValue(0.1); //set default value + + int bh = 25/typeButtons.size(); + for (int i = 0; i < typeButtons.size(); i++) + { + typeButtons[i]->setBounds(110,getHeight()-30+i*bh,50,bh); + } + // std::cout << "Canvas thinks LfpDisplay should be this high: " + // << lfpDisplay->getTotalHeight() << std::endl; + +} + +void LfpDisplayCanvas::beginAnimation() +{ + std::cout << "Beginning animation." << std::endl; + + displayBufferSize = displayBuffer->getNumSamples(); + + for (int i = 0; i < screenBufferIndex.size(); i++) + { + screenBufferIndex.set(i,0); + } + + startCallbacks(); +} + +void LfpDisplayCanvas::endAnimation() +{ + std::cout << "Ending animation." << std::endl; + + stopCallbacks(); +} + +void LfpDisplayCanvas::update() +{ + nChans = jmax(processor->getNumInputs(),1); + + sampleRate.clear(); + screenBufferIndex.clear(); + lastScreenBufferIndex.clear(); + displayBufferIndex.clear(); + + for (int i = 0; i <= nChans; i++) // extra channel for events + { + if (processor->getNumInputs() > 0) + { + if (i < nChans) + sampleRate.add(processor->channels[i]->sampleRate); + else + sampleRate.add(processor->channels[i - 1]->sampleRate); // for event channel (IT'S A HACK -- BE CAREFUL!) + } + else + sampleRate.add(30000); + + // std::cout << "Sample rate for ch " << i << " = " << sampleRate[i] << std::endl; + displayBufferIndex.add(0); + screenBufferIndex.add(0); + lastScreenBufferIndex.add(0); + } + + + + if (nChans != lfpDisplay->getNumChannels()) + { + //std::cout << "Setting num inputs on LfpDisplayCanvas to " << nChans << std::endl; + + refreshScreenBuffer(); + + lfpDisplay->setNumChannels(nChans); // add an extra channel for events + + // update channel names + for (int i = 0; i < processor->getNumInputs(); i++) + { + + String chName = processor->channels[i]->getName(); + + //std::cout << chName << std::endl; + + lfpDisplay->channelInfo[i]->setName(chName); + lfpDisplay->enableChannel(isChannelEnabled[i], i); + + } + + lfpDisplay->setBounds(0,0,getWidth()-scrollBarThickness*2, lfpDisplay->getTotalHeight()); + + resized(); + } + else + { + for (int i = 0; i < processor->getNumInputs(); i++) + { + lfpDisplay->channels[i]->updateType(); + lfpDisplay->channelInfo[i]->updateType(); + } + + } + +} + +void LfpDisplayCanvas::buttonClicked(Button* b) +{ + if (b == invertInputButton) + { + lfpDisplay->setInputInverted(b->getToggleState()); + return; + } + if (b == drawMethodButton) + { + lfpDisplay->setDrawMethod(b->getToggleState()); // this should be done the same way as drawClipWarning - or the other way around. + return; + } + if (b == drawClipWarningButton) + { + drawClipWarning = b->getToggleState(); + + fullredraw=true; + repaint(); + refresh(); + return; + } + if (b == drawSaturateWarningButton) + { + drawSaturationWarning = b->getToggleState(); + + fullredraw=true; + repaint(); + refresh(); + return; + } + + if (b == pauseButton) + { + lfpDisplay->isPaused = b->getToggleState(); + return; + } + + int idx = typeButtons.indexOf((UtilityButton*)b); + if ((idx >= 0) && (b->getToggleState())) + { + for (int i = 0; i < processor->getNumInputs(); i++) + { + if (lfpDisplay->channels[i]->getSelected()) + { + lfpDisplay->channels[i]->deselect(); + lfpDisplay->channels[i]->repaint(); + } + } + setSelectedType((ChannelType) idx, false); + } + +} + + +void LfpDisplayCanvas::comboBoxChanged(ComboBox* cb) +{ + + if (cb == timebaseSelection) + { + if (cb->getSelectedId()) + { + timebase = timebases[cb->getSelectedId()-1].getFloatValue(); + } + else + { + timebase = cb->getText().getFloatValue(); + if (timebase) + { + if (timebase < timebases[0].getFloatValue()) + { + cb->setSelectedId(1,dontSendNotification); + timebase = timebases[0].getFloatValue(); + } + else if (timebase > timebases[timebases.size()-1].getFloatValue()) + { + cb->setSelectedId(timebases.size(),dontSendNotification); + timebase = timebases[timebases.size()-1].getFloatValue(); + } + else + cb->setText(String(timebase,1),dontSendNotification); + } + else + { + if (selectedSpread == 0) + { + cb->setText(selectedTimebaseValue,dontSendNotification); + timebase = selectedTimebaseValue.getFloatValue(); + } + else + { + cb->setSelectedId(selectedTimebase,dontSendNotification); + timebase = timebases[selectedTimebase-1].getFloatValue(); + } + + } + } + } + else if (cb == rangeSelection) + { + if (cb->getSelectedId()) + { + lfpDisplay->setRange(voltageRanges[selectedChannelType][cb->getSelectedId()-1].getFloatValue()*rangeGain[selectedChannelType] + ,selectedChannelType); + } + else + { + float vRange = cb->getText().getFloatValue(); + if (vRange) + { + if (vRange < voltageRanges[selectedChannelType][0].getFloatValue()) + { + cb->setSelectedId(1,dontSendNotification); + vRange = voltageRanges[selectedChannelType][0].getFloatValue(); + } + else if (vRange > voltageRanges[selectedChannelType][voltageRanges[selectedChannelType].size()-1].getFloatValue()) + { + // cb->setSelectedId(voltageRanges[selectedChannelType].size(),dontSendNotification); + // vRange = voltageRanges[selectedChannelType][voltageRanges[selectedChannelType].size()-1].getFloatValue(); + } + else + { + if (rangeGain[selectedChannelType] > 1) + cb->setText(String(vRange,1),dontSendNotification); + else + cb->setText(String(vRange),dontSendNotification); + } + lfpDisplay->setRange(vRange*rangeGain[selectedChannelType],selectedChannelType); + } + else + { + if (selectedVoltageRange[selectedChannelType]) + cb->setText(selectedVoltageRangeValues[selectedChannelType],dontSendNotification); + else + cb->setSelectedId(selectedVoltageRange[selectedChannelType],dontSendNotification); + } + } + selectedVoltageRange[selectedChannelType] = cb->getSelectedId(); + selectedVoltageRangeValues[selectedChannelType] = cb->getText(); + //std::cout << "Setting range to " << voltageRanges[cb->getSelectedId()-1].getFloatValue() << std::endl; + fullredraw = true; //issue full redraw + repaint(); + refresh(); + } + else if (cb == spreadSelection) + { + if (cb->getSelectedId()) + { + lfpDisplay->setChannelHeight(spreads[cb->getSelectedId()-1].getIntValue()); + resized(); + } + else + { + int spread = cb->getText().getIntValue(); + if (spread) + { + if (spread < spreads[0].getFloatValue()) + { + cb->setSelectedId(1,dontSendNotification); + spread = spreads[0].getFloatValue(); + } + else if (spread > spreads[spreads.size()-1].getFloatValue()) + { + cb->setSelectedId(spreads.size(),dontSendNotification); + spread = spreads[spreads.size()-1].getFloatValue(); + } + else + { + cb->setText(String(spread),dontSendNotification); + } + lfpDisplay->setChannelHeight(spread); + resized(); + } + else + { + if (selectedSpread == 0) + cb->setText(selectedSpreadValue,dontSendNotification); + else + cb->setSelectedId(selectedSpread,dontSendNotification); + } + } + selectedSpread = cb->getSelectedId(); + selectedSpreadValue = cb->getText(); + fullredraw = true; //issue full redraw + repaint(); + refresh(); + //std::cout << "Setting spread to " << spreads[cb->getSelectedId()-1].getFloatValue() << std::endl; + } + else if (cb == saturationWarningSelection) + { + if (cb->getSelectedId()) + { + selectedSaturationValueFloat=(saturationThresholds[cb->getSelectedId()-1].getFloatValue()); + } + else + { + selectedSaturationValueFloat = cb->getText().getFloatValue(); + if (selectedSaturationValueFloat) + { + std::cout << "Setting saturation warning to to " << selectedSaturationValueFloat << std::endl; + if (selectedSaturationValueFloat < 0) + { + cb->setSelectedId(1,dontSendNotification); + selectedSaturationValueFloat = saturationThresholds[0].getFloatValue(); + } + else + { + // cb->setText(String(selectedSaturationValueFloat),dontSendNotification); + } + } + else + { + // cb->setSelectedId(1,dontSendNotification); + //selectedSaturationValueFloat = saturationThresholds[0].getFloatValue(); + + } + } + // selectedSpread = cb->getSelectedId(); + // selectedSpreadValue = cb->getText(); + // lfpDisplay->setChannelHeight( lfpDisplay->getChannelHeight()); + fullredraw = true; //issue full redraw + repaint(); + refresh(); + std::cout << "Setting saturation warning to to " << selectedSaturationValueFloat << std::endl; + } + else if (cb == overlapSelection) + { + if (cb->getSelectedId()) + { + channelOverlapFactor=(overlaps[cb->getSelectedId()-1].getFloatValue()); + resized(); + } + else + { + float overlap = cb->getText().getFloatValue(); + if (overlap) + { + if (overlap < overlaps[0].getFloatValue()) + { + cb->setSelectedId(1,dontSendNotification); + overlap = overlaps[0].getFloatValue(); + } + else if (overlap > overlaps[overlaps.size()-1].getFloatValue()) + { + cb->setSelectedId(overlaps.size(),dontSendNotification); + overlap = overlaps[overlaps.size()-1].getFloatValue(); + } + else + { + cb->setText(String(overlap),dontSendNotification); + } + channelOverlapFactor= overlap; + resized(); + } + else + { + if (selectedSpread == 0) + cb->setText(selectedSpreadValue,dontSendNotification); + else + cb->setSelectedId(selectedSpread,dontSendNotification); + } + } + selectedSpread = cb->getSelectedId(); + selectedSpreadValue = cb->getText(); + lfpDisplay->setChannelHeight( lfpDisplay->getChannelHeight()); + fullredraw = true; //issue full redraw + repaint(); + refresh(); + //std::cout << "Setting spread to " << spreads[cb->getSelectedId()-1].getFloatValue() << std::endl; + } + + else if (cb == colorGroupingSelection) + { + // set color grouping hre + + lfpDisplay->setColorGrouping(colorGroupings[cb->getSelectedId()-1].getIntValue());// so that channel colors get re-assigned + fullredraw = true; //issue full redraw + repaint(); + refresh(); + } + + timescale->setTimebase(timebase); +} + + +void LfpDisplayCanvas::sliderValueChanged(Slider* sl) +{ + if (sl == brightnessSliderA) + histogramParameterA = sl->getValue(); + + if (sl == brightnessSliderB) + histogramParameterB = sl->getValue(); + + fullredraw=true; + //repaint(); + refresh(); + +} + + +void LfpDisplayCanvas::sliderEvent(Slider* sl) {} + +int LfpDisplayCanvas::getChannelHeight() +{ + //return spreads[spreadSelection->getSelectedId()-1].getIntValue(); + return (int)spreadSelection->getText().getIntValue(); + +} + + +void LfpDisplayCanvas::setParameter(int param, float val) +{ + // not used for anything, since LfpDisplayCanvas is not a processor +} + +void LfpDisplayCanvas:: setRangeSelection(float range, bool canvasMustUpdate) +{ + if (canvasMustUpdate) + { + rangeSelection->setText(String(range/rangeGain[selectedChannelType]), sendNotification); + } + else + { + rangeSelection->setText(String(range/rangeGain[selectedChannelType]),dontSendNotification); + selectedVoltageRange[selectedChannelType]=rangeSelection->getSelectedId(); + selectedVoltageRangeValues[selectedChannelType]=rangeSelection->getText(); + + repaint(); + refresh(); + } + +} + +void LfpDisplayCanvas:: setSpreadSelection(int spread, bool canvasMustUpdate) +{ + if (canvasMustUpdate) + { + spreadSelection->setText(String(spread),sendNotification); + } + else + { + spreadSelection->setText(String(spread),dontSendNotification); + selectedSpread=spreadSelection->getSelectedId(); + selectedSpreadValue=spreadSelection->getText(); + + repaint(); + refresh(); + } +} + +void LfpDisplayCanvas::refreshState() +{ + // called when the component's tab becomes visible again + + for (int i = 0; i <= displayBufferIndex.size(); i++) // include event channel + { + + displayBufferIndex.set(i, processor->getDisplayBufferIndex(i)); + screenBufferIndex.set(i,0); + } + +} + +void LfpDisplayCanvas::refreshScreenBuffer() +{ + + for (int i = 0; i < screenBufferIndex.size(); i++) + screenBufferIndex.set(i,0); + + screenBuffer->clear(); + screenBufferMin->clear(); + screenBufferMean->clear(); + screenBufferMax->clear(); + + + // int w = lfpDisplay->getWidth(); + // //std::cout << "Refreshing buffer size to " << w << "pixels." << std::endl; + + // for (int i = 0; i < w; i++) + // { + // float x = float(i); + + // for (int n = 0; n < nChans; n++) + // { + // waves[n][i*2] = x; + // waves[n][i*2+1] = 0.5f; // line in center of display + // } + // } + +} + +void LfpDisplayCanvas::updateScreenBuffer() +{ + + // copy new samples from the displayBuffer into the screenBuffer + int maxSamples = lfpDisplay->getWidth() - leftmargin; + + ScopedLock displayLock(*processor->getMutex()); + + for (int channel = 0; channel <= nChans; channel++) // pull one extra channel for event display + { + + if (screenBufferIndex[channel] >= maxSamples) // wrap around if we reached right edge before + screenBufferIndex.set(channel, 0); + + // hold these values locally for each channel - is this a good idea? + int sbi = screenBufferIndex[channel]; + int dbi = displayBufferIndex[channel]; + + lastScreenBufferIndex.set(channel,sbi); + + int index = processor->getDisplayBufferIndex(channel); + + int nSamples = index - dbi; // N new samples (not pixels) to be added to displayBufferIndex + + if (nSamples < 0) // buffer has reset to 0 -- xxx 2do bug: this shouldnt happen because it makes the range/histogram display not work properly/look off for one pixel + { + nSamples = (displayBufferSize - dbi) + index +1; + // std::cout << "nsamples 0 " ; + } + + //if (channel == 15 || channel == 16) + // std::cout << channel << " " << sbi << " " << dbi << " " << nSamples << std::endl; + + + float ratio = sampleRate[channel] * timebase / float(getWidth() - leftmargin - scrollBarThickness); // samples / pixel + // this number is crucial: converting from samples to values (in px) for the screen buffer + int valuesNeeded = (int) float(nSamples) / ratio; // N pixels needed for this update + + if (sbi + valuesNeeded > maxSamples) // crop number of samples to fit canvas width + { + valuesNeeded = maxSamples - sbi; + } + float subSampleOffset = 0.0; + + dbi %= displayBufferSize; // make sure we're not overshooting + int nextPos = (dbi + 1) % displayBufferSize; // position next to displayBufferIndex in display buffer to copy from + + // if (channel == 0) + // std::cout << "Channel " + // << channel << " : " + // << sbi << " : " + // << index << " : " + // << dbi << " : " + // << valuesNeeded << " : " + // << ratio + // << std::endl; + + if (valuesNeeded > 0 && valuesNeeded < 1000000) + { + for (int i = 0; i < valuesNeeded; i++) // also fill one extra sample for line drawing interpolation to match across draws + { + //If paused don't update screen buffers, but update all indexes as needed + if (!lfpDisplay->isPaused) + { + float gain = 1.0; + float alpha = (float) subSampleOffset; + float invAlpha = 1.0f - alpha; + + screenBuffer->clear(channel, sbi, 1); + screenBufferMin->clear(channel, sbi, 1); + screenBufferMax->clear(channel, sbi, 1); + + dbi %= displayBufferSize; // just to be sure + + // interpolate between two samples with invAlpha and alpha + screenBuffer->addFrom(channel, // destChannel + sbi, // destStartSample + displayBuffer->getReadPointer(channel, dbi), // source + 1, // numSamples + invAlpha*gain); // gain + + + screenBuffer->addFrom(channel, // destChannel + sbi, // destStartSample + displayBuffer->getReadPointer(channel, nextPos), // source + 1, // numSamples + alpha*gain); // gain + + // same thing again, but this time add the min,mean, and max of all samples in current pixel + float sample_min = 10000000; + float sample_max = -10000000; + + int nextpix = (dbi +(int)ratio +1) % (displayBufferSize+1); // position to next pixels index + + if (nextpix <= dbi) { // at the end of the displaybuffer, this can occur and it causes the display to miss one pixel woth of sample - this circumvents that + // std::cout << "np " ; + nextpix=dbi; + } + + for (int j = dbi; j <= nextpix; j++) + { + float sample_current = displayBuffer->getSample(channel, j); + //sample_mean = sample_mean + sample_current; + + if (sample_min>sample_current) + { + sample_min=sample_current; + } + + if (sample_max<sample_current) + { + sample_max=sample_current; + } + + } + + // similarly, for each pixel on the screen, we want a list of all values so we can draw a histogram later + // for simplicity, we'll just do this as 2d array, samplesPerPixel[px][samples] + // with an additional array sampleCountPerPixel[px] that holds the N samples per pixel + if (channel < nChans) // we're looping over one 'extra' channel for events above, so make sure not to loop over that one here + { + int c = 0; + for (int j = dbi; j <= nextpix & c < MAX_N_SAMP_PER_PIXEL; j++) + { + float sample_current = displayBuffer->getSample(channel, j); + samplesPerPixel[channel][sbi][c]=sample_current; + c++; + } + if (c>0){ + sampleCountPerPixel[sbi]=c-1; // save count of samples for this pixel + }else{ + sampleCountPerPixel[sbi]=0; + } + //sample_mean = sample_mean/c; + //screenBufferMean->addSample(channel, sbi, sample_mean*gain); + + screenBufferMin->addSample(channel, sbi, sample_min*gain); + screenBufferMax->addSample(channel, sbi, sample_max*gain); + } + sbi++; + } + + subSampleOffset += ratio; + + while (subSampleOffset >= 1.0) + { + if (++dbi > displayBufferSize) + dbi = 0; + + nextPos = (dbi + 1) % displayBufferSize; + subSampleOffset -= 1.0; + } + + } + + // update values after we're done + screenBufferIndex.set(channel, sbi); + displayBufferIndex.set(channel, dbi); + } + + } + +} + +const float LfpDisplayCanvas::getXCoord(int chan, int samp) +{ + return samp; +} + +int LfpDisplayCanvas::getNumChannels() +{ + return nChans; +} + +const float LfpDisplayCanvas::getYCoord(int chan, int samp) +{ + return *screenBuffer->getReadPointer(chan, samp); +} + +const float LfpDisplayCanvas::getYCoordMean(int chan, int samp) +{ + return *screenBufferMean->getReadPointer(chan, samp); +} +const float LfpDisplayCanvas::getYCoordMin(int chan, int samp) +{ + return *screenBufferMin->getReadPointer(chan, samp); +} +const float LfpDisplayCanvas::getYCoordMax(int chan, int samp) +{ + return *screenBufferMax->getReadPointer(chan, samp); +} + +const float* LfpDisplayCanvas::getSamplesPerPixel(int chan, int px) +{ + return samplesPerPixel[chan][px]; +} +const int LfpDisplayCanvas::getSampleCountPerPixel(int px) +{ + return sampleCountPerPixel[px]; +} + + + +bool LfpDisplayCanvas::getInputInvertedState() +{ + return invertInputButton->getToggleState(); +} + +bool LfpDisplayCanvas::getDrawMethodState() +{ + return drawMethodButton->getToggleState(); +} + +void LfpDisplayCanvas::paint(Graphics& g) +{ + + //std::cout << "Painting" << std::endl; + + //g.setColour(Colour(0,0,0)); // for high-precision per-pixel density display, make background black for better visibility + g.setColour(lfpDisplay->backgroundColour); //background color + g.fillRect(0, 0, getWidth(), getHeight()); + + g.setGradientFill(ColourGradient(Colour(50,50,50),0,0, + Colour(25,25,25),0,30, + false)); + + g.fillRect(0, 0, getWidth()-scrollBarThickness, 30); + + g.setColour(Colours::black); + + g.drawLine(0,30,getWidth()-scrollBarThickness,30); + + g.setColour(Colour(25,25,60)); // timing grid color + + int w = getWidth()-scrollBarThickness-leftmargin; + + for (int i = 0; i < 10; i++) + { + if (i == 5 || i == 0) + g.drawLine(w/10*i+leftmargin,0,w/10*i+leftmargin,getHeight()-60,3.0f); + else + g.drawLine(w/10*i+leftmargin,0,w/10*i+leftmargin,getHeight()-60,1.0f); + } + + g.drawLine(0,getHeight()-60,getWidth(),getHeight()-60,3.0f); + + g.setFont(Font("Default", 16, Font::plain)); + + g.setColour(Colour(100,100,100)); + + g.drawText("Range("+ rangeUnits[selectedChannelType] +")",5,getHeight()-55,300,20,Justification::left, false); + g.drawText("Timebase(s)",140,getHeight()-55,300,20,Justification::left, false); + g.drawText("Size(px)",240,getHeight()-55,300,20,Justification::left, false); + g.drawText("Clip",315,getHeight()-55,300,20,Justification::left, false); + g.drawText("Warn",373,getHeight()-55,300,20,Justification::left, false); + + g.drawText("Sat.Warn.",315+105,getHeight()-55,300,20,Justification::left, false); + //g.drawText("Warn",375+90,getHeight()-55,300,20,Justification::left, false); + + g.drawText("Color grouping",620,getHeight()-55,300,20,Justification::left, false); + + + //g.drawText(typeNames[selectedChannelType],110,getHeight()-30,50,20,Justification::centredLeft,false); + + g.drawText("Event disp.",500,getHeight()-55,300,20,Justification::left, false); + + if(drawClipWarning) + { + g.setColour(Colours::white); + g.fillRoundedRectangle(408-30,getHeight()-30-1,24,24,6.0f); + } + + if(drawSaturationWarning) + { + g.setColour(Colours::red); + g.fillRoundedRectangle(408-30+90,getHeight()-30-1,24,24,6.0f); + } + + +} + +void LfpDisplayCanvas::refresh() +{ + + updateScreenBuffer(); + + lfpDisplay->refresh(); // redraws only the new part of the screen buffer + + //getPeer()->performAnyPendingRepaintsNow(); + +} + +bool LfpDisplayCanvas::keyPressed(const KeyPress& key) +{ + if (key.getKeyCode() == key.spaceKey) + { + pauseButton->setToggleState(!pauseButton->getToggleState(), sendNotification); + return true; + } + + return false; +} + +bool LfpDisplayCanvas::keyPressed(const KeyPress& key, Component* orig) +{ + if (getTopLevelComponent() == orig && isVisible()) + { + return keyPressed(key); + } + return false; +} + +void LfpDisplayCanvas::saveVisualizerParameters(XmlElement* xml) +{ + + XmlElement* xmlNode = xml->createNewChildElement("LFPDISPLAY"); + + + xmlNode->setAttribute("Range",selectedVoltageRangeValues[0]+","+selectedVoltageRangeValues[1]+ + ","+selectedVoltageRangeValues[2]); + xmlNode->setAttribute("Timebase",timebaseSelection->getText()); + xmlNode->setAttribute("Spread",spreadSelection->getText()); + xmlNode->setAttribute("colorGrouping",colorGroupingSelection->getSelectedId()); + xmlNode->setAttribute("isInverted",invertInputButton->getToggleState()); + xmlNode->setAttribute("drawMethod",drawMethodButton->getToggleState()); + + int eventButtonState = 0; + + for (int i = 0; i < 8; i++) + { + if (lfpDisplay->eventDisplayEnabled[i]) + { + eventButtonState += (1 << i); + } + } + + xmlNode->setAttribute("EventButtonState", eventButtonState); + + String channelDisplayState = ""; + + for (int i = 0; i < nChans; i++) + { + if (lfpDisplay->getEnabledState(i)) + { + channelDisplayState += "1"; + } + else + { + channelDisplayState += "0"; + } + } + + xmlNode->setAttribute("ChannelDisplayState", channelDisplayState); + + xmlNode->setAttribute("ScrollX",viewport->getViewPositionX()); + xmlNode->setAttribute("ScrollY",viewport->getViewPositionY()); +} + + +void LfpDisplayCanvas::loadVisualizerParameters(XmlElement* xml) +{ + forEachXmlChildElement(*xml, xmlNode) + { + if (xmlNode->hasTagName("LFPDISPLAY")) + { + StringArray ranges; + ranges.addTokens(xmlNode->getStringAttribute("Range"),",",String::empty); + selectedVoltageRangeValues[0] = ranges[0]; + selectedVoltageRangeValues[1] = ranges[1]; + selectedVoltageRangeValues[2] = ranges[2]; + selectedVoltageRange[0] = voltageRanges[0].indexOf(ranges[0])+1; + selectedVoltageRange[1] = voltageRanges[1].indexOf(ranges[1])+1; + selectedVoltageRange[2] = voltageRanges[2].indexOf(ranges[2])+1; + rangeSelection->setText(ranges[0]); + + timebaseSelection->setText(xmlNode->getStringAttribute("Timebase")); + spreadSelection->setText(xmlNode->getStringAttribute("Spread")); + if (xmlNode->hasAttribute("colorGrouping")) + { + colorGroupingSelection->setSelectedId(xmlNode->getIntAttribute("colorGrouping")); + } + else + { + colorGroupingSelection->setSelectedId(1); + } + + invertInputButton->setToggleState(xmlNode->getBoolAttribute("isInverted", true), sendNotification); + + drawMethodButton->setToggleState(xmlNode->getBoolAttribute("drawMethod", true), sendNotification); + + viewport->setViewPosition(xmlNode->getIntAttribute("ScrollX"), + xmlNode->getIntAttribute("ScrollY")); + + int eventButtonState = xmlNode->getIntAttribute("EventButtonState"); + + for (int i = 0; i < 8; i++) + { + lfpDisplay->eventDisplayEnabled[i] = (eventButtonState >> i) & 1; + + eventDisplayInterfaces[i]->checkEnabledState(); + } + + String channelDisplayState = xmlNode->getStringAttribute("ChannelDisplayState"); + + for (int i = 0; i < channelDisplayState.length(); i++) + { + + if (channelDisplayState.substring(i,i+1).equalsIgnoreCase("1")) + { + //std::cout << "LfpDisplayCanvas enabling channel " << i << std::endl; + lfpDisplay->enableChannel(true, i); + isChannelEnabled.set(i,true); //lfpDisplay->enableChannel(true, i); + } + else + { + //std::cout << "LfpDisplayCanvas disabling channel " << i << std::endl; + lfpDisplay->enableChannel(false, i); + isChannelEnabled.set(i,false); + } + + + } + } + } + +} + +ChannelType LfpDisplayCanvas::getChannelType(int n) +{ + if (n < processor->getNumInputs()) + return processor->channels[n]->getType(); + else + return HEADSTAGE_CHANNEL; +} + +ChannelType LfpDisplayCanvas::getSelectedType() +{ + return selectedChannelType; +} + +void LfpDisplayCanvas::setSelectedType(ChannelType type, bool toggleButton) +{ + if (selectedChannelType == type) + return; //Nothing to do here + selectedChannelType = type; + rangeSelection->clear(dontSendNotification); + rangeSelection->addItemList(voltageRanges[type],1); + int id = selectedVoltageRange[type]; + if (id) + rangeSelection->setSelectedId(id,sendNotification); + else + rangeSelection->setText(selectedVoltageRangeValues[selectedChannelType],dontSendNotification); + repaint(5,getHeight()-55,300,100); + + if (toggleButton) + typeButtons[type]->setToggleState(true,dontSendNotification); +} + +String LfpDisplayCanvas::getTypeName(ChannelType type) +{ + return typeNames[type]; +} + +int LfpDisplayCanvas::getRangeStep(ChannelType type) +{ + return rangeSteps[type]; +} + +//void LfpDisplayCanvas::sliderValueChanged(Slider* s) +//{ +// sliderEvent(slider); +//} + + +// ------------------------------------------------------------- + +LfpTimescale::LfpTimescale(LfpDisplayCanvas* c) : canvas(c) +{ + + font = Font("Default", 16, Font::plain); +} + +LfpTimescale::~LfpTimescale() +{ + +} + +void LfpTimescale::paint(Graphics& g) +{ + + g.setFont(font); + + g.setColour(Colour(100,100,100)); + + g.drawText("ms:",5,0,100,getHeight(),Justification::left, false); + + for (int i = 1; i < 10; i++) + { + if (i == 5) + g.drawLine(getWidth()/10*i,0,getWidth()/10*i,getHeight(),3.0f); + else + g.drawLine(getWidth()/10*i,0,getWidth()/10*i,getHeight(),1.0f); + + g.drawText(labels[i-1],getWidth()/10*i+3,0,100,getHeight(),Justification::left, false); + } + +} + +void LfpTimescale::setTimebase(float t) +{ + timebase = t; + + labels.clear(); + + for (float i = 1.0f; i < 10.0; i++) + { + String labelString = String(timebase/10.0f*1000.0f*i); + + labels.add(labelString.substring(0,6)); + } + + repaint(); + +} + + +// --------------------------------------------------------------- + +LfpDisplay::LfpDisplay(LfpDisplayCanvas* c, Viewport* v) : + singleChan(-1), canvas(c), viewport(v) +{ + totalHeight = 0; + colorGrouping=1; + + range[0] = 1000; + range[1] = 500; + range[2] = 500000; + + addMouseListener(this, true); + + // hue cycle + //for (int i = 0; i < 15; i++) + //{ + // channelColours.add(Colour(float(sin((3.14/2)*(float(i)/15))),float(1.0),float(1),float(1.0))); + //} + + backgroundColour = Colour(0,18,43); + + //hand-built palette + channelColours.add(Colour(224,185,36)); + channelColours.add(Colour(214,210,182)); + channelColours.add(Colour(243,119,33)); + channelColours.add(Colour(186,157,168)); + channelColours.add(Colour(237,37,36)); + channelColours.add(Colour(179,122,79)); + channelColours.add(Colour(217,46,171)); + channelColours.add(Colour(217, 139,196)); + channelColours.add(Colour(101,31,255)); + channelColours.add(Colour(141,111,181)); + channelColours.add(Colour(48,117,255)); + channelColours.add(Colour(184,198,224)); + channelColours.add(Colour(116,227,156)); + channelColours.add(Colour(150,158,155)); + channelColours.add(Colour(82,173,0)); + channelColours.add(Colour(125,99,32)); + + isPaused=false; + +} + +LfpDisplay::~LfpDisplay() +{ + deleteAllChildren(); +} + + + +int LfpDisplay::getNumChannels() +{ + return numChans; +} + + + +int LfpDisplay::getColorGrouping() +{ + return colorGrouping; +} + +void LfpDisplay::setColorGrouping(int i) +{ + colorGrouping=i; + setColors(); // so that channel colors get re-assigned + +} + + +void LfpDisplay::setNumChannels(int numChannels) +{ + numChans = numChannels; + + deleteAllChildren(); + + channels.clear(); + channelInfo.clear(); + + totalHeight = 0; + + for (int i = 0; i < numChans; i++) + { + + //std::cout << "Adding new display for channel " << i << std::endl; + + LfpChannelDisplay* lfpChan = new LfpChannelDisplay(canvas, this, i); + + //lfpChan->setColour(channelColours[i % channelColours.size()]); + lfpChan->setRange(range[canvas->getChannelType(i)]); + lfpChan->setChannelHeight(canvas->getChannelHeight()); + + addAndMakeVisible(lfpChan); + + channels.add(lfpChan); + + LfpChannelDisplayInfo* lfpInfo = new LfpChannelDisplayInfo(canvas, this, i); + + //lfpInfo->setColour(channelColours[i % channelColours.size()]); + lfpInfo->setRange(range[canvas->getChannelType(i)]); + lfpInfo->setChannelHeight(canvas->getChannelHeight()); + + addAndMakeVisible(lfpInfo); + + channelInfo.add(lfpInfo); + + savedChannelState.add(true); + + totalHeight += lfpChan->getChannelHeight(); + + } + + setColors(); + + + //std::cout << "TOTAL HEIGHT = " << totalHeight << std::endl; + +} + +void LfpDisplay::setColors() +{ + for (int i = 0; i < numChans; i++) + { + + channels[i]->setColour(channelColours[(int(i/colorGrouping)+1) % channelColours.size()]); + channelInfo[i]->setColour(channelColours[(int(i/colorGrouping)+1) % channelColours.size()]); + } + +} + + +int LfpDisplay::getTotalHeight() +{ + return totalHeight; +} + +void LfpDisplay::resized() +{ + + //canvas->channelOverlapFactor + + int totalHeight = 0; + + for (int i = 0; i < channels.size(); i++) + { + + LfpChannelDisplay* disp = channels[i]; + + disp->setBounds(canvas->leftmargin, + totalHeight-(disp->getChannelOverlap()*canvas->channelOverlapFactor)/2, + getWidth(), + disp->getChannelHeight()+(disp->getChannelOverlap()*canvas->channelOverlapFactor)); + + disp-> resized(); + + LfpChannelDisplayInfo* info = channelInfo[i]; + + info->setBounds(0, + totalHeight-disp->getChannelHeight()/4, + canvas->leftmargin, + disp->getChannelHeight()); + + totalHeight += disp->getChannelHeight(); + + } + + canvas->fullredraw = true; //issue full redraw + if (singleChan != -1) + viewport->setViewPosition(Point<int>(0,singleChan*getChannelHeight())); + + + + lfpChannelBitmap = Image(Image::ARGB, getWidth(), getHeight(), false); + + //inititalize black background + Graphics gLfpChannelBitmap(lfpChannelBitmap); + gLfpChannelBitmap.setColour(Colour(0,0,0)); //background color + gLfpChannelBitmap.fillRect(0,0, getWidth(), getHeight()); + + + canvas->fullredraw = true; + + refresh(); + // std::cout << "Total height: " << totalHeight << std::endl; + +} + +void LfpDisplay::paint(Graphics& g) +{ + + g.drawImageAt(lfpChannelBitmap, canvas->leftmargin,0); + +} + + +void LfpDisplay::refresh() +{ + // X-bounds of this update + int fillfrom = canvas->lastScreenBufferIndex[0]; + int fillto = (canvas->screenBufferIndex[0]); + + if (fillfrom<0){fillfrom=0;}; + if (fillto>lfpChannelBitmap.getWidth()){fillto=lfpChannelBitmap.getWidth();}; + + int topBorder = viewport->getViewPositionY(); + int bottomBorder = viewport->getViewHeight() + topBorder; + + // clear appropriate section of the bitmap -- + // we need to do this before each channel draws its new section of data into lfpChannelBitmap + Graphics gLfpChannelBitmap(lfpChannelBitmap); + gLfpChannelBitmap.setColour(backgroundColour); //background color + + if (canvas->fullredraw) + { + gLfpChannelBitmap.fillRect(0,0, getWidth(), getHeight()); + } else { + gLfpChannelBitmap.setColour(backgroundColour); //background color + + gLfpChannelBitmap.fillRect(fillfrom,0, (fillto-fillfrom)+1, getHeight()); + }; + + + for (int i = 0; i < numChans; i++) + { + + int componentTop = channels[i]->getY(); + int componentBottom = channels[i]->getHeight() + componentTop; + + if ((topBorder <= componentBottom && bottomBorder >= componentTop)) // only draw things that are visible + { + if (canvas->fullredraw) + { + channels[i]->fullredraw = true; + + channels[i]->pxPaint(); + channelInfo[i]->repaint(); + + } + else + { + channels[i]->pxPaint(); // draws to lfpChannelBitmap + + // it's not clear why, but apparently because the pxPaint() in a child component of LfpDisplay, we also need to issue repaint() calls for each channel, even though there's nothin to repaint there. Otherwise, the repaint call in LfpDisplay::refresh(), a few lines down, lags behind the update line by ~60 px. This could ahev something to do with teh reopaint message passing in juce. In any case, this seemingly redundant repaint here seems to fix the issue. + + // we redraw from 0 to +2 (px) relative to the real redraw window, the +1 draws the vertical update line + channels[i]->repaint(fillfrom, 0, (fillto-fillfrom)+2, channels[i]->getHeight()); + + + } + //std::cout << i << std::endl; + } + + } + + + if (canvas->fullredraw) + { + repaint(0,topBorder,getWidth(),bottomBorder-topBorder); + }else{ + //repaint(fillfrom, topBorder, (fillto-fillfrom)+1, bottomBorder-topBorder); // doesntb seem to be needed and results in duplicate repaint calls + } + + canvas->fullredraw = false; + +} + + + +void LfpDisplay::setRange(float r, ChannelType type) +{ + range[type] = r; + + for (int i = 0; i < numChans; i++) + { + if (channels[i]->getType() == type) + channels[i]->setRange(range[type]); + } + canvas->fullredraw = true; //issue full redraw +} + +int LfpDisplay::getRange() +{ + return getRange(canvas->getSelectedType()); +} + +int LfpDisplay::getRange(ChannelType type) +{ + for (int i=0; i < numChans; i++) + { + if (channels[i]->getType() == type) + return channels[i]->getRange(); + } + return 0; +} + + +void LfpDisplay::setChannelHeight(int r, bool resetSingle) +{ + + for (int i = 0; i < numChans; i++) + { + channels[i]->setChannelHeight(r); + channelInfo[i]->setChannelHeight(r); + } + if (resetSingle && singleChan != -1) + { + std::cout << "width " << getWidth() << " numchans " << numChans << " height " << getChannelHeight() << std::endl; + setSize(getWidth(),numChans*getChannelHeight()); + viewport->setScrollBarsShown(true,false); + viewport->setViewPosition(Point<int>(0,singleChan*r)); + singleChan = -1; + for (int n = 0; n < numChans; n++) + { + channelInfo[n]->setEnabledState(savedChannelState[n]); + } + } + + resized(); + +} + +void LfpDisplay::setInputInverted(bool isInverted) +{ + + for (int i = 0; i < numChans; i++) + { + channels[i]->setInputInverted(isInverted); + } + + resized(); + +} + +void LfpDisplay::setDrawMethod(bool isDrawMethod) +{ + for (int i = 0; i < numChans; i++) + { + channels[i]->setDrawMethod(isDrawMethod); + } + resized(); + +} + + +int LfpDisplay::getChannelHeight() +{ + return channels[0]->getChannelHeight(); +} + + + +void LfpDisplay::mouseWheelMove(const MouseEvent& e, const MouseWheelDetails& wheel) +{ + + //std::cout << "Mouse wheel " << e.mods.isCommandDown() << " " << wheel.deltaY << std::endl; + //TODO Changing ranges with the wheel is currently broken. With multiple ranges, most + //of the wheel range code needs updating + + + if (e.mods.isCommandDown()) // CTRL + scroll wheel -> change channel spacing + { + int h = getChannelHeight(); + int hdiff=0; + + // std::cout << wheel.deltaY << std::endl; + + if (wheel.deltaY > 0) + { + hdiff = 2; + } + else + { + if (h > 5) + hdiff = -2; + } + + if (abs(h) > 100) // accelerate scrolling for large ranges + hdiff *= 3; + + setChannelHeight(h+hdiff); + int oldX=viewport->getViewPositionX(); + int oldY=viewport->getViewPositionY(); + + setBounds(0,0,getWidth()-0, getChannelHeight()*canvas->nChans); // update height so that the scrollbar is correct + + int mouseY=e.getMouseDownY(); // should be y pos relative to inner viewport (0,0) + int scrollBy = (mouseY/h)*hdiff*2;// compensate for motion of point under current mouse position + viewport->setViewPosition(oldX,oldY+scrollBy); // set back to previous position plus offset + + canvas->setSpreadSelection(h+hdiff); // update combobox + + canvas->fullredraw = true;//issue full redraw - scrolling without modifier doesnt require a full redraw + } + else + { + if (e.mods.isAltDown()) // ALT + scroll wheel -> change channel range (was SHIFT but that clamps wheel.deltaY to 0 on OSX for some reason..) + { + int h = getRange(); + + + int step = canvas->getRangeStep(canvas->getSelectedType()); + + // std::cout << wheel.deltaY << std::endl; + + if (wheel.deltaY > 0) + { + setRange(h+step,canvas->getSelectedType()); + } + else + { + if (h > step+1) + setRange(h-step,canvas->getSelectedType()); + } + + canvas->setRangeSelection(h); // update combobox + canvas->fullredraw = true; //issue full redraw - scrolling without modifier doesnt require a full redraw + + } + else // just scroll + { + // passes the event up to the viewport so the screen scrolls + if (viewport != nullptr && e.eventComponent == this) // passes only if it's not a listening event + viewport->mouseWheelMove(e.getEventRelativeTo(canvas), wheel); + + } + + + } + //refresh(); // doesn't seem to be needed now that channels daraw to bitmap + +} + +void LfpDisplay::toggleSingleChannel(int chan) +{ + //std::cout << "Toggle channel " << chan << std::endl; + + if (chan != singleChan) + { + singleChan = chan; + int newHeight = viewport->getHeight(); + channelInfo[chan]->setEnabledState(true); + setChannelHeight(newHeight, false); + setSize(getWidth(), numChans*getChannelHeight()); + viewport->setScrollBarsShown(false,false); + viewport->setViewPosition(Point<int>(0,chan*newHeight)); + for (int n = 0; n < numChans; n++) + { + savedChannelState.set(n, channels[n]->getEnabledState()); + if (n != chan) channelInfo[n]->setEnabledState(false); + } + + } + else + { + setChannelHeight(canvas->getChannelHeight()); + } +} + +bool LfpDisplay::getSingleChannelState() +{ + if (singleChan < 0) return false; + else return true; +} + + +void LfpDisplay::mouseDown(const MouseEvent& event) +{ + //int y = event.getMouseDownY(); //relative to each channel pos + MouseEvent canvasevent = event.getEventRelativeTo(viewport); + int y = canvasevent.getMouseDownY() + viewport->getViewPositionY(); // need to account for scrolling + + int dist = 0; + int mindist = 10000; + int closest = 5; + for (int n = 0; n < numChans; n++) // select closest instead of relying on eventComponent + { + channels[n]->deselect(); + + int cpos = (channels[n]->getY() + (channels[n]->getHeight()/2)); + dist = int(abs(y - cpos)); + + //std::cout << "Mouse down at " << y << " pos is "<< cpos << "n:" << n << " dist " << dist << std::endl; + + if (dist < mindist) + { + mindist = dist-1; + closest = n; + } + } + + channels[closest]->select(); + canvas->setSelectedType(channels[closest]->getType()); + + if (event.getNumberOfClicks() == 2) + toggleSingleChannel(closest); + + if (event.mods.isRightButtonDown()) + { + PopupMenu channelMenu = channels[closest]->getOptions(); + const int result = channelMenu.show(); + channels[closest]->changeParameter(result); + } + + canvas->fullredraw = true;//issue full redraw + + refresh(); + +} + + +bool LfpDisplay::setEventDisplayState(int ch, bool state) +{ + eventDisplayEnabled[ch] = state; + return eventDisplayEnabled[ch]; +} + + +bool LfpDisplay::getEventDisplayState(int ch) +{ + return eventDisplayEnabled[ch]; +} + +void LfpDisplay::enableChannel(bool state, int chan) +{ + + if (chan < numChans) + { + channelInfo[chan]->setEnabledState(state); + canvas->isChannelEnabled.set(chan, state); + } +} + +void LfpDisplay::setEnabledState(bool state, int chan) +{ + + if (chan < numChans) + { + channels[chan]->setEnabledState(state); + canvas->isChannelEnabled.set(chan, state); + } +} + +bool LfpDisplay::getEnabledState(int chan) +{ + if (chan < numChans) + { + return channels[chan]->getEnabledState(); + } + + return false; +} + + +// ------------------------------------------------------------------ + +LfpChannelDisplay::LfpChannelDisplay(LfpDisplayCanvas* c, LfpDisplay* d, int channelNumber) : + canvas(c), display(d), isSelected(false), chan(channelNumber), + channelOverlap(300), channelHeight(40), range(1000.0f), + isEnabled(true), inputInverted(false), canBeInverted(true), drawMethod(false) +{ + + + name = String(channelNumber+1); // default is to make the channelNumber the name + + + channelHeightFloat = (float) channelHeight; + + channelFont = Font("Default", channelHeight*0.6, Font::plain); + + lineColour = Colour(255,255,255); + + type = c->getChannelType(channelNumber); + typeStr = c->getTypeName(type); + + + +} + +LfpChannelDisplay::~LfpChannelDisplay() +{ + +} + +void LfpChannelDisplay::resized() +{ + // all of this will likely need to be moved into the sharedLfpDisplay image in the lfpDisplay, not here + // now that the complete height is know, the sharedLfpDisplay image that we'll draw the pixel-wise lfp plot to needs to be resized + //lfpChannelBitmap = Image(Image::ARGB, getWidth(), getHeight(), false); +} + + +void LfpChannelDisplay::updateType() +{ + type = canvas->getChannelType(chan); + typeStr = canvas->getTypeName(type); +} + +void LfpChannelDisplay::setEnabledState(bool state) +{ + + //if (state) + //std::cout << "Setting channel " << name << " to true." << std::endl; + //else + //std::cout << "Setting channel " << name << " to false." << std::endl; + + isEnabled = state; + +} + +void LfpChannelDisplay::pxPaint() +{ + if (isEnabled) + { + Image::BitmapData bdLfpChannelBitmap(display->lfpChannelBitmap, 0,0, display->lfpChannelBitmap.getWidth(), display->lfpChannelBitmap.getHeight()); + + int center = getHeight()/2; + + // max and min of channel in absolute px coords for event displays etc - actual data might be drawn outside of this range + int jfrom_wholechannel= (int) (getY()+center-channelHeight/2)+1 +0 ; + int jto_wholechannel= (int) (getY()+center+channelHeight/2) -0; + + int jfrom_wholechannel_almost= (int) (getY()+center-channelHeight/3)+1 +0 ; // a bit less tall, for saturation warnings + int jto_wholechannel_almost= (int) (getY()+center+channelHeight/3) -0; + + + // max and min of channel, this is the range where actual data is drawn + int jfrom_wholechannel_clip= (int) (getY()+center-(channelHeight)*canvas->channelOverlapFactor)+1 ; + int jto_wholechannel_clip = (int) (getY()+center+(channelHeight)*canvas->channelOverlapFactor) -0; + + + + if (jfrom_wholechannel<0) {jfrom_wholechannel=0;}; + if (jto_wholechannel >= display->lfpChannelBitmap.getHeight()) {jto_wholechannel=display->lfpChannelBitmap.getHeight()-1;}; + + // draw most recent drawn sample position + if (canvas->screenBufferIndex[chan]+1 <= display->lfpChannelBitmap.getWidth()) + for (int k=jfrom_wholechannel; k<=jto_wholechannel; k+=2) // draw line + bdLfpChannelBitmap.setPixelColour(canvas->screenBufferIndex[chan]+1,k, Colours::yellow); + + + bool clipWarningHi =false; // keep track if something clipped in the display, so we can draw warnings after the data pixels are done + bool clipWarningLo =false; + + bool saturateWarningHi =false; // similar, but for saturating the amplifier, not just the display - make this warning very visible + bool saturateWarningLo =false; + + // pre compute some colors for later so we dont do it once per pixel. + Colour lineColourBright = lineColour.withMultipliedBrightness(2.0f); + //Colour lineColourDark = lineColour.withMultipliedSaturation(0.5f).withMultipliedBrightness(0.3f); + Colour lineColourDark = lineColour.withMultipliedSaturation(0.5f*canvas->histogramParameterB).withMultipliedBrightness(canvas->histogramParameterB); + + + int stepSize = 1; + int from = 0; // for vertical line drawing in the LFP data + int to = 0; + + int ifrom = canvas->lastScreenBufferIndex[chan] - 1; // need to start drawing a bit before the actual redraw window for the interpolated line to join correctly + + if (ifrom < 0) + ifrom = 0; + + int ito = canvas->screenBufferIndex[chan] +0; + + if (fullredraw) + { + ifrom = 0; //canvas->leftmargin; + ito = getWidth()-stepSize; + fullredraw = false; + } + + + for (int i = ifrom; i < ito ; i += stepSize) // redraw only changed portion + { + + //draw zero line + int m = getY()+center; + if(m>0 & m<display->lfpChannelBitmap.getHeight()){ + if ( bdLfpChannelBitmap.getPixelColour(i,m) == display->backgroundColour ) { // make sure we're not drawing over an existing plot from another channel + bdLfpChannelBitmap.setPixelColour(i,m,Colour(50,50,50)); + } + } + + //draw range markers + if (isSelected) + { + m = getY()+center+channelHeight/2; + if(m>0 & m<display->lfpChannelBitmap.getHeight()){ + if ( bdLfpChannelBitmap.getPixelColour(i,m) == display->backgroundColour ) { // make sure we're not drawing over an existing plot from another channel + bdLfpChannelBitmap.setPixelColour(i,m,Colour(80,80,80)); + } + } + m = getY()+center-channelHeight/2; + if(m>0 & m<display->lfpChannelBitmap.getHeight()){ + if ( bdLfpChannelBitmap.getPixelColour(i,m) == display->backgroundColour ) { // make sure we're not drawing over an existing plot from another channel + bdLfpChannelBitmap.setPixelColour(i,m,Colour(80,80,80)); + } + } + } + + // draw event markers + int rawEventState = canvas->getYCoord(canvas->getNumChannels(), i);// get last channel+1 in buffer (represents events) + + //if (i == ifrom) + // std::cout << rawEventState << std::endl; + + for (int ev_ch = 0; ev_ch < 8 ; ev_ch++) // for all event channels + { + if (display->getEventDisplayState(ev_ch)) // check if plotting for this channel is enabled + { + if (rawEventState & (1 << ev_ch)) // events are representet by a bit code, so we have to extract the individual bits with a mask + { + //std::cout << "Drawing event." << std::endl; + Colour currentcolor=display->channelColours[ev_ch*2]; + + for (int k=jfrom_wholechannel; k<=jto_wholechannel; k++) // draw line + bdLfpChannelBitmap.setPixelColour(i,k,bdLfpChannelBitmap.getPixelColour(i,k).interpolatedWith(currentcolor,0.3f)); + + } + } + } + + //std::cout << "e " << canvas->getYCoord(canvas->getNumChannels()-1, i) << std::endl; + + + // set max-min range for plotting, used in all methods + double a = (canvas->getYCoordMax(chan, i)/range*channelHeightFloat); + double b = (canvas->getYCoordMin(chan, i)/range*channelHeightFloat); + + double a_raw = canvas->getYCoordMax(chan, i); + double b_raw = canvas->getYCoordMin(chan, i); + double from_raw=0; double to_raw=0; + + //double m = (canvas->getYCoordMean(chan, i)/range*channelHeightFloat)+getHeight()/2; + if (a<b) + { + from = (a); to = (b); + from_raw = (a_raw); to_raw = (b_raw); + + } + else + { + from = (b); to = (a); + from_raw = (b_raw); to_raw = (a_raw); + } + + // start by clipping so that we're not populating pixels that we dont want to plot + int lm= channelHeightFloat*canvas->channelOverlapFactor; + if (lm>0) + lm=-lm; + + if (from > -lm) {from = -lm; clipWarningHi=true;}; + if (to > -lm) {to = -lm; clipWarningHi=true;}; + if (from < lm) {from = lm; clipWarningLo=true;}; + if (to < lm) {to = lm; clipWarningLo=true;}; + + + // test if raw data is clipped for displaying saturation warning + if (from_raw > canvas->selectedSaturationValueFloat) { saturateWarningHi=true;}; + if (to_raw > canvas->selectedSaturationValueFloat) { saturateWarningHi=true;}; + if (from_raw < -canvas->selectedSaturationValueFloat) { saturateWarningLo=true;}; + if (to_raw < -canvas->selectedSaturationValueFloat) { saturateWarningLo=true;}; + + + from=from+getHeight()/2; // so the plot is centered in the channeldisplay + to=to+getHeight()/2; + + int samplerange=to-from; + + + + if (drawMethod) // switched between 'supersampled' drawing and simple pixel wise drawing + { // histogram based supersampling method + + const float *samplesThisPixel = canvas->getSamplesPerPixel(chan, i); + int sampleCountThisPixel = canvas->getSampleCountPerPixel(i); + + if (samplerange>0 & sampleCountThisPixel>0) + { + + //float localHist[samplerange]; // simple histogram + float rangeHist[samplerange]; // paired range histogram, same as plotting at higher res. and subsampling + + for (int k=0; k<=samplerange; k++) + rangeHist[k]=0; + + + + + + for (int k=0; k<=sampleCountThisPixel; k++) // add up paired-range histogram per pixel - for each pair fill intermediate with uniform distr. + { + int cs_this = (((samplesThisPixel[k]/range*channelHeightFloat)+getHeight()/2)-from); // sample values -> pixel coordinates relative to from + int cs_next = (((samplesThisPixel[k+1]/range*channelHeightFloat)+getHeight()/2)-from); + + + if (cs_this<0) {cs_this=0;}; //here we could clip the diaplay to the max/min, or ignore out of bound values, not sure which one is better + if (cs_this>samplerange) {cs_this=samplerange;}; + if (cs_next<0) {cs_next=0;}; + if (cs_next>samplerange) {cs_next=samplerange;}; + + int hfrom=0; + int hto=0; + + if (cs_this<cs_next) + { + hfrom = (cs_this); hto = (cs_next); + } + else + { + hfrom = (cs_next); hto = (cs_this); + } + float hrange=hto-hfrom; + float ha=1; + for (int l=hfrom; l<hto; l++) + { + rangeHist[l]+=ha; //this emphasizes fast Y components + + //rangeHist[l]+=1/hrange; // this is like an oscilloscope, same energy depositetd per dx, not dy + } + } + + + for (int s = 0; s <= samplerange; s ++) // plot histogram one pixel per bin + { + float a=15*((rangeHist[s])/(sampleCountThisPixel)) *(2*(0.2+canvas->histogramParameterA)); + if (a>1.0f) {a=1.0f;}; + if (a<0.0f) {a=0.0f;}; + + + //Colour gradedColor = lineColour.withMultipliedBrightness(2.0f).interpolatedWith(lineColour.withMultipliedSaturation(0.6f).withMultipliedBrightness(0.3f),1-a) ; + Colour gradedColor = lineColourBright.interpolatedWith(lineColourDark,1-a); + //Colour gradedColor = Colour(0,255,0); + + int ploty = from+s+getY(); + if(ploty>0 & ploty < display->lfpChannelBitmap.getHeight()) { + bdLfpChannelBitmap.setPixelColour(i,from+s+getY(),gradedColor); + } + } + + } else { + + int ploty = from+getY(); + if(ploty>0 & ploty < display->lfpChannelBitmap.getHeight()) { + bdLfpChannelBitmap.setPixelColour(i,ploty,lineColour); + } + } + + + + } + else //drawmethod + { // simple per-pixel min-max drawing, has no anti-aliasing, but runs faster + + int jfrom=from+getY(); + int jto=to+getY(); + + //if (yofs<0) {yofs=0;}; + + if (i<0) {i=0;}; + if (i >= display->lfpChannelBitmap.getWidth()) {i = display->lfpChannelBitmap.getWidth()-1;}; // this shouldnt happen, there must be some bug above - to replicate, run at max refresh rate where draws overlap the right margin by a lot + + if (jfrom<0) {jfrom=0;}; + if (jto >= display->lfpChannelBitmap.getHeight()) {jto=display->lfpChannelBitmap.getHeight()-1;}; + + + for (int j = jfrom; j <= jto; j += 1) + { + + //uint8* const pu8Pixel = bdSharedLfpDisplay.getPixelPointer( (int)(i),(int)(j)); + //*(pu8Pixel) = 200; + //*(pu8Pixel+1) = 200; + //*(pu8Pixel+2) = 200; + + bdLfpChannelBitmap.setPixelColour(i,j,lineColour); + + } + + } + + // now draw warnings, if needed + if (canvas->drawClipWarning) // draw simple warning if display cuts off data + { + + if(clipWarningHi) { + for (int j=0; j<=3; j++) + { + int clipmarker = jto_wholechannel_clip; + + if(clipmarker>0 & clipmarker<display->lfpChannelBitmap.getHeight()){ + bdLfpChannelBitmap.setPixelColour(i,clipmarker-j,Colour(255,255,255)); + } + } + } + + if(clipWarningLo) { + for (int j=0; j<=3; j++) + { + int clipmarker = jfrom_wholechannel_clip; + + if(clipmarker>0 & clipmarker<display->lfpChannelBitmap.getHeight()){ + bdLfpChannelBitmap.setPixelColour(i,clipmarker+j,Colour(255,255,255)); + } + } + } + + clipWarningHi=false; + clipWarningLo=false; + } + + + if (canvas->drawSaturationWarning) // draw bigger warning if actual data gets cuts off + { + + if(saturateWarningHi || saturateWarningLo) { + + + for (int k=jfrom_wholechannel; k<=jto_wholechannel; k++){ // draw line + Colour thiscolour=Colour(255,0,0); + if (fmod((i+k),50)>25){ + thiscolour=Colour(255,255,255); + } + if(k>0 & k<display->lfpChannelBitmap.getHeight()){ + bdLfpChannelBitmap.setPixelColour(i,k,thiscolour); + } + }; + } + + saturateWarningHi=false; // we likely just need one of this because for this warning we dont care if its saturating on the positive or negative side + saturateWarningLo=false; + } + + + } // for i (x pixels) + + } // isenabled + + +} + +void LfpChannelDisplay::paint(Graphics& g) {} + + + +PopupMenu LfpChannelDisplay::getOptions() +{ + + PopupMenu menu; + menu.addItem(1, "Invert signal", true, inputInverted); + + return menu; +} + +void LfpChannelDisplay::changeParameter(int id) +{ + switch (id) + { + case 1: + setInputInverted(!inputInverted); + default: + break; + } +} + +void LfpChannelDisplay::setRange(float r) +{ + + range = r; + + //std::cout << "Range: " << r << std::endl; +} + +int LfpChannelDisplay::getRange() +{ + return range; +} + + +void LfpChannelDisplay::select() +{ + isSelected = true; +} + +void LfpChannelDisplay::deselect() +{ + isSelected = false; +} + +bool LfpChannelDisplay::getSelected() +{ + return isSelected; +} + +void LfpChannelDisplay::setColour(Colour c) +{ + lineColour = c; +} + + +void LfpChannelDisplay::setChannelHeight(int c) +{ + channelHeight = c; + + channelHeightFloat = (float) channelHeight; + + if (!inputInverted) + channelHeightFloat = -channelHeightFloat; + + channelOverlap = channelHeight*2; +} + +int LfpChannelDisplay::getChannelHeight() +{ + + return channelHeight; +} + +void LfpChannelDisplay::setChannelOverlap(int overlap) +{ + channelOverlap = overlap; +} + + +int LfpChannelDisplay::getChannelOverlap() +{ + return channelOverlap; +} + +void LfpChannelDisplay::setCanBeInverted(bool _canBeInverted) +{ + canBeInverted = _canBeInverted; +} + +void LfpChannelDisplay::setInputInverted(bool isInverted) +{ + if (canBeInverted) + { + inputInverted = isInverted; + setChannelHeight(channelHeight); + } +} + +void LfpChannelDisplay::setDrawMethod(bool isDrawMethod) +{ + + drawMethod = isDrawMethod; + +} + + +void LfpChannelDisplay::setName(String name_) +{ + name = name_; +} + +ChannelType LfpChannelDisplay::getType() +{ + return type; +} + +// ------------------------------- + +LfpChannelDisplayInfo::LfpChannelDisplayInfo(LfpDisplayCanvas* canvas_, LfpDisplay* display_, int ch) + : LfpChannelDisplay(canvas_, display_, ch) +{ + + chan = ch; + + enableButton = new UtilityButton(String(ch+1), Font("Small Text", 13, Font::plain)); + enableButton->setRadius(5.0f); + + enableButton->setEnabledState(true); + enableButton->setCorners(true, true, true, true); + enableButton->addListener(this); + enableButton->setClickingTogglesState(true); + enableButton->setToggleState(true, dontSendNotification); + + addAndMakeVisible(enableButton); + +} + +void LfpChannelDisplayInfo::updateType() +{ + type = canvas->getChannelType(chan); + typeStr = canvas->getTypeName(type); + repaint(); +} + +void LfpChannelDisplayInfo::buttonClicked(Button* button) +{ + + bool state = button->getToggleState(); + + display->setEnabledState(state, chan); + + //UtilityButton* b = (UtilityButton*) button; + + // if (state) + // { + // b->setLabel("ON"); + // } else { + // b->setLabel("OFF"); + // } + + //std::cout << "Turn channel " << chan << " to " << button->getToggleState() << std::endl; + +} + +void LfpChannelDisplayInfo::setEnabledState(bool state) +{ + enableButton->setToggleState(state, sendNotification); +} + +void LfpChannelDisplayInfo::paint(Graphics& g) +{ + + int center = getHeight()/2; + + g.setColour(lineColour); + + //if (chan > 98) + // g.fillRoundedRectangle(5,center-8,51,22,8.0f); + //else + g.fillRoundedRectangle(5,center-8,41,22,8.0f); + + g.setFont(Font("Small Text", 13, Font::plain)); + g.drawText(typeStr,5,center+16,41,10,Justification::centred,false); + // g.setFont(channelHeightFloat*0.3); + + // g.drawText(name, 10, center-channelHeight/2, 200, channelHeight, Justification::left, false); + +} + +void LfpChannelDisplayInfo::resized() +{ + + int center = getHeight()/2; + + //if (chan > 98) + // enableButton->setBounds(8,center-5,45,16); + //else + enableButton->setBounds(8,center-5,35,16); +} + + + +// Event display Options -------------------------------------------------------------------- + +EventDisplayInterface::EventDisplayInterface(LfpDisplay* display_, LfpDisplayCanvas* canvas_, int chNum): + isEnabled(true), display(display_), canvas(canvas_) +{ + + channelNumber = chNum; + + chButton = new UtilityButton(String(channelNumber+1), Font("Small Text", 13, Font::plain)); + chButton->setRadius(5.0f); + chButton->setBounds(4,4,14,14); + chButton->setEnabledState(true); + chButton->setCorners(true, false, true, false); + //chButton.color = display->channelColours[channelNumber*2]; + chButton->addListener(this); + addAndMakeVisible(chButton); + + + checkEnabledState(); + +} + +EventDisplayInterface::~EventDisplayInterface() +{ + +} + +void EventDisplayInterface::checkEnabledState() +{ + isEnabled = display->getEventDisplayState(channelNumber); + + //repaint(); +} + +void EventDisplayInterface::buttonClicked(Button* button) +{ + checkEnabledState(); + if (isEnabled) + { + display->setEventDisplayState(channelNumber, false); + } + else + { + display->setEventDisplayState(channelNumber, true); + } + + repaint(); + +} + + +void EventDisplayInterface::paint(Graphics& g) +{ + + checkEnabledState(); + + if (isEnabled) + { + g.setColour(display->channelColours[channelNumber*2]); + g.fillRoundedRectangle(2,2,18,18,6.0f); + } + + + //g.drawText(String(channelNumber), 8, 2, 200, 15, Justification::left, false); + +} + +// Lfp Viewport ------------------------------------------- + +LfpViewport::LfpViewport(LfpDisplayCanvas *canvas) + : Viewport() +{ + this->canvas = canvas; +} + +void LfpViewport::visibleAreaChanged(const Rectangle<int>& newVisibleArea) +{ + canvas->fullredraw = true; + canvas->refresh(); +} diff --git a/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayCanvas.h b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayCanvas.h new file mode 100644 index 0000000000000000000000000000000000000000..8873da4e95a8b80b7e9d61fd6d0932f6bf4234db --- /dev/null +++ b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayCanvas.h @@ -0,0 +1,487 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2013 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 __LFPDISPLAYCANVAS_H_B711873A__ +#define __LFPDISPLAYCANVAS_H_B711873A__ + +#include "../../../JuceLibraryCode/JuceHeader.h" +#include "LfpDisplayNode.h" +#include "../../Processors/Visualization/Visualizer.h" +#define CHANNEL_TYPES 3 + +namespace LfpDisplayNodeBeta { + +class LfpDisplayNode; + +class LfpTimescale; +class LfpDisplay; +class LfpChannelDisplay; +class LfpChannelDisplayInfo; +class EventDisplayInterface; +class LfpViewport; + +/** + + Displays multiple channels of continuous data. + + @see LfpDisplayNode, LfpDisplayEditor + +*/ + +class LfpDisplayCanvas : public Visualizer, + public Slider::Listener, + public ComboBox::Listener, + public Button::Listener, + public KeyListener +{ +public: + LfpDisplayCanvas(LfpDisplayNode* n); + ~LfpDisplayCanvas(); + + void beginAnimation(); + void endAnimation(); + + void refreshState(); + void update(); + + void setParameter(int, float); + void setParameter(int, int, int, float) {} + + void setRangeSelection(float range, bool canvasMustUpdate = false); // set range selection combo box to correct value if it has been changed by scolling etc. + void setSpreadSelection(int spread, bool canvasMustUpdate = false); // set spread selection combo box to correct value if it has been changed by scolling etc. + + void paint(Graphics& g); + + void refresh(); + + void resized(); + + int getChannelHeight(); + + float channelOverlapFactor; + + float histogramParameterA; + float histogramParameterB; + + int getNumChannels(); + bool getInputInvertedState(); + bool getDrawMethodState(); + + const float getXCoord(int chan, int samp); + const float getYCoord(int chan, int samp); + + const float *getSamplesPerPixel(int chan, int px); + const int getSampleCountPerPixel(int px); + + const float getYCoordMin(int chan, int samp); + const float getYCoordMean(int chan, int samp); + const float getYCoordMax(int chan, int samp); + + Array<int> screenBufferIndex; + Array<int> lastScreenBufferIndex; + + void comboBoxChanged(ComboBox* cb); + void buttonClicked(Button* button); + + /** Handles slider events for all editors. */ + void sliderValueChanged(Slider* sl); + + /** Called by sliderValueChanged(). Deals with clicks on custom sliders. Subclasses + of GenericEditor should modify this method only.*/ + void sliderEvent(Slider* sl); + + void saveVisualizerParameters(XmlElement* xml); + void loadVisualizerParameters(XmlElement* xml); + + bool keyPressed(const KeyPress& key); + bool keyPressed(const KeyPress& key, Component* orig); + + ChannelType getChannelType(int n); + ChannelType getSelectedType(); + String getTypeName(ChannelType type); + int getRangeStep(ChannelType type); + + void setSelectedType(ChannelType type, bool toggleButton = true); + + //void scrollBarMoved(ScrollBar *scrollBarThatHasMoved, double newRangeStart); + + bool fullredraw; // used to indicate that a full redraw is required. is set false after each full redraw, there is a similar switch for each display; + static const int leftmargin=50; // left margin for lfp plots (so the ch number text doesnt overlap) + + Array<bool> isChannelEnabled; + + bool drawClipWarning; // optinally draw (subtle) warning if data is clipped in display + bool drawSaturationWarning; // optionally raise hell if the actual data is saturating + + float selectedSaturationValueFloat; // TODO: this is way ugly - we should refactor all these parameters soon and get them into a nicer format- probably when we do the genreal plugin parameter overhaul. + + + int nChans; + +private: + + Array<float> sampleRate; + float timebase; + float displayGain; + float timeOffset; + //int spread ; // vertical spacing between channels + + + static const int MAX_N_CHAN = 2048; // maximum number of channels + static const int MAX_N_SAMP = 5000; // maximum display size in pixels + static const int MAX_N_SAMP_PER_PIXEL = 1000; // maximum samples considered for drawing each pixel + //float waves[MAX_N_CHAN][MAX_N_SAMP*2]; // we need an x and y point for each sample + + LfpDisplayNode* processor; + AudioSampleBuffer* displayBuffer; // sample wise data buffer for display + AudioSampleBuffer* screenBuffer; // subsampled buffer- one int per pixel + + //'define 3 buffers for min mean and max for better plotting of spikes + // not pretty, but 'AudioSampleBuffer works only for channels X samples + AudioSampleBuffer* screenBufferMin; // like screenBuffer but holds min/mean/max values per pixel + AudioSampleBuffer* screenBufferMean; // like screenBuffer but holds min/mean/max values per pixel + AudioSampleBuffer* screenBufferMax; // like screenBuffer but holds min/mean/max values per pixel + + MidiBuffer* eventBuffer; + + ScopedPointer<LfpTimescale> timescale; + ScopedPointer<LfpDisplay> lfpDisplay; + ScopedPointer<LfpViewport> viewport; + + ScopedPointer<ComboBox> timebaseSelection; + ScopedPointer<ComboBox> rangeSelection; + ScopedPointer<ComboBox> spreadSelection; + + ScopedPointer<ComboBox> overlapSelection; + ScopedPointer<UtilityButton> drawClipWarningButton; // optinally draw (subtle) warning if data is clipped in display + + ScopedPointer<ComboBox> saturationWarningSelection; + ScopedPointer<UtilityButton> drawSaturateWarningButton; // optionally raise hell if the actual data is saturating + + ScopedPointer<ComboBox> colorGroupingSelection; + ScopedPointer<UtilityButton> invertInputButton; + ScopedPointer<UtilityButton> drawMethodButton; + ScopedPointer<UtilityButton> pauseButton; + OwnedArray<UtilityButton> typeButtons; + + + ScopedPointer<Slider> brightnessSliderA; + ScopedPointer<Slider> brightnessSliderB; + + ScopedPointer<Label> sliderALabel; + ScopedPointer<Label> sliderBLabel; + + StringArray voltageRanges[CHANNEL_TYPES]; + StringArray timebases; + StringArray spreads; // option for vertical spacing between channels + StringArray colorGroupings; // option for coloring every N channels the same + StringArray overlaps; // + StringArray saturationThresholds; //default values for when different amplifiers saturate + + + ChannelType selectedChannelType; + int selectedVoltageRange[CHANNEL_TYPES]; + String selectedVoltageRangeValues[CHANNEL_TYPES]; + float rangeGain[CHANNEL_TYPES]; + StringArray rangeUnits; + StringArray typeNames; + int rangeSteps[CHANNEL_TYPES]; + + int selectedSpread; + String selectedSpreadValue; + + int selectedTimebase; + String selectedTimebaseValue; + + int selectedOverlap; + String selectedOverlapValue; + + int selectedSaturation; // for saturation warning + String selectedSaturationValue; + + + OwnedArray<EventDisplayInterface> eventDisplayInterfaces; + + void refreshScreenBuffer(); + void updateScreenBuffer(); + + Array<int> displayBufferIndex; + int displayBufferSize; + + int scrollBarThickness; + + //float samplesPerPixel[MAX_N_SAMP][MAX_N_SAMP_PER_PIXEL]; + float*** samplesPerPixel; + int sampleCountPerPixel[MAX_N_SAMP]; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayCanvas); + +}; + +class LfpTimescale : public Component +{ +public: + LfpTimescale(LfpDisplayCanvas*); + ~LfpTimescale(); + + void paint(Graphics& g); + + void setTimebase(float t); + +private: + + LfpDisplayCanvas* canvas; + + float timebase; + + Font font; + + StringArray labels; + +}; + +class LfpDisplay : public Component +{ +public: + LfpDisplay(LfpDisplayCanvas*, Viewport*); + ~LfpDisplay(); + + Image lfpChannelBitmap; // plot as bitmap instead of separately setting pixels + // this is done purely for the preformance improvement + + void setNumChannels(int numChannels); + int getNumChannels(); + + int getTotalHeight(); + + void paint(Graphics& g); + + void refresh(); + + void resized(); + + void mouseDown(const MouseEvent& event); + void mouseWheelMove(const MouseEvent& event, const MouseWheelDetails& wheel) ; + + + void setRange(float range, ChannelType type); + + //Withouth parameters returns selected type + int getRange(); + int getRange(ChannelType type); + + void setChannelHeight(int r, bool resetSingle = true); + int getChannelHeight(); + void setInputInverted(bool); + void setDrawMethod(bool); + + void setColors(); + + bool setEventDisplayState(int ch, bool state); + bool getEventDisplayState(int ch); + + int getColorGrouping(); + void setColorGrouping(int i); + + void setEnabledState(bool, int); + bool getEnabledState(int); + void enableChannel(bool, int); + + bool getSingleChannelState(); + + Colour backgroundColour; + + Array<Colour> channelColours; + + Array<LfpChannelDisplay*> channels; + Array<LfpChannelDisplayInfo*> channelInfo; + + bool eventDisplayEnabled[8]; + bool isPaused; // simple pause function, skips screen bufer updates + + +private: + + + void toggleSingleChannel(int chan); + int singleChan; + Array<bool> savedChannelState; + + int numChans; + + int totalHeight; + + int colorGrouping; + + LfpDisplayCanvas* canvas; + Viewport* viewport; + + float range[3]; + + +}; + +class LfpChannelDisplay : public Component +{ +public: + LfpChannelDisplay(LfpDisplayCanvas*, LfpDisplay*, int channelNumber); + ~LfpChannelDisplay(); + + void resized(); + + void paint(Graphics& g); + + void pxPaint(); // like paint, but just populate lfpChannelBitmap + // needs to avoid a paint(Graphics& g) mechanism here becauswe we need to clear the screen in the lfpDisplay repaint(), + // because otherwise we cant deal with the channel overlap (need to clear a vertical section first, _then_ all channels are dawn, so cant do it per channel) + + + void select(); + void deselect(); + + bool getSelected(); + + void setName(String); + + void setColour(Colour c); + + void setChannelHeight(int); + int getChannelHeight(); + + void setChannelOverlap(int); + int getChannelOverlap(); + + void setRange(float range); + int getRange(); + + void setInputInverted(bool); + void setCanBeInverted(bool); + + void setDrawMethod(bool); + + PopupMenu getOptions(); + void changeParameter(const int id); + + void setEnabledState(bool); + bool getEnabledState() + { + return isEnabled; + } + + ChannelType getType(); + void updateType(); + + bool fullredraw; // used to indicate that a full redraw is required. is set false after each full redraw + +protected: + + + LfpDisplayCanvas* canvas; + LfpDisplay* display; + + bool isSelected; + + int chan; + + String name; + + Font channelFont; + + Colour lineColour; + + int channelOverlap; + int channelHeight; + float channelHeightFloat; + + float range; + + bool isEnabled; + bool inputInverted; + bool canBeInverted; + bool drawMethod; + + ChannelType type; + String typeStr; + + + +}; + +class LfpChannelDisplayInfo : public LfpChannelDisplay, + public Button::Listener +{ +public: + LfpChannelDisplayInfo(LfpDisplayCanvas*, LfpDisplay*, int channelNumber); + + void paint(Graphics& g); + + void buttonClicked(Button* button); + + void resized(); + + void setEnabledState(bool); + void updateType(); + +private: + + ScopedPointer<UtilityButton> enableButton; + +}; + +class EventDisplayInterface : public Component, + public Button::Listener +{ +public: + EventDisplayInterface(LfpDisplay*, LfpDisplayCanvas*, int chNum); + ~EventDisplayInterface(); + + void paint(Graphics& g); + + void buttonClicked(Button* button); + + void checkEnabledState(); + + bool isEnabled; + +private: + + int channelNumber; + + LfpDisplay* display; + LfpDisplayCanvas* canvas; + + ScopedPointer<UtilityButton> chButton; + +}; + +class LfpViewport : public Viewport +{ +public: + LfpViewport(LfpDisplayCanvas* canvas); + void visibleAreaChanged(const Rectangle<int>& newVisibleArea); + +private: + LfpDisplayCanvas* canvas; +}; +}; + +#endif // __LFPDISPLAYCANVAS_H_B711873A__ diff --git a/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayEditor.cpp b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayEditor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6f4d5aacf0e0ba20d972f9c34151d5271f6ea562 --- /dev/null +++ b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayEditor.cpp @@ -0,0 +1,68 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2013 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 "LfpDisplayEditor.h" + +using namespace LfpDisplayNodeBeta; + + +LfpDisplayEditor::LfpDisplayEditor(GenericProcessor* parentNode, bool useDefaultParameterEditors=true) + : VisualizerEditor(parentNode, useDefaultParameterEditors) + +{ + + tabText = "LFP"; + + desiredWidth = 180; + +} + +LfpDisplayEditor::~LfpDisplayEditor() +{ +} + + +Visualizer* LfpDisplayEditor::createNewCanvas() +{ + + LfpDisplayNode* processor = (LfpDisplayNode*) getProcessor(); + return new LfpDisplayCanvas(processor); + +} + +void LfpDisplayEditor::buttonCallback(Button* button) +{ + + int gId = button->getRadioGroupId(); + + if (gId > 0) + { + if (canvas != 0) + { + canvas->setParameter(gId-1, button->getName().getFloatValue()); + } + + } + +} + diff --git a/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayEditor.h b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayEditor.h new file mode 100644 index 0000000000000000000000000000000000000000..557512fddc4e76c8250fd95f080e8974cff9b057 --- /dev/null +++ b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayEditor.h @@ -0,0 +1,65 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2013 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 __LFPDISPLAYEDITOR_H_3438800D__ +#define __LFPDISPLAYEDITOR_H_3438800D__ + +#include "../../../JuceLibraryCode/JuceHeader.h" +#include "../../Processors/Editors/GenericEditor.h" +#include "../../UI/UIComponent.h" +#include "../../UI/DataViewport.h" +#include "../../Processors/Visualization/DataWindow.h" +#include "LfpDisplayNode.h" +#include "LfpDisplayCanvas.h" +#include "../../Processors/Editors/VisualizerEditor.h" + +class Visualizer; + +namespace LfpDisplayNodeBeta { + +/** + + User interface for the LfpDisplayNode sink. + + @see LfpDisplayNode, LfpDisplayCanvas + +*/ + +class LfpDisplayEditor : public VisualizerEditor +{ +public: + LfpDisplayEditor(GenericProcessor*, bool useDefaultParameterEditors); + ~LfpDisplayEditor(); + + void buttonCallback(Button* button); + + Visualizer* createNewCanvas(); + +private: + + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayEditor); + +}; +}; +#endif // __LFPDISPLAYEDITOR_H_3438800D__ diff --git a/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayNode.cpp b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayNode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d1b0e335c298939f4331927cc8907ec4c413f4b8 --- /dev/null +++ b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayNode.cpp @@ -0,0 +1,349 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2013 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 "LfpDisplayNode.h" +#include "LfpDisplayCanvas.h" +#include <stdio.h> + +using namespace LfpDisplayNodeBeta; + +LfpDisplayNode::LfpDisplayNode() + : GenericProcessor("LFP Viewer Beta"), + displayGain(1), bufferLength(20.0f), + abstractFifo(100) +{ + //std::cout << " LFPDisplayNodeConstructor" << std::endl; + displayBuffer = new AudioSampleBuffer(8, 100); + + arrayOfOnes = new float[5000]; + + for (int n = 0; n < 5000; n++) + { + arrayOfOnes[n] = 1; + } + +} + +LfpDisplayNode::~LfpDisplayNode() +{ + +} + +AudioProcessorEditor* LfpDisplayNode::createEditor() +{ + + editor = new LfpDisplayEditor(this, true); + return editor; + +} + +void LfpDisplayNode::updateSettings() +{ + std::cout << "Setting num inputs on LfpDisplayNode to " << getNumInputs() << std::endl; + + channelForEventSource.clear(); + eventSourceNodes.clear(); + ttlState.clear(); + + for (int i = 0; i < eventChannels.size(); i++) + { + if (!eventSourceNodes.contains(eventChannels[i]->sourceNodeId) && eventChannels[i]->type == EVENT_CHANNEL) + { + eventSourceNodes.add(eventChannels[i]->sourceNodeId); + + } + }\ + + numEventChannels = eventSourceNodes.size(); + + std::cout << "Found " << numEventChannels << " event channels." << std::endl; + + for (int i = 0; i < eventSourceNodes.size(); i++) + { + std::cout << "Adding channel " << getNumInputs() + i << " for event source node " << eventSourceNodes[i] << std::endl; + channelForEventSource[eventSourceNodes[i]] = getNumInputs() + i; + ttlState[eventSourceNodes[i]] = 0; + Channel* eventChan = new Channel(this, getNumInputs() + i, EVENT_CHANNEL); + eventChan->sourceNodeId = eventSourceNodes[i]; + channels.add(eventChan); // add a channel for event data for each source node + } + + displayBufferIndex.clear(); + displayBufferIndex.insertMultiple(0, 0, getNumInputs() + numEventChannels); + +} + +bool LfpDisplayNode::resizeBuffer() +{ + int nSamples = (int) getSampleRate()*bufferLength; + int nInputs = getNumInputs(); + + std::cout << "Resizing buffer. Samples: " << nSamples << ", Inputs: " << nInputs << std::endl; + + if (nSamples > 0 && nInputs > 0) + { + abstractFifo.setTotalSize(nSamples); + displayBuffer->setSize(nInputs + numEventChannels, nSamples); // add extra channels for TTLs + return true; + } + else + { + return false; + } + +} + +bool LfpDisplayNode::enable() +{ + + if (resizeBuffer()) + { + LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor(); + editor->enable(); + return true; + } + else + { + return false; + } + +} + +bool LfpDisplayNode::disable() +{ + LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor(); + editor->disable(); + return true; +} + +void LfpDisplayNode::setParameter(int parameterIndex, float newValue) +{ + editor->updateParameterButtons(parameterIndex); + //Sets Parameter in parameters array for processor + Parameter* parameterPointer = parameters.getRawDataPointer(); + parameterPointer = parameterPointer+parameterIndex; + parameterPointer->setValue(newValue, currentChannel); + + //std::cout << "Saving Parameter from " << currentChannel << ", channel "; + + LfpDisplayEditor* ed = (LfpDisplayEditor*) getEditor(); + if (ed->canvas != 0) + ed->canvas->setParameter(parameterIndex, newValue); +} + +void LfpDisplayNode::handleEvent(int eventType, MidiMessage& event, int sampleNum) +{ + if (eventType == TTL) + { + const uint8* dataptr = event.getRawData(); + + //int eventNodeId = *(dataptr+1); + int eventId = *(dataptr+2); + int eventChannel = *(dataptr+3); + int eventTime = event.getTimeStamp(); + + int eventSourceNodeId = *(dataptr+5); + + int nSamples = numSamples.at(eventSourceNodeId); + + int samplesToFill = nSamples - eventTime; + + // std::cout << "Received event from " << eventSourceNode << ", channel " + // << eventChannel << ", with ID " << eventId << ", copying to " + // << channelForEventSource[eventSourceNode] << std::endl; + //// + int bufferIndex = (displayBufferIndex[channelForEventSource[eventSourceNodeId]] + eventTime - nSamples) % displayBuffer->getNumSamples(); + + bufferIndex = bufferIndex >= 0 ? bufferIndex : + displayBuffer->getNumSamples() + bufferIndex; + + + if (eventId == 1) + { + ttlState[eventSourceNodeId] |= (1L << eventChannel); + } + else + { + ttlState[eventSourceNodeId] &= ~(1L << eventChannel); + } + + if (samplesToFill + bufferIndex < displayBuffer->getNumSamples()) + { + + //std::cout << bufferIndex << " " << samplesToFill << " " << ttlState[eventSourceNode] << std::endl; + + displayBuffer->copyFrom(channelForEventSource[eventSourceNodeId], // destChannel + bufferIndex, // destStartSample + arrayOfOnes, // source + samplesToFill, // numSamples + float(ttlState[eventSourceNodeId])); // gain + } + else + { + + int block2Size = (samplesToFill + bufferIndex) % displayBuffer->getNumSamples(); + int block1Size = samplesToFill - block2Size; + + //std::cout << "OVERFLOW." << std::endl; + + //std::cout << bufferIndex << " " << block1Size << " " << ttlState << std::endl; + + displayBuffer->copyFrom(channelForEventSource[eventSourceNodeId], // destChannel + bufferIndex, // destStartSample + arrayOfOnes, // source + block1Size, // numSamples + float(ttlState[eventSourceNodeId])); // gain + + //std::cout << 0 << " " << block2Size << " " << ttlState << std::endl; + + displayBuffer->copyFrom(channelForEventSource[eventSourceNodeId], // destChannel + 0, // destStartSample + arrayOfOnes, // source + block2Size, // numSamples + float(ttlState[eventSourceNodeId])); // gain + + + } + + + // std::cout << "ttlState: " << ttlState << std::endl; + + // std::cout << "Received event from " << eventNodeId << + // " on channel " << eventChannel << + // " with value " << eventId << + // " at timestamp " << event.getTimeStamp() << std::endl; + + + } + +} + +void LfpDisplayNode::initializeEventChannels() +{ + + for (int i = 0; i < eventSourceNodes.size(); i++) + { + + int chan = channelForEventSource[eventSourceNodes[i]]; + int index = displayBufferIndex[chan]; + + //std::cout << "Event source node " << i << ", channel " << chan << std::endl; + + int samplesLeft = displayBuffer->getNumSamples() - index; + + int nSamples = numSamples.at(eventSourceNodes[i]); + + + + if (nSamples < samplesLeft) + { + + // std::cout << getNumInputs()+1 << " " << displayBufferIndex << " " << totalSamples << " " << ttlState << std::endl; + // + displayBuffer->copyFrom(chan, // destChannel + index, // destStartSample + arrayOfOnes, // source + nSamples, // numSamples + float(ttlState[eventSourceNodes[i]])); // gain + + displayBufferIndex.set(chan, index + nSamples); + } + else + { + + int extraSamples = nSamples - samplesLeft; + + // std::cout << "OVERFLOW." << std::endl; + // std::cout << bufferIndex << " " << block1Size << " " << ttlState << std::endl; + + displayBuffer->copyFrom(chan, // destChannel + index, // destStartSample + arrayOfOnes, // source + samplesLeft, // numSamples + float(ttlState[eventSourceNodes[i]])); // gain + // std::cout << 0 << " " << block2Size << " " << ttlState << std::endl; + + displayBuffer->copyFrom(chan, // destChannel + 0, // destStartSample + arrayOfOnes, // source + extraSamples, // numSamples + float(ttlState[eventSourceNodes[i]])); // gain + + displayBufferIndex.set(chan, extraSamples); + } + } +} + +void LfpDisplayNode::process(AudioSampleBuffer& buffer, MidiBuffer& events) +{ + // 1. place any new samples into the displayBuffer + //std::cout << "Display node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl; + + initializeEventChannels(); + + checkForEvents(events); // see if we got any TTL events + + ScopedLock displayLock(displayMutex); + + for (int chan = 0; chan < buffer.getNumChannels(); chan++) + { + int samplesLeft = displayBuffer->getNumSamples() - displayBufferIndex[chan]; + int nSamples = getNumSamples(chan); + + if (nSamples < samplesLeft) + { + + displayBuffer->copyFrom(chan, // destChannel + displayBufferIndex[chan], // destStartSample + buffer, // source + chan, // source channel + 0, // source start sample + nSamples); // numSamples + + displayBufferIndex.set(chan, displayBufferIndex[chan] + nSamples); + } + else + { + + int extraSamples = nSamples - samplesLeft; + + displayBuffer->copyFrom(chan, // destChannel + displayBufferIndex[chan], // destStartSample + buffer, // source + chan, // source channel + 0, // source start sample + samplesLeft); // numSamples + + displayBuffer->copyFrom(chan, + 0, + buffer, + chan, + samplesLeft, + extraSamples); + + displayBufferIndex.set(chan, extraSamples); + } + } + +} + diff --git a/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayNode.h b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayNode.h new file mode 100644 index 0000000000000000000000000000000000000000..9b595e827a40b6003c25aa9f99248811c3aec8aa --- /dev/null +++ b/Source/Plugins/LfpDisplayNodeBeta/LfpDisplayNode.h @@ -0,0 +1,119 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2013 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 __LFPDISPLAYNODE_H_D969A379__ +#define __LFPDISPLAYNODE_H_D969A379__ + +#include "../../../JuceLibraryCode/JuceHeader.h" +#include "LfpDisplayEditor.h" +#include "../../Processors/Editors/VisualizerEditor.h" +#include "../../Processors/GenericProcessor/GenericProcessor.h" + + +class DataViewport; + +namespace LfpDisplayNodeBeta { + +/** + + Holds data in a displayBuffer to be used by the LfpDisplayCanvas + for rendering continuous data streams. + + @see GenericProcessor, LfpDisplayEditor, LfpDisplayCanvas + +*/ + +class LfpDisplayNode : public GenericProcessor + +{ +public: + + LfpDisplayNode(); + ~LfpDisplayNode(); + + AudioProcessorEditor* createEditor(); + + bool isSink() + { + return true; + } + + void process(AudioSampleBuffer& buffer, MidiBuffer& midiMessages); + + void setParameter(int, float); + + void updateSettings(); + + bool enable(); + bool disable(); + + void handleEvent(int, MidiMessage&, int); + + AudioSampleBuffer* getDisplayBufferAddress() + { + return displayBuffer; + } + int getDisplayBufferIndex(int chan) + { + return displayBufferIndex[chan]; + } + + CriticalSection* getMutex() + { + return &displayMutex; + } + +private: + + void initializeEventChannels(); + + ScopedPointer<AudioSampleBuffer> displayBuffer; + + Array<int> displayBufferIndex; + Array<int> eventSourceNodes; + std::map<int, int> channelForEventSource; + + int numEventChannels; + + float displayGain; // + float bufferLength; // s + + AbstractFifo abstractFifo; + + int64 bufferTimestamp; + std::map<int, int> ttlState; + float* arrayOfOnes; + int totalSamples; + + bool resizeBuffer(); + + CriticalSection displayMutex; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LfpDisplayNode); + +}; +}; + + + +#endif // __LFPDISPLAYNODE_H_D969A379__ diff --git a/Source/Plugins/LfpDisplayNodeBeta/Makefile b/Source/Plugins/LfpDisplayNodeBeta/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..7ea147feb7214c68e4ac0b8d490b5a6d7705ef7e --- /dev/null +++ b/Source/Plugins/LfpDisplayNodeBeta/Makefile @@ -0,0 +1,39 @@ + +LIBNAME := $(notdir $(CURDIR)) +OBJDIR := $(OBJDIR)/$(LIBNAME) +TARGET := $(LIBNAME).so + + +SRC_DIR := ${shell find ./ -type d -print} +VPATH := $(SOURCE_DIRS) + +SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cpp)) +OBJ := $(addprefix $(OBJDIR)/,$(notdir $(SRC:.cpp=.o))) + +BLDCMD := $(CXX) -shared -o $(OUTDIR)/$(TARGET) $(OBJ) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) + +VPATH = $(SRC_DIR) + +.PHONY: objdir + +$(OUTDIR)/$(TARGET): objdir $(OBJ) + -@mkdir -p $(BINDIR) + -@mkdir -p $(LIBDIR) + -@mkdir -p $(OUTDIR) + @echo "Building $(TARGET)" + @$(BLDCMD) + +$(OBJDIR)/%.o : %.cpp + @echo "Compiling $<" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + + +objdir: + -@mkdir -p $(OBJDIR) + +clean: + @echo "Cleaning $(LIBNAME)" + -@rm -rf $(OBJDIR) + -@rm -f $(OUTDIR)/$(TARGET) + +-include $(OBJ:%.o=%.d) diff --git a/Source/Plugins/LfpDisplayNodeBeta/OpenEphysLib.cpp b/Source/Plugins/LfpDisplayNodeBeta/OpenEphysLib.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2e7f81cdd745c5113edb78cee0d643a2e2e96c7c --- /dev/null +++ b/Source/Plugins/LfpDisplayNodeBeta/OpenEphysLib.cpp @@ -0,0 +1,72 @@ +/* +------------------------------------------------------------------ + +This file is part of the Open Ephys GUI +Copyright (C) 2013 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 "../../Processors/PluginManager/OpenEphysPlugin.h" +#include "LfpDisplayNode.h" +#include <string> +#ifdef WIN32 +#include <Windows.h> +#define EXPORT __declspec(dllexport) +#else +#define EXPORT +#endif + +using namespace Plugin; +using namespace LfpDisplayNodeBeta; + +#define NUM_PLUGINS 1 + +extern "C" EXPORT void getLibInfo(Plugin::LibraryInfo* info) +{ + info->apiVersion = PLUGIN_API_VER; + info->name = "LFP viewer Beta"; + info->libVersion = 1; + info->numPlugins = NUM_PLUGINS; +} + +extern "C" EXPORT int getPluginInfo(int index, Plugin::PluginInfo* info) +{ + switch (index) + { + case 0: + info->type = Plugin::ProcessorPlugin; + info->processor.name = "LFP Viewer Beta"; + info->processor.type = Plugin::SinkProcessor; + info->processor.creator = &(Plugin::createProcessor<LfpDisplayNodeBeta::LfpDisplayNode>); + break; + default: + return -1; + break; + } + return 0; +} + +#ifdef WIN32 +BOOL WINAPI DllMain(IN HINSTANCE hDllHandle, + IN DWORD nReason, + IN LPVOID Reserved) +{ + return TRUE; +} + +#endif \ No newline at end of file diff --git a/Source/Plugins/NetworkEvents/Makefile b/Source/Plugins/NetworkEvents/Makefile index 64235b796ccf7b7bc9e99faa788a2fbb979d61f9..c916381bcc66174e176da18f4d1f0898da744914 100644 --- a/Source/Plugins/NetworkEvents/Makefile +++ b/Source/Plugins/NetworkEvents/Makefile @@ -2,7 +2,6 @@ LIBNAME := $(notdir $(CURDIR)) OBJDIR := $(OBJDIR)/$(LIBNAME) TARGET := $(LIBNAME).so -OS := $(shell uname) SRC_DIR := ${shell find ./ -type d -print} VPATH := $(SOURCE_DIRS) @@ -10,10 +9,6 @@ VPATH := $(SOURCE_DIRS) SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cpp)) OBJ := $(addprefix $(OBJDIR)/,$(notdir $(SRC:.cpp=.o))) -ifeq ($(OS),Darwin) -CXXFLAGS := $(CXXFLAGS) -I/opt/local/include -LDFLAGS := $(LDFLAGS) -L/opt/local/lib -endif CXXFLAGS := $(CXXFLAGS) -D "ZEROMQ" LDFLAGS := $(LDFLAGS) -lzmq diff --git a/Source/Plugins/NetworkEvents/NetworkEvents.cpp b/Source/Plugins/NetworkEvents/NetworkEvents.cpp index 5c62eb28f4f64bccd11f0c0cd9df60b1612b287f..0982e85d85acd260b2329ba808304b55f513da87 100644 --- a/Source/Plugins/NetworkEvents/NetworkEvents.cpp +++ b/Source/Plugins/NetworkEvents/NetworkEvents.cpp @@ -298,7 +298,7 @@ void NetworkEvents::postTimestamppedStringToMidiBuffer(StringTS s, MidiBuffer& e (uint8) s.len+1,//+8, msg_with_ts); - delete msg_with_ts; + delete[] msg_with_ts; } void NetworkEvents::simulateStopRecord() @@ -507,10 +507,8 @@ String NetworkEvents::handleSpecialMessages(StringTS msg) status += CoreServices::RecordNode::getExperimentNumber(); return status; } - else - { - return String("NotHandled"); - } + + return String("NotHandled"); } void NetworkEvents::process(AudioSampleBuffer& buffer, @@ -596,7 +594,7 @@ void NetworkEvents::run() zmq_close(responder); - delete buffer; + delete[] buffer; threadRunning = false; return; #endif diff --git a/Source/Plugins/SpikeSorter/SpikeSortBoxes.cpp b/Source/Plugins/SpikeSorter/SpikeSortBoxes.cpp index 2d3824c1c6d3d9776f4489b1124ed6aeb50309a9..6158a63fa29e45212bb1ab8656e6054e83e9e9c7 100644 --- a/Source/Plugins/SpikeSorter/SpikeSortBoxes.cpp +++ b/Source/Plugins/SpikeSorter/SpikeSortBoxes.cpp @@ -1753,7 +1753,7 @@ float PCAjob::pythag(float a, float b) int PCAjob::svdcmp(float** a, int nRows, int nCols, float* w, float** v) { - int flag, i, its, j, jj, k, l, nm; + int flag, i, its, j, jj, k, l = 0, nm = 0; float anorm, c, f, g, h, s, scale, x, y, z, *rv1; rv1 = new float[nCols]; @@ -2029,7 +2029,7 @@ void PCAjob::computeCov() cov[j][i] = sum / (dim-1); } } - delete mean; + delete[] mean; // delete covariances //for (int k = 0; k < dim; k++) diff --git a/Source/Plugins/SpikeSorter/SpikeSorter.cpp b/Source/Plugins/SpikeSorter/SpikeSorter.cpp index 9ebb67483f4c11a8e6afb90994b655cd43215bc9..d437744ab5a7376ba1c8668b095ab53930268da7 100644 --- a/Source/Plugins/SpikeSorter/SpikeSorter.cpp +++ b/Source/Plugins/SpikeSorter/SpikeSorter.cpp @@ -1464,8 +1464,8 @@ std::vector<int> SpikeSorter::getElectrodeChannels(int ID) ch[j] = electrodes[k]->channels[j]; } - return ch; mut.exit(); + return ch; } @@ -1861,7 +1861,7 @@ void ContinuousCircularBuffer::update(AudioSampleBuffer& buffer, int64 hardware_ // we don't start from zero because of subsampling issues. // previous packet may not have ended exactly at the last given sample. int k = leftover_k; - int lastUsedSample; + int lastUsedSample = 0; for (; k < numpts; k+=subSampling) { lastUsedSample = k; @@ -1899,7 +1899,7 @@ void ContinuousCircularBuffer::update(std::vector<std::vector<bool>> contdata, i // we don't start from zero because of subsampling issues. // previous packet may not have ended exactly at the last given sample. int k = leftover_k; - int lastUsedSample; + int lastUsedSample = 0; for (; k < numpts; k+=subSampling) { lastUsedSample = k; diff --git a/Source/Plugins/SpikeSorter/SpikeSorterCanvas.cpp b/Source/Plugins/SpikeSorter/SpikeSorterCanvas.cpp index e33c7cf4270bf2eba45b21d2e9a6a9781b62fc56..1baf9cf1233052ee65a001772f4a770328c44982 100644 --- a/Source/Plugins/SpikeSorter/SpikeSorterCanvas.cpp +++ b/Source/Plugins/SpikeSorter/SpikeSorterCanvas.cpp @@ -701,11 +701,13 @@ void SpikeHistogramPlot::resized() float width = (float)getWidth()-10; float height = (float) getHeight()-25; - float axesWidth, axesHeight; + float axesWidth = 0; + float axesHeight = 0; // to compute the axes positions we need to know how many columns of proj and wave axes should exist // using these two values we can calculate the positions of all of the sub axes - int nProjCols, nWaveCols; + int nProjCols = 0; + int nWaveCols = 0; switch (plotType) { @@ -755,7 +757,7 @@ void SpikeHistogramPlot::modifyRange(std::vector<float> values) { for (int k = 0; k < NUM_RANGE; k++) { - if (abs(values[index] - range_array[k]) < 0.1) + if (std::abs(values[index] - range_array[k]) < 0.1) { newIndex = k; break; @@ -777,7 +779,7 @@ void SpikeHistogramPlot::modifyRange(int index,bool up) String label; for (int k = 0; k < NUM_RANGE; k++) { - if (abs(ranges[index] - range_array[k]) < 0.1) + if (std::abs(ranges[index] - range_array[k]) < 0.1) { int newIndex; if (up) @@ -1007,7 +1009,7 @@ double GenericDrawAxes::ad16ToUv(int x, int gain) // -------------------------------------------------- -WaveformAxes::WaveformAxes(SpikeHistogramPlot* plt, SpikeSorter* p,int electrodeID_, int _channel) : GenericDrawAxes(channel), electrodeID(electrodeID_), +WaveformAxes::WaveformAxes(SpikeHistogramPlot* plt, SpikeSorter* p,int electrodeID_, int _channel) : GenericDrawAxes(_channel), electrodeID(electrodeID_), signalFlipped(false), channel(_channel), drawGrid(true), diff --git a/Source/Plugins/SpikeSorter/SpikeSorterEditor.cpp b/Source/Plugins/SpikeSorter/SpikeSorterEditor.cpp index 989d0c518d926b8a7623b7088e3d3e252b3e28db..bf4bff7e8ac50b7c7878c46919eaf6ecdad37086 100644 --- a/Source/Plugins/SpikeSorter/SpikeSorterEditor.cpp +++ b/Source/Plugins/SpikeSorter/SpikeSorterEditor.cpp @@ -368,10 +368,10 @@ void SpikeSorterEditor::buttonEvent(Button* button) probeMenu.addSubMenu("Depth probe", depthprobeMenu,true); const int result = probeMenu.show(); - int nChansPerElectrode; - int nElectrodes; - double interelectrodeDistance=0; - double firstElectrodeOffset ; + int nChansPerElectrode = 0; + int nElectrodes = 0; + double interelectrodeDistance = 0; + double firstElectrodeOffset = 0; int numProbes = numElectrodes->getText().getIntValue(); String ProbeType; @@ -494,42 +494,43 @@ void SpikeSorterEditor::setThresholdValue(int channel, double threshold) repaint(); } -void SpikeSorterEditor::channelChanged(int chan) +void SpikeSorterEditor::channelChanged (int channel, bool newState) { //std::cout << "New channel: " << chan << std::endl; - if (chan <=0) + if (channel <= 0) return; - for (int i = 0; i < electrodeButtons.size(); i++) + const int numElectrodeButtons = electrodeButtons.size(); + for (int i = 0; i < numElectrodeButtons; ++i) { if (electrodeButtons[i]->getToggleState()) { - electrodeButtons[i]->setChannelNum(chan); + electrodeButtons[i]->setChannelNum (channel); electrodeButtons[i]->repaint(); + Array<int> a; - a.add(chan-1); - channelSelector->setActiveChannels(a); + a.add (channel - 1); + channelSelector->setActiveChannels (a); + SpikeSorter* processor = (SpikeSorter*) getProcessor(); processor->setChannel(electrodeList->getSelectedItemIndex(), i, - chan-1); + channel - 1); // if DAC is selected, update the mapping. - int dacchannel = dacCombo->getSelectedId()-2; + int dacchannel = dacCombo->getSelectedId() - 2; if (dacchannel >=0) { - processor->assignDACtoChannel(dacchannel, chan-1); + processor->assignDACtoChannel (dacchannel, channel - 1); } if (processor->getAutoDacAssignmentStatus()) { - processor->assignDACtoChannel(0,chan-1); - processor->assignDACtoChannel(1,chan-1); + processor->assignDACtoChannel (0, channel - 1); + processor->assignDACtoChannel (1, channel - 1); break; } - } } - } int SpikeSorterEditor::getSelectedElectrode() diff --git a/Source/Plugins/SpikeSorter/SpikeSorterEditor.h b/Source/Plugins/SpikeSorter/SpikeSorterEditor.h index 08c51458a3aef0092bc4b2b0d3bc6d7730f02670..b0213feb07963ff5eb7e6ab118df78471e5829c3 100644 --- a/Source/Plugins/SpikeSorter/SpikeSorterEditor.h +++ b/Source/Plugins/SpikeSorter/SpikeSorterEditor.h @@ -54,7 +54,7 @@ public: void comboBoxChanged(ComboBox* comboBox); void sliderEvent(Slider* slider); - void channelChanged(int chan); + void channelChanged (int chan, bool newState) override; Visualizer* createNewCanvas(); void checkSettings(); diff --git a/Source/Processors/AudioNode/AudioEditor.cpp b/Source/Processors/AudioNode/AudioEditor.cpp index c2e84edc4d7791dcb2a2262c4c22200eb456b33b..26433af8ed3bd78b7d65de74bec4a6444c2c1925 100755 --- a/Source/Processors/AudioNode/AudioEditor.cpp +++ b/Source/Processors/AudioNode/AudioEditor.cpp @@ -24,117 +24,144 @@ #include "AudioEditor.h" #include "../../Audio/AudioComponent.h" #include "../../AccessClass.h" +#include "../../UI/LookAndFeel/MaterialSliderLookAndFeel.h" -MuteButton::MuteButton() - : ImageButton("MuteButton") -{ +static const Colour COLOUR_SLIDER_TRACK (Colour::fromRGB (92, 92, 92)); +static const Colour COLOUR_SLIDER_TRACK_FILL (Colour::fromRGB (255, 255, 255)); + +static const Font FONT_LABEL ("Small Text", 12, Font::plain); - Image offimage = ImageCache::getFromMemory(BinaryData::muteoff_png, BinaryData::muteoff_pngSize); - Image onimage = ImageCache::getFromMemory(BinaryData::muteon_png, BinaryData::muteon_pngSize); - setImages(false, true, true, - offimage, 1.0f, Colours::white.withAlpha(0.0f), - offimage, 1.0f, Colours::black.withAlpha(0.0f), - onimage, 1.0f, Colours::white.withAlpha(0.0f)); +MuteButton::MuteButton() + : ImageButton ("MuteButton") +{ + Image offimage = ImageCache::getFromMemory (BinaryData::muteoff_png, BinaryData::muteoff_pngSize); + Image onimage = ImageCache::getFromMemory (BinaryData::muteon_png, BinaryData::muteon_pngSize); + + setImages (false, true, true, + offimage, 1.0f, Colours::white.withAlpha (0.0f), + offimage, 1.0f, Colours::black.withAlpha (0.0f), + onimage, 1.0f, Colours::lightgrey); - setClickingTogglesState(true); + setClickingTogglesState (true); - setTooltip("Mute audio"); + setTooltip ("Mute audio"); } + MuteButton::~MuteButton() { } + AudioWindowButton::AudioWindowButton() - : Button("AudioWindowButton") + : Button ("AudioWindowButton") { - setClickingTogglesState(true); - - //MemoryInputStream mis(BinaryData::silkscreenserialized, BinaryData::silkscreenserializedSize, false); - //Typeface::Ptr typeface = new CustomTypeface(mis); - font = Font("Small Text", 12, Font::plain); //Font(typeface); - //font.setHeight(12); - textString = "AUDIO"; - setTooltip("Change the buffer size"); + setClickingTogglesState (true); + + textString = ":AUDIO"; + setTooltip ("Change the buffer size"); } + AudioWindowButton::~AudioWindowButton() { } -void AudioWindowButton::paintButton(Graphics& g, bool isMouseOver, bool isButtonDown) + +void AudioWindowButton::paintButton (Graphics& g, bool isMouseOver, bool isButtonDown) { if (getToggleState()) - g.setColour(Colours::yellow); + g.setColour (Colours::yellow); else - g.setColour(Colours::lightgrey); + g.setColour (Colours::lightgrey); - g.setFont(font); - //g.drawSingleLineText(" AUDIO",0,0); - g.drawSingleLineText(textString,0,15); + const bool isLatencyLabelVisible = getParentComponent()->getWidth() >= 450; + auto textToDraw = isLatencyLabelVisible ? textString : textString.fromLastOccurrenceOf (":", false, true); + g.setFont (FONT_LABEL); + g.drawSingleLineText (textToDraw, 0, 15); } -void AudioWindowButton::setText(String text) + +void AudioWindowButton::setText (const String& newText) { - textString = text; + textString = newText; repaint(); } -AudioEditor::AudioEditor(AudioNode* owner) - : AudioProcessorEditor(owner), lastValue(1.0f), isEnabled(true), acw(0) +AudioEditor::AudioEditor (AudioNode* owner) + : AudioProcessorEditor (owner) + , lastValue (1.0f) + , isEnabled (true) + , audioConfigurationWindow (nullptr) { - muteButton = new MuteButton(); - muteButton->addListener(this); - muteButton->setToggleState(false, dontSendNotification); - addAndMakeVisible(muteButton); + muteButton->addListener (this); + muteButton->setToggleState (false, dontSendNotification); + addAndMakeVisible (muteButton); audioWindowButton = new AudioWindowButton(); - audioWindowButton->addListener(this); - audioWindowButton->setToggleState(false, dontSendNotification); - - //AccessClass* audioNode = (AccessClass*) getAudioProcessor(); - // - addAndMakeVisible(audioWindowButton); - - volumeSlider = new Slider("Volume Slider"); - volumeSlider->setRange(0,100,1); - volumeSlider->addListener(this); - volumeSlider->setTextBoxStyle(Slider::NoTextBox, - false, 0, 0); - volumeSlider->setColour(Slider::trackColourId,Colours::yellow); - addAndMakeVisible(volumeSlider); - - noiseGateSlider = new Slider("Noise Gate Slider"); - noiseGateSlider->setRange(0,100,1); - noiseGateSlider->addListener(this); - noiseGateSlider->setTextBoxStyle(Slider::NoTextBox, - false, 0, 0); - addAndMakeVisible(noiseGateSlider); - - - //acw = new AudioConfigurationWindow(getAudioComponent()->deviceManager, (Button*) audioWindowButton); - + audioWindowButton->addListener (this); + audioWindowButton->setToggleState (false, dontSendNotification); + addAndMakeVisible (audioWindowButton); + + volumeSlider = new Slider ("Volume Slider"); + volumeSlider->setSliderStyle (Slider::LinearHorizontal); + volumeSlider->setTextBoxStyle (Slider::NoTextBox, + false, 0, 0); + volumeSlider->setRange (0, 100, 1); + volumeSlider->setColour (Slider::backgroundColourId, COLOUR_SLIDER_TRACK); + volumeSlider->setColour (Slider::trackColourId, COLOUR_SLIDER_TRACK_FILL); + volumeSlider->setColour (Slider::thumbColourId, COLOUR_SLIDER_TRACK_FILL); + volumeSlider->setLookAndFeel (materialSliderLookAndFeel); + volumeSlider->addListener (this); + addAndMakeVisible (volumeSlider); + + noiseGateSlider = new Slider ("Noise Gate Slider"); + volumeSlider->setSliderStyle (Slider::LinearHorizontal); + noiseGateSlider->setTextBoxStyle (Slider::NoTextBox, + false, 0, 0); + noiseGateSlider->setRange (0,100,1); + noiseGateSlider->setColour (Slider::backgroundColourId, COLOUR_SLIDER_TRACK); + noiseGateSlider->setColour (Slider::trackColourId, COLOUR_SLIDER_TRACK_FILL); + noiseGateSlider->setColour (Slider::thumbColourId, COLOUR_SLIDER_TRACK_FILL); + noiseGateSlider->setLookAndFeel (materialSliderLookAndFeel); + noiseGateSlider->addListener (this); + addAndMakeVisible (noiseGateSlider); } + AudioEditor::~AudioEditor() { - deleteAllChildren(); - deleteAndZero(acw); } + void AudioEditor::resized() { - muteButton->setBounds(0,5,30,25); - volumeSlider->setBounds(35,8,50,getHeight()-5); - noiseGateSlider->setBounds(85,8,50,getHeight()-5); - audioWindowButton->setBounds(140,5,200,getHeight()); + const int width = getWidth(); + const int height = getHeight(); + + // Since width of the label on button is always the same, we should reserve it. + const bool isLatencyLabelVisible = width >= 450; + const int audioWindowButtonWidth = isLatencyLabelVisible ? 110 : 60; + const int gateLabelWidth = 45; + + const int availableWidth = width - audioWindowButtonWidth - gateLabelWidth; + const int sliderWidth = availableWidth * 0.4; + const int sliderHeight = height - 6; + const int sliderY = (height - sliderHeight) / 2; + const int margin = availableWidth * 0.03; + + muteButton->setBounds (margin, 5, 20, 20); + volumeSlider->setBounds (margin + 30, sliderY, sliderWidth, sliderHeight); + noiseGateSlider->setBounds (volumeSlider->getRight() + margin + gateLabelWidth, sliderY, sliderWidth, sliderHeight); + audioWindowButton->setBounds (width - audioWindowButtonWidth + 2, 5, audioWindowButtonWidth, height); } -bool AudioEditor::keyPressed(const KeyPress& key) + +bool AudioEditor::keyPressed (const KeyPress& key) { //std::cout << name << " received " << key.getKeyCode() << std::endl; return false; @@ -143,46 +170,47 @@ bool AudioEditor::keyPressed(const KeyPress& key) void AudioEditor::updateBufferSizeText() { + String t = String (AccessClass::getAudioComponent()->getBufferSizeMs()); + t = "Latency: " + t + " ms"; - String t = String(AccessClass::getAudioComponent()->getBufferSizeMs()); - t += " ms"; - - audioWindowButton->setText(t); + audioWindowButton->setText (t); } + void AudioEditor::enable() { isEnabled = true; - audioWindowButton->setClickingTogglesState(true); + audioWindowButton->setClickingTogglesState (true); } + void AudioEditor::disable() { isEnabled = false; - if (acw != 0) + if (audioConfigurationWindow) { - acw->setVisible(false); - audioWindowButton->setToggleState(false, dontSendNotification); + audioConfigurationWindow->setVisible (false); + audioWindowButton->setToggleState (false, dontSendNotification); } - audioWindowButton->setClickingTogglesState(false); + audioWindowButton->setClickingTogglesState (false); } -void AudioEditor::buttonClicked(Button* button) + +void AudioEditor::buttonClicked (Button* button) { if (button == muteButton) { - if (muteButton->getToggleState()) { lastValue = volumeSlider->getValue(); - getAudioProcessor()->setParameter(1,0.0f); + getAudioProcessor()->setParameter (1,0.0f); std::cout << "Mute on." << std::endl; } else { - getAudioProcessor()->setParameter(1,lastValue); + getAudioProcessor()->setParameter (1,lastValue); std::cout << "Mute off." << std::endl; } } @@ -190,142 +218,124 @@ void AudioEditor::buttonClicked(Button* button) { if (audioWindowButton->getToggleState()) { - if (acw == 0) + if (! audioConfigurationWindow) { - - // AudioComponent* audioComponent = getAudioComponent(); - // audioComponent->restartDevice(); - - // if (audioComponent != 0) { - acw = new AudioConfigurationWindow(AccessClass::getAudioComponent()->deviceManager, audioWindowButton); - //} + audioConfigurationWindow = new AudioConfigurationWindow (AccessClass::getAudioComponent()->deviceManager, + audioWindowButton); } - AccessClass::getAudioComponent()->restartDevice(); - acw->setVisible(true); - + AccessClass::getAudioComponent()->restartDevice(); + audioConfigurationWindow->setVisible (true); } else { updateBufferSizeText(); - //audioWindowButton->setText(String(getAudioComponent()->getBufferSize())); - acw->setVisible(false); - //deleteAndZero(acw); - AccessClass::getAudioComponent()->stopDevice(); + audioConfigurationWindow->setVisible (false); + AccessClass::getAudioComponent()->stopDevice(); } } } -void AudioEditor::sliderValueChanged(Slider* slider) + +void AudioEditor::sliderValueChanged (Slider* slider) { if (slider == volumeSlider) - getAudioProcessor()->setParameter(1,slider->getValue()); + getAudioProcessor()->setParameter (1, slider->getValue()); else if (slider == noiseGateSlider) - getAudioProcessor()->setParameter(2,slider->getValue()); + getAudioProcessor()->setParameter (2, slider->getValue()); } -void AudioEditor::paint(Graphics& g) -{ - //g.setColour(Colours::grey); - // g.fillRect(1,1,getWidth()-2,getHeight()-2); - g.setColour(Colours::grey); - g.setFont(10); - g.drawText("VOLUME:",40,1,50,10,Justification::left,false); - g.drawText("GATE:",90,1,50,10,Justification::left,false); -} -void AudioEditor::saveStateToXml(XmlElement* xml) +void AudioEditor::paint (Graphics& g) { + const int margin = getWidth() * 0.03; + g.setColour (Colours::lightgrey); + g.setFont (FONT_LABEL); + g.drawSingleLineText ("GATE:", volumeSlider->getBounds().getRight() + margin, 20); +} - XmlElement* audioEditorState = xml->createNewChildElement("AUDIOEDITOR"); - audioEditorState->setAttribute("isMuted",muteButton->getToggleState()); - audioEditorState->setAttribute("volume",volumeSlider->getValue()); - audioEditorState->setAttribute("noiseGate",noiseGateSlider->getValue()); - - // String audioDeviceName = getAudioComponent()->deviceManager.getCurrentAudioDeviceType(); - - // audioEditorState->setAttribute("deviceType",audioDeviceName); +void AudioEditor::saveStateToXml (XmlElement* xml) +{ + XmlElement* audioEditorState = xml->createNewChildElement ("AUDIOEDITOR"); + audioEditorState->setAttribute ("isMuted", muteButton->getToggleState()); + audioEditorState->setAttribute ("volume", volumeSlider->getValue()); + audioEditorState->setAttribute ("noiseGate", noiseGateSlider->getValue()); } -void AudioEditor::loadStateFromXml(XmlElement* xml) -{ - forEachXmlChildElement(*xml, xmlNode) +void AudioEditor::loadStateFromXml (XmlElement* xml) +{ + forEachXmlChildElement (*xml, xmlNode) { - if (xmlNode->hasTagName("AUDIOEDITOR")) + if (xmlNode->hasTagName ("AUDIOEDITOR")) { + muteButton->setToggleState (xmlNode->getBoolAttribute ("isMuted", false), dontSendNotification); - muteButton->setToggleState(xmlNode->getBoolAttribute("isMuted",false),dontSendNotification); - volumeSlider->setValue(xmlNode->getDoubleAttribute("volume",0.0f),NotificationType::sendNotification); - noiseGateSlider->setValue(xmlNode->getDoubleAttribute("noiseGate",0.0f),NotificationType::sendNotification); - - // String audioDeviceName = xmlNode->getStringAttribute("deviceType",""); - // getAudioComponent()->deviceManager.setCurrentAudioDeviceType(audioDeviceName, true); + volumeSlider->setValue (xmlNode->getDoubleAttribute ("volume", 0.0f), NotificationType::sendNotification); + noiseGateSlider->setValue (xmlNode->getDoubleAttribute ("noiseGate", 0.0f), NotificationType::sendNotification); } } updateBufferSizeText(); - } -AudioConfigurationWindow::AudioConfigurationWindow(AudioDeviceManager& adm, AudioWindowButton* cButton) - : DocumentWindow("Audio Settings", - Colours::red, - DocumentWindow::closeButton), - controlButton(cButton) + +AudioConfigurationWindow::AudioConfigurationWindow (AudioDeviceManager& adm, AudioWindowButton* cButton) + : DocumentWindow ("Audio Settings", + Colours::red, + DocumentWindow::closeButton) + , controlButton (cButton) { - centreWithSize(360,300); - setUsingNativeTitleBar(true); - setResizable(false,false); + centreWithSize (360,300); + setUsingNativeTitleBar (true); + setResizable (false,false); //std::cout << "Audio CPU usage:" << adm.getCpuUsage() << std::endl; AudioDeviceSelectorComponent* adsc = new AudioDeviceSelectorComponent - (adm, - 0, // minAudioInputChannels - 2, // maxAudioInputChannels - 0, // minAudioOutputChannels - 2, // maxAudioOutputChannels - false, // showMidiInputOptions - false, // showMidiOutputSelector - false, // showChannelsAsStereoPairs - false); // hideAdvancedOptionsWithButton - - adsc->setBounds(0,0,450,240); - - setContentOwned(adsc, true); - setVisible(false); - //setContentComponentSize(getWidth(), getHeight()); + (adm, + 0, // minAudioInputChannels + 2, // maxAudioInputChannels + 0, // minAudioOutputChannels + 2, // maxAudioOutputChannels + false, // showMidiInputOptions + false, // showMidiOutputSelector + false, // showChannelsAsStereoPairs + false); // hideAdvancedOptionsWithButton + + adsc->setBounds (0, 0, 450, 240); + + setContentOwned (adsc, true); + setVisible (false); } + AudioConfigurationWindow::~AudioConfigurationWindow() { - //setContentComponent (0); - //eleteAndZero(deviceManager); - // deleteAndZero (deviceSelector); } + void AudioConfigurationWindow::closeButtonPressed() { - controlButton->setToggleState(false, dontSendNotification); + controlButton->setToggleState (false, dontSendNotification); - //updateBufferSizeText(); - String t = String(AccessClass::getAudioComponent()->getBufferSizeMs()); + String t = String (AccessClass::getAudioComponent()->getBufferSizeMs()); t += " ms"; - controlButton->setText(t); - AccessClass::getAudioComponent()->stopDevice(); - setVisible(false); + controlButton->setText (t); + AccessClass::getAudioComponent()->stopDevice(); + setVisible (false); } + void AudioConfigurationWindow::resized() { - //deviceSelector->setBounds (8, 8, getWidth() - 16, getHeight() - 16); } -void AudioConfigurationWindow::paint(Graphics& g) + +void AudioConfigurationWindow::paint (Graphics& g) { - g.fillAll(Colours::darkgrey); + g.fillAll (Colours::darkgrey); } diff --git a/Source/Processors/AudioNode/AudioEditor.h b/Source/Processors/AudioNode/AudioEditor.h index e64a4a728c6b947bfe96152cecb09e1a567737e6..5c999ebec1fe86b9ae3852e582cd435024e1b0fc 100755 --- a/Source/Processors/AudioNode/AudioEditor.h +++ b/Source/Processors/AudioNode/AudioEditor.h @@ -30,14 +30,14 @@ class AudioNode; class AudioComponent; +class MaterialSliderLookAndFeel; /** - Toggles audio output on and off. + Toggles audio output on and off. - @see AudioNode, AudioEditor + @see AudioNode, AudioEditor */ - class MuteButton : public ImageButton { public: @@ -45,98 +45,100 @@ public: ~MuteButton(); }; + /** - Used to show and hide the AudioConfigurationWindow. + Used to show and hide the AudioConfigurationWindow. - @see AudioNode, AudioEditor + @see AudioNode, AudioEditor */ - class AudioWindowButton : public Button { public: AudioWindowButton(); ~AudioWindowButton(); - void paintButton(Graphics& g, bool isMouseOver, bool isButtonDown); - void setText(String); + + void paintButton (Graphics& g, bool isMouseOver, bool isButtonDown) override; + + void setText (const String& newText); + + private: - Font font; String textString; }; + /** - Allows the user to access audio output settings. + Allows the user to access audio output settings. - @see AudioNode, AudioEditor + @see AudioNode, AudioEditor */ - class AudioConfigurationWindow : public DocumentWindow { public: - AudioConfigurationWindow(AudioDeviceManager& adm, AudioWindowButton* b); + AudioConfigurationWindow (AudioDeviceManager& adm, AudioWindowButton* b); ~AudioConfigurationWindow(); - void paint(Graphics& g); - void resized(); + void paint (Graphics& g) override; + void resized() override; -private: +private: void closeButtonPressed(); AudioWindowButton* controlButton; - }; /** - Holds the interface for editing audio output parameters. + Holds the interface for editing audio output parameters. - @see AudioNode + @see AudioNode */ - -class AudioEditor : public AudioProcessorEditor, - public Button::Listener, - public Slider::Listener +class AudioEditor : public AudioProcessorEditor + , public Button::Listener + , public Slider::Listener { public: - AudioEditor(AudioNode* owner); + AudioEditor (AudioNode* owner); ~AudioEditor(); - void paint(Graphics& g); - - bool keyPressed(const KeyPress& key); - - void resized(); + void paint (Graphics& g) override; + void resized() override; + bool keyPressed (const KeyPress& key) override; void updateBufferSizeText(); void enable(); void disable(); - void saveStateToXml(XmlElement* xml); - void loadStateFromXml(XmlElement* xml); + void saveStateToXml (XmlElement* xml); + void loadStateFromXml (XmlElement* xml); + private: + void buttonClicked (Button* buttonThatWasClicked) override; + + void sliderValueChanged (Slider* slider) override; - void buttonClicked(Button* button); - void sliderValueChanged(Slider* slider); float lastValue; bool isEnabled; - MuteButton* muteButton; - AudioWindowButton* audioWindowButton; - AudioConfigurationWindow* acw; + ScopedPointer<MuteButton> muteButton; + ScopedPointer<AudioWindowButton> audioWindowButton; - Slider* volumeSlider; - Slider* noiseGateSlider; + ScopedPointer<AudioConfigurationWindow> audioConfigurationWindow; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AudioEditor); + ScopedPointer<Slider> volumeSlider; + ScopedPointer<Slider> noiseGateSlider; -}; + SharedResourcePointer<MaterialSliderLookAndFeel> materialSliderLookAndFeel; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioEditor); +}; #endif // __AUDIOEDITOR_H_9D6F1FC3__ diff --git a/Source/Processors/DataThreads/RhythmNode/RHD2000Editor.cpp b/Source/Processors/DataThreads/RhythmNode/RHD2000Editor.cpp index 91ef18f932607cfaae219192a62f8dd9d2843e2c..cc87903c33c9797b58dce989e256fa5f7c66161e 100644 --- a/Source/Processors/DataThreads/RhythmNode/RHD2000Editor.cpp +++ b/Source/Processors/DataThreads/RhythmNode/RHD2000Editor.cpp @@ -867,16 +867,15 @@ void RHD2000Editor::buttonEvent(Button* button) } -void RHD2000Editor::channelChanged(int chan) +void RHD2000Editor::channelChanged (int channel, bool /*newState*/) { for (int i = 0; i < 2; i++) { if (electrodeButtons[i]->getToggleState()) { - electrodeButtons[i]->setChannelNum(chan); + electrodeButtons[i]->setChannelNum (channel); electrodeButtons[i]->repaint(); - board->setDACchannel(i, chan); - + board->setDACchannel (i, channel); } } } @@ -1438,10 +1437,10 @@ void AudioInterface::paint(Graphics& g) // Clock Divider options ClockDivideInterface::ClockDivideInterface(RHD2000Thread* board_, RHD2000Editor* editor_) : - board(board_) - , editor(editor_) - , name("Clock Divider") + name("Clock Divider") , lastDivideRatioString("1") + , board(board_) + , editor(editor_) , actualDivideRatio(1) { diff --git a/Source/Processors/DataThreads/RhythmNode/RHD2000Editor.h b/Source/Processors/DataThreads/RhythmNode/RHD2000Editor.h index 0b7569acc43df65dbcdbd9e26eb6929d89290fd4..74a4d9354a08a486cf09e7476a016b3b58510673 100644 --- a/Source/Processors/DataThreads/RhythmNode/RHD2000Editor.h +++ b/Source/Processors/DataThreads/RhythmNode/RHD2000Editor.h @@ -176,7 +176,7 @@ public: void startAcquisition(); void stopAcquisition(); - void channelChanged(int chan); + void channelChanged (int channel, bool newState) override; void saveCustomParameters(XmlElement* xml); void loadCustomParameters(XmlElement* xml); diff --git a/Source/Processors/DataThreads/RhythmNode/RHD2000Thread.cpp b/Source/Processors/DataThreads/RhythmNode/RHD2000Thread.cpp index 48114e43cd43b0d33249651956dbff3a26af0e6f..629dce1237ac6652aeeedfb022ee3c75b808fa66 100644 --- a/Source/Processors/DataThreads/RhythmNode/RHD2000Thread.cpp +++ b/Source/Processors/DataThreads/RhythmNode/RHD2000Thread.cpp @@ -106,15 +106,13 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn), // Open Opal Kelly XEM6010 board. // Returns 1 if successful, -1 if FrontPanel cannot be loaded, and -2 if XEM6010 can't be found. - File executable = File::getSpecialLocation(File::currentExecutableFile); #if defined(__APPLE__) - const String executableDirectory = - executable.getParentDirectory().getParentDirectory().getParentDirectory().getParentDirectory().getFullPathName(); + File appBundle = File::getSpecialLocation(File::currentApplicationFile); + const String executableDirectory = appBundle.getChildFile("Contents/Resources").getFullPathName(); #else + File executable = File::getSpecialLocation(File::currentExecutableFile); const String executableDirectory = executable.getParentDirectory().getFullPathName(); - - #endif std::cout << executableDirectory << std::endl; @@ -190,10 +188,10 @@ RHD2000Thread::~RHD2000Thread() //deleteAndZero(dataBlock); - delete dacStream; - delete dacChannels; - delete dacThresholds; - delete dacChannelsToUpdate; + delete[] dacStream; + delete[] dacChannels; + delete[] dacThresholds; + delete[] dacChannelsToUpdate; } @@ -358,12 +356,11 @@ void RHD2000Thread::initializeBoard() { String bitfilename; - File executable = File::getSpecialLocation(File::currentExecutableFile); - #if defined(__APPLE__) - const String executableDirectory = - executable.getParentDirectory().getParentDirectory().getParentDirectory().getParentDirectory().getFullPathName(); + File appBundle = File::getSpecialLocation(File::currentApplicationFile); + const String executableDirectory = appBundle.getChildFile("Contents/Resources").getFullPathName(); #else + File executable = File::getSpecialLocation(File::currentExecutableFile); const String executableDirectory = executable.getParentDirectory().getFullPathName(); #endif diff --git a/Source/Processors/Dsp/LinearSmoothedValueAtomic.cpp b/Source/Processors/Dsp/LinearSmoothedValueAtomic.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7da6842e03a3a6882407b605a1990992ac77dc94 --- /dev/null +++ b/Source/Processors/Dsp/LinearSmoothedValueAtomic.cpp @@ -0,0 +1,30 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2015 - ROLI Ltd. + + Permission is granted to use this software under the terms of either: + a) the GPL v2 (or any later version) + b) the Affero GPL v3 + + Details of these licenses can be found at: www.gnu.org/licenses + + JUCE 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. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.juce.com for more information. + + ============================================================================== +*/ + +#include "LinearSmoothedValueAtomic.h" + + +// Explicit instantiations +template class LinearSmoothedValueAtomic<float>; +template class LinearSmoothedValueAtomic<double>; diff --git a/Source/Processors/Dsp/LinearSmoothedValueAtomic.h b/Source/Processors/Dsp/LinearSmoothedValueAtomic.h new file mode 100644 index 0000000000000000000000000000000000000000..6fd301b77ccc6e5552f37c25b8a22299e72cad63 --- /dev/null +++ b/Source/Processors/Dsp/LinearSmoothedValueAtomic.h @@ -0,0 +1,157 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2015 - ROLI Ltd. + + Permission is granted to use this software under the terms of either: + a) the GPL v2 (or any later version) + b) the Affero GPL v3 + + Details of these licenses can be found at: www.gnu.org/licenses + + JUCE 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. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.juce.com for more information. + + ============================================================================== +*/ + +#ifndef JUCE_LINEARSMOOTHEDVALUE_H_INCLUDED +#define JUCE_LINEARSMOOTHEDVALUE_H_INCLUDED + +#include "../PluginManager/OpenEphysPlugin.h" +#include <atomic> + +//============================================================================== +/** + Utility class for linearly smoothed values like volume etc. that should + not change abruptly but as a linear ramp, to avoid audio glitches. + + This class was modified by Open Ephys and just an improvement of LinearSmoothedValue + class from the JUCE 4.0 library, but with some features made that were suggested + by Timur Doumler during his JUCE Summit 2015 talk, to make it lock-free and guarantee + that no race conditions will ever occur using it. + + Usage: + - set value by calling setValue() method; + + - get value by calling updateTarget() and then getNextValue() method. + We need to call updateTarget() because we should suppose the value could be changed before + so we need to update it smoothly and then use it. +*/ + +//============================================================================== +template<typename FloatType> +class LinearSmoothedValueAtomic +{ +public: + /** Constructor. */ + LinearSmoothedValueAtomic() noexcept; + + /** Constructor. */ + LinearSmoothedValueAtomic (FloatType initialValue) noexcept; + + //========================================================================== + /** Reset to a new sample rate and ramp length. */ + void reset (double sampleRate, double rampLengthInSeconds) noexcept; + + //========================================================================== + /** Set a new target value. */ + void setValue (FloatType newValue) noexcept; + + //========================================================================== + void updateTarget() noexcept; + + //========================================================================== + /** Compute the next value. */ + FloatType getNextValue() noexcept; + + +private: + //========================================================================== + std::atomic<FloatType> target; + + FloatType currentValue; + FloatType currentTarget; + FloatType step; + + int countdown; + int stepsToTarget; +}; + + +template <typename FloatType> +LinearSmoothedValueAtomic<FloatType>::LinearSmoothedValueAtomic() noexcept + : target (0) + , currentValue (0) + , step (0) + , countdown (0) + , stepsToTarget (0) +{ +} + + +template <typename FloatType> +LinearSmoothedValueAtomic<FloatType>::LinearSmoothedValueAtomic (FloatType initialValue) noexcept + : target (initialValue) + , currentValue (initialValue) + , step (0) + , countdown (0) + , stepsToTarget (0) +{ +} + + +template<typename FloatType> +void LinearSmoothedValueAtomic<FloatType>::reset (double sampleRate, double rampLengthInSeconds) noexcept +{ + jassert (sampleRate > 0 && rampLengthInSeconds >= 0); + stepsToTarget = (int) std::floor (rampLengthInSeconds * sampleRate); + currentValue = target; + countdown = 0; +} + + +template<typename FloatType> +void LinearSmoothedValueAtomic<FloatType>::setValue (FloatType newValue) noexcept +{ + target.store (newValue); +} + + +template<typename FloatType> +void LinearSmoothedValueAtomic<FloatType>::updateTarget() noexcept +{ + FloatType newTarget = target.load(); + if (newTarget != currentTarget) + { + currentTarget = newTarget; + countdown = stepsToTarget; + + if (countdown <= 0) + currentValue = currentTarget; + else + step = (currentTarget - currentValue) / (FloatType) countdown; + } +} + + +template<typename FloatType> +FloatType LinearSmoothedValueAtomic<FloatType>::getNextValue() noexcept +{ + if (countdown <= 0) + return currentTarget; + + --countdown; + currentValue += step; + return currentValue; +} + + +#endif // JUCE_LINEARSMOOTHEDVALUE_H_INCLUDED diff --git a/Source/Processors/Editors/ChannelSelector.cpp b/Source/Processors/Editors/ChannelSelector.cpp index 43281c7bdc7b9f5309e4dd223cde579a59a6b75b..e44e5ff0a14279e44ac8d75deab0f590364bb0be 100755 --- a/Source/Processors/Editors/ChannelSelector.cpp +++ b/Source/Processors/Editors/ChannelSelector.cpp @@ -1,25 +1,25 @@ /* - ------------------------------------------------------------------ - - This file is part of the Open Ephys GUI - Copyright (C) 2013 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/>. - - */ +------------------------------------------------------------------ + +This file is part of the Open Ephys GUI +Copyright (C) 2013 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 "ChannelSelector.h" #include <math.h> @@ -31,93 +31,137 @@ #include "../../UI/GraphViewer.h" ChannelSelector::ChannelSelector(bool createButtons, Font& titleFont_) : -eventsOnly(false), paramsToggled(true), paramsActive(true), -recActive(true), radioStatus(false), isNotSink(createButtons), -moveRight(false), moveLeft(false), offsetLR(0), offsetUD(0), desiredOffset(0), titleFont(titleFont_), acquisitionIsActive(false) + eventsOnly(false), paramsToggled(true), paramsActive(true), + recActive(true), radioStatus(false), isNotSink(createButtons), + moveRight(false), moveLeft(false), offsetLR(0), offsetUD(0), desiredOffset(0), titleFont(titleFont_), acquisitionIsActive(false) { - // initialize buttons audioButton = new EditorButton("AUDIO", titleFont); audioButton->addListener(this); addAndMakeVisible(audioButton); if (!createButtons) audioButton->setState(false); - + recordButton = new EditorButton("REC", titleFont); recordButton->addListener(this); addAndMakeVisible(recordButton); if (!createButtons) recordButton->setState(false); - + paramsButton = new EditorButton("PARAM", titleFont); paramsButton->addListener(this); addAndMakeVisible(paramsButton); - + paramsButton->setToggleState(true, dontSendNotification); - - audioButtons.clear(); - recordButtons.clear(); - + // set button layout parameters parameterOffset = 0; recordOffset = getDesiredWidth(); - audioOffset = getDesiredWidth()*2; - - parameterButtons.clear(); - + audioOffset = getDesiredWidth() * 2; + allButton = new EditorButton("all", titleFont); allButton->addListener(this); addAndMakeVisible(allButton); - + noneButton = new EditorButton("none", titleFont); noneButton->addListener(this); addAndMakeVisible(noneButton); - - channelSelectorRegion = new ChannelSelectorRegion(this); - //channelSelectorRegion->setBounds(0,20,0,getHeight()-35); - addAndMakeVisible(channelSelectorRegion); - channelSelectorRegion->toBack(); - + + selectButtonParam = new EditorButton("+", titleFont); + selectButtonParam->addListener(this); + addAndMakeVisible(selectButtonParam); + + deselectButtonParam = new EditorButton("-", titleFont); + deselectButtonParam->addListener(this); + addAndMakeVisible(deselectButtonParam); + + selectButtonRecord = new EditorButton("+", titleFont); + selectButtonRecord->addListener(this); + addAndMakeVisible(selectButtonRecord); + + deselectButtonRecord = new EditorButton("-", titleFont); + deselectButtonRecord->addListener(this); + addAndMakeVisible(deselectButtonRecord); + + selectButtonAudio = new EditorButton("+", titleFont); + selectButtonAudio->addListener(this); + addAndMakeVisible(selectButtonAudio); + + deselectButtonAudio = new EditorButton("-", titleFont); + deselectButtonAudio->addListener(this); + addAndMakeVisible(deselectButtonAudio); + + addAndMakeVisible (paramBox = new ChannelSelectorBox); + addAndMakeVisible (recordBox = new ChannelSelectorBox); + addAndMakeVisible (audioBox = new ChannelSelectorBox); + numColumnsLessThan100 = 8; numColumnsGreaterThan100 = 6; - + + addAndMakeVisible (audioButtonsManager); + addAndMakeVisible (recordButtonsManager); + addAndMakeVisible (parameterButtonsManager); + + // Enable fast mode selection for buttons + audioButtonsManager.setFastSelectionModeEnabled (true); + recordButtonsManager.setFastSelectionModeEnabled (true); + parameterButtonsManager.setFastSelectionModeEnabled (true); + + audioButtonsManager.setMinPaddingBetweenButtons (0); + recordButtonsManager.setMinPaddingBetweenButtons (0); + parameterButtonsManager.setMinPaddingBetweenButtons (0); + + audioButtonsManager.setColour (ButtonGroupManager::outlineColourId, Colour (0x0)); + recordButtonsManager.setColour (ButtonGroupManager::outlineColourId, Colour (0x0)); + parameterButtonsManager.setColour (ButtonGroupManager::outlineColourId, Colour (0x0)); + + // Register listeners for buttons + audioButtonsManager.setButtonListener (this); + recordButtonsManager.setButtonListener (this); + parameterButtonsManager.setButtonListener (this); } ChannelSelector::~ChannelSelector() { + // Just a temporary workaround as we don't want to delete these buttons managers by hands. + // We will remove it after getting rid of the ugly calling of deleteAllChildren() method. + // We should really use some RAII technuiqes to avoid calling this method. + // TODO: refactor the code to follow RAII best principles and to avoid using raw pointers after merge with priyanjitdey94 + removeChildComponent (&audioButtonsManager); + removeChildComponent (&recordButtonsManager); + removeChildComponent (¶meterButtonsManager); + deleteAllChildren(); - } void ChannelSelector::paint(Graphics& g) { - ColourGradient grad1 = ColourGradient(Colours::black.withAlpha(0.8f),0.0,0.0, - Colours::black.withAlpha(0.1f),0.0,25.0f, + ColourGradient grad1 = ColourGradient(Colours::black.withAlpha(0.8f), 0.0, 0.0, + Colours::black.withAlpha(0.1f), 0.0, 25.0f, false); g.setGradientFill(grad1); - g.fillRect(0, 15, getWidth(), getHeight()-30); - - ColourGradient grad2 = ColourGradient(Colours::black.withAlpha(0.2f),0.0,0.0, - Colours::black.withAlpha(0.0f),5.0f,0.0f, + g.fillRect(0, 15, getWidth(), getHeight() - 30); + + ColourGradient grad2 = ColourGradient(Colours::black.withAlpha(0.2f), 0.0, 0.0, + Colours::black.withAlpha(0.0f), 5.0f, 0.0f, false); g.setGradientFill(grad2); - g.fillRect(0, 15, getWidth(), getHeight()-30); - - ColourGradient grad3 = ColourGradient(Colours::black.withAlpha(0.2f),(float) getDesiredWidth(),0.0, - Colours::black.withAlpha(0.0f),(float) getDesiredWidth()-5.0f,0.0f, + g.fillRect(0, 15, getWidth(), getHeight() - 30); + + ColourGradient grad3 = ColourGradient(Colours::black.withAlpha(0.2f), (float)getDesiredWidth(), 0.0, + Colours::black.withAlpha(0.0f), (float)getDesiredWidth() - 5.0f, 0.0f, false); g.setGradientFill(grad3); - g.fillRect(0, 15, getWidth(), getHeight()-30); + g.fillRect(0, 15, getWidth(), getHeight() - 30); } void ChannelSelector::setNumChannels(int numChans) { - - int difference = numChans - parameterButtons.size(); - + int difference = numChans - parameterButtonsManager.getNumButtons(); + // std::cout << difference << " buttons needed." << std::endl; - + if (difference > 0) { for (int n = 0; n < difference; n++) @@ -132,96 +176,106 @@ void ChannelSelector::setNumChannels(int numChans) removeButton(); } } - + + const int numButtons = parameterButtonsManager.getNumButtons(); //Reassign numbers according to the actual channels (useful for channel mapper) - for (int n = 0; n < parameterButtons.size(); n++) + for (int n = 0; n < numButtons; ++n) { - int num = ((GenericEditor*)getParentComponent())->getChannel(n)->nodeIndex; - parameterButtons[n]->setChannel(n+1, num+1); + int num = ( (GenericEditor*)getParentComponent())->getChannel (n)->nodeIndex; + static_cast<ChannelSelectorButton*> (parameterButtonsManager.getButtonAt (n))->setChannel (n + 1, num + 1); + if (isNotSink) { - recordButtons[n]->setChannel(n+1, num+1); - audioButtons[n]->setChannel(n+1, num+1); + static_cast<ChannelSelectorButton*> (recordButtonsManager.getButtonAt (n))->setChannel (n + 1, num + 1); + static_cast<ChannelSelectorButton*> (audioButtonsManager.getButtonAt (n))->setChannel (n + 1, num + 1); } } - + refreshButtonBoundaries(); - } int ChannelSelector::getNumChannels() { - return parameterButtons.size(); + return parameterButtonsManager.getNumButtons(); } void ChannelSelector::shiftChannelsVertical(float amount) { - - if (parameterButtons.size() > 32) + if (parameterButtonsManager.getNumButtons() > 16) { - offsetUD -= amount*10; + offsetUD -= amount * 10; offsetUD = jmin(offsetUD, 0.0f); - offsetUD = jmax(offsetUD, (float) -overallHeight); + offsetUD = jmax(offsetUD, (float)-overallHeight); } - + //std::cout << "offsetUD = " << offsetUD << std::endl; - + refreshButtonBoundaries(); - } void ChannelSelector::refreshButtonBoundaries() { - - channelSelectorRegion->setBounds(0,20,getWidth(),getHeight()-35); - - int rowHeight = 14; int column = 0; int row = 0; int nColumns; - - for (int i = 0; i < parameterButtons.size(); i++) - { - - if (i < 96) - nColumns = numColumnsLessThan100; - else - nColumns = numColumnsGreaterThan100; - - int columnWidth = getDesiredWidth() / (nColumns + 1) + 1; - - int xLoc = columnWidth / 2 + offsetLR + columnWidth*column; - int yLoc = row * rowHeight + offsetUD; - - parameterButtons[i]->setBounds(xLoc, yLoc, columnWidth, rowHeight); - - if (isNotSink) - { - recordButtons[i]->setBounds(xLoc - getDesiredWidth(), yLoc, columnWidth, rowHeight); - audioButtons[i]->setBounds(xLoc - getDesiredWidth()*2, yLoc, columnWidth, rowHeight); - } - - column++; - - if (column >= nColumns) - { - column = 0; - row++; - overallHeight = row * rowHeight; - } - - } - - int w = getWidth()/3; - int h = 15; - - audioButton->setBounds(0, 0, w, h); - recordButton->setBounds(w, 0, w, h); - paramsButton->setBounds(w*2, 0, w, h); - - allButton->setBounds(0, getHeight()-15, getWidth()/2, 15); - noneButton->setBounds(getWidth()/2, getHeight()-15, getWidth()/2, 15); - + + const int numButtons = parameterButtonsManager.getNumButtons(); + const int columnWidth = getDesiredWidth() / (numColumnsGreaterThan100 + 1) + 1; + const int rowHeight = 14; + + audioButtonsManager.setButtonSize (columnWidth, rowHeight); + recordButtonsManager.setButtonSize (columnWidth, rowHeight); + parameterButtonsManager.setButtonSize (columnWidth, rowHeight); + + const int headerHeight = 25; + //const int xLoc = columnWidth / 2 + offsetLR; + //const int yLoc = offsetUD + headerHeight; + const int xLoc = offsetLR + 3; + const int yLoc = offsetUD + headerHeight * 2 - 5; + + const int tabButtonHeight = 15; + juce::Rectangle<int> buttonManagerBounds (xLoc, yLoc, getDesiredWidth() - 6, getHeight() - yLoc - tabButtonHeight); + parameterButtonsManager.setBounds (buttonManagerBounds); + buttonManagerBounds.translate (- getDesiredWidth(), 0); + recordButtonsManager.setBounds (buttonManagerBounds); + buttonManagerBounds.translate (- getDesiredWidth(), 0); + audioButtonsManager.setBounds (buttonManagerBounds); + + juce::Rectangle<int> textEditBounds (xLoc, yLoc - headerHeight, 90, 20); + paramBox->setBounds (textEditBounds); + textEditBounds.translate (- getDesiredWidth(), 0); + recordBox->setBounds (textEditBounds); + textEditBounds.translate (- getDesiredWidth(), 0); + audioBox->setBounds (textEditBounds); + + /* + audio,record and param tabs + */ + const int tabButtonWidth = getWidth() / 3; + audioButton->setBounds (0, 0, tabButtonWidth, tabButtonHeight); + recordButton->setBounds (tabButtonWidth, 0, tabButtonWidth, tabButtonHeight); + paramsButton->setBounds (tabButtonWidth * 2, 0, tabButtonWidth, tabButtonHeight); + + /* + select and deselect button under each tab + */ + juce::Rectangle<int> selectionControlBounds (xLoc + 95, 20, 20, 20); + selectButtonParam->setBounds (selectionControlBounds); + deselectButtonParam->setBounds (selectionControlBounds.translated (22, 0)); + + selectionControlBounds.translate (- getDesiredWidth(), 0); + selectButtonRecord->setBounds (selectionControlBounds); + deselectButtonRecord->setBounds (selectionControlBounds.translated (22, 0)); + + selectionControlBounds.translate (- getDesiredWidth(), 0); + selectButtonAudio->setBounds (selectionControlBounds); + deselectButtonAudio->setBounds (selectionControlBounds.translated (22, 0)); + + /* + All and None buttons + */ + allButton->setBounds (0, getHeight() - 15, getWidth() / 2, tabButtonHeight); + noneButton->setBounds (getWidth() / 2, getHeight() - 15, getWidth() / 2, tabButtonHeight); } void ChannelSelector::resized() @@ -231,9 +285,8 @@ void ChannelSelector::resized() void ChannelSelector::timerCallback() { - //std::cout << desiredOffset - offsetLR << std::endl; - + if (offsetLR != desiredOffset) { if (desiredOffset - offsetLR > 0) @@ -246,157 +299,143 @@ void ChannelSelector::timerCallback() { offsetLR -= 25; } - } else { stopTimer(); } - + refreshButtonBoundaries(); - } void ChannelSelector::addButton() { - - int size = parameterButtons.size(); - - ChannelSelectorButton* b = new ChannelSelectorButton(size+1, PARAMETER, titleFont); - parameterButtons.add(b); - channelSelectorRegion->addAndMakeVisible(b); - + const int size = parameterButtonsManager.getNumButtons(); + + ChannelSelectorButton* b = new ChannelSelectorButton (size + 1, PARAMETER, titleFont); + parameterButtonsManager.addButton (b); + if (paramsToggled) b->setToggleState(true, dontSendNotification); else b->setToggleState(false, dontSendNotification); - + if (!paramsActive) b->setActive(false); - - b->addListener(this); - + if (isNotSink) { - ChannelSelectorButton* br = new ChannelSelectorButton(size+1, RECORD, titleFont); - recordButtons.add(br); - channelSelectorRegion->addAndMakeVisible(br); - br->addListener(this); - - ChannelSelectorButton* ba = new ChannelSelectorButton(size+1, AUDIO, titleFont); - audioButtons.add(ba); - channelSelectorRegion->addAndMakeVisible(ba); - ba->addListener(this); + ChannelSelectorButton* br = new ChannelSelectorButton(size + 1, RECORD, titleFont); + recordButtonsManager.addButton (br); + + ChannelSelectorButton* ba = new ChannelSelectorButton(size + 1, AUDIO, titleFont); + audioButtonsManager.addButton (ba); } } void ChannelSelector::removeButton() { - int size = parameterButtons.size(); - - ChannelSelectorButton* b = parameterButtons.remove(size-1); - channelSelectorRegion->removeChildComponent(b); - deleteAndZero(b); - + int size = parameterButtonsManager.getNumButtons(); + + parameterButtonsManager.removeButton (size - 1); + if (isNotSink) { - ChannelSelectorButton* br = recordButtons.remove(size-1); - channelSelectorRegion->removeChildComponent(br); - deleteAndZero(br); - - ChannelSelectorButton* ba = audioButtons.remove(size-1); - channelSelectorRegion->removeChildComponent(ba); - deleteAndZero(ba); + recordButtonsManager.removeButton (size - 1); + audioButtonsManager.removeButton (size - 1); } } Array<int> ChannelSelector::getActiveChannels() { Array<int> a; - - if (!eventsOnly) + + if (! eventsOnly) { - for (int i = 0; i < parameterButtons.size(); i++) + const int numButtons = parameterButtonsManager.getNumButtons(); + for (int i = 0; i < numButtons; ++i) { - if (parameterButtons[i]->getToggleState()) - a.add(i); + if (parameterButtonsManager.getButtonAt (i)->getToggleState()) + a.add (i); } } else { - a.add(0); + a.add (0); } - + return a; } void ChannelSelector::setActiveChannels(Array<int> a) { - //std::cout << "Setting active channels!" << std::endl; - - for (int i = 0; i < parameterButtons.size(); i++) + + const int numButtons = parameterButtonsManager.getNumButtons(); + for (int i = 0; i < numButtons; ++i) { - parameterButtons[i]->setToggleState(false, dontSendNotification); + parameterButtonsManager.getButtonAt (i)->setToggleState (false, dontSendNotification); } - + for (int i = 0; i < a.size(); i++) { - if (a[i] < parameterButtons.size()) + if (a[i] < numButtons) { - parameterButtons[a[i]]->setToggleState(true, dontSendNotification); + parameterButtonsManager.getButtonAt (a[i])->setToggleState (true, dontSendNotification); } } } void ChannelSelector::inactivateButtons() { - paramsActive = false; - - for (int i = 0; i < parameterButtons.size(); i++) + + const int numButtons = parameterButtonsManager.getNumButtons(); + for (int i = 0; i < numButtons; ++i) { - parameterButtons[i]->setActive(false); - parameterButtons[i]->repaint(); + const auto& button = static_cast<ChannelSelectorButton*> (parameterButtonsManager.getButtonAt (i)); + button->setActive (false); + button->repaint(); } } void ChannelSelector::activateButtons() { - paramsActive = true; - - for (int i = 0; i < parameterButtons.size(); i++) + + const int numButtons = parameterButtonsManager.getNumButtons(); + for (int i = 0; i < numButtons; ++i) { - parameterButtons[i]->setActive(true); - parameterButtons[i]->repaint(); + const auto& button = static_cast<ChannelSelectorButton*> (parameterButtonsManager.getButtonAt (i)); + button->setActive (true); + button->repaint(); } - } void ChannelSelector::inactivateRecButtons() { - recActive = false; - - for (int i = 0; i < recordButtons.size(); i++) + + const int numButtons = recordButtonsManager.getNumButtons(); + for (int i = 0; i < numButtons; ++i) { - recordButtons[i]->setActive(false); - recordButtons[i]->repaint(); + const auto& button = static_cast<ChannelSelectorButton*> (recordButtonsManager.getButtonAt (i)); + button->setActive (false); + button->repaint(); } } void ChannelSelector::activateRecButtons() { - recActive = true; - - for (int i = 0; i < recordButtons.size(); i++) + + const int numButtons = recordButtonsManager.getNumButtons(); + for (int i = 0; i < numButtons; ++i) { - recordButtons[i]->setActive(true); - recordButtons[i]->repaint(); + const auto& button = static_cast<ChannelSelectorButton*> (recordButtonsManager.getButtonAt (i)); + button->setActive (true); + button->repaint(); } - } void ChannelSelector::refreshParameterColors() @@ -422,90 +461,67 @@ void ChannelSelector::stopAcquisition() void ChannelSelector::setRadioStatus(bool radioOn) { - if (radioStatus != radioOn) { - radioStatus = radioOn; - - for (int i = 0; i < parameterButtons.size(); i++) + + const int numButtons = parameterButtonsManager.getNumButtons(); + for (int i = 0; i < numButtons; ++i) { - if (radioOn) - { - parameterButtons[i]->setToggleState(false, dontSendNotification); - parameterButtons[i]->setRadioGroupId(999); - } - else - { - parameterButtons[i]->setToggleState(false, dontSendNotification); - parameterButtons[i]->setRadioGroupId(0); - } + parameterButtonsManager.getButtonAt (i)->setToggleState (false, dontSendNotification); } - + + parameterButtonsManager.setRadioButtonMode (radioStatus); } - - - } bool ChannelSelector::getParamStatus(int chan) { - - if (chan >= 0 && chan < parameterButtons.size()) - return parameterButtons[chan]->getToggleState(); + if (chan >= 0 && chan < parameterButtonsManager.getNumButtons()) + return parameterButtonsManager.getButtonAt (chan)->getToggleState(); else return false; - } bool ChannelSelector::getRecordStatus(int chan) { - - if (chan >= 0 && chan < recordButtons.size()) - return recordButtons[chan]->getToggleState(); + if (chan >= 0 && chan < recordButtonsManager.getNumButtons()) + return recordButtonsManager.getButtonAt (chan)->getToggleState(); else return false; - } bool ChannelSelector::getAudioStatus(int chan) { - - if (chan >= 0 && chan < audioButtons.size()) - return audioButtons[chan]->getToggleState(); + if (chan >= 0 && chan < audioButtonsManager.getNumButtons()) + return audioButtonsManager.getButtonAt (chan)->getToggleState(); else return false; - } void ChannelSelector::setParamStatus(int chan, bool b) { - - if (chan >= 0 && chan < parameterButtons.size()) - parameterButtons[chan]->setToggleState(b, sendNotification); - + if (chan >= 0 && chan < parameterButtonsManager.getNumButtons()) + parameterButtonsManager.getButtonAt (chan)->setToggleState(b, sendNotification); } void ChannelSelector::setRecordStatus(int chan, bool b) { - - if (chan >= 0 && chan < recordButtons.size()) - recordButtons[chan]->setToggleState(b, sendNotification); - + if (chan >= 0 && chan < recordButtonsManager.getNumButtons()) + recordButtonsManager.getButtonAt (chan)->setToggleState(b, sendNotification); } void ChannelSelector::setAudioStatus(int chan, bool b) { - - if (chan >= 0 && chan < audioButtons.size()) - audioButtons[chan]->setToggleState(b, sendNotification); - + if (chan >= 0 && chan < audioButtonsManager.getNumButtons()) + audioButtonsManager.getButtonAt (chan)->setToggleState (b, sendNotification); } void ChannelSelector::clearAudio() { - for (int chan = 0; chan < audioButtons.size(); chan++) - audioButtons[chan]->setToggleState(false, sendNotification); + const int numButtons = audioButtonsManager.getNumButtons(); + for (int chan = 0; chan < numButtons; ++chan) + audioButtonsManager.getButtonAt (chan)->setToggleState (false, sendNotification); } int ChannelSelector::getDesiredWidth() @@ -527,11 +543,11 @@ void ChannelSelector::buttonClicked(Button* button) else if (button == audioButton) { // make sure audio buttons are visible - + if (audioButton->getState()) { allButton->setState(false); - + desiredOffset = audioOffset; startTimer(20); } @@ -561,21 +577,17 @@ void ChannelSelector::buttonClicked(Button* button) // select all active buttons if (offsetLR == recordOffset) { - - - for (int i = 0; i < recordButtons.size(); i++) + for (int i = 0; i < recordButtonsManager.getNumButtons(); ++i) { - recordButtons[i]->setToggleState(true, sendNotification); + recordButtonsManager.getButtonAt (i)->setToggleState (true, sendNotification); } - + } else if (offsetLR == parameterOffset) { - - - for (int i = 0; i < parameterButtons.size(); i++) + for (int i = 0; i < parameterButtonsManager.getNumButtons(); ++i) { - parameterButtons[i]->setToggleState(true, sendNotification); + parameterButtonsManager.getButtonAt (i)->setToggleState (true, sendNotification); } } else if (offsetLR == audioOffset) @@ -588,49 +600,217 @@ void ChannelSelector::buttonClicked(Button* button) // deselect all active buttons if (offsetLR == recordOffset) { - for (int i = 0; i < recordButtons.size(); i++) + for (int i = 0; i < recordButtonsManager.getNumButtons(); ++i) { - recordButtons[i]->setToggleState(false, sendNotification); + recordButtonsManager.getButtonAt (i)->setToggleState (false, sendNotification); } } else if (offsetLR == parameterOffset) { - for (int i = 0; i < parameterButtons.size(); i++) + for (int i = 0; i < parameterButtonsManager.getNumButtons(); ++i) { - parameterButtons[i]->setToggleState(false, sendNotification); + parameterButtonsManager.getButtonAt (i)->setToggleState (false, sendNotification); } } else if (offsetLR == audioOffset) { - for (int i = 0; i < audioButtons.size(); i++) + for (int i = 0; i < audioButtonsManager.getNumButtons(); ++i) { - audioButtons[i]->setToggleState(false, sendNotification); + audioButtonsManager.getButtonAt (i)->setToggleState (false, sendNotification); } } - + if (radioStatus) // if radio buttons are active { // send a message to parent GenericEditor* editor = (GenericEditor*) getParentComponent(); - editor->channelChanged(-1); + editor->channelChanged (-1, false); + } + } + else if (button == selectButtonParam) + { // select channels in parameter tab + selectButtonParam->removeListener(this); + deselectButtonParam->removeListener(this); + std::vector<int> getBoxList; + int fa, lim, comd, i; + getBoxList = paramBox->getBoxInfo (parameterButtonsManager.getNumButtons()); + if (getBoxList.size() < 3) + { + selectButtonParam->addListener(this); + deselectButtonParam->addListener(this); + return; + } + i = 0; + while (i <= getBoxList.size() - 3) + { + fa = getBoxList[i]; + lim = getBoxList[i + 1]; + comd = getBoxList[i + 2]; + for (; fa <= lim; fa += comd) + { + parameterButtonsManager.getButtonAt (fa)->setToggleState (true, sendNotification); + } + i += 3; + } + selectButtonParam->addListener(this); + deselectButtonParam->addListener(this); + } + else if (button == selectButtonRecord) + { // select channels in record tab + selectButtonRecord->removeListener(this); + deselectButtonRecord->removeListener(this); + std::vector<int> getBoxList; + int fa, lim, comd, i; + getBoxList = recordBox->getBoxInfo (recordButtonsManager.getNumButtons()); + if (getBoxList.size() < 3) + { + selectButtonRecord->addListener(this); + deselectButtonRecord->addListener(this); + return; + } + i = 0; + while (i <= getBoxList.size() - 3) + { + fa = getBoxList[i]; + lim = getBoxList[i + 1]; + comd = getBoxList[i + 2]; + for (; fa <= lim; fa += comd) + { + recordButtonsManager.getButtonAt (fa)->setToggleState (true, sendNotification); + } + i += 3; + } + selectButtonRecord->addListener(this); + deselectButtonRecord->addListener(this); + } + else if (button == selectButtonAudio) + { // select channels in audio tab + selectButtonAudio->removeListener(this); + deselectButtonAudio->removeListener(this); + std::vector<int> getBoxList; + int fa, lim, comd, i; + getBoxList = audioBox->getBoxInfo (audioButtonsManager.getNumButtons()); + if (getBoxList.size() < 3) + { + selectButtonAudio->addListener(this); + deselectButtonAudio->addListener(this); + return; + } + i = 0; + while (i <= getBoxList.size() - 3) + { + fa = getBoxList[i]; + lim = getBoxList[i + 1]; + comd = getBoxList[i + 2]; + for (; fa <= lim; fa += comd) + { + audioButtonsManager.getButtonAt (fa)->setToggleState(true, sendNotification); + } + i += 3; + } + selectButtonAudio->addListener(this); + deselectButtonAudio->addListener(this); + } + else if (button == deselectButtonParam) + { // deselect channels in param tab + selectButtonParam->removeListener(this); + deselectButtonParam->removeListener(this); + std::vector<int> getBoxList; + int fa, lim, comd, i; + getBoxList = paramBox->getBoxInfo (parameterButtonsManager.getNumButtons()); + if (getBoxList.size() < 3) + { + selectButtonParam->addListener(this); + deselectButtonParam->addListener(this); + return; + } + i = 0; + while (i <= getBoxList.size() - 3) + { + fa = getBoxList[i]; + lim = getBoxList[i + 1]; + comd = getBoxList[i + 2]; + for (; fa <= lim; fa += comd) + { + parameterButtonsManager.getButtonAt (fa)->setToggleState (false, sendNotification); + } + i += 3; } + selectButtonParam->addListener(this); + deselectButtonParam->addListener(this); + } + else if (button == deselectButtonRecord) + { // deselect channels in record tab + selectButtonRecord->removeListener(this); + deselectButtonRecord->removeListener(this); + std::vector<int> getBoxList; + int fa, lim, comd, i; + getBoxList = recordBox->getBoxInfo (recordButtonsManager.getNumButtons()); + if (getBoxList.size() < 3) + { + selectButtonRecord->addListener(this); + deselectButtonRecord->addListener(this); + return; + } + i = 0; + while (i <= getBoxList.size() - 3) + { + fa = getBoxList[i]; + lim = getBoxList[i + 1]; + comd = getBoxList[i + 2]; + for (; fa <= lim; fa += comd) + { + recordButtonsManager.getButtonAt (fa)->setToggleState (false, sendNotification); + } + i += 3; + } + selectButtonRecord->addListener(this); + deselectButtonRecord->addListener(this); + } + else if (button == deselectButtonAudio) + { // deselect channels in audio tab + selectButtonAudio->removeListener(this); + deselectButtonAudio->removeListener(this); + std::vector<int> getBoxList; + int fa, lim, comd, i; + getBoxList = audioBox->getBoxInfo (audioButtonsManager.getNumButtons()); + if (getBoxList.size() < 3) + { + selectButtonAudio->addListener(this); + deselectButtonAudio->addListener(this); + return; + } + i = 0; + while (i <= getBoxList.size() - 3) + { + fa = getBoxList[i]; + lim = getBoxList[i + 1]; + comd = getBoxList[i + 2]; + for (; fa <= lim; fa += comd) + { + audioButtonsManager.getButtonAt (fa)->setToggleState(false, sendNotification); + } + i += 3; + } + selectButtonAudio->addListener(this); + deselectButtonAudio->addListener(this); } else { - - ChannelSelectorButton* b = (ChannelSelectorButton*) button; - + + ChannelSelectorButton* b = (ChannelSelectorButton*)button; + if (b->getType() == AUDIO) { // get audio node, and inform it of the change - GenericEditor* editor = (GenericEditor*) getParentComponent(); - - Channel* ch = editor->getChannel(b->getChannel()-1); + GenericEditor* editor = (GenericEditor*)getParentComponent(); + + Channel* ch = editor->getChannel(b->getChannel() - 1); //int channelNum = editor->getStartChannel() + b->getChannel() - 1; bool status = b->getToggleState(); - - std::cout << "Requesting audio monitor for channel " << ch->nodeIndex+1 << std::endl; - + + std::cout << "Requesting audio monitor for channel " << ch->nodeIndex + 1 << std::endl; + if (acquisitionIsActive) // use setParameter to change parameter safely { AccessClass::getProcessorGraph()-> @@ -640,18 +820,18 @@ void ChannelSelector::buttonClicked(Button* button) { ch->isMonitored = status; } - - + + } else if (b->getType() == RECORD) { // get record node, and inform it of the change - GenericEditor* editor = (GenericEditor*) getParentComponent(); - - Channel* ch = editor->getChannel(b->getChannel()-1); + GenericEditor* editor = (GenericEditor*)getParentComponent(); + + Channel* ch = editor->getChannel(b->getChannel() - 1); //int channelNum = editor->getStartChannel() + b->getChannel() - 1; bool status = b->getToggleState(); - + if (acquisitionIsActive) // use setParameter to change parameter safely { AccessClass::getProcessorGraph()-> @@ -663,25 +843,24 @@ void ChannelSelector::buttonClicked(Button* button) //std::cout << "Setting record status for channel " << b->getChannel() << std::endl; ch->setRecordState(status); } - + AccessClass::getGraphViewer()->repaint(); - + } else // parameter type { - GenericEditor* editor = (GenericEditor*) getParentComponent(); - editor->channelChanged(b->getChannel()-1); - + editor->channelChanged (b->getChannel() - 1, b->getToggleState()); + // do nothing if (radioStatus) // if radio buttons are active { // send a message to parent GenericEditor* editor = (GenericEditor*) getParentComponent(); - editor->channelChanged(b->getChannel()); + editor->channelChanged (b->getChannel(), b->getToggleState()); } } - + } refreshParameterColors(); } @@ -692,32 +871,33 @@ void ChannelSelector::buttonClicked(Button* button) EditorButton::EditorButton(const String& name, Font& f) : Button(name) { - + isEnabled = true; - + buttonFont = f; + buttonFont.setHeight(10); - + if (!getName().equalsIgnoreCase("all") && !getName().equalsIgnoreCase("none")) { setRadioGroupId(999); setClickingTogglesState(true); } - - selectedGrad = ColourGradient(Colour(240,179,12),0.0,0.0, - Colour(207,160,33),0.0, 20.0f, + + selectedGrad = ColourGradient(Colour(240, 179, 12), 0.0, 0.0, + Colour(207, 160, 33), 0.0, 20.0f, false); - selectedOverGrad = ColourGradient(Colour(209,162,33),0.0, 5.0f, - Colour(190,150,25),0.0, 0.0f, + selectedOverGrad = ColourGradient(Colour(209, 162, 33), 0.0, 5.0f, + Colour(190, 150, 25), 0.0, 0.0f, false); - neutralGrad = ColourGradient(Colour(220,220,220),0.0,0.0, - Colour(170,170,170),0.0, 20.0f, + neutralGrad = ColourGradient(Colour(220, 220, 220), 0.0, 0.0, + Colour(170, 170, 170), 0.0, 20.0f, false); - neutralOverGrad = ColourGradient(Colour(180,180,180),0.0,5.0f, - Colour(150,150,150),0.0, 0.0, + neutralOverGrad = ColourGradient(Colour(180, 180, 180), 0.0, 5.0f, + Colour(150, 150, 150), 0.0, 0.0, false); - - + + } EditorButton::~EditorButton() {} @@ -730,7 +910,7 @@ bool EditorButton::getState() void EditorButton::setState(bool state) { isEnabled = state; - + if (!state) { removeListener((Button::Listener*) getParentComponent()); @@ -739,105 +919,119 @@ void EditorButton::setState(bool state) { addListener((Button::Listener*) getParentComponent()); } - + repaint(); } void EditorButton::resized() { // float radius = 5.0f; - float width = (float) getWidth(); - float height = (float) getHeight(); - + float width = (float)getWidth(); + float height = (float)getHeight(); + if (getName().equalsIgnoreCase("AUDIO")) { //outlinePath.startNewSubPath(0, height); outlinePath.lineTo(0, 0);//radius); //outlinePath.addArc(0, 0, radius*2, radius*2, 1.5*double_Pi, 2.0*double_Pi ); - + outlinePath.lineTo(width, 0);//getHeight()); - + outlinePath.lineTo(width, height); - + outlinePath.lineTo(0, height); //outlinePath.addArc(0, getHeight()-radius*2, radius*2, radius*2, double_Pi, 1.5*double_Pi); //outlinePath.lineTo(0, radius); outlinePath.closeSubPath(); - + } else if (getName().equalsIgnoreCase("PARAM")) { //outlinePath.startNewSubPath(0, 0); - + outlinePath.lineTo(width, 0); - + //outlinePath.addArc(width-radius*2, 0, radius*2, radius*2, 0, 0.5*double_Pi); - + outlinePath.lineTo(getWidth(), height); - + //outlinePath.addArc(getWidth()-radius*2, getHeight()-radius*2, radius*2, radius*2, 0.5*double_Pi, double_Pi); - + outlinePath.lineTo(0, height); outlinePath.lineTo(0, 0); //outlinePath.closeSubPath(); - - + + } else if (getName().equalsIgnoreCase("REC")) { - - outlinePath.addRectangle(0,0,getWidth(),getHeight()); - + + outlinePath.addRectangle(0, 0, getWidth(), getHeight()); + } else if (getName().equalsIgnoreCase("all")) { - + //outlinePath.startNewSubPath(0, 0); - + outlinePath.lineTo(width, 0); - + //outlinePath.addArc(width-radius*2, 0, radius*2, radius*2, 0, 0.5*double_Pi); - + outlinePath.lineTo(width, height); - + //outlinePath.addArc(getWidth()-radius*2, getHeight()-radius*2, radius*2, radius*2, 0.5*double_Pi, double_Pi); - + outlinePath.lineTo(0, height); //outlinePath.addArc(0, height-radius*2, radius*2, radius*2, double_Pi, 1.5*double_Pi); - + outlinePath.lineTo(0, 0); //outlinePath.closeSubPath(); - + } else if (getName().equalsIgnoreCase("none")) { - + //outlinePath.startNewSubPath(0, 0); - + outlinePath.lineTo(width, 0); - + //outlinePath.addArc(width-radius*2, 0, radius*2, radius*2, 0, 0.5*double_Pi); - + outlinePath.lineTo(width, height); - + //outlinePath.addArc(width-radius*2, height-radius*2, radius*2, radius*2, 0.5*double_Pi, double_Pi); - + outlinePath.lineTo(0, height); - + outlinePath.lineTo(0, 0); //outlinePath.closeSubPath(); - + } - + else if (getName().equalsIgnoreCase("+") ) + { + outlinePath.lineTo(width, 0); + outlinePath.lineTo(width, height); + outlinePath.lineTo(0, height); + outlinePath.lineTo(0, 0); + } + else if (getName().equalsIgnoreCase("-") ) + { + outlinePath.lineTo(width, 0); + outlinePath.lineTo(width, height); + outlinePath.lineTo(0, height); + outlinePath.lineTo(0, 0); + } + } void EditorButton::paintButton(Graphics& g, bool isMouseOver, bool isButtonDown) { - + g.setColour(Colours::grey); g.fillPath(outlinePath); - + if (getToggleState()) { if (isMouseOver && isEnabled) @@ -852,23 +1046,25 @@ void EditorButton::paintButton(Graphics& g, bool isMouseOver, bool isButtonDown) else g.setGradientFill(neutralGrad); } - - AffineTransform a = AffineTransform::scale(0.98f, 0.94f, float(getWidth())/2.0f, - float(getHeight())/2.0f); + + + AffineTransform a = AffineTransform::scale(0.98f, 0.94f, float(getWidth()) / 2.0f, + float(getHeight()) / 2.0f); g.fillPath(outlinePath, a); - + buttonFont.setHeight(10.0f); int stringWidth = buttonFont.getStringWidth(getName()); - + g.setFont(buttonFont); - + if (isEnabled) g.setColour(Colours::darkgrey); else g.setColour(Colours::lightgrey); - - g.drawSingleLineText(getName(), getWidth()/2 - stringWidth/2, 11); - + + + g.drawSingleLineText(getName(), getWidth() / 2 - stringWidth / 2, 11); + } @@ -878,11 +1074,11 @@ ChannelSelectorButton::ChannelSelectorButton(int num_, int type_, Font& f) : But num = num_; displayNum = num_; type = type_; - + setClickingTogglesState(true); - + buttonFont = f; - buttonFont.setHeight(10); + buttonFont.setHeight (11); } ChannelSelectorButton::~ChannelSelectorButton() {} @@ -916,7 +1112,7 @@ void ChannelSelectorButton::paintButton(Graphics& g, bool isMouseOver, bool isBu g.setColour(Colours::orange); else g.setColour(Colours::darkgrey); - + if (isMouseOver) g.setColour(Colours::white); } @@ -927,14 +1123,14 @@ void ChannelSelectorButton::paintButton(Graphics& g, bool isMouseOver, bool isBu else g.setColour(Colours::lightgrey); } - + // g.fillRect(0,0,getWidth(),getHeight()); - + g.setFont(buttonFont); - + // g.drawRect(0,0,getWidth(),getHeight(),1.0); - - g.drawText(String(displayNum),0,0,getWidth(),getHeight(),Justification::centred,true); + + g.drawText(String(displayNum), 0, 0, getWidth(), getHeight(), Justification::centred, true); } void ChannelSelectorButton::setActive(bool t) @@ -943,27 +1139,180 @@ void ChannelSelectorButton::setActive(bool t) setClickingTogglesState(t); } -ChannelSelectorRegion::ChannelSelectorRegion(ChannelSelector* cs) + +/* + Constructor and Destructor of ChannelSelectorBox. +*/ +ChannelSelectorBox::ChannelSelectorBox() { - channelSelector = cs; - - addMouseListener((MouseListener*) this, true); + setMultiLine(false, true); // No multi lines. + setReturnKeyStartsNewLine(false); // Return key donot start a new line. + setTabKeyUsedAsCharacter(false); + setTooltip("General Format: [a:b:c]->to select all channels from a to c at intervals of b"); } -ChannelSelectorRegion::~ChannelSelectorRegion() +ChannelSelectorBox::~ChannelSelectorBox() { - deleteAllChildren(); + } -void ChannelSelectorRegion::mouseWheelMove(const MouseEvent& event, - const MouseWheelDetails& wheel) +/* + convert a string to integer. +*/ +int ChannelSelectorBox::convertToInteger(std::string s) { - - // std::cout << "Got wheel move: " << wheel.deltaY << std::endl; - channelSelector->shiftChannelsVertical(-wheel.deltaY); + char ar[20]; + int i, k = 0; + for (i = 0; i < s.size(); i++) + { + if (s[i] >= 48 && s[i] <= 57) + { + ar[k] = s[i]; + k++; + } + } + if (k>7) + { + return 1000000; + } + ar[k] = '\0'; + k = atoi(ar); + return k; } -void ChannelSelectorRegion::paint(Graphics& g) + +/* + TextBox to take input. Valid formats: + 1. [ : ] -> select/deselect all channels + 2. [ a : b] -> select/deselect all channels from a to b. + 3. [ a : c : b] -> select/deselect all channels from a to b such that the difference between in each consecutive selected channel is c. +*/ +std::vector<int> ChannelSelectorBox::getBoxInfo(int len) { - // g.fillAll(Colours::white); -} \ No newline at end of file + std::string s = ","; + s += getText().toStdString(); + std::vector<int> finalList,separator,rangeseparator; + int i, j, a, b, k, openb, closeb, otherchar,x,y; + s += ","; + for (i = 0; i < s.size(); i++) //split string by ' , ' or ' ; ' + { + if (s[i] == ';' || s[i] == ',') + { + separator.push_back(i); + } + } + for (i = 0; i < separator.size()-1; i++) // split ranges by ' : ' or ' - ' + { + j = k = separator[i] + 1; + openb = closeb = otherchar = 0; + rangeseparator.clear(); + for (; j < separator[i + 1]; j++) + { + if (s[j] == '-' || s[j] == ':') + { + rangeseparator.push_back(j); + } + else if (((int)s[j] == 32)) + { + continue; + } + else if (s[j] == '[' || s[j] == '{' || s[j] == '(') + { + openb++; + } + else if (s[j] == ']' || s[j] == '}' || s[j] == ')') + { + closeb++; + } + else if ( (int)s[j] > 57 || (int)s[j] < 48) + { + otherchar++; + } + } + + if (openb != closeb || openb > 1 || closeb > 1 || otherchar > 0) //Invalid input + { + continue; + } + + + for (x = separator[i] + 1; x < separator[i + 1]; x++) //trim whitespace and brackets from front + { + if (((int)s[x] >= 48 && (int)s[x] <= 57) || s[x] == ':' || s[x] == '-') + { + break; + } + } + for (y = separator[i + 1] - 1; y > separator[i]; y--) //trim whitespace and brackets from end + { + if (((int)s[y] >= 48 && (int)s[y] <= 57) || s[y] == ':' || s[y] == '-') + { + break; + } + } + if (x > y) + { + continue; + } + + + if (rangeseparator.size() == 0) //syntax of form - x or [x] + { + a = convertToInteger(s.substr(x, y - x + 1)); + if (a == 0||a>len) + { + continue; + } + finalList.push_back(a - 1); + finalList.push_back(a - 1); + finalList.push_back(1); + } + else if (rangeseparator.size() == 1) // syntax of type - x-y or [x-y] + { + a = convertToInteger(s.substr(x, rangeseparator[0] - x + 1)); + b = convertToInteger(s.substr(rangeseparator[0], y - rangeseparator[0] + 1)); + if (a == 0) + { + a = 1; + } + if (b == 0) + { + b = len; + } + if (a > b || a > len || b > len) + { + continue; + } + finalList.push_back(a - 1); + finalList.push_back(b - 1); + finalList.push_back(1); + } + else if (rangeseparator.size() == 2) // syntax of type [x:y:z] or x-y-z + { + a = convertToInteger(s.substr(x, rangeseparator[0] - x + 1)); + k = convertToInteger(s.substr(rangeseparator[0], rangeseparator[1] - rangeseparator[0] + 1)); + b = convertToInteger(s.substr(rangeseparator[1], y - rangeseparator[1] + 1)); + if (a == 0) + { + a = 1; + } + if (b == 0) + { + b = len; + } + if (k == 0) + { + k = 1; + } + if (a > b || a > len || b > len) + { + continue; + } + finalList.push_back(a - 1); + finalList.push_back(b - 1); + finalList.push_back(k); + } + } + return finalList; +} + diff --git a/Source/Processors/Editors/ChannelSelector.h b/Source/Processors/Editors/ChannelSelector.h index 898275275cfdfc1a728b114712e2ea9527a54bb4..23f1ea248ca600befdc610cae4c7878f3b26c6db 100644 --- a/Source/Processors/Editors/ChannelSelector.h +++ b/Source/Processors/Editors/ChannelSelector.h @@ -1,31 +1,32 @@ /* - ------------------------------------------------------------------ - - This file is part of the Open Ephys GUI - Copyright (C) 2013 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/>. - - */ +------------------------------------------------------------------ + +This file is part of the Open Ephys GUI +Copyright (C) 2013 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 __CHANNELSELECTOR_H_68124E35__ #define __CHANNELSELECTOR_H_68124E35__ #include "../../../JuceLibraryCode/JuceHeader.h" #include "../Editors/GenericEditor.h" +#include "../../UI/Utils/TiledButtonGroupManager.h" #include "../Channel/Channel.h" @@ -34,252 +35,245 @@ class ChannelSelectorRegion; class ChannelSelectorButton; class EditorButton; +class ChannelSelectorBox; +class ShowAlertMessage; /** - - Automatically creates an interactive editor for selecting channels. - - Contains tabs for "Params", "Audio", and "Record", which allow - channels to be selected for different purposes. - - @see GenericEditor - - */ +Automatically creates an interactive editor for selecting channels. + +Contains tabs for "Params", "Audio", and "Record", which allow +channels to be selected for different purposes. + +@see GenericEditor + +*/ class PLUGIN_API ChannelSelector : public Component, -public Button::Listener, -public Timer + public Button::Listener, + public Timer { public: - + /** constructor */ ChannelSelector(bool createButtons, Font& titleFont); - + /** destructor */ ~ChannelSelector(); - + /** button callback */ void buttonClicked(Button* button); - + /** Return an array of selected channels. */ Array<int> getActiveChannels(); - + /** Set the selected channels. */ void setActiveChannels(Array<int>); - + /** Set the total number of channels. */ void setNumChannels(int); - + /** get the total number of channels. */ int getNumChannels(); - + /** Return whether a particular channel should be recording. */ bool getRecordStatus(int chan); - + /** Return whether a particular channel should be monitored. */ bool getAudioStatus(int chan); - + /** Return whether a particular channel is selected for editing parameters. */ bool getParamStatus(int chan); - + /** Set whether a particular channel should be recording. */ void setRecordStatus(int, bool); - + /** Set whether a particular channel should be monitored. */ void setAudioStatus(int, bool); - + /** Sets all audio monitors to 'false' */ void clearAudio(); - + /** Set whether a particular channel is selected for editing parameters. */ void setParamStatus(int, bool); - + /** Return component's desired width. */ int getDesiredWidth(); - + /** Called prior to the start of data acquisition.*/ void startAcquisition(); - + /** Called immediately after data acquisition ends.*/ void stopAcquisition(); - + /** Inactivates all the ChannelSelectorButtons under the "param" tab.*/ void inactivateButtons(); - + /** Activates all the ChannelSelectorButtons under the "param" tab.*/ void activateButtons(); - + /** Inactivates all the ChannelSelectorButtons under the "rec" tab.*/ void inactivateRecButtons(); - + /** Activates all the ChannelSelectorButtons under the "rec" tab.*/ void activateRecButtons(); - + /** Refreshes Parameter Colors on change*/ void refreshParameterColors(); - + /** Controls the behavior of ChannelSelectorButtons; they can either behave - like radio buttons (only one selected at a time) or like toggle buttons (an - arbitrary number can be selected at once).*/ + like radio buttons (only one selected at a time) or like toggle buttons (an + arbitrary number can be selected at once).*/ void setRadioStatus(bool); - + void paramButtonsToggledByDefault(bool t); //void paramButtonsActiveByDefault(bool t) {paramsActive = t;} - + /** Used to scroll channels */ void shiftChannelsVertical(float amount); - + bool eventsOnly; - + private: - + EditorButton* audioButton; EditorButton* recordButton; EditorButton* paramsButton; EditorButton* allButton; EditorButton* noneButton; - + EditorButton* selectButtonParam; //Select Channels in parameter tab + EditorButton* deselectButtonParam; //Deselect Channels in parameter tab + EditorButton* selectButtonRecord; //Select Channels in record tab + EditorButton* deselectButtonRecord;//Deselect Channels in record tab + EditorButton* selectButtonAudio; //Select Channels in audio tab + EditorButton* deselectButtonAudio; //Deselect Channels in audio tab + /** An array of ChannelSelectorButtons used to select the channels that - will be updated when a parameter is changed. */ - Array<ChannelSelectorButton*> parameterButtons; - + will be updated when a parameter is changed. + paramBox: TextBox where user input is taken for param tab. + */ + TiledButtonGroupManager parameterButtonsManager; + ChannelSelectorBox* paramBox; + /** An array of ChannelSelectorButtons used to select the channels that - are sent to the audio monitor. */ - Array<ChannelSelectorButton*> audioButtons; - + are sent to the audio monitor. + audioBox: TextBox where user input is taken for audio tab + */ + TiledButtonGroupManager audioButtonsManager; + ChannelSelectorBox* audioBox; + /** An array of ChannelSelectorButtons used to select the channels that - will be written to disk when the record button is pressed. */ - Array<ChannelSelectorButton*> recordButtons; - + will be written to disk when the record button is pressed. + recordBox: TextBox where user input is taken for record tab + */ + TiledButtonGroupManager recordButtonsManager; + ChannelSelectorBox* recordBox; + bool paramsToggled; bool paramsActive; bool recActive; bool radioStatus; - + bool isNotSink; bool moveRight; bool moveLeft; - + int offsetLR; float offsetUD; - + int numColumnsLessThan100; int numColumnsGreaterThan100; int overallHeight; - + int parameterOffset; int audioOffset; int recordOffset; - + int desiredOffset; - + void resized(); - + void addButton(); void removeButton(); void refreshButtonBoundaries(); - + /** Controls the speed of animations. */ void timerCallback(); - + /** Draws the ChannelSelector. */ void paint(Graphics& g); - + Font& titleFont; - - enum {AUDIO, RECORD, PARAMETER}; - + + enum { AUDIO, RECORD, PARAMETER }; + bool acquisitionIsActive; - + ChannelSelectorRegion* channelSelectorRegion; - + }; /** - - A button within the ChannelSelector that allows the user to switch - between tabs of all the channels. - - @see ChannelSelector - - */ + +A button within the ChannelSelector that allows the user to switch +between tabs of all the channels. + +@see ChannelSelector + +*/ class EditorButton : public Button { public: EditorButton(const String& name, Font& f); ~EditorButton(); - + bool getState(); - + void setState(bool state); - + private: void paintButton(Graphics& g, bool isMouseOver, bool isButtonDown); - + void resized(); - + Path outlinePath; - + int type; Font buttonFont; - + bool isEnabled; - + ColourGradient selectedGrad, selectedOverGrad, neutralGrad, neutralOverGrad; }; -/** - - Holds the ChannelSelector buttons. - - @see ChannelSelector - - */ - -class ChannelSelectorRegion : public Component -{ - -public: - ChannelSelectorRegion(ChannelSelector* cs); - ~ChannelSelectorRegion(); - - /** Allows the user to scroll the channels if they are not all visible.*/ - void mouseWheelMove(const MouseEvent& event, const MouseWheelDetails& wheel); - void paint(Graphics& g); - -private: - ChannelSelector* channelSelector; - -}; /** - - A button within the ChannelSelector representing an individual channel. - - @see ChannelSelector - - */ + +A button within the ChannelSelector representing an individual channel. + +@see ChannelSelector + +*/ class ChannelSelectorButton : public Button { public: ChannelSelectorButton(int num, int type, Font& f); ~ChannelSelectorButton(); - + int getType(); int getChannel(); //Channel* getChannel() {return ch;} void setActive(bool t); void setChannel(int n); void setChannel(int n, int d); - + private: void paintButton(Graphics& g, bool isMouseOver, bool isButtonDown); - + //Channel* ch; - + int type; int num; int displayNum; @@ -287,5 +281,18 @@ private: bool isActive; }; +/* + A textbox within the channelSelector to select multiple channels at a time. +*/ +class ChannelSelectorBox :public TextEditor +{ +public: + ChannelSelectorBox(); + ~ChannelSelectorBox(); + + + std::vector<int> getBoxInfo(int len); // Extract Information from the box. + int convertToInteger(std::string s); // Conversion of string to integer. +}; -#endif // __CHANNELSELECTOR_H_68124E35__ \ No newline at end of file +#endif // __CHANNELSELECTOR_H_68124E35__ diff --git a/Source/Processors/Editors/GenericEditor.cpp b/Source/Processors/Editors/GenericEditor.cpp index 40cd6758e1d4e046ac9656f1fc9cbf208be95660..c41d7caf49077be3cc8ce870543870b42660eb9e 100755 --- a/Source/Processors/Editors/GenericEditor.cpp +++ b/Source/Processors/Editors/GenericEditor.cpp @@ -72,7 +72,7 @@ void GenericEditor::constructorInitialize(GenericProcessor* owner, bool useDefau //MemoryInputStream mis(BinaryData::silkscreenserialized, BinaryData::silkscreenserializedSize, false); //Typeface::Ptr typeface = new CustomTypeface(mis); - titleFont = Font("Small Text", 10, Font::plain); + titleFont = Font ("Default", 14, Font::bold); if (!owner->isMerger() && !owner->isSplitter() && !owner->isUtility()) { @@ -84,11 +84,11 @@ void GenericEditor::constructorInitialize(GenericProcessor* owner, bool useDefau if (!owner->isSink()) { - channelSelector = new ChannelSelector(true, titleFont); + channelSelector = new ChannelSelector (true, titleFont); } else { - channelSelector = new ChannelSelector(false, titleFont); + channelSelector = new ChannelSelector (false, titleFont); } addChildComponent(channelSelector); @@ -280,6 +280,12 @@ void GenericEditor::setEnabledState(bool t) isEnabled = p->enabledState(); } +void GenericEditor::setDesiredWidth (int width) +{ + desiredWidth = width; + repaint(); +} + void GenericEditor::startRecording() { if (channelSelector != 0) @@ -357,8 +363,8 @@ void GenericEditor::paint(Graphics& g) g.fillAll(); } - g.setFont(titleFont); - g.setFont(14); + g.setFont (titleFont); + g.setFont (16); if (isEnabled) { @@ -375,13 +381,13 @@ void GenericEditor::paint(Graphics& g) // if (!getProcessor()->isMerger() && !getProcessor()->isSplitter()) // g.drawText(name+" ("+String(nodeId)+")", 6, 5, 500, 15, Justification::left, false); // else - g.drawText(displayName, 6, 5, 500, 15, Justification::left, false); + g.drawText (displayName.toUpperCase(), 10, 5, 500, 15, Justification::left, false); } else { g.addTransform(AffineTransform::rotation(-M_PI/2.0)); - g.drawText(displayName, -getHeight()+6, 5, 500, 15, Justification::left, false); + g.drawText (displayName.toUpperCase(), - getHeight() + 6, 5, 500, 15, Justification::left, false); g.addTransform(AffineTransform::rotation(M_PI/2.0)); } @@ -1152,7 +1158,7 @@ void GenericEditor::updateSettings() {} void GenericEditor::updateVisualizer() {} -void GenericEditor::channelChanged(int chan) {} +void GenericEditor::channelChanged (int channel, bool newState) {} void GenericEditor::saveCustomParameters(XmlElement* xml) { } @@ -1394,3 +1400,4 @@ void ThresholdSlider::setValues(Array<double> v) { valueArray = v; } + diff --git a/Source/Processors/Editors/GenericEditor.h b/Source/Processors/Editors/GenericEditor.h index c448d38e78c6ccee91abed3be97ebc5838bfa21c..d6481971a04019b4b63d9de3e72678523211a719 100755 --- a/Source/Processors/Editors/GenericEditor.h +++ b/Source/Processors/Editors/GenericEditor.h @@ -107,6 +107,9 @@ public: /** Used to enable or disable an editor's processor.*/ void setEnabledState(bool); + /** Used to set desired width of editor. */ + void setDesiredWidth (int width); + /** Called at the start of a recording **/ void startRecording(); @@ -183,6 +186,9 @@ public: title bar and channel selector drawer. */ virtual void buttonClicked(Button* button); + /** Called when the boundaries of the editor are updated. */ + virtual void resized() override; + /** Called by buttonClicked(). Deals with clicks on custom buttons. Subclasses of GenericEditor should modify this method only.*/ virtual void buttonEvent(Button* button); @@ -228,7 +234,7 @@ public: virtual void updateVisualizer(); /** Used by SpikeDetectorEditor. */ - virtual void channelChanged(int chan); + virtual void channelChanged (int channel, bool newState); /** Returns all selected channels from the ChannelSelector. */ Array<int> getActiveChannels(); @@ -306,7 +312,6 @@ protected: //Ideally this would be virtual, but since it's run in the construct and because virtual functions don't get overriden in the constructor, it's not. void addParameterEditors(bool useStandard); - /** A pointer to the editor's ChannelSelector. */ ChannelSelector* channelSelector; @@ -317,9 +322,6 @@ private: /** Used for fading in the editor. */ virtual void timerCallback(); - /** Called when the boundaries of the editor are updated. */ - virtual void resized(); - /** Stores the editor's background color. */ Colour backgroundColor; diff --git a/Source/Processors/FileReader/FileReader.cpp b/Source/Processors/FileReader/FileReader.cpp index 727c27de4c9b0248dca04fe01b61c153a4db3c54..e19275f84e9361f47dbbb20d9668bb3c51208e19 100644 --- a/Source/Processors/FileReader/FileReader.cpp +++ b/Source/Processors/FileReader/FileReader.cpp @@ -80,7 +80,7 @@ bool FileReader::isReady() /* const */ } else { - return true; + return input->isReady(); } } diff --git a/Source/Processors/FileReader/FileSource.cpp b/Source/Processors/FileReader/FileSource.cpp index ab32ecbd392750d785a21dc83ec005d1b5191a1a..7657f27c7375096577636a4e3952e4463d65bd52 100644 --- a/Source/Processors/FileReader/FileSource.cpp +++ b/Source/Processors/FileReader/FileSource.cpp @@ -23,92 +23,113 @@ #include "FileSource.h" -FileSource::FileSource() : fileOpened(false), numRecords(0), activeRecord(-1) + +FileSource::FileSource() + : fileOpened (false) + , numRecords (0) + , activeRecord (-1) + , filename ("") { } + FileSource::~FileSource() { } -int FileSource::getNumRecords() + +int FileSource::getNumRecords() const { return numRecords; } -String FileSource::getRecordName(int index) + +String FileSource::getRecordName (int index) const { return infoArray[index].name; } -int FileSource::getRecordNumChannels(int index) + +int FileSource::getRecordNumChannels (int index) const { return infoArray[index].channels.size(); } -int FileSource::getActiveNumChannels() + +int FileSource::getActiveNumChannels() const { - return getRecordNumChannels(activeRecord); + return getRecordNumChannels (activeRecord); } -float FileSource::getRecordSampleRate(int index) + +float FileSource::getRecordSampleRate (int index) const { return infoArray[index].sampleRate; } -float FileSource::getActiveSampleRate() + +float FileSource::getActiveSampleRate() const { - return getRecordSampleRate(activeRecord); + return getRecordSampleRate (activeRecord); } -int64 FileSource::getRecordNumSamples(int index) + +int64 FileSource::getRecordNumSamples (int index) const { return infoArray[index].numSamples; } -int64 FileSource::getActiveNumSamples() + +int64 FileSource::getActiveNumSamples() const { - return getRecordNumSamples(activeRecord); + return getRecordNumSamples (activeRecord); } -int FileSource::getActiveRecord() + +int FileSource::getActiveRecord() const { return activeRecord; } -RecordedChannelInfo FileSource::getChannelInfo(int recordIndex, int channel) + +RecordedChannelInfo FileSource::getChannelInfo (int recordIndex, int channel) const { return infoArray[recordIndex].channels[channel]; } -RecordedChannelInfo FileSource::getChannelInfo(int channel) + +RecordedChannelInfo FileSource::getChannelInfo (int channel) const { - return getChannelInfo(activeRecord, channel); + return getChannelInfo (activeRecord, channel); } -void FileSource::setActiveRecord(int index) +void FileSource::setActiveRecord (int index) { activeRecord = index; updateActiveRecord(); } -bool FileSource::fileIsOpened() + +bool FileSource::isFileOpened() const { return fileOpened; } -String FileSource::getFileName() + +String FileSource::getFileName() const { return filename; } -bool FileSource::OpenFile(File file) + +bool FileSource::OpenFile (File file) { - if (Open(file)) + if (Open (file)) { fileOpened = true; fillRecordInfo(); + filename = file.getFullPathName(); } else @@ -116,5 +137,11 @@ bool FileSource::OpenFile(File file) fileOpened = false; filename = String::empty; } + return fileOpened; -} \ No newline at end of file +} + +bool FileSource::isReady() +{ + return true; +} diff --git a/Source/Processors/FileReader/FileSource.h b/Source/Processors/FileReader/FileSource.h index d5a9ec7685248dccad082c20653d360ae558d61c..68c6c6a07f40a208d1b879ef439eb5647fc49e15 100644 --- a/Source/Processors/FileReader/FileSource.h +++ b/Source/Processors/FileReader/FileSource.h @@ -27,42 +27,47 @@ #include "../../../JuceLibraryCode/JuceHeader.h" #include "../PluginManager/OpenEphysPlugin.h" + struct RecordedChannelInfo { String name; float bitVolts; }; + class PLUGIN_API FileSource { public: FileSource(); virtual ~FileSource(); - int getNumRecords(); - String getRecordName(int index); + int getNumRecords() const; + int getActiveRecord() const; + + String getRecordName (int index) const; - int getActiveRecord(); - void setActiveRecord(int index); + float getRecordSampleRate (int index) const; + int getRecordNumChannels (int index) const; + int64 getRecordNumSamples (int index) const; - float getRecordSampleRate(int index); - int getRecordNumChannels(int index); - int64 getRecordNumSamples(int index); + float getActiveSampleRate() const; + int getActiveNumChannels() const; + int64 getActiveNumSamples() const; - float getActiveSampleRate(); - int getActiveNumChannels(); - int64 getActiveNumSamples(); + RecordedChannelInfo getChannelInfo (int recordIndex, int channel) const; + RecordedChannelInfo getChannelInfo (int channel) const; - RecordedChannelInfo getChannelInfo(int recordIndex, int channel); - RecordedChannelInfo getChannelInfo(int channel); + void setActiveRecord (int index); - bool OpenFile(File file); - bool fileIsOpened(); - String getFileName(); + bool OpenFile (File file); + bool isFileOpened() const; + String getFileName() const; - virtual int readData(int16* buffer, int nSamples) =0; - virtual void processChannelData(int16* inBuffer, float* outBuffer, int channel, int64 numSamples)=0; - virtual void seekTo(int64 sample) =0; + virtual int readData (int16* buffer, int nSamples) = 0; + virtual void processChannelData (int16* inBuffer, float* outBuffer, int channel, int64 numSamples) = 0; + virtual void seekTo (int64 sample) = 0; + + virtual bool isReady(); protected: struct RecordInfo @@ -79,14 +84,14 @@ protected: int activeRecord; String filename; + private: - virtual bool Open(File file)=0; - virtual void fillRecordInfo()=0; - virtual void updateActiveRecord()=0; + virtual bool Open (File file) = 0; + virtual void fillRecordInfo() = 0; + virtual void updateActiveRecord() = 0; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FileSource); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileSource); }; - #endif // FILESOURCE_H_INCLUDED diff --git a/Source/Processors/GenericProcessor/GenericProcessor.cpp b/Source/Processors/GenericProcessor/GenericProcessor.cpp index ffc990e41ca02b85cdca1eb19bb4686462a081d4..90e34c315a92fd011c1438e10c24f9af7f6c2d57 100755 --- a/Source/Processors/GenericProcessor/GenericProcessor.cpp +++ b/Source/Processors/GenericProcessor/GenericProcessor.cpp @@ -632,7 +632,7 @@ void GenericProcessor::setTimestamp(MidiBuffer& events, int64 timestamp) 0, 0, 0, - data.length() + 1, //It doesn't hurt to send the end-string null and can help avoid issues + data.sizeInBytes(), //It doesn't hurt to send the end-string null and can help avoid issues (uint8*)data.getAddress(), true); diff --git a/Source/Processors/GenericProcessor/GenericProcessor.h b/Source/Processors/GenericProcessor/GenericProcessor.h index d9aa51173e8c67e3108c8602bb6d5cc49a485cc1..dddaaa25110c86c85a28ef306b44f1004709bc9c 100755 --- a/Source/Processors/GenericProcessor/GenericProcessor.h +++ b/Source/Processors/GenericProcessor/GenericProcessor.h @@ -37,6 +37,7 @@ enum ChannelType {HEADSTAGE_CHANNEL = 0, AUX_CHANNEL = 1, ADC_CHANNEL = 2, EVENT #include "../Channel/Channel.h" #include "../../CoreServices.h" #include "../PluginManager/PluginClass.h" +#include "../../Processors/Dsp/LinearSmoothedValueAtomic.h" #include <time.h> #include <stdio.h> diff --git a/Source/Processors/MessageCenter/MessageCenter.cpp b/Source/Processors/MessageCenter/MessageCenter.cpp index 2f4540c727532884edccfb507e72ffcf6dafa401..ba17df9bb0fbf39d45a264c72de166666146715f 100644 --- a/Source/Processors/MessageCenter/MessageCenter.cpp +++ b/Source/Processors/MessageCenter/MessageCenter.cpp @@ -134,7 +134,7 @@ void MessageCenter::process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer) 0, 0, 0, - data.length() + 1, //It doesn't hurt to send the end-string null and can help avoid issues + data.sizeInBytes(), //It doesn't hurt to send the end-string null and can help avoid issues (uint8*)data.getAddress()); needsToSendTimestampMessage = false; @@ -153,7 +153,7 @@ void MessageCenter::process(AudioSampleBuffer& buffer, MidiBuffer& eventBuffer) 0, 0, 0, - data.length()+1, //It doesn't hurt to send the end-string null and can help avoid issues + data.sizeInBytes(), //It doesn't hurt to send the end-string null and can help avoid issues (uint8*) data.getAddress()); newEventAvailable = false; diff --git a/Source/Processors/Parameter/Parameter.cpp b/Source/Processors/Parameter/Parameter.cpp index b5da5de779b838cd06fd476560c0ea4e8251f547..7dd7e7a50efd24c4f9e530adadc5707a66a24762 100755 --- a/Source/Processors/Parameter/Parameter.cpp +++ b/Source/Processors/Parameter/Parameter.cpp @@ -54,6 +54,8 @@ Parameter::Parameter(const String& name_, float low, float high, isBool = false; isDisc = false; + // Initialize default value + values.set (0, defaultValue); } Parameter::Parameter(const String& name_, Array<var> a, int defaultVal, diff --git a/Source/Processors/Parameter/ParameterEditor.cpp b/Source/Processors/Parameter/ParameterEditor.cpp index 7cfb3649b270361cd5dc6a5556b7e9b7f5e8fa74..d863f54f826d253008657a8a9d04a49974473193 100755 --- a/Source/Processors/Parameter/ParameterEditor.cpp +++ b/Source/Processors/Parameter/ParameterEditor.cpp @@ -447,12 +447,12 @@ void ParameterCheckbox::paintButton(Graphics& g, bool isMouseOver, bool isButton ParameterSlider::ParameterSlider(float min, float max, float def, Font labelFont) : Slider("name"), isEnabled(true), font(labelFont) { - setSliderStyle(Slider::Rotary); setRange(min,max,1.0f); setValue(def); setTextBoxStyle(Slider::NoTextBox, false, 40, 20); + setColour (Slider::rotarySliderFillColourId, Colour (240, 179, 12)); } ParameterSlider::~ParameterSlider() {} @@ -477,7 +477,7 @@ void ParameterSlider::paint(Graphics& g) p = makeRotaryPath(getMinimum(), getMaximum(), getValue()); if (isEnabled) - g.setColour(Colour(240,179,12)); + g.setColour (findColour (Slider::rotarySliderFillColourId)); else g.setColour(Colour(75,75,75)); @@ -523,7 +523,6 @@ void ParameterEditor::channelSelectionUI() int numChannels=channelSelector->getNumChannels(); if (parameter->isBoolean()) { - } else if (parameter->isContinuous()) { diff --git a/Source/Processors/Parameter/ParameterEditor.h b/Source/Processors/Parameter/ParameterEditor.h index 02faf68d8adc24efe29de389de3b8b7196ee5fb0..65ab696c0c58b61c5a9f116054d07b79f23d2496 100755 --- a/Source/Processors/Parameter/ParameterEditor.h +++ b/Source/Processors/Parameter/ParameterEditor.h @@ -80,7 +80,7 @@ private: Parameter* parameter; GenericProcessor* processor; - ChannelSelector* channelSelector; + ScopedPointer<ChannelSelector> channelSelector; enum { diff --git a/Source/Processors/PluginManager/PluginManager.cpp b/Source/Processors/PluginManager/PluginManager.cpp index f02d7a0290f2fde5d8423645b09d75c25664a672..7b9a61b8ba55ab0d704ffd75911f36c26a7ba9b6 100644 --- a/Source/Processors/PluginManager/PluginManager.cpp +++ b/Source/Processors/PluginManager/PluginManager.cpp @@ -23,10 +23,7 @@ #include <iostream> #include <stdio.h> -#ifdef WIN32 -//simple hack to avoid to much conditionals -#define dlclose(h) FreeLibrary(h) -#else +#if !defined(WIN32) && !defined(__APPLE__) #include <dlfcn.h> #include <execinfo.h> #endif @@ -35,20 +32,43 @@ #include "../../UI/ProcessorList.h" #include "../../UI/ControlPanel.h" + +static inline void closeHandle(decltype(LoadedLibInfo::handle) handle) { + if (handle) { #ifdef WIN32 -//And this one because Windows doesn't provide an error-to-string anything -static const char* dlerror(void) -{ - static char buf[32]; - DWORD ret = GetLastError(); - if (!ret) return NULL; - sprintf(buf, "DLL Error 0x%x",ret); - return buf; + FreeLibrary(handle); +#elif defined(__APPLE__) + CFRelease(handle); +#else + dlclose(handle); +#endif + } } -#define ERROR_MSG(fmt,...) do{fprintf(stderr,"%s:%d:",__FILE__,__LINE__); fprintf(stderr,fmt,__VA_ARGS__);} while(0) + + +static void errorMsg(const char *file, int line, const char *msg) { + fprintf(stderr, "%s:%d: %s", file, line, msg); + +#ifdef WIN32 + DWORD ret = GetLastError(); + if (ret) { + fprintf(stderr, ": DLL Error 0x%x", ret); + } +#elif defined(__APPLE__) + // Any additional error messages are logged directly by the system + // and are not available to the application #else -#define ERROR_MSG(fmt,args...) do{fprintf(stderr,"%s:%d:",__FILE__,__LINE__); fprintf(stderr,fmt,## args);} while(0) + const char *error = dlerror(); + if (error) { + fprintf(stderr, ": %s", error); + } #endif + + fprintf(stderr, "\n"); +} + +#define ERROR_MSG(msg) errorMsg(__FILE__, __LINE__, msg) + PluginManager::PluginManager() { @@ -66,6 +86,9 @@ void PluginManager::loadAllPlugins() #ifdef WIN32 File pluginPath = File::getSpecialLocation(File::currentApplicationFile).getParentDirectory().getChildFile("plugins"); String pluginExt("*.dll"); +#elif defined(__APPLE__) + File pluginPath = File::getSpecialLocation(File::currentApplicationFile).getChildFile("Contents/PlugIns"); + String pluginExt("*.bundle"); #else File pluginPath = File::getSpecialLocation(File::currentApplicationFile).getParentDirectory().getChildFile("plugins"); String pluginExt("*.so"); @@ -78,7 +101,11 @@ void PluginManager::loadAllPlugins() return; } +#ifdef __APPLE__ + pluginPath.findChildFiles(foundDLLs, File::findDirectories, false, pluginExt); +#else pluginPath.findChildFiles(foundDLLs, File::findFiles, true, pluginExt); +#endif for (int i = 0; i < foundDLLs.size(); i++) { @@ -112,7 +139,18 @@ int PluginManager::loadPlugin(const String& pluginLoc) { */ const char* processorLocCString = static_cast<const char*>(pluginLoc.toUTF8()); -#ifndef WIN32 +#ifdef WIN32 + HINSTANCE handle; + handle = LoadLibrary(processorLocCString); +#elif defined(__APPLE__) + CFURLRef bundleURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, + reinterpret_cast<const UInt8 *>(processorLocCString), + strlen(processorLocCString), + true); + assert(bundleURL); + CFBundleRef handle = CFBundleCreate(kCFAllocatorDefault, bundleURL); + CFRelease(bundleURL); +#else // Clear errors dlerror(); @@ -124,32 +162,30 @@ int PluginManager::loadPlugin(const String& pluginLoc) { */ void *handle = 0; handle = dlopen(processorLocCString,RTLD_GLOBAL|RTLD_NOW); -#else - HINSTANCE handle; - handle = LoadLibrary(processorLocCString); #endif if (!handle) { - ERROR_MSG("%s\n", dlerror()); - dlclose(handle); + ERROR_MSG("Failed to load plugin DLL"); + closeHandle(handle); return -1; } - dlerror(); LibraryInfoFunction infoFunction = 0; #ifdef WIN32 infoFunction = (LibraryInfoFunction)GetProcAddress(handle, "getLibInfo"); +#elif defined(__APPLE__) + infoFunction = (LibraryInfoFunction)CFBundleGetFunctionPointerForName(handle, CFSTR("getLibInfo")); #else + dlerror(); infoFunction = (LibraryInfoFunction)(dlsym(handle, "getLibInfo")); #endif if (!infoFunction) { - ERROR_MSG("%s\n", dlerror()); - dlclose(handle); + ERROR_MSG("Failed to load function 'getLibInfo'"); + closeHandle(handle); return -1; } - dlerror(); Plugin::LibraryInfo libInfo; infoFunction(&libInfo); @@ -157,24 +193,26 @@ int PluginManager::loadPlugin(const String& pluginLoc) { if (libInfo.apiVersion != PLUGIN_API_VER) { std::cerr << pluginLoc << " invalid version" << std::endl; - dlclose(handle); + closeHandle(handle); return -1; } PluginInfoFunction piFunction = 0; #ifdef WIN32 piFunction = (PluginInfoFunction)GetProcAddress(handle, "getPluginInfo"); +#elif defined(__APPLE__) + piFunction = (PluginInfoFunction)CFBundleGetFunctionPointerForName(handle, CFSTR("getPluginInfo")); #else + dlerror(); piFunction = (PluginInfoFunction)(dlsym(handle, "getPluginInfo")); #endif if (!piFunction) { - ERROR_MSG("%s\n", dlerror()); - dlclose(handle); + ERROR_MSG("Failed to load function 'getPluginInfo'"); + closeHandle(handle); return -1; } - dlerror(); LoadedLibInfo lib; lib.apiVersion = libInfo.apiVersion; @@ -230,6 +268,11 @@ int PluginManager::loadPlugin(const String& pluginLoc) { fileSourcePlugins.add(info); break; } + default: + { + std::cerr << pluginLoc << " invalid plugin type: " << pInfo.type << std::endl; + break; + } } } return lib.numPlugins; @@ -414,23 +457,25 @@ PluginManager::Plugin::~Plugin() { void PluginManager::Manager::unloadPlugin(PluginManager::Plugin *processor) { if (!processor) { - ERROR_MSG("PluginManager::unloadPlugin: Invalid processor\n"); + ERROR_MSG("PluginManager::unloadPlugin: Invalid processor"); return; } #ifdef WIN32 HINSTANCE handle; +#elif defined(__APPLE__) + CFBundleRef handle; #else void *handle = 0; #endif handle = processor->processorHandle; - dlclose(handle); + closeHandle(handle); removeListPlugin(processor); } void PluginManager::Manager::insertListPlugin(PluginManager::Plugin *processor) { std::cout << "Size of list before is: " << pluginList.size() << std::endl; if(!processor) { - ERROR_MSG("PluginManager::insertListPlugin: Invalid processor.\n"); + ERROR_MSG("PluginManager::insertListPlugin: Invalid processor."); return; } pluginList.push_back(processor); @@ -441,7 +486,7 @@ void PluginManager::Manager::insertListPlugin(PluginManager::Plugin *processor) void PluginManager::Manager::removeListPlugin(PluginManager::Plugin *processor) { std::cout << "Size of list before is: " << pluginList.size() << std::endl; if(!processor) { - ERROR_MSG("PluginManager::removeListPlugin: Invalid processor.\n"); + ERROR_MSG("PluginManager::removeListPlugin: Invalid processor."); return; } pluginList.remove(processor); @@ -451,6 +496,8 @@ void PluginManager::Manager::removeListPlugin(PluginManager::Plugin *processor) void PluginManager::Manager::removeAllPlugins() { #ifdef WIN32 HINSTANCE handle; +#elif defined(__APPLE__) + CFBundleRef handle; #else void *handle; #endif @@ -459,7 +506,7 @@ void PluginManager::Manager::removeAllPlugins() { handle = (*i)->processorHandle; removeListPlugin(*i); delete *i; - dlclose(handle); + closeHandle(handle); std::cout << "Size of list after all is: " << pluginList.size() << std::endl; } } diff --git a/Source/Processors/PluginManager/PluginManager.h b/Source/Processors/PluginManager/PluginManager.h index ccc50462b5d9992c478c4a2cb4095e7336f8dcca..f5f40ad249f5ffcecce4bcb28bb8a5e2ad583678 100644 --- a/Source/Processors/PluginManager/PluginManager.h +++ b/Source/Processors/PluginManager/PluginManager.h @@ -27,6 +27,8 @@ #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include <Windows.h> +#elif defined(__APPLE__) +#include <CoreFoundation/CFBundle.h> #endif #include <list> @@ -39,6 +41,8 @@ struct LoadedLibInfo : public Plugin::LibraryInfo { #ifdef WIN32 HINSTANCE handle; +#elif defined(__APPLE__) + CFBundleRef handle; #else void* handle; #endif diff --git a/Source/Processors/RecordNode/DataQueue.cpp b/Source/Processors/RecordNode/DataQueue.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a1f4b0cf5d2c520dacaa8a5fc95897cc0491512 --- /dev/null +++ b/Source/Processors/RecordNode/DataQueue.cpp @@ -0,0 +1,218 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 "../../../JuceLibraryCode/JuceHeader.h" +#include "DataQueue.h" + +DataQueue::DataQueue(int blockSize, int nBlocks) : +m_blockSize(blockSize), +m_numBlocks(nBlocks), +m_maxSize(blockSize*nBlocks), +m_readInProgress(false), +m_numChans(0), +m_buffer(0, blockSize*nBlocks) +{} + +DataQueue::~DataQueue() +{} + +void DataQueue::setChannels(int nChans) +{ + if (m_readInProgress) + return; + + m_fifos.clear(); + m_readSamples.clear(); + m_numChans = nChans; + m_timestamps.clear(); + m_lastReadTimestamps.clear(); + + for (int i = 0; i < nChans; ++i) + { + m_fifos.add(new AbstractFifo(m_maxSize)); + m_readSamples.add(0); + m_timestamps.add(new Array<int64>()); + m_timestamps.getLast()->resize(m_numBlocks); + m_lastReadTimestamps.add(0); + } + m_buffer.setSize(nChans, m_maxSize); +} + +void DataQueue::resize(int nBlocks) +{ + if (m_readInProgress) + return; + + int size = m_blockSize*nBlocks; + m_maxSize = size; + m_numBlocks = nBlocks; + + for (int i = 0; i < m_numChans; ++i) + { + m_fifos[i]->setTotalSize(size); + m_fifos[i]->reset(); + m_readSamples.set(i, 0); + m_timestamps[i]->resize(nBlocks); + m_lastReadTimestamps.set(i, 0); + } + m_buffer.setSize(m_numChans, size); +} + +void DataQueue::fillTimestamps(int channel, int index, int size, int64 timestamp) +{ + //Search for the next block start. + int blockMod = index % m_blockSize; + int blockIdx = index / m_blockSize; + int64 startTimestamp; + int blockStartPos; + + if (blockMod == 0) //block starts here + { + startTimestamp = timestamp; + blockStartPos = index; + } + else //we're in the middle of a block, correct to jump to the start of the next- + { + startTimestamp = timestamp + (m_blockSize - blockMod); + blockStartPos = index + (m_blockSize - blockMod); + blockIdx++; + } + + //check that the block is in range + for (int i = 0; i < size; i += m_blockSize) + { + if ((blockStartPos + i) < (index + size)) + { + int64 ts = startTimestamp + (i*m_blockSize); + m_timestamps[channel]->set(blockIdx, ts); + } + + } +} + +void DataQueue::writeChannel(const AudioSampleBuffer& buffer, int channel, int sourceChannel, int nSamples, int64 timestamp) +{ + int index1, size1, index2, size2; + m_fifos[channel]->prepareToWrite(nSamples, index1, size1, index2, size2); + if ((size1 + size2) < nSamples) + { //TODO: turn this into a proper notification. Probably returning a bool. + std::cerr << "Recording Data Queue Overflow" << std::endl; + } + m_buffer.copyFrom(channel, + index1, + buffer, + sourceChannel, + 0, + size1); + + fillTimestamps(channel, index1, size1, timestamp); + + if (size2 > 0) + { + m_buffer.copyFrom(channel, + index2, + buffer, + sourceChannel, + size1, + size2); + + fillTimestamps(channel, index2, size2, timestamp + size1); + } + m_fifos[channel]->finishedWrite(size1 + size2); +} + +/* +We could copy the internal circular buffer to an external one, as DataBuffer does. This class +is, however, intended for disk writing, which is one of the most CPU-critical systems. Just +allowing the record subsytem to access the internal buffer is way faster, altough it has to be +done with special care and manually finish the read process. +*/ + +const AudioSampleBuffer& DataQueue::getAudioBufferReference() const +{ + return m_buffer; +} + +bool DataQueue::startRead(Array<CircularBufferIndexes>& indexes, Array<int64>& timestamps, int nMax) +{ + //This should never happen, but it never hurts to be on the safe side. + if (m_readInProgress) + return false; + + m_readInProgress = true; + indexes.clear(); //Just in case it's not empty already + timestamps.clear(); + + for (int chan = 0; chan < m_numChans; ++chan) + { + CircularBufferIndexes idx; + int readyToRead = m_fifos[chan]->getNumReady(); + int samplesToRead = ((readyToRead > nMax) && (nMax > 0)) ? nMax : readyToRead; + + m_fifos[chan]->prepareToRead(samplesToRead, idx.index1, idx.size1, idx.index2, idx.size2); + indexes.add(idx); + m_readSamples.set(chan, idx.size1 + idx.size2); + + int blockMod = idx.index1 % m_blockSize; + int blockDiff = (blockMod == 0) ? 0 : (m_blockSize - blockMod); + + //If the next timestamp block is within the data we're reading, include the translated timestamp in the output + if (blockDiff < (idx.size1 + idx.size2)) + { + int blockIdx = ((idx.index1 + blockDiff) / m_blockSize) % m_numBlocks; + int64 ts = m_timestamps[chan]->getUnchecked(blockIdx) - blockDiff; + timestamps.add(ts); + //update to the end of the block + m_lastReadTimestamps.set(chan, ts+ idx.size1 + idx.size2); + } + //If not, copy the last sent again + else + { + int64 ts = m_lastReadTimestamps[chan]; + timestamps.add(ts); + m_lastReadTimestamps.set(chan, ts + idx.size1 + idx.size2); + } + } + return true; +} + +void DataQueue::stopRead() +{ + if (!m_readInProgress) + return; + + for (int i = 0; i < m_numChans; ++i) + { + m_fifos[i]->finishedRead(m_readSamples[i]); + m_readSamples.set(i, 0); + } + m_readInProgress = false; +} + +void DataQueue::getTimestampsForBlock(int idx, Array<int64>& timestamps) const +{ + timestamps.clear(); + for (int chan = 0; chan < m_numChans; ++chan) + { + timestamps.add((*m_timestamps[chan])[idx]); + } +} \ No newline at end of file diff --git a/Source/Processors/RecordNode/DataQueue.h b/Source/Processors/RecordNode/DataQueue.h new file mode 100644 index 0000000000000000000000000000000000000000..1d52d5fc22998157f3bbadf75bc1b6dc93852783 --- /dev/null +++ b/Source/Processors/RecordNode/DataQueue.h @@ -0,0 +1,73 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 DATAQUEUE_H_INCLUDED +#define DATAQUEUE_H_INCLUDED + +#include "../../../JuceLibraryCode/JuceHeader.h" + +struct CircularBufferIndexes +{ + int index1; + int size1; + int index2; + int size2; +}; + +class DataQueue +{ +public: + DataQueue(int blockSize, int nBlocks); + ~DataQueue(); + void setChannels(int nChans); + void resize(int nBlocks); + void getTimestampsForBlock(int idx, Array<int64>& timestamps) const; + + //Only the methods after this comment are considered thread-safe. + //Caution must be had to avoid calling more than one of the methods above simulatenously + void writeChannel(const AudioSampleBuffer& buffer, int channel, int sourceChannel, int nSamples, int64 timestamp); + bool startRead(Array<CircularBufferIndexes>& indexes, Array<int64>& timestamps, int nMax); + const AudioSampleBuffer& getAudioBufferReference() const; + void stopRead(); + + +private: + void fillTimestamps(int channel, int index, int size, int64 timestamp); + + OwnedArray<AbstractFifo> m_fifos; + AudioSampleBuffer m_buffer; + Array<int> m_readSamples; + OwnedArray<Array<int64>> m_timestamps; + Array<int64> m_lastReadTimestamps; + + int m_numChans; + const int m_blockSize; + bool m_readInProgress; + int m_numBlocks; + int m_maxSize; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DataQueue); +}; + + +#endif // DATAQUEUE_H_INCLUDED diff --git a/Source/Processors/RecordNode/EngineConfigWindow.cpp b/Source/Processors/RecordNode/EngineConfigWindow.cpp index e86beb6240f5ef28ce1344ce704c75701c494b04..c0f9601ac14ec9b4770f1ae70499e50c4ee55b73 100644 --- a/Source/Processors/RecordNode/EngineConfigWindow.cpp +++ b/Source/Processors/RecordNode/EngineConfigWindow.cpp @@ -1,25 +1,25 @@ /* - ------------------------------------------------------------------ + ------------------------------------------------------------------ - This file is part of the Open Ephys GUI - Copyright (C) 2014 Florian Franzen + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 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. + 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/>. + 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 "EngineConfigWindow.h" diff --git a/Source/Processors/RecordNode/EngineConfigWindow.h b/Source/Processors/RecordNode/EngineConfigWindow.h index e0f0bf823cac72e9e0fe99accd5bec3fdfc44c8c..61d22f0b572b6b913e7f81adb2454fddc6f3e05a 100644 --- a/Source/Processors/RecordNode/EngineConfigWindow.h +++ b/Source/Processors/RecordNode/EngineConfigWindow.h @@ -1,25 +1,25 @@ /* - ------------------------------------------------------------------ + ------------------------------------------------------------------ - This file is part of the Open Ephys GUI - Copyright (C) 2014 Florian Franzen + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 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. + 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/>. + 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 ENGINECONFIGWINDOW_H_INCLUDED #define ENGINECONFIGWINDOW_H_INCLUDED diff --git a/Source/Processors/RecordNode/EventQueue.h b/Source/Processors/RecordNode/EventQueue.h new file mode 100644 index 0000000000000000000000000000000000000000..22dd238fc57847f7292f26d373ec7e4567cffef6 --- /dev/null +++ b/Source/Processors/RecordNode/EventQueue.h @@ -0,0 +1,141 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 EVENTQUEUE_H_INCLUDED +#define EVENTQUEUE_H_INCLUDED + +#include "../../../JuceLibraryCode/JuceHeader.h" +#include <vector> + +struct SpikeObject; + +template <class MsgContainer> +class AsyncEventMessage : + public ReferenceCountedObject +{ +public: + AsyncEventMessage(const MsgContainer& m, int64 t, int extra) : + ReferenceCountedObject(), + m_data(m), + m_timestamp(t), + m_extra(extra) + {} + + ~AsyncEventMessage() {}; + + const MsgContainer& getData() const { return m_data; } + const int64& getTimestamp() const { return m_timestamp; } + const int& getExtra() const { return m_extra; } + +private: + const MsgContainer m_data; + const int64 m_timestamp; + const int m_extra; + +}; + +template <class EventClass> +class EventQueue +{ +public: + typedef AsyncEventMessage<EventClass> EventContainer; + typedef ReferenceCountedObjectPtr<EventContainer> EventClassPtr; + + EventQueue(int size) : + m_fifo(size) + { + m_data.resize(size); + } + + ~EventQueue() + {} + + int getRemainingEvents() const + { + return m_fifo.getNumReady(); + } + + void reset() + { + m_data.clear(); + m_data.resize(m_fifo.getTotalSize()); + } + + void resize(int size) + { + m_data.clear(); + m_fifo.setTotalSize(size); + m_data.resize(size); + } + + void addEvent(const EventClass& ev, int64 t, int extra = 0) + { + int pos1, size1, pos2, size2; + size1 = 0; + m_fifo.prepareToWrite(1, pos1, size1, pos2, size2); + + /* This means there is a buffer overrun. Instead of overwritting the existing data and risking a collision of both threads + we just skip the incoming samples. TODO: use this to notify of the overrun and act consequently */ + if (size1 > 0) + { + m_data[pos1] = new EventContainer(ev, t, extra); + m_fifo.finishedWrite(1); + } + } + + int getEvents(std::vector<EventClassPtr>& vec, int max) + { + int pos1, size1, pos2, size2; + int numAvailable = m_fifo.getNumReady(); + int numToRead = ((max < numAvailable) && (max > 0)) ? max : numAvailable; + m_fifo.prepareToRead(numToRead, pos1, size1, pos2, size2); + vec.resize(numToRead); + for (int i = 0; i < size1; ++i) + { + vec[i] = m_data[pos1 + i]; + } + if (size2 > 0) + { + for (int i = 0; i < size2; ++i) + { + vec[size1 + i] = m_data[pos2 + i]; + } + } + m_fifo.finishedRead(numToRead); + return numToRead; + } + +private: + std::vector<EventClassPtr> m_data; + AbstractFifo m_fifo; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(EventQueue); +}; + +typedef EventQueue<MidiMessage> EventMsgQueue; +typedef EventQueue<SpikeObject> SpikeMsgQueue; +typedef ReferenceCountedObjectPtr<AsyncEventMessage<MidiMessage>> EventMessagePtr; +typedef ReferenceCountedObjectPtr<AsyncEventMessage<SpikeObject>> SpikeMessagePtr; + +#endif // EVENTQUEUE_H_INCLUDED + diff --git a/Source/Processors/RecordNode/OriginalRecording.cpp b/Source/Processors/RecordNode/OriginalRecording.cpp index 864514ae6ed08e8bb97579bbe4d4a0a5f378ee4d..7e5aab4d8ce661367b50162f9df89e057cfce445 100644 --- a/Source/Processors/RecordNode/OriginalRecording.cpp +++ b/Source/Processors/RecordNode/OriginalRecording.cpp @@ -1,23 +1,23 @@ /* ------------------------------------------------------------------- + ------------------------------------------------------------------ -This file is part of the Open Ephys GUI -Copyright (C) 2013 Florian Franzen + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 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. + 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/>. + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -62,12 +62,12 @@ OriginalRecording::~OriginalRecording() delete recordMarker;*/ } -String OriginalRecording::getEngineID() +String OriginalRecording::getEngineID() const { return "OPENEPHYS"; } -void OriginalRecording::addChannel(int index, Channel* chan) +void OriginalRecording::addChannel(int index, const Channel* chan) { //Just populate the file array with null so we can address it by index afterwards fileArray.add(nullptr); @@ -75,7 +75,7 @@ void OriginalRecording::addChannel(int index, Channel* chan) samplesSinceLastTimestamp.add(0); } -void OriginalRecording::addSpikeElectrode(int index, SpikeRecordInfo* elec) +void OriginalRecording::addSpikeElectrode(int index, const SpikeRecordInfo* elec) { spikeFileArray.add(nullptr); } @@ -382,27 +382,23 @@ String OriginalRecording::generateSpikeHeader(SpikeRecordInfo* elec) return header; } -void OriginalRecording::writeEvent(int eventType, MidiMessage& event, int samplePosition) +void OriginalRecording::writeEvent(int eventType, const MidiMessage& event, int64 timestamp) { if (isWritableEvent(eventType)) - writeTTLEvent(event,samplePosition); + writeTTLEvent(event, timestamp); if (eventType == GenericProcessor::MESSAGE) - writeMessage(event,samplePosition); + writeMessage(event, timestamp); } -void OriginalRecording::writeMessage(MidiMessage& event, int samplePosition) +void OriginalRecording::writeMessage(const MidiMessage& event, int64 timestamp) { if (messageFile == nullptr) return; - uint64 samplePos = (uint64) samplePosition; - uint8 sourceNodeId = event.getNoteNumber(); - - int64 eventTimestamp = (*timestamps)[sourceNodeId] + samplePos; int msgLength = event.getRawDataSize() - 6; const char* dataptr = (const char*)event.getRawData() + 6; - String timestampText(eventTimestamp); + String timestampText(timestamp); diskWriteLock.enter(); fwrite(timestampText.toUTF8(),1,timestampText.length(),messageFile); @@ -413,7 +409,7 @@ void OriginalRecording::writeMessage(MidiMessage& event, int samplePosition) } -void OriginalRecording::writeTTLEvent(MidiMessage& event, int samplePosition) +void OriginalRecording::writeTTLEvent(const MidiMessage& event, int64 timestamp) { // find file and write samples to disk // std::cout << "Received event!" << std::endl; @@ -423,15 +419,12 @@ void OriginalRecording::writeTTLEvent(MidiMessage& event, int samplePosition) const uint8* dataptr = event.getRawData(); - uint64 samplePos = (uint64) samplePosition; - - uint8 sourceNodeId = event.getNoteNumber(); - - int64 eventTimestamp = (*timestamps)[sourceNodeId] + samplePos; // add the sample position to the buffer timestamp + //With the new external recording thread, this field has no sense. + int16 samplePos = 0; diskWriteLock.enter(); - fwrite(&eventTimestamp, // ptr + fwrite(×tamp, // ptr 8, // size of each element 1, // count eventFile); // ptr to FILE object @@ -453,64 +446,59 @@ void OriginalRecording::writeTTLEvent(MidiMessage& event, int samplePosition) diskWriteLock.exit(); } -void OriginalRecording::writeData(AudioSampleBuffer& buffer) +void OriginalRecording::writeData(int writeChannel, int realChannel, const float* buffer, int size) { + int samplesWritten = 0; - for (int i = 0; i < buffer.getNumChannels(); i++) - { - if (getChannel(i)->getRecordState()) - { - int samplesWritten = 0; - - int sourceNodeId = getChannel(i)->sourceNodeId; + int sourceNodeId = getChannel(realChannel)->sourceNodeId; - samplesSinceLastTimestamp.set(i,0); + //TODO: optimize. Now we use realchannel, we should optimize the whole thing to only use recorded channels + samplesSinceLastTimestamp.set(realChannel, 0); - int nSamples = (*numSamples)[sourceNodeId]; + int nSamples = size; while (samplesWritten < nSamples) // there are still unwritten samples in this buffer { int numSamplesToWrite = nSamples - samplesWritten; - if (blockIndex[i] + numSamplesToWrite < BLOCK_LENGTH) // we still have space in this block + if (blockIndex[realChannel] + numSamplesToWrite < BLOCK_LENGTH) // we still have space in this block { // write buffer to disk! - writeContinuousBuffer(buffer.getReadPointer(i,samplesWritten), + writeContinuousBuffer(buffer + samplesWritten, numSamplesToWrite, - i); + writeChannel); //timestamp += numSamplesToWrite; - samplesSinceLastTimestamp.set(i, samplesSinceLastTimestamp[i] + numSamplesToWrite); - blockIndex.set(i, blockIndex[i] + numSamplesToWrite); + samplesSinceLastTimestamp.set(realChannel, samplesSinceLastTimestamp[realChannel] + numSamplesToWrite); + blockIndex.set(realChannel, blockIndex[realChannel] + numSamplesToWrite); samplesWritten += numSamplesToWrite; } else // there's not enough space left in this block for all remaining samples { - numSamplesToWrite = BLOCK_LENGTH - blockIndex[i]; + numSamplesToWrite = BLOCK_LENGTH - blockIndex[realChannel]; // write buffer to disk! - writeContinuousBuffer(buffer.getReadPointer(i,samplesWritten), + writeContinuousBuffer(buffer + samplesWritten, numSamplesToWrite, - i); + writeChannel); // update our variables samplesWritten += numSamplesToWrite; //timestamp += numSamplesToWrite; - samplesSinceLastTimestamp.set(i, samplesSinceLastTimestamp[i] + numSamplesToWrite); - blockIndex.set(i,0); // back to the beginning of the block + samplesSinceLastTimestamp.set(realChannel, samplesSinceLastTimestamp[realChannel] + numSamplesToWrite); + blockIndex.set(realChannel,0); // back to the beginning of the block } } - } - } } -void OriginalRecording::writeContinuousBuffer(const float* data, int nSamples, int channel) +void OriginalRecording::writeContinuousBuffer(const float* data, int nSamples, int writeChannel) { + int channel = getRealChannel(writeChannel); // check to see if the file exists if (fileArray[channel] == nullptr) return; @@ -526,7 +514,7 @@ void OriginalRecording::writeContinuousBuffer(const float* data, int nSamples, i if (blockIndex[channel] == 0) { - writeTimestampAndSampleCount(fileArray[channel], channel); + writeTimestampAndSampleCount(fileArray[channel], writeChannel); } diskWriteLock.enter(); @@ -554,9 +542,9 @@ void OriginalRecording::writeTimestampAndSampleCount(FILE* file, int channel) uint16 samps = BLOCK_LENGTH; - int sourceNodeId = getChannel(channel)->sourceNodeId; + // int sourceNodeId = getChannel(channel)->sourceNodeId; - int64 ts = (*timestamps)[sourceNodeId] + samplesSinceLastTimestamp[channel]; + int64 ts = getTimestamp(channel) + samplesSinceLastTimestamp[channel]; fwrite(&ts, // ptr 8, // size of each element @@ -642,7 +630,7 @@ void OriginalRecording::closeFiles() // this->timestamp = timestamp; // } -void OriginalRecording::writeSpike(const SpikeObject& spike, int electrodeIndex) +void OriginalRecording::writeSpike(int electrodeIndex, const SpikeObject& spike, int64 timestamp) { uint8_t spikeBuffer[MAX_SPIKE_BUFFER_LEN]; diff --git a/Source/Processors/RecordNode/OriginalRecording.h b/Source/Processors/RecordNode/OriginalRecording.h index 82cd89092cbce28a99f3335e6deb65561f25fc1b..0aa252e12963ee5f870a8fbe939682fa0f5e1dfd 100644 --- a/Source/Processors/RecordNode/OriginalRecording.h +++ b/Source/Processors/RecordNode/OriginalRecording.h @@ -1,26 +1,25 @@ /* - ------------------------------------------------------------------ + ------------------------------------------------------------------ - This file is part of the Open Ephys GUI - Copyright (C) 2013 Florian Franzen + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 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. + 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/>. - - */ + 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 ORIGINALRECORDING_H_INCLUDED #define ORIGINALRECORDING_H_INCLUDED @@ -46,16 +45,15 @@ public: ~OriginalRecording(); void setParameter(EngineParameter& parameter); - String getEngineID(); - void openFiles(File rootFolder, int experimentNumber, int recordingNumber); - void closeFiles(); - void writeData(AudioSampleBuffer& buffer); - void writeEvent(int eventType, MidiMessage& event, int samplePosition); - void addChannel(int index, Channel* chan); - void resetChannels(); - //void updateTimeStamp(int64 timestamp); - void addSpikeElectrode(int index, SpikeRecordInfo* elec); - void writeSpike(const SpikeObject& spike, int electrodeIndex); + String getEngineID() const override; + void openFiles(File rootFolder, int experimentNumber, int recordingNumber) override; + void closeFiles() override; + void writeData(int writeChannel, int realChannel, const float* buffer, int size) override; + void writeEvent(int eventType, const MidiMessage& event, int64 timestamp) override; + void addChannel(int index, const Channel* chan) override; + void resetChannels() override; + void addSpikeElectrode(int index, const SpikeRecordInfo* elec) override; + void writeSpike(int electrodeIndex, const SpikeObject& spike, int64 timestamp) override; static RecordEngineManager* getEngineManager(); @@ -71,8 +69,8 @@ private: String generateSpikeHeader(SpikeRecordInfo* elec); void openMessageFile(File rootFolder); - void writeTTLEvent(MidiMessage& event, int samplePosition); - void writeMessage(MidiMessage& event, int samplePosition); + void writeTTLEvent(const MidiMessage& event, int64 timestamp); + void writeMessage(const MidiMessage& event, int64 timestamp); void writeXml(); diff --git a/Source/Processors/RecordNode/RecordEngine.cpp b/Source/Processors/RecordNode/RecordEngine.cpp index e62c06b4811c1dd8dc255f5a91305e78efcf32e4..507cd68e06810d24b9566bd59534603ebfa1fe9e 100644 --- a/Source/Processors/RecordNode/RecordEngine.cpp +++ b/Source/Processors/RecordNode/RecordEngine.cpp @@ -1,25 +1,25 @@ /* - ------------------------------------------------------------------ + ------------------------------------------------------------------ - This file is part of the Open Ephys GUI - Copyright (C) 2014 Florian Franzen + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 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. + 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/>. + 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 "RecordEngine.h" #include "RecordNode.h" @@ -40,33 +40,56 @@ void RecordEngine::setParameter(EngineParameter& parameter) {} void RecordEngine::resetChannels() {} -void RecordEngine::registerProcessor(GenericProcessor* processor) {} +void RecordEngine::registerProcessor(const GenericProcessor* processor) {} -Channel* RecordEngine::getChannel(int index) +void RecordEngine::addChannel(int index, const Channel* chan) {} + +void RecordEngine::startChannelBlock(bool lastBlock) {} + +void RecordEngine::endChannelBlock(bool lastBlock) {} + +Channel* RecordEngine::getChannel(int index) const { return AccessClass::getProcessorGraph()->getRecordNode()->getDataChannel(index); } -String RecordEngine::generateDateString() +String RecordEngine::generateDateString() const { return AccessClass::getProcessorGraph()->getRecordNode()->generateDateString(); } -SpikeRecordInfo* RecordEngine::getSpikeElectrode(int index) +SpikeRecordInfo* RecordEngine::getSpikeElectrode(int index) const { return AccessClass::getProcessorGraph()->getRecordNode()->getSpikeElectrode(index); } -void RecordEngine::updateTimestamps(std::map<uint8, int64>* ts) +void RecordEngine::updateTimestamps(const Array<int64>& ts, int channel) +{ + if (channel < 0) + timestamps = ts; + else + timestamps.set(channel, ts[channel]); +} + +void RecordEngine::setChannelMapping(const Array<int>& chans) { - timestamps = ts; + channelMap = chans; } -void RecordEngine::updateNumSamples(std::map<uint8, int>* ns) +int64 RecordEngine::getTimestamp(int channel) const { - numSamples = ns; + return timestamps[channel]; } +int RecordEngine::getRealChannel(int channel) const +{ + return channelMap[channel]; +} + +int RecordEngine::getNumRecordedChannels() const +{ + return channelMap.size(); +} void RecordEngine::registerSpikeSource(GenericProcessor* processor) {} diff --git a/Source/Processors/RecordNode/RecordEngine.h b/Source/Processors/RecordNode/RecordEngine.h index e9fc8585fd9f1acdea83a530a987f362a23f9484..1bd4af8c0020afb67f98586d2397a99b5bffc555 100644 --- a/Source/Processors/RecordNode/RecordEngine.h +++ b/Source/Processors/RecordNode/RecordEngine.h @@ -1,25 +1,25 @@ /* - ------------------------------------------------------------------ + ------------------------------------------------------------------ - This file is part of the Open Ephys GUI - Copyright (C) 2014 Florian Franzen + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 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. + 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/>. + 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 RECORDENGINE_H_INCLUDED #define RECORDENGINE_H_INCLUDED @@ -59,23 +59,31 @@ class PLUGIN_API RecordEngine public: RecordEngine(); virtual ~RecordEngine(); - virtual String getEngineID() =0; + virtual String getEngineID() const =0; - /** All the public methods (except registerManager) are called by RecordNode: + /** All the public methods (except registerManager) are called by RecordNode or RecordingThread: When acquisition starts (in the specified order): 1-resetChannels 2-registerProcessor, addChannel, registerSpikeSource, addspikeelectrode 3-configureEngine (which calls setParameter) 3-startAcquisition - During acquisition: - updateTimeStamps When recording starts (in the specified order): 1-directoryChanged (if needed) - 2-openFiles - During recording: - writeData, writeEvent, writeSpike + 2-(setChannelMapping) + 3-(updateTimestamps*) + 4-openFiles* + During recording: (RecordThread loop) + 1-(updateTimestamps*) (can be called in a per-channel basis when the circular buffer wraps) + 2-startChannelBlock* + 3-writeData* (per channel. Can be called more than once to account for the circular buffer wrap) + 4-endChannelBlock* + 4-writeEvent* (if needed) + 5-writeSpike* (if needed) When recording stops: - closeFiles + closeFiles* + + Methods marked with a * are called via the RecordThread thread. + Methods marked with parenthesis are not overloaded methods */ /** Called for registering parameters @@ -91,25 +99,31 @@ public: */ virtual void closeFiles() = 0; - /** Write continuous data. - This method gets the full data buffer, it must query getRecordState for - each registered channel to determine which channels to actually write to disk. - The number of samples to write will be found in the numSamples object. + /** Called by the record thread before it starts writing the channels to disk + */ + virtual void startChannelBlock(bool lastBlock); + + /** Write continuous data for a channel. The raw buffer pointer is passed for speed, + care must be taken to only read the specified number of bytes. */ - virtual void writeData(AudioSampleBuffer& buffer) = 0; + virtual void writeData(int writeChannel, int realChannel, const float* buffer, int size) = 0; + + /** Called by the record thread after it has written a channel block + */ + virtual void endChannelBlock(bool lastBlock); /** Write a single event to disk. */ - virtual void writeEvent(int eventType, MidiMessage& event, int samplePosition) = 0; + virtual void writeEvent(int eventType, const MidiMessage& event, int64 timestamp) = 0; /** Called when acquisition starts once for each processor that might record continuous data */ - virtual void registerProcessor(GenericProcessor* processor); + virtual void registerProcessor(const GenericProcessor* processor); /** Called after registerProcessor, once for each output channel of the processor */ - virtual void addChannel(int index, Channel* chan) = 0; + virtual void addChannel(int index, const Channel* chan); /** Called when acquisition starts once for each processor that might record spikes */ @@ -117,23 +131,25 @@ public: /** Called after registerSpikesource, once for each channel group */ - virtual void addSpikeElectrode(int index, SpikeRecordInfo* elec) = 0; + virtual void addSpikeElectrode(int index, const SpikeRecordInfo* elec) = 0; /** Write a spike to disk */ - virtual void writeSpike(const SpikeObject& spike, int electrodeIndex) = 0; + virtual void writeSpike(int electrodeIndex, const SpikeObject& spike, int64 timestamp) = 0; /** Called when a new acquisition starts, to clean all channel data before registering the processors */ virtual void resetChannels(); - /** Called every time a new timestamp event is received + /** Called at the start of every write block */ - void updateTimestamps(std::map<uint8, int64>* timestamps); + void updateTimestamps(const Array<int64>& timestamps, int channel = -1); - /** Called every time a new numSamples event is received */ - void updateNumSamples(std::map<uint8, int>* numSamples); + /** Called prior to opening files, to set the map between recorded + channels and actual channel numbers + */ + void setChannelMapping(const Array<int>& channels); /** Called after all channels and spike groups have been registered, just before acquisition starts @@ -157,20 +173,31 @@ protected: /** Gets the specified channel from the channel array stored in RecordNode */ - Channel* getChannel(int index); + Channel* getChannel(int index) const; /** Gets the specified channel group info structure from the array stored in RecordNode */ - SpikeRecordInfo* getSpikeElectrode(int index); + SpikeRecordInfo* getSpikeElectrode(int index) const; /** Generate a Matlab-compatible datestring */ - String generateDateString(); + String generateDateString() const; + + /** Gets the current block's first timestamp for a given channel + */ + int64 getTimestamp(int channel) const; + + /** Gets the actual channel number from a recorded channel index + */ + int getRealChannel(int channel) const; - std::map<uint8, int>* numSamples; - std::map<uint8, int64>* timestamps; + /** Gets the number of recorded channels + */ + int getNumRecordedChannels() const; private: + Array<int64> timestamps; + Array<int> channelMap; RecordEngineManager* manager; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RecordEngine); diff --git a/Source/Processors/RecordNode/RecordNode.cpp b/Source/Processors/RecordNode/RecordNode.cpp index 83a80bef5a0d233a74b718b56d0238b311439257..8e56c9b824518c2a35f383b2fc5a964b78ce5e95 100755 --- a/Source/Processors/RecordNode/RecordNode.cpp +++ b/Source/Processors/RecordNode/RecordNode.cpp @@ -27,6 +27,8 @@ #include "../../UI/ControlPanel.h" #include "../../AccessClass.h" #include "RecordEngine.h" +#include "RecordThread.h" +#include "DataQueue.h" #define EVERY_ENGINE for(int eng = 0; eng < engineArray.size(); eng++) engineArray[eng] @@ -41,15 +43,11 @@ RecordNode::RecordNode() isProcessing = false; isRecording = false; - allFilesOpened = false; - signalFilesShouldClose = false; - - signalFilesShouldClose = false; + setFirstBlock = false; settings.numInputs = 2048; settings.numOutputs = 0; - eventChannel = new Channel(this, 0, EVENT_CHANNEL); recordingNumber = -1; spikeElectrodeIndex = 0; @@ -60,13 +58,16 @@ RecordNode::RecordNode() // 128 inputs, 0 outputs setPlayConfigDetails(getNumInputs(),getNumOutputs(),44100.0,128); - + m_recordThread = new RecordThread(engineArray); + m_dataQueue = new DataQueue(WRITE_BLOCK_LENGTH, DATA_BUFFER_NBLOCKS); + m_eventQueue = new EventMsgQueue(EVENT_BUFFER_NEVENTS); + m_spikeQueue = new SpikeMsgQueue(SPIKE_BUFFER_NSPIKES); + m_recordThread->setQueuePointers(m_dataQueue, m_eventQueue, m_spikeQueue); } RecordNode::~RecordNode() { - delete eventChannel; // Memory leak fixed by Michael Borisov } void RecordNode::setChannel(Channel* ch) @@ -117,19 +118,6 @@ void RecordNode::filenameComponentChanged(FilenameComponent* fnc) } -void RecordNode::updateChannelName(int channelIndex, String newname) -{ - /* if (channelPointers[channelIndex] != nullptr && channelIndex < channelPointers.size()) - { - channelPointers[channelIndex]->name = newname; - updateFileName(channelPointers[channelIndex]); - } else*/ - { - // keep name and do the change when the pointer actually points to something... ? - modifiedChannelNames.add(newname); - modifiedChannelInd.add(channelIndex); - } -} void RecordNode::getChannelNamesAndRecordingStatus(StringArray& names, Array<bool>& recording) { @@ -186,17 +174,6 @@ void RecordNode::addInputChannel(GenericProcessor* sourceNode, int chan) } -void RecordNode::updateTrialNumber() -{ - trialNum++; -} - -void RecordNode::appendTrialNumber(bool t) -{ - appendTrialNum = t; -} - - void RecordNode::createNewDirectory() { std::cout << "Creating new directory." << std::endl; @@ -299,9 +276,8 @@ void RecordNode::setParameter(int parameterIndex, float newValue) if (parameterIndex == 1) { - isRecording = true; - hasRecorded = true; - // std::cout << "START RECORDING." << std::endl; + + // std::cout << "START RECORDING." << std::endl; if (newDirectoryNeeded) { @@ -327,28 +303,64 @@ void RecordNode::setParameter(int parameterIndex, float newValue) settingsNeeded = false; } - EVERY_ENGINE->openFiles(rootFolder, experimentNumber, recordingNumber); + m_recordThread->setFileComponents(rootFolder, experimentNumber, recordingNumber); + + channelMap.clear(); + int totChans = channelPointers.size(); + for (int ch = 0; ch < totChans; ++ch) + { + if (channelPointers[ch]->getRecordState()) + { + channelMap.add(ch); + } + } + int numRecordedChannels = channelMap.size(); + + EVERY_ENGINE->setChannelMapping(channelMap); + m_recordThread->setChannelMap(channelMap); + m_dataQueue->setChannels(numRecordedChannels); + m_eventQueue->reset(); + m_spikeQueue->reset(); + m_recordThread->setFirstBlockFlag(false); + + setFirstBlock = false; + m_recordThread->startThread(); - allFilesOpened = true; + isRecording = true; + hasRecorded = true; } else if (parameterIndex == 0) { - // std::cout << "STOP RECORDING." << std::endl; + std::cout << "STOP RECORDING." << std::endl; if (isRecording) { - - // close necessary files - signalFilesShouldClose = true; + isRecording = false; + + // close the writing thread. + m_recordThread->signalThreadShouldExit(); + m_recordThread->waitForThreadToExit(2000); + while (m_recordThread->isThreadRunning()) + { + std::cerr << "RecordEngine timeout" << std::endl; + if (AlertWindow::showOkCancelBox(AlertWindow::WarningIcon, "Record Thread timeout", + "The recording thread is taking too long to close.\nThis could mean there is still data waiting to be written in the buffer, but it normally " + "shouldn't take this long.\nYou can either wait a bit more or forcefully close the thread. Note that data might be lost or corrupted" + "if forcibly closing the thread.", "Stop the thread", "Wait a bit more")) + { + m_recordThread->stopThread(100); + m_recordThread->forceCloseFiles(); + } + else + { + m_recordThread->waitForThreadToExit(2000); + } + } } - - isRecording = false; - - } else if (parameterIndex == 2) { @@ -379,15 +391,6 @@ void RecordNode::setParameter(int parameterIndex, float newValue) } } -void RecordNode::closeAllFiles() -{ - if (allFilesOpened) - { - EVERY_ENGINE->closeFiles(); - allFilesOpened = false; - } -} - bool RecordNode::enable() { if (hasRecorded) @@ -411,9 +414,6 @@ bool RecordNode::disable() // close files if necessary setParameter(0, 10.0f); - if (isProcessing) - closeAllFiles(); - isProcessing = false; return true; @@ -427,13 +427,15 @@ float RecordNode::getFreeSpace() void RecordNode::handleEvent(int eventType, MidiMessage& event, int samplePosition) { - if (isRecording && allFilesOpened) + if (isRecording) { if (isWritableEvent(eventType)) { if (*(event.getRawData()+4) > 0) // saving flag > 0 (i.e., event has not already been processed) { - EVERY_ENGINE->writeEvent(eventType, event, samplePosition); + uint8 sourceNodeId = event.getNoteNumber(); + int64 timestamp = timestamps[sourceNodeId] + samplePosition; + m_eventQueue->addEvent(event, timestamp, eventType); } } } @@ -442,34 +444,32 @@ void RecordNode::handleEvent(int eventType, MidiMessage& event, int samplePositi void RecordNode::process(AudioSampleBuffer& buffer, MidiBuffer& events) { - //update timstamp data even if we're not recording yet - EVERY_ENGINE->updateTimestamps(×tamps); - EVERY_ENGINE->updateNumSamples(&numSamples); // FIRST: cycle through events -- extract the TTLs and the timestamps checkForEvents(events); - if (isRecording && allFilesOpened) + if (isRecording) { // SECOND: write channel data - if (channelPointers.size() > 0) - { - EVERY_ENGINE->writeData(buffer); - } + int recordChans = channelMap.size(); + for (int chan = 0; chan < recordChans; ++chan) + { + int realChan = channelMap[chan]; + int sourceNodeId = channelPointers[realChan]->sourceNodeId; + int nSamples = numSamples.at(sourceNodeId); + int timestamp = timestamps.at(sourceNodeId); + m_dataQueue->writeChannel(buffer, chan, realChan, nSamples, timestamp); + } // std::cout << nSamples << " " << samplesWritten << " " << blockIndex << std::endl; - - return; - + if (!setFirstBlock) + { + m_recordThread->setFirstBlockFlag(true); + setFirstBlock = true; + } + } - // this is intended to prevent parameter changes from closing files - // before recording stops - if (signalFilesShouldClose) - { - closeAllFiles(); - signalFilesShouldClose = false; - } } @@ -488,7 +488,7 @@ void RecordNode::registerRecordEngine(RecordEngine* engine) engineArray.add(engine); } -void RecordNode::registerSpikeSource(GenericProcessor* processor) +void RecordNode::registerSpikeSource(GenericProcessor* processor) { EVERY_ENGINE->registerSpikeSource(processor); } @@ -503,7 +503,10 @@ int RecordNode::addSpikeElectrode(SpikeRecordInfo* elec) void RecordNode::writeSpike(SpikeObject& spike, int electrodeIndex) { - EVERY_ENGINE->writeSpike(spike,electrodeIndex); + if (isRecording) + { + m_spikeQueue->addEvent(spike, spike.timestamp, electrodeIndex); + } } SpikeRecordInfo* RecordNode::getSpikeElectrode(int index) diff --git a/Source/Processors/RecordNode/RecordNode.h b/Source/Processors/RecordNode/RecordNode.h index 70facf9f34c5780e95188806916f3842f31ae964..92af93e5920e4f1e46f0e4e45ad417c5211a875e 100755 --- a/Source/Processors/RecordNode/RecordNode.h +++ b/Source/Processors/RecordNode/RecordNode.h @@ -26,18 +26,23 @@ #include "../../../JuceLibraryCode/JuceHeader.h" #include <stdio.h> #include <map> +#include <atomic> #include "../GenericProcessor/GenericProcessor.h" #include "../Channel/Channel.h" +#include "EventQueue.h" - -#define HEADER_SIZE 1024 -#define BLOCK_LENGTH 1024 +#define WRITE_BLOCK_LENGTH 1024 +#define DATA_BUFFER_NBLOCKS 300 +#define EVENT_BUFFER_NEVENTS 512 +#define SPIKE_BUFFER_NSPIKES 512 struct SpikeRecordInfo; struct SpikeObject; class RecordEngine; +class RecordThread; +class DataQueue; /** @@ -92,9 +97,6 @@ public: /** returns channel names and whether we record them */ void getChannelNamesAndRecordingStatus(StringArray& names, Array<bool>& recording); - /** update channel name */ - void updateChannelName(int channelIndex, String newname); - /** Get channel stored in channelPointers array */ Channel* getDataChannel(int index); @@ -132,10 +134,6 @@ public: return rootFolder; } - void appendTrialNumber(bool); - - void updateTrialNumber(); - /** Adds a Record Engine to use */ void registerRecordEngine(RecordEngine* engine); @@ -163,8 +161,7 @@ public: /** Signals when to create a new data directory when recording starts.*/ bool newDirectoryNeeded; - bool isRecording; - bool allFilesOpened; + std::atomic<bool> isRecording; /** Generate a Matlab-compatible datestring */ String generateDateString(); @@ -173,7 +170,7 @@ private: /** Keep the RecordNode informed of acquisition and record states. */ - bool isProcessing, signalFilesShouldClose; + bool isProcessing; /** User-selectable directory for saving data files. Currently defaults to the user's home directory. @@ -196,16 +193,14 @@ private: */ Time timer; - /** Closes all open files after recording has finished. - */ - void closeAllFiles(); - /** Pointers to all continuous channels */ Array<Channel*> channelPointers; /** Pointers to all event channels */ Array<Channel*> eventChannelPointers; + Array<int> channelMap; + OwnedArray<SpikeRecordInfo> spikeElectrodePointers; int spikeElectrodeIndex; @@ -213,41 +208,22 @@ private: int experimentNumber; bool hasRecorded; bool settingsNeeded; - + std::atomic<bool> setFirstBlock; /** Generates a default directory name, based on the current date and time */ String generateDirectoryName(); /** Cycle through the event buffer, looking for data to save */ void handleEvent(int eventType, MidiMessage& event, int samplePos); - /** Object for holding information about the events file */ - Channel* eventChannel; - - /** Method for writing continuous buffers to disk. - */ - void writeContinuousBuffer(const float* data, int nSamples, int channel); - - /** Method for writing event buffers to disk. - */ - void writeEventBuffer(MidiMessage& event, int samplePos); - - void writeRecordMarker(FILE*); - void writeTimestampAndSampleCount(FILE*); - - /** Used to indicate the end of each record */ - char* recordMarker; - - CriticalSection diskWriteLock; - - Array<String> modifiedChannelNames; - Array<int> modifiedChannelInd; - - bool appendTrialNum; - int trialNum; - /**RecordEngines loaded**/ OwnedArray<RecordEngine> engineArray; + ScopedPointer<RecordThread> m_recordThread; + ScopedPointer<DataQueue> m_dataQueue; + ScopedPointer<EventMsgQueue> m_eventQueue; + ScopedPointer<SpikeMsgQueue> m_spikeQueue; + + Array<int> m_recordedChannelMap; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RecordNode); diff --git a/Source/Processors/RecordNode/RecordThread.cpp b/Source/Processors/RecordNode/RecordThread.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c3e8d75ad64cfc01feadaf17cb996f284806bdf5 --- /dev/null +++ b/Source/Processors/RecordNode/RecordThread.cpp @@ -0,0 +1,158 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 "RecordThread.h" +#include "../Visualization/SpikeObject.h" +#include "RecordEngine.h" + +#define EVERY_ENGINE for(int eng = 0; eng < m_engineArray.size(); eng++) m_engineArray[eng] + + +RecordThread::RecordThread(const OwnedArray<RecordEngine>& engines) : +Thread("Record Thread"), +m_engineArray(engines), +m_receivedFirstBlock(false), +m_cleanExit(true) +{ +} + +RecordThread::~RecordThread() +{ +} + +void RecordThread::setFileComponents(File rootFolder, int experimentNumber, int recordingNumber) +{ + if (isThreadRunning()) + return; + + m_rootFolder = rootFolder; + m_experimentNumber = experimentNumber; + m_recordingNumber = recordingNumber; +} + +void RecordThread::setChannelMap(const Array<int>& channels) +{ + if (isThreadRunning()) + return; + m_channelArray = channels; + m_numChannels = channels.size(); +} + +void RecordThread::setQueuePointers(DataQueue* data, EventMsgQueue* events, SpikeMsgQueue* spikes) +{ + m_dataQueue = data; + m_eventQueue = events; + m_spikeQueue = spikes; +} + +void RecordThread::setFirstBlockFlag(bool state) +{ + m_receivedFirstBlock = state; + this->notify(); +} + +void RecordThread::run() +{ + const AudioSampleBuffer& dataBuffer = m_dataQueue->getAudioBufferReference(); + bool closeEarly = true; + //1-Wait until the first block has arrived, so we can align the timestamps + while (!m_receivedFirstBlock && !threadShouldExit()) + { + wait(100); + } + + //2-Open Files + if (!threadShouldExit()) + { + m_cleanExit = false; + closeEarly = false; + Array<int64> timestamps; + m_dataQueue->getTimestampsForBlock(0, timestamps); + EVERY_ENGINE->updateTimestamps(timestamps); + EVERY_ENGINE->openFiles(m_rootFolder, m_experimentNumber, m_recordingNumber); + } + //3-Normal loop + while (!threadShouldExit()) + { + writeData(dataBuffer, BLOCK_MAX_WRITE_SAMPLES, BLOCK_MAX_WRITE_EVENTS, BLOCK_MAX_WRITE_SPIKES); + } + std::cout << "Exiting record thread" << std::endl; + //4-Before closing the thread, try to write the remaining samples + if (!closeEarly) + { + writeData(dataBuffer, -1, -1, -1, true); + + std::cout << "Closing files" << std::endl; + //5-Close files + EVERY_ENGINE->closeFiles(); + } + m_cleanExit = true; + m_receivedFirstBlock = false; +} + +void RecordThread::writeData(const AudioSampleBuffer& dataBuffer, int maxSamples, int maxEvents, int maxSpikes, bool lastBlock) +{ + Array<int64> timestamps; + Array<CircularBufferIndexes> idx; + m_dataQueue->startRead(idx, timestamps, maxSamples); + EVERY_ENGINE->updateTimestamps(timestamps); + EVERY_ENGINE->startChannelBlock(lastBlock); + for (int chan = 0; chan < m_numChannels; ++chan) + { + if (idx[chan].size1 > 0) + { + EVERY_ENGINE->writeData(chan, m_channelArray[chan], dataBuffer.getReadPointer(chan, idx[chan].index1), idx[chan].size1); + if (idx[chan].size2 > 0) + { + timestamps.set(chan, timestamps[chan] + idx[chan].size1); + EVERY_ENGINE->updateTimestamps(timestamps, chan); + EVERY_ENGINE->writeData(chan, m_channelArray[chan], dataBuffer.getReadPointer(chan, idx[chan].index2), idx[chan].size2); + } + } + } + m_dataQueue->stopRead(); + EVERY_ENGINE->endChannelBlock(lastBlock); + + std::vector<EventMessagePtr> events; + int nEvents = m_eventQueue->getEvents(events, maxEvents); + for (int ev = 0; ev < nEvents; ++ev) + { + EVERY_ENGINE->writeEvent(events[ev]->getExtra(), events[ev]->getData(), events[ev]->getTimestamp()); + } + + std::vector<SpikeMessagePtr> spikes; + int nSpikes = m_spikeQueue->getEvents(spikes, maxSpikes); + for (int sp = 0; sp < nSpikes; ++sp) + { + EVERY_ENGINE->writeSpike(spikes[sp]->getExtra(), spikes[sp]->getData(), spikes[sp]->getTimestamp()); + } +} + +void RecordThread::forceCloseFiles() +{ + if (isThreadRunning() || m_cleanExit) + return; + + EVERY_ENGINE->closeFiles(); + m_cleanExit = true; +} \ No newline at end of file diff --git a/Source/Processors/RecordNode/RecordThread.h b/Source/Processors/RecordNode/RecordThread.h new file mode 100644 index 0000000000000000000000000000000000000000..1102c12a52cee0388db0786490877b6245855199 --- /dev/null +++ b/Source/Processors/RecordNode/RecordThread.h @@ -0,0 +1,74 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2014 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 RECORDTHREAD_H_INCLUDED +#define RECORDTHREAD_H_INCLUDED + +#include "../../../JuceLibraryCode/JuceHeader.h" +#include "EventQueue.h" +#include "DataQueue.h" +#include <atomic> + +#define BLOCK_MAX_WRITE_SAMPLES 4096 +#define BLOCK_MAX_WRITE_EVENTS 32 +#define BLOCK_MAX_WRITE_SPIKES 32 + +class Channel; +class RecordEngine; + + +class RecordThread : public Thread +{ +public: + RecordThread(const OwnedArray<RecordEngine>& engines); + ~RecordThread(); + void setFileComponents(File rootFolder, int experimentNumber, int recordingNumber); + void setChannelMap(const Array<int>& channels); + void setQueuePointers(DataQueue* data, EventMsgQueue* events, SpikeMsgQueue* spikes); + + void run() override; + + void setFirstBlockFlag(bool state); + void forceCloseFiles(); + +private: + void writeData(const AudioSampleBuffer& buffer, int maxSamples, int maxEvents, int maxSpikes, bool lastBlock = false); + + const OwnedArray<RecordEngine>& m_engineArray; + Array<int> m_channelArray; + + DataQueue* m_dataQueue; + EventMsgQueue* m_eventQueue; + SpikeMsgQueue *m_spikeQueue; + + std::atomic<bool> m_receivedFirstBlock; + std::atomic<bool> m_cleanExit; + + File m_rootFolder; + int m_experimentNumber; + int m_recordingNumber; + int m_numChannels; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RecordThread); +}; + +#endif // RECORDTHREAD_H_INCLUDED diff --git a/Source/UI/ControlPanel.cpp b/Source/UI/ControlPanel.cpp index a41c544bb51cc809b6b93c33c5e937aff1e48d15..b5328948a98abd20e0f53e1328070471e36d7bce 100755 --- a/Source/UI/ControlPanel.cpp +++ b/Source/UI/ControlPanel.cpp @@ -29,6 +29,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "../Processors/RecordNode/RecordEngine.h" #include "../Processors/PluginManager/PluginManager.h" + +const int SIZE_AUDIO_EDITOR_MAX_WIDTH = 500; +//const int SIZE_AUDIO_EDITOR_MIN_WIDTH = 250; + + PlayButton::PlayButton() : DrawableButton("PlayButton", DrawableButton::ImageFitted) { @@ -547,6 +552,30 @@ void ControlPanel::updateRecordEngineList() recordSelector->setSelectedId(selectedEngine, sendNotification); } +String ControlPanel::getSelectedRecordEngineId() +{ + return recordEngines[recordSelector->getSelectedId() - 1]->getID(); +} + +bool ControlPanel::setSelectedRecordEngineId(String id) +{ + if (getAcquisitionState()) + { + return false; + } + + int nEngines = recordEngines.size(); + for (int i = 0; i < nEngines; ++i) + { + if (recordEngines[i]->getID() == id) + { + recordSelector->setSelectedId(i + 1, sendNotificationSync); + return true; + } + } + return false; +} + void ControlPanel::createPaths() { /* int w = getWidth() - 325; @@ -580,8 +609,8 @@ void ControlPanel::createPaths() void ControlPanel::paint(Graphics& g) { - g.setColour(backgroundColour); - g.fillRect(0,0,getWidth(),getHeight()); + g.setColour (backgroundColour); + g.fillRect (0, 0, getWidth(), getHeight()); if (open) { @@ -590,131 +619,155 @@ void ControlPanel::paint(Graphics& g) g.fillPath(p1); g.fillPath(p2); } - } void ControlPanel::resized() { - int w = getWidth(); - int h = 32; //getHeight(); - - if (playButton != 0) - { - if (w > 330) - playButton->setBounds(w-h*10,5,h-5,h-10); - \ - else - playButton->setBounds(5,5,h-5,h-10); - \ - } - - if (recordButton != 0) - { - if (w > 330) - recordButton->setBounds(w-h*9,5,h-5,h-10); - else - recordButton->setBounds(5+h,5,h-5,h-10); - } - - if (masterClock != 0) - { - if (w > 330) - masterClock->setBounds(w-h*7-15,0,h*7-15,h); - else - masterClock->setBounds(5+h*2+15,0,h*7-15,h); - } - - int offset1 = 750 - getWidth(); + const int w = getWidth(); + const int h = 32; //getHeight(); + + // We have 3 possible layout schemes: + // when there are 1, 2 or 3 rows within which our elements are placed. + const int twoRowsWidth = 750; + const int threeRowsWidth = 570; + int offset1 = twoRowsWidth - getWidth(); if (offset1 > h) offset1 = h; - int offset2 = 570 - getWidth(); + int offset2 = threeRowsWidth - getWidth(); if (offset2 > h) offset2 = h; - if (cpuMeter != 0) + const int currentNumRows = (w < twoRowsWidth && w >= threeRowsWidth - 23) + ? 2 + : (w < threeRowsWidth - 23) + ? 3 : 1; + + // Set positions for CPU and Disk meter components + // ==================================================================== + int meterComponentsY = h / 4; + int meterComponentsWidth = h * 3; + const int meterComponentsHeight = h / 2; + const int meterComponentsMargin = 8; + switch (currentNumRows) { - - if (getWidth() < 750 && getWidth() >= 570) - cpuMeter->setBounds(8,h/4+offset1,h*3,h/2); - else if (getWidth() < 570) - cpuMeter->setBounds(8,h/4+offset1+offset2,h*3,h/2); - else - cpuMeter->setBounds(8,h/4,h*3,h/2); + case 2: + meterComponentsY += offset1; + //meterComponentsWidth = w / 2 - meterComponentsMargin * 2 - 12; + break; + + case 3: + meterComponentsY += offset1 + offset2; + //meterComponentsWidth = w / 2 - meterComponentsMargin * 2 - 12; + break; + + default: + break; } - if (diskMeter != 0) + juce::Rectangle<int> meterBounds (meterComponentsMargin, meterComponentsY, meterComponentsWidth, meterComponentsHeight); + cpuMeter->setBounds (meterBounds); + diskMeter->setBounds (meterBounds.translated (meterComponentsWidth + meterComponentsMargin, 0)); + // ==================================================================== + + // Set positions for controls and clock + // ==================================================================== + const int controlButtonWidth = h - 5; + const int controlButtonHeight = h - 10; + const int masterClockWidth = h * 6 - 10; + const int controlsMargin = 10; + const int totalControlsWidth = controlButtonWidth * 2 + controlsMargin + masterClockWidth; + if (currentNumRows != 3) { - if (getWidth() < 750 && getWidth() >= 570) - diskMeter->setBounds(16+h*3,h/4+offset1,h*3,h/2); - else if (getWidth() < 570) - diskMeter->setBounds(16+h*3,h/4+offset1+offset2,h*3,h/2); - else - diskMeter->setBounds(16+h*3,h/4,h*3,h/2); - + playButton->setBounds (w - h * 8, 5, controlButtonWidth, controlButtonHeight); + recordButton->setBounds (w - h * 7, 5, controlButtonWidth, controlButtonHeight); + masterClock->setBounds (w - masterClockWidth, 0, masterClockWidth, h); } - - if (audioEditor != 0) + else { - if (getWidth() < 750 && getWidth() >= 570) - audioEditor->setBounds(w-526,0,h*8,h); - else if (getWidth() < 570) - audioEditor->setBounds(8,0+offset2,h*8,h); - else - audioEditor->setBounds(h*7,0,h*8,h); + const int startX = (w - totalControlsWidth) / 2; + playButton->setBounds (startX, 5, controlButtonWidth, controlButtonHeight); + recordButton->setBounds (startX + h, 5, controlButtonWidth, controlButtonHeight); + masterClock->setBounds (startX + h * 2 + controlsMargin * 2, 0, masterClockWidth, h); } + // ==================================================================== - if (cpb != 0) + if (audioEditor) { - if (open) - cpb->setBounds(w-28,getHeight()-5-h*2+10,h-10,h-10); - else - cpb->setBounds(w-28,getHeight()-5-h+10,h-10,h-10); + const bool isThereElementOnLeft = diskMeter->getBounds().getY() <= h; + const bool isSecondRowAvailable = diskMeter->getBounds().getY() >= 2 * h; + const int leftElementWidth = diskMeter->getBounds().getRight(); + const int rightElementWidth = w - playButton->getBounds().getX(); + + int maxAvailableWidthForEditor = w; + if (isThereElementOnLeft) + maxAvailableWidthForEditor -= leftElementWidth + rightElementWidth; + else if (! isSecondRowAvailable) + maxAvailableWidthForEditor -= rightElementWidth; + + const bool isEnoughSpaceForFullSize = maxAvailableWidthForEditor >= SIZE_AUDIO_EDITOR_MAX_WIDTH; + + const int rowIndex = (isSecondRowAvailable) ? 1 : 0; + const int editorWidth = isEnoughSpaceForFullSize + ? SIZE_AUDIO_EDITOR_MAX_WIDTH + : maxAvailableWidthForEditor * 0.95; + const int editorX = (rowIndex != 0) + ? (w - editorWidth) / 2 + : isThereElementOnLeft + ? leftElementWidth + (maxAvailableWidthForEditor - editorWidth) / 2 + : (maxAvailableWidthForEditor - editorWidth) / 2; + const int editorY = (rowIndex == 0 ) ? 0 : offset1; + + audioEditor->setBounds (editorX, editorY, editorWidth, h); } + + if (open) + cpb->setBounds (w - 28, getHeight() - 5 - h * 2 + 10, h - 10, h - 10); + else + cpb->setBounds (w - 28, getHeight() - 5 - h + 10, h - 10, h - 10); + createPaths(); if (open) { - int topBound = getHeight()-h+10-5; + int topBound = getHeight() - h + 10 - 5; - recordSelector->setBounds((w - 435) > 40 ? 35 : w-450, topBound, 100, h-10); - recordSelector->setVisible(true); + recordSelector->setBounds ( (w - 435) > 40 ? 35 : w - 450, topBound, 100, h - 10); + recordSelector->setVisible (true); - recordOptionsButton->setBounds((w - 435) > 40 ? 140 : w-350,topBound, h-10, h-10); - recordOptionsButton->setVisible(true); + recordOptionsButton->setBounds ( (w - 435) > 40 ? 140 : w - 350, topBound, h - 10, h - 10); + recordOptionsButton->setVisible (true); - filenameComponent->setBounds(165, topBound, w-500, h-10); - filenameComponent->setVisible(true); + filenameComponent->setBounds (165, topBound, w - 500, h - 10); + filenameComponent->setVisible (true); - newDirectoryButton->setBounds(w-h+4, topBound, h-10, h-10); - newDirectoryButton->setVisible(true); + newDirectoryButton->setBounds (w - h + 4, topBound, h - 10, h - 10); + newDirectoryButton->setVisible (true); - prependText->setBounds(165+w-490, topBound, 50, h-10); - prependText->setVisible(true); + prependText->setBounds (165 + w - 490, topBound, 50, h - 10); + prependText->setVisible (true); - dateText->setBounds(165+w-435, topBound, 175, h-10); - dateText->setVisible(true); + dateText->setBounds (165 + w - 435, topBound, 175, h - 10); + dateText->setVisible (true); - appendText->setBounds(165+w-255, topBound, 50, h-10); - appendText->setVisible(true); + appendText->setBounds (165 + w - 255, topBound, 50, h - 10); + appendText->setVisible (true); } else { - filenameComponent->setVisible(false); - newDirectoryButton->setVisible(false); - prependText->setVisible(false); - dateText->setVisible(false); - appendText->setVisible(false); - recordSelector->setVisible(false); - recordOptionsButton->setVisible(false); + filenameComponent->setVisible (false); + newDirectoryButton->setVisible (false); + prependText->setVisible (false); + dateText->setVisible (false); + appendText->setVisible (false); + recordSelector->setVisible (false); + recordOptionsButton->setVisible (false); } repaint(); - - } void ControlPanel::openState(bool os) @@ -755,7 +808,7 @@ void ControlPanel::stopRecording() masterClock->stopRecording(); newDirectoryButton->setEnabledState(true); - backgroundColour = Colour(58,58,58); + backgroundColour = Colour (51, 51, 51); prependText->setEditable(true); appendText->setEditable(true); @@ -768,7 +821,6 @@ void ControlPanel::stopRecording() void ControlPanel::buttonClicked(Button* button) { - if (button == newDirectoryButton && newDirectoryButton->getEnabledState()) { graph->getRecordNode()->newDirectoryNeeded = true; @@ -778,7 +830,6 @@ void ControlPanel::buttonClicked(Button* button) dateText->setColour(Label::textColourId, Colours::grey); return; - } if (button == playButton) diff --git a/Source/UI/ControlPanel.h b/Source/UI/ControlPanel.h index 8b733c6dd26a9e0988d2255dde47c9b1fa890e87..f63296ecf6761813a3bc7548691443b6b1384e2d 100755 --- a/Source/UI/ControlPanel.h +++ b/Source/UI/ControlPanel.h @@ -30,7 +30,7 @@ #include "../Processors/ProcessorGraph/ProcessorGraph.h" #include "../Processors/RecordNode/RecordNode.h" #include "../Processors/RecordNode/RecordEngine.h" -#include "CustomLookAndFeel.h" +#include "LookAndFeel/CustomLookAndFeel.h" #include "../AccessClass.h" #include "../Processors/Editors/GenericEditor.h" // for UtilityButton #include <queue> @@ -357,13 +357,17 @@ public: StringArray getRecentlyUsedFilenames(); /** Sets the list of recently used directories for saving data. */ - void setRecentlyUsedFilenames(const StringArray& filenames); + void setRecentlyUsedFilenames (const StringArray& filenames); /** Adds the RecordNode as a listener of the FilenameComponent (so it knows when the data directory has changed).*/ void updateChildComponents(); - void updateRecordEngineList(); + void updateRecordEngineList(); + + String getSelectedRecordEngineId(); + + bool setSelectedRecordEngineId(String id); ScopedPointer<RecordButton> recordButton; private: diff --git a/Source/UI/CustomLookAndFeel.cpp b/Source/UI/LookAndFeel/CustomLookAndFeel.cpp similarity index 97% rename from Source/UI/CustomLookAndFeel.cpp rename to Source/UI/LookAndFeel/CustomLookAndFeel.cpp index 77c02117b46d85a58e170e270672c4fbc75c5c90..42b9d00d359e103444e059a141124a868751cca7 100755 --- a/Source/UI/CustomLookAndFeel.cpp +++ b/Source/UI/LookAndFeel/CustomLookAndFeel.cpp @@ -22,7 +22,7 @@ */ #include "CustomLookAndFeel.h" -#include "CustomArrowButton.h" +#include "../CustomArrowButton.h" CustomLookAndFeel::CustomLookAndFeel() : // third argument to MIS means don't copy the binary data to make a new stream diff --git a/Source/UI/CustomLookAndFeel.h b/Source/UI/LookAndFeel/CustomLookAndFeel.h similarity index 96% rename from Source/UI/CustomLookAndFeel.h rename to Source/UI/LookAndFeel/CustomLookAndFeel.h index 35b708ceb051db233848f05c9718573a0e2b1754..d0cf08b9d279bd1ac85f071775d88da6c2ae4690 100755 --- a/Source/UI/CustomLookAndFeel.h +++ b/Source/UI/LookAndFeel/CustomLookAndFeel.h @@ -24,7 +24,7 @@ #ifndef __CUSTOMLOOKANDFEEL_H_6B021009__ #define __CUSTOMLOOKANDFEEL_H_6B021009__ -#include "../../JuceLibraryCode/JuceHeader.h" +#include "../../../JuceLibraryCode/JuceHeader.h" /** diff --git a/Source/UI/LookAndFeel/MaterialButtonLookAndFeel.cpp b/Source/UI/LookAndFeel/MaterialButtonLookAndFeel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e94d2e6142824187393fd8120357f1db0750819b --- /dev/null +++ b/Source/UI/LookAndFeel/MaterialButtonLookAndFeel.cpp @@ -0,0 +1,76 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 "MaterialButtonLookAndFeel.h" + + +MaterialButtonLookAndFeel::MaterialButtonLookAndFeel() +{ +} + + +void MaterialButtonLookAndFeel::drawButtonBackground (Graphics& g, + Button& button, + const Colour& backgroundColour, + bool isMouseOverButton, bool isButtonDown) +{ + // Only flat button style available for now + const bool isFlatButton = true; + if (isFlatButton) + { + const bool isButtonToggled = button.getToggleState(); + + Colour bgColourToUse; + if (isButtonToggled) + bgColourToUse = backgroundColour; + else if (isButtonDown || isMouseOverButton) + bgColourToUse = backgroundColour.darker(); + + const float cornerSize = 0.f; + g.setColour (bgColourToUse); + g.fillRoundedRectangle (button.getLocalBounds().toFloat(), cornerSize); + } +} + + +void MaterialButtonLookAndFeel::drawButtonText (Graphics& g, + TextButton& button, + bool isMouseOverButton, bool isButtonDown) +{ + auto buttonText = button.getButtonText().toUpperCase(); + + auto textColour = button.getToggleState() + ? button.findColour (TextButton::textColourOnId) + : button.findColour (TextButton::textColourOffId); + + const int padding = 4; + g.setFont (Font ("Default Bold", 13.f, Font::plain)); + g.setColour (textColour); + g.drawFittedText (buttonText, + padding, 0, + button.getWidth() - padding * 2, button.getHeight(), + Justification::centred, + 1); +} + + diff --git a/Source/UI/LookAndFeel/MaterialButtonLookAndFeel.h b/Source/UI/LookAndFeel/MaterialButtonLookAndFeel.h new file mode 100644 index 0000000000000000000000000000000000000000..ee04e4bc9d0c13d14ca826f5986fbe41e8053fa4 --- /dev/null +++ b/Source/UI/LookAndFeel/MaterialButtonLookAndFeel.h @@ -0,0 +1,60 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 MATERIALBUTTONLOOKANDFEEL_H_INCLUDED +#define MATERIALBUTTONLOOKANDFEEL_H_INCLUDED + +#include "../../../JuceLibraryCode/JuceHeader.h" +#include "../../Processors/PluginManager/OpenEphysPlugin.h" +#include "CustomLookAndFeel.h" + + +/** + + Used to modify the appearance of the buttons following Google Material Design Guidelines. + + Currently contains methods for drawing flat buttons only. + +*/ +class PLUGIN_API MaterialButtonLookAndFeel : public LookAndFeel_V2 +{ +public: + MaterialButtonLookAndFeel(); + + void drawButtonBackground (Graphics& g, + Button& button, + const Colour& backgroundColour, + bool isMouseOverButton, bool isButtonDown) override; + + void drawButtonText (Graphics& g, + TextButton& button, + bool isMouseOverButton, bool isButtonDown) override; + +private: + + // ========================================================= + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MaterialButtonLookAndFeel) +}; + + +#endif // MATERIALBUTTONLOOKANDFEEL_H_INCLUDED diff --git a/Source/UI/LookAndFeel/MaterialSliderLookAndFeel.cpp b/Source/UI/LookAndFeel/MaterialSliderLookAndFeel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..43d422c96f153682b36a41386ee444f63402887b --- /dev/null +++ b/Source/UI/LookAndFeel/MaterialSliderLookAndFeel.cpp @@ -0,0 +1,164 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 "MaterialSliderLookAndFeel.h" + + +static const Colour COLOUR_BORDER (Colour (0x0)); // may be usefull for future + +// If we want to drop shadow for slider later we can just change this parameter +static const bool DROP_SHADOW = false; + + +MaterialSliderLookAndFeel::MaterialSliderLookAndFeel() +{ +} + + +MaterialSliderLookAndFeel::~MaterialSliderLookAndFeel() +{ +} + + +void MaterialSliderLookAndFeel::drawLinearSlider (Graphics& g, + int x, int y, + int width, int height, + float sliderPos, float minSliderPos, float maxSliderPos, + const Slider::SliderStyle sliderStyle, + Slider& slider) +{ + if (sliderStyle == Slider::LinearVertical || sliderStyle == Slider::LinearHorizontal) + { + drawLinearSliderBackground (g, x, y, width, height, sliderPos, minSliderPos, maxSliderPos, sliderStyle, slider); + drawLinearSliderThumb (g, x, y, width, height, sliderPos, minSliderPos, maxSliderPos, sliderStyle, slider); + } +} + + +void MaterialSliderLookAndFeel::drawLinearSliderBackground (Graphics& g, + int x, int y, + int width, int height, + float sliderPos, float minSliderPos, float maxSliderPos, + const Slider::SliderStyle style, + Slider& slider) +{ + const float sliderRadius = getSliderThumbRadius (slider) - 7.0f; + Path on; + Path off; + + if (slider.isHorizontal()) + { + const float iy = y + height * 0.5f - sliderRadius * 0.5f; + Rectangle<float> r (x - sliderRadius * 0.5f, iy, width + sliderRadius, sliderRadius); + const float onW = r.getWidth() * ((float) slider.valueToProportionOfLength (slider.getValue())); + + on.addRectangle (r.removeFromLeft (onW)); + off.addRectangle (r); + } + else + { + const float ix = x + width * 0.5f - sliderRadius * 0.5f; + Rectangle<float> r (ix, y - sliderRadius * 0.5f, sliderRadius, height + sliderRadius); + const float onH = r.getHeight() * ((float) slider.valueToProportionOfLength (slider.getValue())); + + on.addRectangle (r.removeFromBottom (onH)); + off.addRectangle (r); + } + + g.setColour (slider.findColour (Slider::backgroundColourId)); + g.fillPath (off); + + g.setColour (slider.findColour (Slider::trackColourId)); + g.fillPath (on); + + g.setColour (COLOUR_BORDER); + g.strokePath (on, PathStrokeType (1.f)); + g.strokePath (off, PathStrokeType (1.f)); +} + + +void MaterialSliderLookAndFeel::drawLinearSliderThumb (Graphics& g, + int x, int y, + int width, int height, + float sliderPos, float minSliderPos, float maxSliderPos, + const Slider::SliderStyle style, + Slider& slider) +{ + const float sliderRadius = (float) (getSliderThumbRadius (slider) - 2); + + bool isDownOrDragging = slider.isEnabled() && (slider.isMouseOverOrDragging() || slider.isMouseButtonDown()); + Colour knobColour (slider.findColour (Slider::thumbColourId) + .withMultipliedSaturation ((slider.hasKeyboardFocus (false) || isDownOrDragging) ? 1.3f : 0.9f) + .withMultipliedAlpha (slider.isEnabled() ? 1.0f : 0.7f)); + + if (style == Slider::LinearHorizontal || style == Slider::LinearVertical) + { + float kx; + float ky; + + if (style == Slider::LinearVertical) + { + kx = x + width * 0.5f; + ky = sliderPos; + } + else + { + kx = sliderPos; + ky = y + height * 0.5f; + } + + const float outlineThickness = slider.isEnabled() ? 0.8f : 0.3f; + + drawRoundThumb (g, + kx - sliderRadius, + ky - sliderRadius, + sliderRadius * 2.0f, + knobColour, outlineThickness); + } +} + + +void MaterialSliderLookAndFeel::drawRoundThumb (Graphics& g, + const float x, const float y, + const float diameter, + const Colour& colour, + float outlineThickness) +{ + const float halfThickness = outlineThickness * 0.5f; + + Path p; + p.addEllipse (x + halfThickness, y + halfThickness, diameter - outlineThickness, diameter - outlineThickness); + + if (DROP_SHADOW) + { + const DropShadow ds (Colours::black, 3, Point<int> (1, 1)); + ds.drawForPath (g, p); + } + + g.setColour (colour); + g.fillPath (p); + + g.setColour (COLOUR_BORDER); + g.strokePath (p, PathStrokeType (outlineThickness)); +} + diff --git a/Source/UI/LookAndFeel/MaterialSliderLookAndFeel.h b/Source/UI/LookAndFeel/MaterialSliderLookAndFeel.h new file mode 100644 index 0000000000000000000000000000000000000000..a3b3b5e8cbdc326ac4833e71c828874db6f9046d --- /dev/null +++ b/Source/UI/LookAndFeel/MaterialSliderLookAndFeel.h @@ -0,0 +1,77 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 MATERIALSLIDERLOOKANDFEEL_H_INCLUDED +#define MATERIALSLIDERLOOKANDFEEL_H_INCLUDED + +#include "../../JuceLibraryCode/JuceHeader.h" + + +/** + + Used to modify the appearance of the sliders following Google Material Design Guidelines. + + Currently contains methods for drawing linear sliders only. + +*/ + +class MaterialSliderLookAndFeel : public LookAndFeel_V2 +{ +public: + MaterialSliderLookAndFeel(); + ~MaterialSliderLookAndFeel(); + + void drawLinearSlider (Graphics& g, + int x, int y, + int width, int height, + float sliderPos, float minSliderPos, float maxSliderPos, + const Slider::SliderStyle style, + Slider& slider) override; + + + void drawLinearSliderThumb (Graphics& g, + int x, int y, + int width, int height, + float sliderPos, float minSliderPos, float maxSliderPos, + const Slider::SliderStyle style, + Slider& slider) override; + + + void drawLinearSliderBackground (Graphics& g, + int x, int y, + int width, int height, + float sliderPos, float minSliderPos, float maxSliderPos, + const Slider::SliderStyle style, + Slider& slider) override; + + +private: + void drawRoundThumb (Graphics& g, + const float x, const float y, + const float diameter, + const Colour& colour, + float outlineThickness); +}; + + +#endif // MATERIALSLIDERLOOKANDFEEL_H_INCLUDED diff --git a/Source/UI/ProcessorList.cpp b/Source/UI/ProcessorList.cpp index f0089cfeb509e36141a29c49a5bf3eb63bd574f5..7fe05b0b623ecd54ecd228ca760771986082657e 100755 --- a/Source/UI/ProcessorList.cpp +++ b/Source/UI/ProcessorList.cpp @@ -650,7 +650,7 @@ void ProcessorList::fillItemList() // =================================================================== ProcessorListItem::ProcessorListItem(const String& name_, int pid, int ptype) - : selected(false), open(true), name(name_), processorId(pid), processorType(ptype) + : processorId(pid), processorType(ptype), selected(false), open(true), name(name_) { } diff --git a/Source/UI/Utils/ButtonGroupManager.cpp b/Source/UI/Utils/ButtonGroupManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55ddb82deedc93f7a3fa16d4e51868c055700014 --- /dev/null +++ b/Source/UI/Utils/ButtonGroupManager.cpp @@ -0,0 +1,177 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 "ButtonGroupManager.h" + +#include <algorithm> + + +static const Colour COLOUR_DIVIDER (Colours::black.withAlpha (0.12f)); +static const Colour COLOUR_BORDER (Colour::fromRGB (189, 189, 189)); +static const Colour COLOUR_PRIMARY (Colours::black.withAlpha (0.87f)); + + +ButtonGroupManager::ButtonGroupManager() + : m_isRadioButtonMode (true) + , m_buttonListener (nullptr) + , m_buttonsLookAndFeel (nullptr) + , m_componentProxyHandler (new Component) +{ + setColour (backgroundColourId, Colour (0x0)); + setColour (outlineColourId, COLOUR_BORDER); + + + addAndMakeVisible (m_buttonsViewport); + m_buttonsViewport.setViewedComponent (m_componentProxyHandler, false); + m_buttonsViewport.setScrollBarsShown (false, false, true, false); +} + + +ButtonGroupManager::~ButtonGroupManager() +{ + m_buttons.clear(); +} + + +void ButtonGroupManager::paint (Graphics& g) +{ + auto floatLocalBounds = getLocalBounds().toFloat(); + const float cornerSize = 3.f; + + // Fill background + g.setColour (findColour (backgroundColourId)); + g.fillRoundedRectangle (floatLocalBounds.reduced (1, 1), cornerSize); + + // Draw border + g.setColour (findColour (outlineColourId)); + g.drawRoundedRectangle (floatLocalBounds, cornerSize, 1.f); +} + + +void ButtonGroupManager::resized() +{ + const int width = getWidth(); + const int height = getHeight(); + + if (m_buttons.size()) + m_componentProxyHandler->setBounds (0, 0, width, jmax (height, + m_buttons[m_buttons.size() - 1]->getBounds().getBottom())); + else + m_componentProxyHandler->setBounds (0, 0, width, height); + + m_buttonsViewport.setBounds (0, 0, getWidth(), getHeight()); +} + + +void ButtonGroupManager::colourChanged() +{ + repaint(); +} + + +void ButtonGroupManager::buttonClicked (Button* buttonThatWasClicked) +{ + if (m_buttonListener != nullptr) + m_buttonListener->buttonClicked (buttonThatWasClicked); +} + + +int ButtonGroupManager::getNumButtons() const +{ + return m_buttons.size(); +} + + +Button* ButtonGroupManager::getButtonAt (int index) const +{ + jassert (index >= 0 && index < m_buttons.size()); + + return m_buttons[index]; +} + + +bool ButtonGroupManager::isRadioButtonMode() const +{ + return m_isRadioButtonMode; +} + + +void ButtonGroupManager::addButton (Button* newButton) +{ + newButton->addListener (this); + newButton->setLookAndFeel (m_buttonsLookAndFeel); + + m_componentProxyHandler->addAndMakeVisible (newButton); + m_buttons.add (newButton); + + if (m_isRadioButtonMode) + { + newButton->setRadioGroupId (1); + } + + resized(); +} + + +void ButtonGroupManager::removeButton (int index) +{ + if (index < 0 + || index >= m_buttons.size()) + { + jassertfalse; + return; + } + + m_buttons.remove (index); +} + + +void ButtonGroupManager::setRadioButtonMode (bool isRadioButtonMode) +{ + m_isRadioButtonMode = isRadioButtonMode; + + const int numButtons = m_buttons.size(); + for (int i = 0; i < numButtons; ++i) + { + m_buttons[i]->setRadioGroupId ( (int)isRadioButtonMode); + } + + repaint(); +} + + +void ButtonGroupManager::setButtonsLookAndFeel (LookAndFeel* newButtonsLookAndFeel) +{ + m_buttonsLookAndFeel = newButtonsLookAndFeel; + + std::for_each (m_buttons.begin(), m_buttons.end(), [this] (Button* button) + { button->setLookAndFeel (m_buttonsLookAndFeel); }); + + repaint(); +} + + +void ButtonGroupManager::setButtonListener (Button::Listener* newListener) +{ + m_buttonListener = newListener; +} diff --git a/Source/UI/Utils/ButtonGroupManager.h b/Source/UI/Utils/ButtonGroupManager.h new file mode 100644 index 0000000000000000000000000000000000000000..4c3f1431dfbee865f59cb7a54c2693f8a3472a18 --- /dev/null +++ b/Source/UI/Utils/ButtonGroupManager.h @@ -0,0 +1,129 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 BUTTONGROUPMANAGER_H_INCLUDED +#define BUTTONGROUPMANAGER_H_INCLUDED + +#include "../../../JuceLibraryCode/JuceHeader.h" +#include "../../Processors/PluginManager/OpenEphysPlugin.h" + +/** + + This class provides is a base class for other ButtonGroupManagers. + It stores set of buttons inside and responsible for positioning of buttons, lookAndFeel, any animations. + + @see LinearButtonGroupManager +*/ +class PLUGIN_API ButtonGroupManager : public Component + , public Button::Listener +{ +public: + ButtonGroupManager(); + virtual ~ButtonGroupManager(); + + //============================================================================== + /** A set of colour IDs to use to change the colour of various aspects of the button. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + backgroundColourId = 0x1000100, /**< The colour used to fill the buttons' manager background. */ + outlineColourId = 0x1000101, /**< The colour used for the outline of button manager. */ + }; + + // Component methods + // =========================================================== + void paint (Graphics& g) override; + void colourChanged() override; + + /** All component, that inherit ButtonGroupManager should override the resized() method + in order to control buttons positioning inside it */ + virtual void resized(); + // =========================================================== + + // Button::Listener methods + // =========================================================== + void buttonClicked (Button* buttonThatWasClicked) override; + + /** Returns the number of stored buttons. */ + int getNumButtons() const; + + /** Returns the button at the given index */ + Button* getButtonAt (int index) const; + + /** Return whether all managed buttons are in the radiobutton mode now */ + bool isRadioButtonMode() const; + + /** Add button to the array of buttons to manage it. + + This class controls ownership of buttons. + + Can be overriden by other buttons to change behaviour of the way, how buttons are added, + e.g. use decorators for some buttons, etc. + */ + virtual void addButton (Button* newButton); + + /** Remove button from the manager array buttons */ + void removeButton (int index); + + /** Set if all buttons will have radiobutton behaviour */ + void setRadioButtonMode (bool isRadioButtonMode); + + /** Sets custom LookAndFeel for each button */ + void setButtonsLookAndFeel (LookAndFeel* newButtonLookAndFeel); + + /** Sets the listener that will receive events from buttons */ + void setButtonListener (Button::Listener* newButtonListener); + + +protected: + /** Displays if radiobutton mode is used for each button */ + bool m_isRadioButtonMode; + + Button::Listener* m_buttonListener; + + /** Pointer to the LookAndFeel which will be used for each button */ + LookAndFeel* m_buttonsLookAndFeel; + + /** Viewport whick will show appropriate buttons */ + Viewport m_buttonsViewport; + + /** We will instead all of our buttons to this component instead of current object + to be sure that we can use it with viewport support - it will be easy to show + a very big quantity of buttons with scrolling feature */ + ScopedPointer<Component> m_componentProxyHandler; + + /** An array which stores buttons that will be managed by this class */ + OwnedArray<Button> m_buttons; + + // =========================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonGroupManager) +}; + + + +#endif // BUTTONGROUPMANAGER_H_INCLUDED diff --git a/Source/UI/Utils/LinearButtonGroupManager.cpp b/Source/UI/Utils/LinearButtonGroupManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8c4488b3dd649b7fd5874bcdc2a9c6b9b0769538 --- /dev/null +++ b/Source/UI/Utils/LinearButtonGroupManager.cpp @@ -0,0 +1,150 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 "LinearButtonGroupManager.h" + +#include <algorithm> + + +static const Colour COLOUR_DIVIDER (Colours::black.withAlpha (0.12f)); +static const Colour COLOUR_BORDER (Colour::fromRGB (189, 189, 189)); +static const Colour COLOUR_PRIMARY (Colours::black.withAlpha (0.87f)); + + +static bool inline areEqualValues (float p1, float p2) +{ + const float epsilon = 0.001f; + return fabs (p2 - p1) < epsilon; +} + + +LinearButtonGroupManager::LinearButtonGroupManager() + : m_isShowDividers (true) + , m_selectedButtonIdx (0) + , m_desiredButtonLineX (0.f) + , m_currentButtonLineX (0.f) + , m_animationStepX (0.f) +{ + setColour (accentColourId, Colours::white); + setColour (dividersColourId, COLOUR_DIVIDER); +} + + +void LinearButtonGroupManager::paintOverChildren (Graphics& g) +{ + const int height = getHeight(); + + // Draw dividers between buttons + if (m_isShowDividers) + { + g.setColour (findColour (dividersColourId)); + + const int dividerOffsetY = 5; + const int numDividers = m_buttons.size() - 1; + + for (int i = 0; i < numDividers; ++i) + { + int dividerX = m_buttons[i]->getRight(); + g.drawVerticalLine (dividerX, dividerOffsetY, height - dividerOffsetY); + } + } + + // Draw line which displays current selected button + g.setColour (findColour (accentColourId)); + if (m_isRadioButtonMode) + { + const int lineWidth = m_buttons[m_selectedButtonIdx]->getBounds().getWidth(); + const int lineHeight = 3; + g.fillRect ( (int)m_currentButtonLineX, height - lineHeight - 1, lineWidth, lineHeight); + } +} + + +void LinearButtonGroupManager::resized() +{ + ButtonGroupManager::resized(); + + const int width = getWidth(); + const int height = getHeight(); + + const int numButtons = m_buttons.size(); + const int buttonWidth = width / numButtons; + + // Set bounds for each button + juce::Rectangle<int> buttonBounds (0, 0, buttonWidth, height); + for (int i = 0; i < numButtons; ++i) + { + m_buttons[i]->setBounds (buttonBounds); + + buttonBounds.translate (buttonWidth, 0); + } +} + + +void LinearButtonGroupManager::buttonClicked (Button* buttonThatWasClicked) +{ + ButtonGroupManager::buttonClicked (buttonThatWasClicked); + + if (m_isRadioButtonMode) + { + stopTimer(); + m_desiredButtonLineX = buttonThatWasClicked->getBounds().getX(); + m_selectedButtonIdx = m_buttons.indexOf (static_cast<Button*> (buttonThatWasClicked)); + + const float numAnimationSteps = 10.f; + m_animationStepX = (m_desiredButtonLineX - m_currentButtonLineX) / numAnimationSteps; + //std::cout << "== Calculation: Animation step: " << m_animationStepX << std::endl; + + startTimer (30); + } +} + + +void LinearButtonGroupManager::timerCallback() +{ + // Move line which displays current selected button + if (! areEqualValues (m_currentButtonLineX, m_desiredButtonLineX)) + { + //std::cout << "Current X: " << m_currentButtonLineX << std::endl; + //std::cout << "Desiredd X: " << m_desiredButtonLineX << std::endl; + m_currentButtonLineX += m_animationStepX; + } + else + { + //std::cout <<"Timer stopped" << std::endl; + m_animationStepX = 0; + stopTimer(); + } + + repaint(); +} + + +void LinearButtonGroupManager::setShowDividers (bool isShow) +{ + if (isShow == m_isShowDividers) + return; + + m_isShowDividers = isShow; + repaint(); +} diff --git a/Source/UI/Utils/LinearButtonGroupManager.h b/Source/UI/Utils/LinearButtonGroupManager.h new file mode 100644 index 0000000000000000000000000000000000000000..a35bf62b9e16053399ffc6af33d2e69318b5c9b8 --- /dev/null +++ b/Source/UI/Utils/LinearButtonGroupManager.h @@ -0,0 +1,99 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 LINEARBUTTONGROUPMANAGER_H_INCLUDED +#define LINEARBUTTONGROUPMANAGER_H_INCLUDED + +#include "../../../JuceLibraryCode/JuceHeader.h" +#include "../../Processors/PluginManager/OpenEphysPlugin.h" +#include "ButtonGroupManager.h" + +/** + + This class provides possibility to store buttons with radiobutton behaviour in the single + component - button manager. It is responsible for positioning of buttons, any animations + during switching, etc. + + All buttons will be stored lineary - either in horizontal or vertical + box-like component. (only horizontal mode available now) + +*/ +class PLUGIN_API LinearButtonGroupManager : public ButtonGroupManager + , private Timer +{ +public: + LinearButtonGroupManager(); + + //============================================================================== + /** A set of colour IDs to use to change the colour of various aspects of the button. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + accentColourId = 0x1000110, /**< The colour used as colour of underline which displays + current selected button. */ + dividersColourId = 0x1000111 /**< The colour used to draw dividers between buttons. */ + }; + + + // Component methods + // =========================================================== + void paintOverChildren (Graphics& g) override; + void resized() override; + + // Button::Listener methods + // =========================================================== + void buttonClicked (Button* buttonThatWasClicked) override; + + /** Sets whether dividers between buttons will be visible or not */ + void setShowDividers (bool isShow); + + +private: + // Timer methods + // =========================================================== + void timerCallback() override; + + /** Displays if dividers between buttons will be drawn. */ + bool m_isShowDividers; + + /** Stores an index of currently selected button. + That variable become useless in the non-radiobutton mode. + */ + int m_selectedButtonIdx; + + float m_desiredButtonLineX; + float m_currentButtonLineX; + float m_animationStepX; + + // =========================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LinearButtonGroupManager) +}; + + + +#endif // LINEARBUTTONGROUPMANAGER_H_INCLUDED diff --git a/Source/UI/Utils/TiledButtonGroupManager.cpp b/Source/UI/Utils/TiledButtonGroupManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..02d9805619145f07846bbe29959f81a0b0522c71 --- /dev/null +++ b/Source/UI/Utils/TiledButtonGroupManager.cpp @@ -0,0 +1,213 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 "TiledButtonGroupManager.h" +#include "../LookAndFeel/MaterialButtonLookAndFeel.h" + +#include <algorithm> + + +TiledButtonGroupManager::TiledButtonGroupManager() + : m_buttonWidth (10) + , m_buttonHeight (10) + , m_minPaddingForButtons (5) + , m_firstSelectedButtonIdx (-1) + , m_lastSelectedButtonIdx (-1) + , m_isToggleOnMode (true) + , m_isDraggingMouseNow (false) + , m_isSelectButtonsByDragging (false) + , m_materialButtonsLookAndFeel (new MaterialButtonLookAndFeel) +{ + setRadioButtonMode (false); + setButtonsLookAndFeel (m_materialButtonsLookAndFeel); +} + + +void TiledButtonGroupManager::resized() +{ + ButtonGroupManager::resized(); + + const int width = getWidth(); + + if (! width) + return; + + const int numButtonsInTheRow = width / (m_buttonWidth + m_minPaddingForButtons); + const int padding = jmax (m_minPaddingForButtons, + (width - numButtonsInTheRow * m_buttonWidth) / (numButtonsInTheRow - 1)); + + juce::Rectangle<int> buttonBounds (0, 0, m_buttonWidth, m_buttonHeight); + const int numButtons = m_buttons.size(); + for (int i = 0; i < numButtons; ++i) + { + m_buttons[i]->setBounds (buttonBounds); + + // Go to the next row + if ( (i + 1) % numButtonsInTheRow == 0) + { + buttonBounds.setX (0); + buttonBounds.translate (0, m_buttonHeight + padding); + } + // Go to the next column + else + { + buttonBounds.translate (m_buttonWidth + padding, 0); + } + } +} + + +void TiledButtonGroupManager::mouseDown (const MouseEvent& e) +{ +} + + +void TiledButtonGroupManager::mouseUp (const MouseEvent& e) +{ + m_isDraggingMouseNow = false; + + m_firstSelectedButtonIdx = -1; + m_lastSelectedButtonIdx = -1; +} + + +void TiledButtonGroupManager::mouseDrag (const MouseEvent& e) +{ + if (! m_isSelectButtonsByDragging) + return; + + m_isDraggingMouseNow = true; + + // Is shift + drag mouse action occurs, then we should toggle on buttons; + // Otherwise - toggle off. + m_isToggleOnMode = ! e.mods.isShiftDown(); + + const int currentButtonIdx = getIndexOfButtonAtPosition (e.getEventRelativeTo (this).getPosition()); + + // Remember the first button on which we started dragging + if (m_firstSelectedButtonIdx == -1 + && m_lastSelectedButtonIdx == -1 + && currentButtonIdx >= 0) + { + m_firstSelectedButtonIdx = currentButtonIdx; + } + + + if (currentButtonIdx != -1 + && currentButtonIdx != m_lastSelectedButtonIdx) + { + m_lastSelectedButtonIdx = currentButtonIdx; + + // Get the indices of range which we should to select (get FROM index and TO index) + const int fromIndex = jmin (m_firstSelectedButtonIdx, m_lastSelectedButtonIdx); + const int toIndex = jmax (m_firstSelectedButtonIdx, m_lastSelectedButtonIdx); + + for (int i = fromIndex; i <= toIndex; ++i) + { + // Trigger click only if the button still isn't selected/deselected (according to the SHIFT holds) + if (m_buttons[i]->getToggleState() != m_isToggleOnMode) + // Trigger click in the button, this will call buttonClicked() method, where we will + m_buttons[i]->triggerClick(); + } + } +} + + +void TiledButtonGroupManager::buttonClicked (Button* buttonThatWasClicked) +{ + // Fast selection enabled and we dragging mouse now to select + if (m_isSelectButtonsByDragging + && m_isDraggingMouseNow) + { + buttonThatWasClicked->setToggleState (m_isToggleOnMode, dontSendNotification); + } + // Default selection + else + { + // Do nothing for now, it's toggled on/off by default + //buttonThatWasClicked->setToggleState (! buttonThatWasClicked->getToggleState(), dontSendNotification); + } + + // Notify the listener + ButtonGroupManager::buttonClicked (buttonThatWasClicked); +} + + +void TiledButtonGroupManager::addButton (Button* newButton) +{ + ButtonGroupManager::addButton (newButton); + + // Disable default clicking on button + newButton->addMouseListener (this, false); +} + + +int TiledButtonGroupManager::getIndexOfButtonAtPosition (Point<int> position) const +{ + + const int numButtons = m_buttons.size(); + const int viewPositionX = m_buttonsViewport.getViewPositionX(); + const int viewPositionY = m_buttonsViewport.getViewPositionY(); + + //DBG ("Down Y position: " + String (position.translated (viewPositionX, viewPositionY).getY())); + + for (int i = 0; i < numButtons; ++i) + { + if (m_buttons[i]->getBounds().contains (position.translated (viewPositionX, viewPositionY))) + return i; + } + + return -1; +} + + +bool TiledButtonGroupManager::isFastSelectionModeEnabled() const +{ + return m_isSelectButtonsByDragging; +} + + +void TiledButtonGroupManager::setFastSelectionModeEnabled (bool isFastSelectionMode) +{ + m_isSelectButtonsByDragging = isFastSelectionMode; +} + + +void TiledButtonGroupManager::setButtonSize (int buttonWidth, int buttonHeight) +{ + m_buttonWidth = buttonWidth; + m_buttonHeight = buttonHeight; + + std::for_each (m_buttons.begin(), m_buttons.end(), + [=] (Button* button) { button->setSize (buttonWidth, buttonHeight); }); + + resized(); +} + + +void TiledButtonGroupManager::setMinPaddingBetweenButtons (int minPadding) +{ + m_minPaddingForButtons = minPadding; + + resized(); +} diff --git a/Source/UI/Utils/TiledButtonGroupManager.h b/Source/UI/Utils/TiledButtonGroupManager.h new file mode 100644 index 0000000000000000000000000000000000000000..d1f1fa17d24fca3e2487d184576aed090b1d4192 --- /dev/null +++ b/Source/UI/Utils/TiledButtonGroupManager.h @@ -0,0 +1,102 @@ +/* + ------------------------------------------------------------------ + + This file is part of the Open Ephys GUI + Copyright (C) 2016 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 TILEDBUTTONGROUPMANAGER_H_INCLUDED +#define TILEDBUTTONGROUPMANAGER_H_INCLUDED + +#include "../../../JuceLibraryCode/JuceHeader.h" +#include "../../Processors/PluginManager/OpenEphysPlugin.h" +#include "ButtonGroupManager.h" + + +/** + + This class provides possibility to store buttons in several rows having tile-structure. + It is responsible for positioning of buttons, any animations during resizing. + It also have "Fast select" feature which allows as to quickly select many buttons + using mouse drag selection. (mouse drag - to select, shift+mouse drag to deselect) + +*/ + + +class PLUGIN_API TiledButtonGroupManager : public ButtonGroupManager +{ +public: + TiledButtonGroupManager(); + + // Component methods + // =========================================================== + void resized() override; + + void mouseDown (const MouseEvent& e) override; + void mouseUp (const MouseEvent& e) override; + void mouseDrag (const MouseEvent& e) override; + // =========================================================== + + // Button::Listener methods + // =========================================================== + void buttonClicked (Button* buttonThatWasClicked) override; + + /** Returns whether fast selection mode (toggle on or off buttons by dragging mouse) is enabled or not */ + bool isFastSelectionModeEnabled() const; + + /** Sets whether fast selection mode (toggle on or off buttons by dragging mouse) will be enabled */ + void setFastSelectionModeEnabled (bool isFastSelectionMode); + + /** Sets the size of each button */ + void setButtonSize (int buttonWidth, int buttonHeight); + + /** Sets the minimal padding which used will be used around buttons */ + void setMinPaddingBetweenButtons (int minPadding); + + /** Add button to the array of buttons to manage it. + + This class controls ownership of buttons. + */ + void addButton (Button* newButton) override; + + +private: + // Returns the index of button at given position. + // If nothing found at this position - returns -1. + int getIndexOfButtonAtPosition (Point<int> position) const; + + int m_buttonWidth; + int m_buttonHeight; + int m_minPaddingForButtons; + + int m_firstSelectedButtonIdx; + int m_lastSelectedButtonIdx; + bool m_isToggleOnMode; + bool m_isDraggingMouseNow; + bool m_isSelectButtonsByDragging; + + ScopedPointer<LookAndFeel> m_materialButtonsLookAndFeel; + + // =========================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TiledButtonGroupManager) +}; + + + +#endif //TILEDBUTTONGROUPMANAGER_H_INCLUDED diff --git a/open-ephys.jucer b/open-ephys.jucer index c71f348c8680a3c604a09b5cd1d45a0b06dbe7bc..6ff0cb146a8fd6465e81d48c30172d11db7c28d5 100644 --- a/open-ephys.jucer +++ b/open-ephys.jucer @@ -13,7 +13,9 @@ <EXPORTFORMATS> <XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="~/SDKs/vstsdk2.4" rtasFolder="~/SDKs/PT_80_SDK" extraLinkerFlags="-ldl -fPIC -rdynamic" objCExtraSuffix="fea2mT" - extraDefs="" extraCompilerFlags="-fPIC "> + extraDefs="" extraCompilerFlags="-fPIC -Wno-inconsistent-missing-override" + postbuildCommand="# Copy Rhythm-related files to application bundle's Resources folder srcdir="${PROJECT_DIR}/../../Resources" dstdir="${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" /usr/bin/rsync -a "$srcdir/Bitfiles/rhd2000.bit" "$srcdir/Bitfiles/rhd2000_usb3.bit" "$srcdir/DLLs/libokFrontPanel.dylib" "$dstdir"" + smallIcon="txUyO4" bigIcon="nFMauU"> <CONFIGURATIONS> <CONFIGURATION name="Debug" isDebug="1" optimisation="3" targetName="open-ephys" osxSDK="default" osxCompatibility="default" osxArchitecture="default" @@ -44,7 +46,7 @@ </XCODE_MAC> <LINUX_MAKE targetFolder="Builds/Linux" vstFolder="~/SDKs/vstsdk2.4" extraLinkerFlags="-ldl -lXext -lGLU -rdynamic -fPIC -fvisibility=hidden" extraCompilerFlags="-rdynamic -std=c++0x -fvisibility=hidden" - extraDefs=""> + extraDefs="" smallIcon="nFMauU" bigIcon="nFMauU"> <CONFIGURATIONS> <CONFIGURATION name="Debug" isDebug="1" optimisation="3" targetName="open-ephys" libraryPath="/usr/X11R6/lib/ /usr/local/include " headerPath=""/> @@ -71,7 +73,7 @@ </LINUX_MAKE> <VS2012 targetFolder="Builds/VisualStudio2012" libraryType="1" extraDefs="NOMINMAX " externalLibraries="setupapi.lib opengl32.lib glu32.lib " - toolset="v110"> + toolset="v110" smallIcon="txUyO4" bigIcon="nFMauU"> <CONFIGURATIONS> <CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit" isDebug="1" optimisation="1" targetName="open-ephys" binaryPath="Builds\VisualStudio2012\Debug\bin" @@ -105,7 +107,8 @@ </MODULEPATHS> </VS2012> <VS2013 targetFolder="Builds/VisualStudio2013" externalLibraries="setupapi.lib opengl32.lib glu32.lib " - extraDefs="NOMINMAX JUCE_API=__declspec(dllexport)"> + extraDefs="NOMINMAX JUCE_API=__declspec(dllexport)" smallIcon="txUyO4" + bigIcon="nFMauU"> <CONFIGURATIONS> <CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="32-bit" isDebug="1" optimisation="1" targetName="open-ephys" binaryPath="Builds\VisualStudio2013\Debug\bin" @@ -145,6 +148,10 @@ </EXPORTFORMATS> <MAINGROUP id="h3HbSTV" name="open-ephys"> <GROUP id="0wpTCpt" name="Resources"> + <GROUP id="{4D9F4AFF-E434-82CD-A6AD-9BF85193FD05}" name="Icons"> + <FILE id="nFMauU" name="icon-large.png" compile="0" resource="1" file="Resources/Icons/icon-large.png"/> + <FILE id="txUyO4" name="icon-small.png" compile="0" resource="1" file="Resources/Icons/icon-small.png"/> + </GROUP> <GROUP id="kVU7EYu" name="Fonts"> <FILE id="g9dipB" name="cpmono-black-serialized" compile="0" resource="1" file="Resources/Fonts/cpmono-black-serialized"/> @@ -263,20 +270,20 @@ <GROUP id="ZMfWAFj" name="Source"> <FILE id="QyaTEa" name="CoreServices.cpp" compile="1" resource="0" file="Source/CoreServices.cpp"/> - <FILE id="BH11mU" name="CoreServices.h" compile="1" resource="0" file="Source/CoreServices.h"/> + <FILE id="BH11mU" name="CoreServices.h" compile="0" resource="0" file="Source/CoreServices.h"/> <FILE id="AXFRUPT" name="AccessClass.cpp" compile="1" resource="0" file="Source/AccessClass.cpp"/> - <FILE id="2ViPrE" name="AccessClass.h" compile="1" resource="0" file="Source/AccessClass.h"/> + <FILE id="2ViPrE" name="AccessClass.h" compile="0" resource="0" file="Source/AccessClass.h"/> <GROUP id="leJrZDi" name="Network"> <FILE id="mOOc0R" name="PracticalSocket.cpp" compile="1" resource="0" file="Source/Network/PracticalSocket.cpp"/> - <FILE id="5XGl6EX" name="PracticalSocket.h" compile="1" resource="0" + <FILE id="5XGl6EX" name="PracticalSocket.h" compile="0" resource="0" file="Source/Network/PracticalSocket.h"/> </GROUP> <GROUP id="gRFzu0" name="Audio"> <FILE id="2vKx2R" name="AudioComponent.cpp" compile="1" resource="0" file="Source/Audio/AudioComponent.cpp"/> - <FILE id="lyiexes" name="AudioComponent.h" compile="1" resource="0" + <FILE id="lyiexes" name="AudioComponent.h" compile="0" resource="0" file="Source/Audio/AudioComponent.h"/> </GROUP> <GROUP id="yQmqZWk" name="Processors"> @@ -291,6 +298,10 @@ file="Source/Processors/PlaceholderProcessor/PlaceholderProcessor.h"/> </GROUP> <GROUP id="{9F37E2FD-6871-8370-4C11-5C97DF132390}" name="Dsp"> + <FILE id="g34Roi" name="LinearSmoothedValueAtomic.cpp" compile="1" + resource="0" file="Source/Processors/Dsp/LinearSmoothedValueAtomic.cpp"/> + <FILE id="mwFwwT" name="LinearSmoothedValueAtomic.h" compile="0" resource="0" + file="Source/Processors/Dsp/LinearSmoothedValueAtomic.h"/> <FILE id="qWmKwI" name="Bessel.cpp" compile="1" resource="0" file="Source/Processors/Dsp/Bessel.cpp"/> <FILE id="bRbpDP" name="Bessel.h" compile="0" resource="0" file="Source/Processors/Dsp/Bessel.h"/> <FILE id="olRf2q" name="Biquad.cpp" compile="1" resource="0" file="Source/Processors/Dsp/Biquad.cpp"/> @@ -353,17 +364,17 @@ file="Source/Processors/PluginManager/OpenEphysPlugin.h"/> <FILE id="a5xlEQ" name="PluginManager.cpp" compile="1" resource="0" file="Source/Processors/PluginManager/PluginManager.cpp"/> - <FILE id="I8EBWd" name="PluginManager.h" compile="1" resource="0" file="Source/Processors/PluginManager/PluginManager.h"/> + <FILE id="I8EBWd" name="PluginManager.h" compile="0" resource="0" file="Source/Processors/PluginManager/PluginManager.h"/> </GROUP> <GROUP id="{1932782D-9D00-9B76-92DC-94E7D42BF0D2}" name="AudioNode"> <FILE id="TV4cOO" name="AudioEditor.cpp" compile="1" resource="0" file="Source/Processors/AudioNode/AudioEditor.cpp"/> - <FILE id="erBMrA" name="AudioEditor.h" compile="1" resource="0" file="Source/Processors/AudioNode/AudioEditor.h"/> + <FILE id="erBMrA" name="AudioEditor.h" compile="0" resource="0" file="Source/Processors/AudioNode/AudioEditor.h"/> <FILE id="jClaJf" name="AudioNode.cpp" compile="1" resource="0" file="Source/Processors/AudioNode/AudioNode.cpp"/> - <FILE id="LHkdoG" name="AudioNode.h" compile="1" resource="0" file="Source/Processors/AudioNode/AudioNode.h"/> + <FILE id="LHkdoG" name="AudioNode.h" compile="0" resource="0" file="Source/Processors/AudioNode/AudioNode.h"/> </GROUP> <GROUP id="{46016F19-8F25-F540-AA1C-D6E87E8D7D31}" name="Channel"> <FILE id="X3I3e9" name="Channel.cpp" compile="1" resource="0" file="Source/Processors/Channel/Channel.cpp"/> - <FILE id="IEZGF3" name="Channel.h" compile="1" resource="0" file="Source/Processors/Channel/Channel.h"/> + <FILE id="IEZGF3" name="Channel.h" compile="0" resource="0" file="Source/Processors/Channel/Channel.h"/> </GROUP> <GROUP id="ZgsuWxi" name="DataThreads"> <GROUP id="{BD34CF88-82A4-3F88-1664-D862A88E97A9}" name="RhythmNode"> @@ -393,160 +404,190 @@ </GROUP> </GROUP> <FILE id="Qfe0ygk" name="DataBuffer.cpp" compile="1" resource="0" file="Source/Processors/DataThreads/DataBuffer.cpp"/> - <FILE id="VCRMcQP" name="DataBuffer.h" compile="1" resource="0" file="Source/Processors/DataThreads/DataBuffer.h"/> + <FILE id="VCRMcQP" name="DataBuffer.h" compile="0" resource="0" file="Source/Processors/DataThreads/DataBuffer.h"/> <FILE id="9JbVKlA" name="DataThread.cpp" compile="1" resource="0" file="Source/Processors/DataThreads/DataThread.cpp"/> - <FILE id="McgNvuR" name="DataThread.h" compile="1" resource="0" file="Source/Processors/DataThreads/DataThread.h"/> + <FILE id="McgNvuR" name="DataThread.h" compile="0" resource="0" file="Source/Processors/DataThreads/DataThread.h"/> </GROUP> <GROUP id="AqvwO6w" name="Editors"> <FILE id="F68NQ3" name="ChannelSelector.cpp" compile="1" resource="0" file="Source/Processors/Editors/ChannelSelector.cpp"/> - <FILE id="cOToxV" name="ChannelSelector.h" compile="1" resource="0" + <FILE id="cOToxV" name="ChannelSelector.h" compile="0" resource="0" file="Source/Processors/Editors/ChannelSelector.h"/> <FILE id="EXjl1X" name="ElectrodeButtons.cpp" compile="1" resource="0" file="Source/Processors/Editors/ElectrodeButtons.cpp"/> - <FILE id="aOEJ7T" name="ElectrodeButtons.h" compile="1" resource="0" + <FILE id="aOEJ7T" name="ElectrodeButtons.h" compile="0" resource="0" file="Source/Processors/Editors/ElectrodeButtons.h"/> <FILE id="dlQddi" name="GenericEditor.cpp" compile="1" resource="0" file="Source/Processors/Editors/GenericEditor.cpp"/> - <FILE id="NZjjLm" name="GenericEditor.h" compile="1" resource="0" file="Source/Processors/Editors/GenericEditor.h"/> + <FILE id="NZjjLm" name="GenericEditor.h" compile="0" resource="0" file="Source/Processors/Editors/GenericEditor.h"/> <FILE id="mqcmr8" name="ImageIcon.cpp" compile="1" resource="0" file="Source/Processors/Editors/ImageIcon.cpp"/> - <FILE id="GLT84s" name="ImageIcon.h" compile="1" resource="0" file="Source/Processors/Editors/ImageIcon.h"/> + <FILE id="GLT84s" name="ImageIcon.h" compile="0" resource="0" file="Source/Processors/Editors/ImageIcon.h"/> <FILE id="c8F02O" name="VisualizerEditor.cpp" compile="1" resource="0" file="Source/Processors/Editors/VisualizerEditor.cpp"/> - <FILE id="qGudPl" name="VisualizerEditor.h" compile="1" resource="0" + <FILE id="qGudPl" name="VisualizerEditor.h" compile="0" resource="0" file="Source/Processors/Editors/VisualizerEditor.h"/> </GROUP> <GROUP id="{27CF9A8D-7C31-9AA9-6DCA-6C719E127923}" name="FileReader"> <FILE id="O6lxmJ" name="FileSource.cpp" compile="1" resource="0" file="Source/Processors/FileReader/FileSource.cpp"/> - <FILE id="CHKZ6y" name="FileSource.h" compile="1" resource="0" file="Source/Processors/FileReader/FileSource.h"/> + <FILE id="CHKZ6y" name="FileSource.h" compile="0" resource="0" file="Source/Processors/FileReader/FileSource.h"/> <FILE id="Pg9JfX" name="FileReader.cpp" compile="1" resource="0" file="Source/Processors/FileReader/FileReader.cpp"/> - <FILE id="SuAWvs" name="FileReader.h" compile="1" resource="0" file="Source/Processors/FileReader/FileReader.h"/> + <FILE id="SuAWvs" name="FileReader.h" compile="0" resource="0" file="Source/Processors/FileReader/FileReader.h"/> <FILE id="Z58rr6" name="FileReaderEditor.cpp" compile="1" resource="0" file="Source/Processors/FileReader/FileReaderEditor.cpp"/> - <FILE id="Ocpu1k" name="FileReaderEditor.h" compile="1" resource="0" + <FILE id="Ocpu1k" name="FileReaderEditor.h" compile="0" resource="0" file="Source/Processors/FileReader/FileReaderEditor.h"/> </GROUP> <GROUP id="{95FA3CAF-7BFA-AFF7-4480-EADCCA5FBA66}" name="GenericProcessor"> <FILE id="l24v5k" name="GenericProcessor.cpp" compile="1" resource="0" file="Source/Processors/GenericProcessor/GenericProcessor.cpp"/> - <FILE id="jSfKFd" name="GenericProcessor.h" compile="1" resource="0" + <FILE id="jSfKFd" name="GenericProcessor.h" compile="0" resource="0" file="Source/Processors/GenericProcessor/GenericProcessor.h"/> </GROUP> <GROUP id="{4B40CAAE-49C7-509A-B7E7-0C7EF011FBA1}" name="Merger"> <FILE id="gZxAmt" name="Merger.cpp" compile="1" resource="0" file="Source/Processors/Merger/Merger.cpp"/> - <FILE id="w8qwHK" name="Merger.h" compile="1" resource="0" file="Source/Processors/Merger/Merger.h"/> + <FILE id="w8qwHK" name="Merger.h" compile="0" resource="0" file="Source/Processors/Merger/Merger.h"/> <FILE id="YIzAwj" name="MergerEditor.cpp" compile="1" resource="0" file="Source/Processors/Merger/MergerEditor.cpp"/> - <FILE id="yquxy4" name="MergerEditor.h" compile="1" resource="0" file="Source/Processors/Merger/MergerEditor.h"/> + <FILE id="yquxy4" name="MergerEditor.h" compile="0" resource="0" file="Source/Processors/Merger/MergerEditor.h"/> </GROUP> <GROUP id="{6E21A406-000C-7894-28D6-2B45D07A304B}" name="MessageCenter"> <FILE id="gnNHUQ" name="MessageCenter.cpp" compile="1" resource="0" file="Source/Processors/MessageCenter/MessageCenter.cpp"/> - <FILE id="vn2uwZ" name="MessageCenter.h" compile="1" resource="0" file="Source/Processors/MessageCenter/MessageCenter.h"/> + <FILE id="vn2uwZ" name="MessageCenter.h" compile="0" resource="0" file="Source/Processors/MessageCenter/MessageCenter.h"/> <FILE id="xGnJo5" name="MessageCenterEditor.cpp" compile="1" resource="0" file="Source/Processors/MessageCenter/MessageCenterEditor.cpp"/> - <FILE id="r1V0KZ" name="MessageCenterEditor.h" compile="1" resource="0" + <FILE id="r1V0KZ" name="MessageCenterEditor.h" compile="0" resource="0" file="Source/Processors/MessageCenter/MessageCenterEditor.h"/> </GROUP> <GROUP id="{86B5AC2A-0A78-6D0E-C5FE-6758DDD096DB}" name="Parameter"> <FILE id="yyyDtp" name="ParameterEditor.cpp" compile="1" resource="0" file="Source/Processors/Parameter/ParameterEditor.cpp"/> - <FILE id="t3vpkl" name="ParameterEditor.h" compile="1" resource="0" + <FILE id="t3vpkl" name="ParameterEditor.h" compile="0" resource="0" file="Source/Processors/Parameter/ParameterEditor.h"/> <FILE id="P4fc98" name="Parameter.cpp" compile="1" resource="0" file="Source/Processors/Parameter/Parameter.cpp"/> - <FILE id="QdTalD" name="Parameter.h" compile="1" resource="0" file="Source/Processors/Parameter/Parameter.h"/> + <FILE id="QdTalD" name="Parameter.h" compile="0" resource="0" file="Source/Processors/Parameter/Parameter.h"/> </GROUP> <GROUP id="{FDEB8810-D49F-8E7C-17A7-685370EF966F}" name="ProcessorGraph"> <FILE id="qil3t5" name="ProcessorGraph.cpp" compile="1" resource="0" file="Source/Processors/ProcessorGraph/ProcessorGraph.cpp"/> - <FILE id="cwGSmb" name="ProcessorGraph.h" compile="1" resource="0" + <FILE id="cwGSmb" name="ProcessorGraph.h" compile="0" resource="0" file="Source/Processors/ProcessorGraph/ProcessorGraph.h"/> </GROUP> <GROUP id="{72D807AC-44A0-1F7A-8699-22225876FE9A}" name="RecordNode"> + <FILE id="WQxge0" name="DataQueue.cpp" compile="1" resource="0" file="Source/Processors/RecordNode/DataQueue.cpp"/> + <FILE id="cZPfsG" name="DataQueue.h" compile="0" resource="0" file="Source/Processors/RecordNode/DataQueue.h"/> + <FILE id="mcvfV8" name="EventQueue.h" compile="0" resource="0" file="Source/Processors/RecordNode/EventQueue.h"/> + <FILE id="r8K6Sh" name="RecordThread.cpp" compile="1" resource="0" + file="Source/Processors/RecordNode/RecordThread.cpp"/> + <FILE id="Q8yVpr" name="RecordThread.h" compile="0" resource="0" file="Source/Processors/RecordNode/RecordThread.h"/> <FILE id="deQ9TU" name="EngineConfigWindow.cpp" compile="1" resource="0" file="Source/Processors/RecordNode/EngineConfigWindow.cpp"/> - <FILE id="iSAT0P" name="EngineConfigWindow.h" compile="1" resource="0" + <FILE id="iSAT0P" name="EngineConfigWindow.h" compile="0" resource="0" file="Source/Processors/RecordNode/EngineConfigWindow.h"/> <FILE id="dpsAhU" name="OriginalRecording.cpp" compile="1" resource="0" file="Source/Processors/RecordNode/OriginalRecording.cpp"/> - <FILE id="okexpc" name="OriginalRecording.h" compile="1" resource="0" + <FILE id="okexpc" name="OriginalRecording.h" compile="0" resource="0" file="Source/Processors/RecordNode/OriginalRecording.h"/> <FILE id="UU77gU" name="RecordEngine.cpp" compile="1" resource="0" file="Source/Processors/RecordNode/RecordEngine.cpp"/> - <FILE id="NSKXGp" name="RecordEngine.h" compile="1" resource="0" file="Source/Processors/RecordNode/RecordEngine.h"/> + <FILE id="NSKXGp" name="RecordEngine.h" compile="0" resource="0" file="Source/Processors/RecordNode/RecordEngine.h"/> <FILE id="ccpPpJ" name="RecordNode.cpp" compile="1" resource="0" file="Source/Processors/RecordNode/RecordNode.cpp"/> - <FILE id="R9n30e" name="RecordNode.h" compile="1" resource="0" file="Source/Processors/RecordNode/RecordNode.h"/> + <FILE id="R9n30e" name="RecordNode.h" compile="0" resource="0" file="Source/Processors/RecordNode/RecordNode.h"/> </GROUP> <GROUP id="{58E5BDC1-3523-0E4D-2402-72726098BA07}" name="SourceNode"> <FILE id="bcB5hN" name="SourceNode.cpp" compile="1" resource="0" file="Source/Processors/SourceNode/SourceNode.cpp"/> - <FILE id="Dyas33" name="SourceNode.h" compile="1" resource="0" file="Source/Processors/SourceNode/SourceNode.h"/> + <FILE id="Dyas33" name="SourceNode.h" compile="0" resource="0" file="Source/Processors/SourceNode/SourceNode.h"/> <FILE id="KQM0Ls" name="SourceNodeEditor.cpp" compile="1" resource="0" file="Source/Processors/SourceNode/SourceNodeEditor.cpp"/> - <FILE id="EWFh9x" name="SourceNodeEditor.h" compile="1" resource="0" + <FILE id="EWFh9x" name="SourceNodeEditor.h" compile="0" resource="0" file="Source/Processors/SourceNode/SourceNodeEditor.h"/> </GROUP> <GROUP id="{393F8FA9-FA27-4F2D-8252-9AB2CAA871DA}" name="Splitter"> <FILE id="xbkXa2" name="Splitter.cpp" compile="1" resource="0" file="Source/Processors/Splitter/Splitter.cpp"/> - <FILE id="kFiAO3" name="Splitter.h" compile="1" resource="0" file="Source/Processors/Splitter/Splitter.h"/> + <FILE id="kFiAO3" name="Splitter.h" compile="0" resource="0" file="Source/Processors/Splitter/Splitter.h"/> <FILE id="mY47Gn" name="SplitterEditor.cpp" compile="1" resource="0" file="Source/Processors/Splitter/SplitterEditor.cpp"/> - <FILE id="KyMfuL" name="SplitterEditor.h" compile="1" resource="0" + <FILE id="KyMfuL" name="SplitterEditor.h" compile="0" resource="0" file="Source/Processors/Splitter/SplitterEditor.h"/> </GROUP> <GROUP id="W4eqkOy" name="Visualization"> <FILE id="Akiup9" name="Visualizer.cpp" compile="1" resource="0" file="Source/Processors/Visualization/Visualizer.cpp"/> <FILE id="ETLsfY" name="DataWindow.cpp" compile="1" resource="0" file="Source/Processors/Visualization/DataWindow.cpp"/> - <FILE id="qDfeYR" name="DataWindow.h" compile="1" resource="0" file="Source/Processors/Visualization/DataWindow.h"/> + <FILE id="qDfeYR" name="DataWindow.h" compile="0" resource="0" file="Source/Processors/Visualization/DataWindow.h"/> <FILE id="tuQVXY" name="SpikeObject.cpp" compile="1" resource="0" file="Source/Processors/Visualization/SpikeObject.cpp"/> - <FILE id="KyhGmE" name="SpikeObject.h" compile="1" resource="0" file="Source/Processors/Visualization/SpikeObject.h"/> - <FILE id="MsSuwS" name="Visualizer.h" compile="1" resource="0" file="Source/Processors/Visualization/Visualizer.h"/> + <FILE id="KyhGmE" name="SpikeObject.h" compile="0" resource="0" file="Source/Processors/Visualization/SpikeObject.h"/> + <FILE id="MsSuwS" name="Visualizer.h" compile="0" resource="0" file="Source/Processors/Visualization/Visualizer.h"/> <FILE id="KQJVIp" name="MatlabLikePlot.cpp" compile="1" resource="0" file="Source/Processors/Visualization/MatlabLikePlot.cpp"/> - <FILE id="EH2pAq" name="MatlabLikePlot.h" compile="1" resource="0" + <FILE id="EH2pAq" name="MatlabLikePlot.h" compile="0" resource="0" file="Source/Processors/Visualization/MatlabLikePlot.h"/> </GROUP> </GROUP> <GROUP id="RNGb1yR" name="UI"> + <GROUP id="{0CCF438B-DD41-FC9E-7C68-3079F4BCB2D2}" name="Utils"> + <FILE id="RLE0Po" name="TiledButtonGroupManager.cpp" compile="1" resource="0" + file="Source/UI/Utils/TiledButtonGroupManager.cpp"/> + <FILE id="n3zYjB" name="TiledButtonGroupManager.h" compile="0" resource="0" + file="Source/UI/Utils/TiledButtonGroupManager.h"/> + <FILE id="cF8nWd" name="LinearButtonGroupManager.cpp" compile="1" resource="0" + file="Source/UI/Utils/LinearButtonGroupManager.cpp"/> + <FILE id="BNeEun" name="LinearButtonGroupManager.h" compile="0" resource="0" + file="Source/UI/Utils/LinearButtonGroupManager.h"/> + <FILE id="GFX1Tc" name="ButtonGroupManager.cpp" compile="1" resource="0" + file="Source/UI/Utils/ButtonGroupManager.cpp"/> + <FILE id="AIybG9" name="ButtonGroupManager.h" compile="0" resource="0" + file="Source/UI/Utils/ButtonGroupManager.h"/> + </GROUP> + <GROUP id="{4DEE2319-EFDC-8525-9E6D-CC2453D07E6A}" name="LookAndFeel"> + <FILE id="GLPszU" name="MaterialButtonLookAndFeel.cpp" compile="1" + resource="0" file="Source/UI/LookAndFeel/MaterialButtonLookAndFeel.cpp"/> + <FILE id="VZAIuz" name="MaterialButtonLookAndFeel.h" compile="0" resource="0" + file="Source/UI/LookAndFeel/MaterialButtonLookAndFeel.h"/> + <FILE id="kKrq6c" name="MaterialSliderLookAndFeel.cpp" compile="1" + resource="0" file="Source/UI/LookAndFeel/MaterialSliderLookAndFeel.cpp"/> + <FILE id="IzNTEQ" name="MaterialSliderLookAndFeel.h" compile="0" resource="0" + file="Source/UI/LookAndFeel/MaterialSliderLookAndFeel.h"/> + <FILE id="mx7gmX" name="CustomLookAndFeel.cpp" compile="1" resource="0" + file="Source/UI/LookAndFeel/CustomLookAndFeel.cpp"/> + <FILE id="kGrvSy" name="CustomLookAndFeel.h" compile="0" resource="0" + file="Source/UI/LookAndFeel/CustomLookAndFeel.h"/> + </GROUP> <FILE id="gXswXJ" name="CustomArrowButton.cpp" compile="1" resource="0" file="Source/UI/CustomArrowButton.cpp"/> - <FILE id="ECOEoc" name="CustomArrowButton.h" compile="1" resource="0" + <FILE id="ECOEoc" name="CustomArrowButton.h" compile="0" resource="0" file="Source/UI/CustomArrowButton.h"/> <FILE id="aHMWGl" name="GraphViewer.cpp" compile="1" resource="0" file="Source/UI/GraphViewer.cpp"/> - <FILE id="EOJ8RU" name="GraphViewer.h" compile="1" resource="0" file="Source/UI/GraphViewer.h"/> + <FILE id="EOJ8RU" name="GraphViewer.h" compile="0" resource="0" file="Source/UI/GraphViewer.h"/> <FILE id="sWZ22HN" name="EditorViewportButtons.cpp" compile="1" resource="0" file="Source/UI/EditorViewportButtons.cpp"/> - <FILE id="WwXnCHj" name="EditorViewportButtons.h" compile="1" resource="0" + <FILE id="WwXnCHj" name="EditorViewportButtons.h" compile="0" resource="0" file="Source/UI/EditorViewportButtons.h"/> <FILE id="lPimHJv" name="SignalChainManager.cpp" compile="1" resource="0" file="Source/UI/SignalChainManager.cpp"/> - <FILE id="0PVPDKZ" name="SignalChainManager.h" compile="1" resource="0" + <FILE id="0PVPDKZ" name="SignalChainManager.h" compile="0" resource="0" file="Source/UI/SignalChainManager.h"/> <FILE id="WgUx2Vj" name="EditorViewport.cpp" compile="1" resource="0" file="Source/UI/EditorViewport.cpp"/> - <FILE id="8npqLFq" name="EditorViewport.h" compile="1" resource="0" + <FILE id="8npqLFq" name="EditorViewport.h" compile="0" resource="0" file="Source/UI/EditorViewport.h"/> <FILE id="Rn2yUfU" name="ProcessorList.cpp" compile="1" resource="0" file="Source/UI/ProcessorList.cpp"/> - <FILE id="lOTMfMY" name="ProcessorList.h" compile="1" resource="0" + <FILE id="lOTMfMY" name="ProcessorList.h" compile="0" resource="0" file="Source/UI/ProcessorList.h"/> - <FILE id="sxXKhY" name="CustomLookAndFeel.cpp" compile="1" resource="0" - file="Source/UI/CustomLookAndFeel.cpp"/> - <FILE id="VLEIXYc" name="CustomLookAndFeel.h" compile="1" resource="0" - file="Source/UI/CustomLookAndFeel.h"/> <FILE id="MuFSLOI" name="InfoLabel.cpp" compile="1" resource="0" file="Source/UI/InfoLabel.cpp"/> - <FILE id="aCcIvXz" name="InfoLabel.h" compile="1" resource="0" file="Source/UI/InfoLabel.h"/> + <FILE id="aCcIvXz" name="InfoLabel.h" compile="0" resource="0" file="Source/UI/InfoLabel.h"/> <FILE id="bWElQSS" name="DataViewport.cpp" compile="1" resource="0" file="Source/UI/DataViewport.cpp"/> - <FILE id="mMoQ3ls" name="DataViewport.h" compile="1" resource="0" file="Source/UI/DataViewport.h"/> + <FILE id="mMoQ3ls" name="DataViewport.h" compile="0" resource="0" file="Source/UI/DataViewport.h"/> <FILE id="we1JIPz" name="ControlPanel.cpp" compile="1" resource="0" file="Source/UI/ControlPanel.cpp"/> - <FILE id="rCft9Ec" name="ControlPanel.h" compile="1" resource="0" file="Source/UI/ControlPanel.h"/> + <FILE id="rCft9Ec" name="ControlPanel.h" compile="0" resource="0" file="Source/UI/ControlPanel.h"/> <FILE id="Ih10hsN" name="UIComponent.cpp" compile="1" resource="0" file="Source/UI/UIComponent.cpp"/> - <FILE id="BMY9oVw" name="UIComponent.h" compile="1" resource="0" file="Source/UI/UIComponent.h"/> + <FILE id="BMY9oVw" name="UIComponent.h" compile="0" resource="0" file="Source/UI/UIComponent.h"/> </GROUP> <FILE id="YFtK48" name="MainWindow.cpp" compile="1" resource="0" file="Source/MainWindow.cpp"/> - <FILE id="JiA1GET" name="MainWindow.h" compile="1" resource="0" file="Source/MainWindow.h"/> + <FILE id="JiA1GET" name="MainWindow.h" compile="0" resource="0" file="Source/MainWindow.h"/> <FILE id="z41Hy7g" name="Main.cpp" compile="1" resource="0" file="Source/Main.cpp"/> </GROUP> </MAINGROUP>