Full Code of McMartin/FRUT for AI

main 0b31a99ca902 cached
586 files
2.4 MB
671.3k tokens
141 symbols
1 requests
Download .txt
Showing preview only (2,677K chars total). Download the full file or copy to clipboard to get everything.
Repository: McMartin/FRUT
Branch: main
Commit: 0b31a99ca902
Files: 586
Total size: 2.4 MB

Directory structure:
gitextract_b0ewfza2/

├── .appveyor.yml
├── .azure-pipelines.yml
├── .cirrus.yml
├── .clang-format
├── .github/
│   └── pull_request_template.md
├── .gitignore
├── .readthedocs.yaml
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Jucer2CMake/
│   ├── CMakeLists.txt
│   ├── src/
│   │   ├── argh.hpp
│   │   ├── juce6.hpp
│   │   ├── juce_core.hpp
│   │   ├── main.cpp
│   │   ├── reprojucer.hpp
│   │   └── utils.hpp
│   └── tests/
│       ├── .gitignore
│       ├── apply-Jucer2CMake-juce6-to-test-jucers.cmake
│       ├── audioplug6/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   ├── PluginEditor.cpp
│       │   │   ├── PluginEditor.h
│       │   │   ├── PluginProcessor.cpp
│       │   │   └── PluginProcessor.h
│       │   └── audioplug6.jucer
│       ├── audioplug6-default/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   ├── PluginEditor.cpp
│       │   │   ├── PluginEditor.h
│       │   │   ├── PluginProcessor.cpp
│       │   │   └── PluginProcessor.h
│       │   └── audioplug6.jucer
│       ├── consoleapp6/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   └── Main.cpp
│       │   └── consoleapp6.jucer
│       ├── consoleapp6-default/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   └── Main.cpp
│       │   └── consoleapp6.jucer
│       ├── guiapp6/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   ├── Main.cpp
│       │   │   ├── MainComponent.cpp
│       │   │   └── MainComponent.h
│       │   └── guiapp6.jucer
│       └── guiapp6-default/
│           ├── CMakeLists.txt
│           ├── Source/
│           │   ├── Main.cpp
│           │   ├── MainComponent.cpp
│           │   └── MainComponent.h
│           └── guiapp6.jucer
├── LICENSE
├── README.rst
├── ci/
│   ├── AllJuceProjects/
│   │   └── CMakeLists.txt
│   ├── apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
│   ├── apply-Jucer2CMake-reprojucer-to-test-jucers.cmake
│   ├── azure-pipelines/
│   │   ├── steps-Makefiles.yml
│   │   ├── steps-VS.yml
│   │   ├── steps-Xcode.yml
│   │   └── steps-iOS.yml
│   └── fake-SDKs/
│       ├── AAX/
│       │   └── Interfaces/
│       │       └── AAX_Exports.cpp
│       ├── VST/
│       │   ├── pluginterfaces/
│       │   │   └── vst2.x/
│       │   │       └── aeffect.h
│       │   └── public.sdk/
│       │       └── source/
│       │           └── vst2.x/
│       │               └── audioeffectx.h
│       └── VST3/
│           └── base/
│               └── source/
│                   └── baseiids.cpp
├── cmake/
│   ├── Reprojucer.cmake
│   ├── data/
│   │   ├── AppConfig-4.h.in
│   │   ├── AppConfig-5.h.in
│   │   ├── AppConfig.h.in
│   │   ├── Info.plist.in
│   │   ├── JuceHeader.h.in
│   │   ├── JuceLibraryCode-Wrapper.cpp.in
│   │   ├── JucePluginDefines.h.in
│   │   ├── LaunchScreen.storyboard
│   │   ├── PkgInfo
│   │   ├── UnityScript.cs.in
│   │   ├── failed-to.md.in
│   │   ├── juce_runtime_arch_detection.cpp
│   │   ├── resources.rc.in
│   │   ├── script.in
│   │   └── target.entitlements.in
│   └── tools/
│       ├── BinaryDataBuilder/
│       │   ├── CMakeLists.txt
│       │   ├── extras/
│       │   │   └── Projucer/
│       │   │       └── Source/
│       │   │           ├── Project/
│       │   │           │   └── jucer_Project.h
│       │   │           ├── Project Saving/
│       │   │           │   ├── jucer_ResourceFile.cpp
│       │   │           │   └── jucer_ResourceFile.h
│       │   │           ├── Utility/
│       │   │           │   ├── jucer_CodeHelpers.cpp
│       │   │           │   ├── jucer_CodeHelpers.h
│       │   │           │   ├── jucer_FileHelpers.cpp
│       │   │           │   ├── jucer_FileHelpers.h
│       │   │           │   ├── jucer_MiscUtilities.cpp
│       │   │           │   └── jucer_MiscUtilities.h
│       │   │           └── jucer_Headers.h
│       │   ├── main.cpp
│       │   └── modules/
│       │       └── juce_gui_extra/
│       │           ├── code_editor/
│       │           │   ├── juce_CPlusPlusCodeTokeniser.cpp
│       │           │   ├── juce_CPlusPlusCodeTokeniser.h
│       │           │   └── juce_CPlusPlusCodeTokeniserFunctions.h
│       │           ├── juce_gui_extra.cpp
│       │           └── juce_gui_extra.h
│       ├── CMakeLists.txt
│       ├── IconBuilder/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   ├── Project Saving/
│       │   │   │   ├── jucer_ProjectExport_MSVC.h
│       │   │   │   ├── jucer_ProjectExport_XCode.h
│       │   │   │   ├── jucer_ProjectExporter.cpp
│       │   │   │   └── jucer_ProjectExporter.h
│       │   │   ├── Utility/
│       │   │   │   ├── jucer_FileHelpers.cpp
│       │   │   │   └── jucer_FileHelpers.h
│       │   │   └── jucer_Headers.h
│       │   └── main.cpp
│       ├── PListMerger/
│       │   ├── CMakeLists.txt
│       │   └── main.cpp
│       ├── XcassetsBuilder/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   ├── ProjectSaving/
│       │   │   │   ├── jucer_ProjectExport_Xcode.h
│       │   │   │   ├── jucer_ProjectExporter.cpp
│       │   │   │   └── jucer_ProjectExporter.h
│       │   │   ├── Utility/
│       │   │   │   ├── jucer_FileHelpers.cpp
│       │   │   │   └── jucer_FileHelpers.h
│       │   │   └── jucer_Headers.h
│       │   └── main.cpp
│       ├── juce_core.cmake
│       └── juce_gui_basics.cmake
├── docs/
│   ├── Reprojucer.cmake/
│   │   ├── command/
│   │   │   ├── jucer_appconfig_header.rst
│   │   │   ├── jucer_audio_plugin_settings.rst
│   │   │   ├── jucer_export_target.rst
│   │   │   ├── jucer_export_target_configuration.rst
│   │   │   ├── jucer_project_begin.rst
│   │   │   ├── jucer_project_end.rst
│   │   │   ├── jucer_project_files.rst
│   │   │   ├── jucer_project_module.rst
│   │   │   └── jucer_project_settings.rst
│   │   └── index.rst
│   ├── conf.py
│   ├── index.rst
│   └── requirements.txt
├── generated/
│   ├── JUCE-4.2.0/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   ├── AUv3Synth/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AnimationAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AudioAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── BouncingBallWavetableDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── ComponentTutorialExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── Demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── HelloWorld/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MPETest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MidiTest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── NetworkGraphicsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCMonitor/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCReceiver/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCSender/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OpenGLAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PluckedStringsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PlugInSamples/
│   │   │   │   ├── Arpeggiator/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── GainPlugIn/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── MultiOutSynth/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── NoiseGate/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── Surround/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── SimpleFFTExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── audio plugin demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   └── audio plugin host/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       ├── binarybuilder/
│   │       │   └── CMakeLists.txt
│   │       └── windows dll/
│   │           └── CMakeLists.txt
│   ├── JUCE-4.3.1/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   ├── AUv3Synth/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AnimationAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AudioAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── BLOCKS/
│   │   │   │   ├── BlocksDrawing/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── BlocksMonitor/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── BlocksSynth/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── BouncingBallWavetableDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── ComponentTutorialExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── Demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── HelloWorld/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MPETest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MidiTest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── NetworkGraphicsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCMonitor/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCReceiver/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCSender/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OpenGLAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PluckedStringsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PlugInSamples/
│   │   │   │   ├── Arpeggiator/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── GainPlugIn/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── MultiOutSynth/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── NoiseGate/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── Surround/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── SimpleFFTExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── audio plugin demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   └── audio plugin host/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       ├── binarybuilder/
│   │       │   └── CMakeLists.txt
│   │       └── windows dll/
│   │           └── CMakeLists.txt
│   ├── JUCE-5.0.0/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   ├── AUv3Synth/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AnimationAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AudioAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── BLOCKS/
│   │   │   │   ├── BlocksDrawing/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── BlocksMonitor/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── BlocksSynth/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── BouncingBallWavetableDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── ComponentTutorialExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── Demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── HelloWorld/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MPETest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MidiTest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── NetworkGraphicsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCMonitor/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCReceiver/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCSender/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OpenGLAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PluckedStringsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PlugInSamples/
│   │   │   │   ├── Arpeggiator/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── GainPlugIn/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── InterAppAudioEffect/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── MultiOutSynth/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── NoiseGate/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── Surround/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── SimpleFFTExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── audio plugin demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   └── audio plugin host/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       ├── binarybuilder/
│   │       │   └── CMakeLists.txt
│   │       └── windows dll/
│   │           └── CMakeLists.txt
│   ├── JUCE-5.2.1/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   ├── AUv3Synth/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AnalyticsCollection/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AnimationAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AudioAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── BLOCKS/
│   │   │   │   ├── BlocksDrawing/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── BlocksMonitor/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── BlocksSynth/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── BouncingBallWavetableDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── ComponentTutorialExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── DSP module plugin demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── DSPDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── Demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── HelloWorld/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── InAppPurchase/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MPETest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MidiTest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── NetworkGraphicsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCMonitor/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCReceiver/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCSender/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OpenGLAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PluckedStringsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PlugInSamples/
│   │   │   │   ├── Arpeggiator/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── GainPlugIn/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── InterAppAudioEffect/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── MultiOutSynth/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── NoiseGate/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── Surround/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── PushNotificationsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── SimpleFFTExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── audio plugin demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   └── audio plugin host/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       ├── binarybuilder/
│   │       │   └── CMakeLists.txt
│   │       └── windows dll/
│   │           └── CMakeLists.txt
│   ├── JUCE-5.3.1/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   └── DemoRunner/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── AudioPluginHost/
│   │       │   └── CMakeLists.txt
│   │       ├── BinaryBuilder/
│   │       │   └── CMakeLists.txt
│   │       ├── NetworkGraphicsDemo/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       └── WindowsDLL/
│   │           └── CMakeLists.txt
│   ├── JUCE-5.4.3/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   └── DemoRunner/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── AudioPluginHost/
│   │       │   └── CMakeLists.txt
│   │       ├── BinaryBuilder/
│   │       │   └── CMakeLists.txt
│   │       ├── NetworkGraphicsDemo/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       └── WindowsDLL/
│   │           └── CMakeLists.txt
│   ├── JUCE-5.4.7/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   └── DemoRunner/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── AudioPluginHost/
│   │       │   └── CMakeLists.txt
│   │       ├── BinaryBuilder/
│   │       │   └── CMakeLists.txt
│   │       ├── NetworkGraphicsDemo/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       └── WindowsDLL/
│   │           └── CMakeLists.txt
│   ├── JUCE-6.0.5/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   └── DemoRunner/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── AudioPluginHost/
│   │       │   └── CMakeLists.txt
│   │       ├── BinaryBuilder/
│   │       │   └── CMakeLists.txt
│   │       ├── NetworkGraphicsDemo/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       └── WindowsDLL/
│   │           └── CMakeLists.txt
│   ├── JUCE-6.1.6/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   └── DemoRunner/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── AudioPluginHost/
│   │       │   └── CMakeLists.txt
│   │       ├── BinaryBuilder/
│   │       │   └── CMakeLists.txt
│   │       ├── NetworkGraphicsDemo/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       └── WindowsDLL/
│   │           └── CMakeLists.txt
│   └── JUCE-7.0.7/
│       ├── CMakeLists.txt
│       ├── README.rst
│       ├── examples/
│       │   └── DemoRunner/
│       │       └── CMakeLists.txt
│       └── extras/
│           ├── AudioPerformanceTest/
│           │   └── CMakeLists.txt
│           ├── AudioPluginHost/
│           │   └── CMakeLists.txt
│           ├── BinaryBuilder/
│           │   └── CMakeLists.txt
│           ├── NetworkGraphicsDemo/
│           │   └── CMakeLists.txt
│           ├── Projucer/
│           │   └── CMakeLists.txt
│           ├── UnitTestRunner/
│           │   └── CMakeLists.txt
│           └── WindowsDLL/
│               └── CMakeLists.txt
├── tests/
│   ├── diff-compiler-args.cmake
│   ├── issue-246/
│   │   ├── CMakeLists.txt
│   │   └── main.cpp
│   ├── test-projects/
│   │   ├── entitlements-generation/
│   │   │   ├── .gitignore
│   │   │   ├── guiapp-MacOSX/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   └── binary_dir/
│   │   │   │       ├── AllSettings.entitlements
│   │   │   │       ├── PushNotificationsCapability.entitlements
│   │   │   │       ├── UseAppSandbox_Inheritance.entitlements
│   │   │   │       ├── UseAppSandbox_NoOptions.entitlements
│   │   │   │       ├── UseAppSandbox_OneOption.entitlements
│   │   │   │       ├── UseAppSandbox_SeveralOptions.entitlements
│   │   │   │       ├── UseHardenedRuntime_NoOptions.entitlements
│   │   │   │       ├── UseHardenedRuntime_OneOption.entitlements
│   │   │   │       ├── UseHardenedRuntime_SeveralOptions.entitlements
│   │   │   │       └── default.entitlements
│   │   │   ├── guiapp-iOS/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   └── binary_dir/
│   │   │   │       ├── AppGroupsCapability-empty.entitlements
│   │   │   │       ├── AppGroupsCapability-one_ID.entitlements
│   │   │   │       ├── AppGroupsCapability-three_IDs.entitlements
│   │   │   │       ├── PushNotificationsCapability.entitlements
│   │   │   │       ├── default.entitlements
│   │   │   │       └── iCloudPermissions.entitlements
│   │   │   ├── plugin-MacOSX/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   └── binary_dir/
│   │   │   │       ├── AUv3-AllSettings.entitlements
│   │   │   │       ├── AUv3-PushNotificationsCapability.entitlements
│   │   │   │       ├── AUv3-UseAppSandbox_Inheritance.entitlements
│   │   │   │       ├── AUv3-UseAppSandbox_NoOptions.entitlements
│   │   │   │       ├── AUv3-UseAppSandbox_OneOption.entitlements
│   │   │   │       ├── AUv3-UseAppSandbox_SeveralOptions.entitlements
│   │   │   │       ├── AUv3-UseHardenedRuntime_NoOptions.entitlements
│   │   │   │       ├── AUv3-UseHardenedRuntime_OneOption.entitlements
│   │   │   │       ├── AUv3-UseHardenedRuntime_SeveralOptions.entitlements
│   │   │   │       ├── AUv3-default.entitlements
│   │   │   │       ├── AllSettings.entitlements
│   │   │   │       ├── PushNotificationsCapability.entitlements
│   │   │   │       ├── UseAppSandbox_Inheritance.entitlements
│   │   │   │       ├── UseAppSandbox_NoOptions.entitlements
│   │   │   │       ├── UseAppSandbox_OneOption.entitlements
│   │   │   │       ├── UseAppSandbox_SeveralOptions.entitlements
│   │   │   │       ├── UseHardenedRuntime_NoOptions.entitlements
│   │   │   │       ├── UseHardenedRuntime_OneOption.entitlements
│   │   │   │       ├── UseHardenedRuntime_SeveralOptions.entitlements
│   │   │   │       └── default.entitlements
│   │   │   └── plugin-iOS/
│   │   │       ├── CMakeLists.txt
│   │   │       └── binary_dir/
│   │   │           ├── AUv3-EnableIAA.entitlements
│   │   │           ├── AUv3-PushNotificationsCapability.entitlements
│   │   │           ├── AUv3-default.entitlements
│   │   │           ├── EnableIAA.entitlements
│   │   │           ├── PushNotificationsCapability.entitlements
│   │   │           └── default.entitlements
│   │   ├── no-modules/
│   │   │   ├── consoleapp420/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── Builds/
│   │   │   │   │   ├── CodeBlocksLinux/
│   │   │   │   │   │   └── consoleapp420.cbp
│   │   │   │   │   ├── CodeBlocksWindows/
│   │   │   │   │   │   └── consoleapp420.cbp
│   │   │   │   │   ├── LinuxMakefile/
│   │   │   │   │   │   └── Makefile
│   │   │   │   │   ├── MacOSX/
│   │   │   │   │   │   ├── RecentFilesMenuTemplate.nib
│   │   │   │   │   │   └── consoleapp420.xcodeproj/
│   │   │   │   │   │       └── project.pbxproj
│   │   │   │   │   ├── VisualStudio2013/
│   │   │   │   │   │   ├── consoleapp420.sln
│   │   │   │   │   │   ├── consoleapp420.vcxproj
│   │   │   │   │   │   ├── consoleapp420.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   └── VisualStudio2015/
│   │   │   │   │       ├── consoleapp420.sln
│   │   │   │   │       ├── consoleapp420.vcxproj
│   │   │   │   │       ├── consoleapp420.vcxproj.filters
│   │   │   │   │       └── resources.rc
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── JuceLibraryCode/
│   │   │   │   │   ├── AppConfig.h
│   │   │   │   │   ├── JuceHeader.h
│   │   │   │   │   └── ReadMe.txt
│   │   │   │   ├── Source/
│   │   │   │   │   └── foo.cpp
│   │   │   │   └── consoleapp420.jucer
│   │   │   ├── consoleapp431/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── Builds/
│   │   │   │   │   ├── CodeBlocksLinux/
│   │   │   │   │   │   └── consoleapp431.cbp
│   │   │   │   │   ├── CodeBlocksWindows/
│   │   │   │   │   │   └── consoleapp431.cbp
│   │   │   │   │   ├── LinuxMakefile/
│   │   │   │   │   │   └── Makefile
│   │   │   │   │   ├── MacOSX/
│   │   │   │   │   │   ├── RecentFilesMenuTemplate.nib
│   │   │   │   │   │   └── consoleapp431.xcodeproj/
│   │   │   │   │   │       └── project.pbxproj
│   │   │   │   │   ├── VisualStudio2013/
│   │   │   │   │   │   ├── consoleapp431.sln
│   │   │   │   │   │   ├── consoleapp431.vcxproj
│   │   │   │   │   │   ├── consoleapp431.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   └── VisualStudio2015/
│   │   │   │   │       ├── consoleapp431.sln
│   │   │   │   │       ├── consoleapp431.vcxproj
│   │   │   │   │       ├── consoleapp431.vcxproj.filters
│   │   │   │   │       └── resources.rc
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── JuceLibraryCode/
│   │   │   │   │   ├── AppConfig.h
│   │   │   │   │   ├── JuceHeader.h
│   │   │   │   │   └── ReadMe.txt
│   │   │   │   ├── Source/
│   │   │   │   │   └── foo.cpp
│   │   │   │   └── consoleapp431.jucer
│   │   │   ├── consoleapp500/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── Builds/
│   │   │   │   │   ├── CodeBlocksLinux/
│   │   │   │   │   │   └── consoleapp500.cbp
│   │   │   │   │   ├── CodeBlocksWindows/
│   │   │   │   │   │   └── consoleapp500.cbp
│   │   │   │   │   ├── LinuxMakefile/
│   │   │   │   │   │   └── Makefile
│   │   │   │   │   ├── MacOSX/
│   │   │   │   │   │   ├── RecentFilesMenuTemplate.nib
│   │   │   │   │   │   └── consoleapp500.xcodeproj/
│   │   │   │   │   │       └── project.pbxproj
│   │   │   │   │   ├── VisualStudio2013/
│   │   │   │   │   │   ├── consoleapp500.sln
│   │   │   │   │   │   ├── consoleapp500_ConsoleApp.vcxproj
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   ├── VisualStudio2015/
│   │   │   │   │   │   ├── consoleapp500.sln
│   │   │   │   │   │   ├── consoleapp500_ConsoleApp.vcxproj
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   └── VisualStudio2017/
│   │   │   │   │       ├── consoleapp500.sln
│   │   │   │   │       ├── consoleapp500_ConsoleApp.vcxproj
│   │   │   │   │       └── resources.rc
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── JuceLibraryCode/
│   │   │   │   │   ├── AppConfig.h
│   │   │   │   │   ├── JuceHeader.h
│   │   │   │   │   └── ReadMe.txt
│   │   │   │   ├── Source/
│   │   │   │   │   └── foo.cpp
│   │   │   │   └── consoleapp500.jucer
│   │   │   ├── consoleapp521/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── Builds/
│   │   │   │   │   ├── CodeBlocksLinux/
│   │   │   │   │   │   └── consoleapp521.cbp
│   │   │   │   │   ├── CodeBlocksWindows/
│   │   │   │   │   │   └── consoleapp521.cbp
│   │   │   │   │   ├── LinuxMakefile/
│   │   │   │   │   │   └── Makefile
│   │   │   │   │   ├── MacOSX/
│   │   │   │   │   │   ├── RecentFilesMenuTemplate.nib
│   │   │   │   │   │   └── consoleapp521.xcodeproj/
│   │   │   │   │   │       └── project.pbxproj
│   │   │   │   │   ├── VisualStudio2013/
│   │   │   │   │   │   ├── consoleapp521.sln
│   │   │   │   │   │   ├── consoleapp521_ConsoleApp.vcxproj
│   │   │   │   │   │   ├── consoleapp521_ConsoleApp.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   ├── VisualStudio2015/
│   │   │   │   │   │   ├── consoleapp521.sln
│   │   │   │   │   │   ├── consoleapp521_ConsoleApp.vcxproj
│   │   │   │   │   │   ├── consoleapp521_ConsoleApp.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   └── VisualStudio2017/
│   │   │   │   │       ├── consoleapp521.sln
│   │   │   │   │       ├── consoleapp521_ConsoleApp.vcxproj
│   │   │   │   │       ├── consoleapp521_ConsoleApp.vcxproj.filters
│   │   │   │   │       └── resources.rc
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── JuceLibraryCode/
│   │   │   │   │   ├── AppConfig.h
│   │   │   │   │   ├── JuceHeader.h
│   │   │   │   │   └── ReadMe.txt
│   │   │   │   ├── Source/
│   │   │   │   │   └── foo.cpp
│   │   │   │   └── consoleapp521.jucer
│   │   │   ├── consoleapp531/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── Builds/
│   │   │   │   │   ├── CodeBlocksLinux/
│   │   │   │   │   │   └── consoleapp531.cbp
│   │   │   │   │   ├── CodeBlocksWindows/
│   │   │   │   │   │   └── consoleapp531.cbp
│   │   │   │   │   ├── LinuxMakefile/
│   │   │   │   │   │   └── Makefile
│   │   │   │   │   ├── MacOSX/
│   │   │   │   │   │   ├── RecentFilesMenuTemplate.nib
│   │   │   │   │   │   └── consoleapp531.xcodeproj/
│   │   │   │   │   │       └── project.pbxproj
│   │   │   │   │   ├── VisualStudio2013/
│   │   │   │   │   │   ├── consoleapp531.sln
│   │   │   │   │   │   ├── consoleapp531_ConsoleApp.vcxproj
│   │   │   │   │   │   ├── consoleapp531_ConsoleApp.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   ├── VisualStudio2015/
│   │   │   │   │   │   ├── consoleapp531.sln
│   │   │   │   │   │   ├── consoleapp531_ConsoleApp.vcxproj
│   │   │   │   │   │   ├── consoleapp531_ConsoleApp.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   └── VisualStudio2017/
│   │   │   │   │       ├── consoleapp531.sln
│   │   │   │   │       ├── consoleapp531_ConsoleApp.vcxproj
│   │   │   │   │       ├── consoleapp531_ConsoleApp.vcxproj.filters
│   │   │   │   │       └── resources.rc
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── JuceLibraryCode/
│   │   │   │   │   ├── AppConfig.h
│   │   │   │   │   ├── JuceHeader.h
│   │   │   │   │   └── ReadMe.txt
│   │   │   │   ├── Source/
│   │   │   │   │   └── foo.cpp
│   │   │   │   └── consoleapp531.jucer
│   │   │   └── consoleapp543/
│   │   │       ├── .gitignore
│   │   │       ├── Builds/
│   │   │       │   ├── CodeBlocksLinux/
│   │   │       │   │   ├── consoleapp543.cbp
│   │   │       │   │   └── resources.rc
│   │   │       │   ├── CodeBlocksWindows/
│   │   │       │   │   ├── consoleapp543.cbp
│   │   │       │   │   └── resources.rc
│   │   │       │   ├── LinuxMakefile/
│   │   │       │   │   └── Makefile
│   │   │       │   ├── MacOSX/
│   │   │       │   │   ├── RecentFilesMenuTemplate.nib
│   │   │       │   │   └── consoleapp543.xcodeproj/
│   │   │       │   │       ├── project.pbxproj
│   │   │       │   │       └── project.xcworkspace/
│   │   │       │   │           └── xcshareddata/
│   │   │       │   │               └── WorkspaceSettings.xcsettings
│   │   │       │   ├── VisualStudio2013/
│   │   │       │   │   ├── consoleapp543.sln
│   │   │       │   │   ├── consoleapp543_ConsoleApp.vcxproj
│   │   │       │   │   ├── consoleapp543_ConsoleApp.vcxproj.filters
│   │   │       │   │   └── resources.rc
│   │   │       │   ├── VisualStudio2015/
│   │   │       │   │   ├── consoleapp543.sln
│   │   │       │   │   ├── consoleapp543_ConsoleApp.vcxproj
│   │   │       │   │   ├── consoleapp543_ConsoleApp.vcxproj.filters
│   │   │       │   │   └── resources.rc
│   │   │       │   └── VisualStudio2017/
│   │   │       │       ├── consoleapp543.sln
│   │   │       │       ├── consoleapp543_ConsoleApp.vcxproj
│   │   │       │       ├── consoleapp543_ConsoleApp.vcxproj.filters
│   │   │       │       └── resources.rc
│   │   │       ├── CMakeLists.txt
│   │   │       ├── JuceLibraryCode/
│   │   │       │   ├── AppConfig.h
│   │   │       │   ├── JuceHeader.h
│   │   │       │   └── ReadMe.txt
│   │   │       ├── Source/
│   │   │       │   └── foo.cpp
│   │   │       └── consoleapp543.jucer
│   │   └── plist-generation/
│   │       ├── .gitignore
│   │       ├── guiapp-MacOSX/
│   │       │   ├── CMakeLists.txt
│   │       │   └── binary_dir/
│   │       │       ├── Info-App-BluetoothUsage-custom.plist
│   │       │       ├── Info-App-BluetoothUsage-default.plist
│   │       │       ├── Info-App-BundleIdentifier.plist
│   │       │       ├── Info-App-CameraUsage-custom.plist
│   │       │       ├── Info-App-CameraUsage-default.plist
│   │       │       ├── Info-App-Copyright-pre-5.2.0.plist
│   │       │       ├── Info-App-Copyright.plist
│   │       │       ├── Info-App-DocumentTypes.plist
│   │       │       ├── Info-App-ExporterBundleIdentifier.plist
│   │       │       ├── Info-App-IconFile.plist
│   │       │       ├── Info-App-MicrophoneUsage-custom.plist
│   │       │       ├── Info-App-MicrophoneUsage-default.plist
│   │       │       ├── Info-App-SendAppleEvents-custom.plist
│   │       │       ├── Info-App-SendAppleEvents-default.plist
│   │       │       ├── Info-App-Version.plist
│   │       │       ├── Info-App-default.plist
│   │       │       └── Info-App-pre-5.2.0.plist
│   │       ├── guiapp-iOS/
│   │       │   ├── CMakeLists.txt
│   │       │   └── binary_dir/
│   │       │       ├── Info-App-AllBackgroundCapabilities.plist
│   │       │       ├── Info-App-AudioBackgroundCapability.plist
│   │       │       ├── Info-App-BluetoothMIDIBackgroundCapability.plist
│   │       │       ├── Info-App-BluetoothUsage-custom.plist
│   │       │       ├── Info-App-BluetoothUsage-default.plist
│   │       │       ├── Info-App-BundleIdentifier.plist
│   │       │       ├── Info-App-CameraUsage-custom.plist
│   │       │       ├── Info-App-CameraUsage-default.plist
│   │       │       ├── Info-App-Copyright.plist
│   │       │       ├── Info-App-ExporterBundleIdentifier.plist
│   │       │       ├── Info-App-FileSharingEnabled.plist
│   │       │       ├── Info-App-MicrophoneUsage-custom.plist
│   │       │       ├── Info-App-MicrophoneUsage-default.plist
│   │       │       ├── Info-App-PushNotificationsCapability.plist
│   │       │       ├── Info-App-RequiresFullScreen-off.plist
│   │       │       ├── Info-App-ScreenOrientations-default.plist
│   │       │       ├── Info-App-ScreenOrientations-different.plist
│   │       │       ├── Info-App-ScreenOrientations-identical.plist
│   │       │       ├── Info-App-StatusBarHidden-pre-6.0.8.plist
│   │       │       ├── Info-App-StatusBarHidden.plist
│   │       │       ├── Info-App-SupportDocumentBrowser.plist
│   │       │       ├── Info-App-Version.plist
│   │       │       ├── Info-App-default.plist
│   │       │       └── Info-App-pre-6.0.8.plist
│   │       ├── plugin-MacOSX/
│   │       │   ├── CMakeLists.txt
│   │       │   └── binary_dir/
│   │       │       ├── Info-AAX-default.plist
│   │       │       ├── Info-AU-default.plist
│   │       │       ├── Info-AU-factoryFunction.plist
│   │       │       ├── Info-AU-pre-5.4.0.plist
│   │       │       ├── Info-AU-sandboxSafe.plist
│   │       │       ├── Info-AUv3_AppExtension-ExporterBundleIdentifier.plist
│   │       │       ├── Info-AUv3_AppExtension-Synth.plist
│   │       │       ├── Info-AUv3_AppExtension-default.plist
│   │       │       ├── Info-AUv3_AppExtension-factoryFunction.plist
│   │       │       ├── Info-AUv3_AppExtension-pre-5.0.0.plist
│   │       │       ├── Info-AUv3_Standalone-pre-5.0.0.plist
│   │       │       ├── Info-RTAS-default.plist
│   │       │       ├── Info-Standalone_Plugin-default.plist
│   │       │       ├── Info-Unity_Plugin-default.plist
│   │       │       ├── Info-VST-default.plist
│   │       │       ├── Info-VST3-default.plist
│   │       │       └── Info-VST3-pre-5.2.0.plist
│   │       └── plugin-iOS/
│   │           ├── CMakeLists.txt
│   │           └── binary_dir/
│   │               ├── Info-AUv3_AppExtension-ExporterBundleIdentifier.plist
│   │               ├── Info-AUv3_AppExtension-Synth.plist
│   │               ├── Info-AUv3_AppExtension-default.plist
│   │               ├── Info-AUv3_AppExtension-factoryFunction.plist
│   │               ├── Info-AUv3_AppExtension-pre-6.0.8.plist
│   │               ├── Info-Standalone_Plugin-IAA.plist
│   │               └── Info-Standalone_Plugin-default.plist
│   └── test-utils/
│       ├── cmake_make_program/
│       │   └── CMakeLists.txt
│       └── simplediff/
│           ├── simplediff.cmake
│           └── test_simplediff.cmake
└── third-party/
    ├── .clang-format
    └── argh/
        ├── LICENSE
        └── argh.h

================================================
FILE CONTENTS
================================================

================================================
FILE: .appveyor.yml
================================================
branches:
  only:
    - main

clone_depth: 50

environment:
  matrix:
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
      GENERATOR: MinGW Makefiles
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
      GENERATOR: Visual Studio 12 2013
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
      GENERATOR: Visual Studio 14 2015
    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
      GENERATOR: Visual Studio 15 2017

install:
  - cmake --version

  - git clone --branch=4.2.0 --depth=1 --single-branch
    -- https://github.com/juce-framework/JUCE.git ci/tmp/JUCE-4.2.0
  - git clone --branch=4.3.1 --depth=1 --single-branch
    -- https://github.com/juce-framework/JUCE.git ci/tmp/JUCE-4.3.1
  - git clone --branch=5.0.0 --depth=1 --single-branch
    -- https://github.com/juce-framework/JUCE.git ci/tmp/JUCE-5.0.0
  - git clone --branch=5.2.1 --depth=1 --single-branch
    -- https://github.com/juce-framework/JUCE.git ci/tmp/JUCE-5.2.1
  - git clone --branch=5.3.1 --depth=1 --single-branch
    -- https://github.com/juce-framework/JUCE.git ci/tmp/JUCE-5.3.1
  - git clone --branch=5.4.3 --depth=1 --single-branch
    -- https://github.com/juce-framework/JUCE.git ci/tmp/JUCE-5.4.3
  - git clone --branch=5.4.7 --depth=1 --single-branch
    -- https://github.com/juce-framework/JUCE.git ci/tmp/JUCE-5.4.7
  - git clone --branch=6.0.5 --depth=1 --single-branch
    -- https://github.com/juce-framework/JUCE.git ci/tmp/JUCE-6.0.5
  - git clone --branch=6.1.6 --depth=1 --single-branch
    -- https://github.com/juce-framework/JUCE.git ci/tmp/JUCE-6.1.6
  - git clone --branch=7.0.7 --depth=1 --single-branch
    -- https://github.com/juce-framework/JUCE.git ci/tmp/JUCE-7.0.7

for:
  - matrix:
      only:
        - GENERATOR: MinGW Makefiles

    build_script:
      - set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
      - set PATH=C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%

      - mkdir %APPVEYOR_BUILD_FOLDER%\build_Debug
      - mkdir %APPVEYOR_BUILD_FOLDER%\build_Release

      # Configure and build FRUT with JUCE 4.2.0
      - cd %APPVEYOR_BUILD_FOLDER%\build_Debug
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-4.2.0"
      - cmake --build . --parallel
      - cd %APPVEYOR_BUILD_FOLDER%\build_Release
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-4.2.0"

      # Configure and build FRUT with JUCE 4.3.1
      - cd %APPVEYOR_BUILD_FOLDER%\build_Debug
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-4.3.1"
      - cmake --build . --parallel
      - cd %APPVEYOR_BUILD_FOLDER%\build_Release
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-4.3.1"

      # JUCE 5.0.0 doesn't build with MinGW due to some undeclared symbols in
      # modules/juce_gui_basics/native/juce_win32_Windowing.cpp

      # Configure and build FRUT with JUCE 5.2.1
      - cd %APPVEYOR_BUILD_FOLDER%\build_Debug
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.2.1"
      - cmake --build . --parallel
      - cd %APPVEYOR_BUILD_FOLDER%\build_Release
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.2.1"

      # JUCE 5.3.1 doesn't build with MinGW due to some undeclared symbols in
      # modules/juce_core/native/juce_win32_Files.cpp

      # Configure and build FRUT with JUCE 5.4.3
      - cd %APPVEYOR_BUILD_FOLDER%\build_Debug
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.4.3"
      - cmake --build . --parallel
      - cd %APPVEYOR_BUILD_FOLDER%\build_Release
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.4.3"

      # Configure and build FRUT with JUCE 5.4.7
      - cd %APPVEYOR_BUILD_FOLDER%\build_Debug
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.4.7"
      - cmake --build . --parallel
      - cd %APPVEYOR_BUILD_FOLDER%\build_Release
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.4.7"

      # Configure and build FRUT with JUCE 6.0.5
      - cd %APPVEYOR_BUILD_FOLDER%\build_Debug
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-6.0.5"
      - cmake --build . --parallel
      - cd %APPVEYOR_BUILD_FOLDER%\build_Release
      - >
        cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
        -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-6.0.5"

      # JUCE 6.1.6 doesn't build with MinGW 5.3.0 due to how juce::UUIDGetter is defined
      # in juce_core/native/juce_win32_ComSmartPtr.h

      # Build and install FRUT in ./prefix
      - cmake .. -DCMAKE_INSTALL_PREFIX="%APPVEYOR_BUILD_FOLDER%/prefix"
      - cmake --build . --target install --parallel

    test_script:
      # Check that generated CMakeLists.txt files are up-to-date
      - cd %APPVEYOR_BUILD_FOLDER%
      - >
        cmake -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P Jucer2CMake/tests/apply-Jucer2CMake-juce6-to-test-jucers.cmake
      - >
        cmake -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P ci/apply-Jucer2CMake-reprojucer-to-test-jucers.cmake
      - >
        cmake -DJUCE_VERSION="4.2.0"
        -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
      - >
        cmake -DJUCE_VERSION="4.3.1"
        -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
      - >
        cmake -DJUCE_VERSION="5.0.0"
        -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
      - >
        cmake -DJUCE_VERSION="5.2.1"
        -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
      - >
        cmake -DJUCE_VERSION="5.3.1"
        -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
      - >
        cmake -DJUCE_VERSION="5.4.3"
        -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
      - >
        cmake -DJUCE_VERSION="5.4.7"
        -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
      - >
        cmake -DJUCE_VERSION="6.0.5"
        -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
      - >
        cmake -DJUCE_VERSION="6.1.6"
        -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
        -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
      - git diff --exit-code

  - matrix:
      only:
        - GENERATOR: Visual Studio 12 2013

    build_script:
      - mkdir %APPVEYOR_BUILD_FOLDER%\build
      - cd %APPVEYOR_BUILD_FOLDER%\build

      # Configure and build FRUT with JUCE 4.2.0
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-4.2.0"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 4.3.1
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-4.3.1"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 5.0.0
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.0.0"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 5.2.1
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.2.1"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 5.3.1
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.3.1"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 5.4.3
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.4.3"
      - cmake --build . --config Debug --parallel

      # JUCE 5.4.3 is the last JUCE version that supports Visual Studio 2013

      # Build and install FRUT in ./prefix
      - cmake .. -DCMAKE_INSTALL_PREFIX="%APPVEYOR_BUILD_FOLDER%/prefix"
      - cmake --build . --config Release --target install --parallel

  - matrix:
      only:
        - GENERATOR: Visual Studio 14 2015

    build_script:
      - mkdir %APPVEYOR_BUILD_FOLDER%\build
      - cd %APPVEYOR_BUILD_FOLDER%\build

      # Configure and build FRUT with JUCE 4.2.0
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-4.2.0"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 4.3.1
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-4.3.1"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 5.0.0
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.0.0"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 5.2.1
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.2.1"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 5.3.1
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.3.1"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 5.4.3
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.4.3"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 5.4.7
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.4.7"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 6.0.5
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-6.0.5"
      - cmake --build . --config Debug --parallel

      # Configure and build FRUT with JUCE 6.1.6
      - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-6.1.6"
      - cmake --build . --config Debug --parallel

      # JUCE 6.1.6 is the last JUCE version that supports Visual Studio 2015

      # Build and install FRUT in ./prefix
      - cmake .. -DCMAKE_INSTALL_PREFIX="%APPVEYOR_BUILD_FOLDER%/prefix"
      - cmake --build . --config Release --target install --parallel


build_script:
  - mkdir %APPVEYOR_BUILD_FOLDER%\build
  - cd %APPVEYOR_BUILD_FOLDER%\build

  # Configure and build FRUT with JUCE 4.2.0
  - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-4.2.0"
  - cmake --build . --config Debug --parallel

  # Configure and build FRUT with JUCE 4.3.1
  - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-4.3.1"
  - cmake --build . --config Debug --parallel

  # Configure and build FRUT with JUCE 5.0.0
  - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.0.0"
  - cmake --build . --config Debug --parallel

  # Configure and build FRUT with JUCE 5.2.1
  - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.2.1"
  - cmake --build . --config Debug --parallel

  # Configure and build FRUT with JUCE 5.3.1
  - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.3.1"
  - cmake --build . --config Debug --parallel

  # Configure and build FRUT with JUCE 5.4.3
  - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.4.3"
  - cmake --build . --config Debug --parallel

  # Configure and build FRUT with JUCE 5.4.7
  - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-5.4.7"
  - cmake --build . --config Debug --parallel

  # Configure and build FRUT with JUCE 6.0.5
  - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-6.0.5"
  - cmake --build . --config Debug --parallel

  # Configure and build FRUT with JUCE 6.1.6
  - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-6.1.6"
  - cmake --build . --config Debug --parallel

  # Configure and build FRUT with JUCE 7.0.7
  - cmake .. -G "%GENERATOR%" -DJUCE_ROOT="%APPVEYOR_BUILD_FOLDER%/ci/tmp/JUCE-7.0.7"
  - cmake --build . --config Debug --parallel

  # Build and install FRUT in ./prefix
  - cmake .. -DCMAKE_INSTALL_PREFIX="%APPVEYOR_BUILD_FOLDER%/prefix"
  - cmake --build . --config Release --target install --parallel

test_script:
  # Check that generated CMakeLists.txt files are up-to-date
  - cd %APPVEYOR_BUILD_FOLDER%
  - >
    cmake -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P Jucer2CMake/tests/apply-Jucer2CMake-juce6-to-test-jucers.cmake
  - >
    cmake -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-test-jucers.cmake
  - >
    cmake -DJUCE_VERSION="4.2.0"
    -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
  - >
    cmake -DJUCE_VERSION="4.3.1"
    -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
  - >
    cmake -DJUCE_VERSION="5.0.0"
    -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
  - >
    cmake -DJUCE_VERSION="5.2.1"
    -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
  - >
    cmake -DJUCE_VERSION="5.3.1"
    -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
  - >
    cmake -DJUCE_VERSION="5.4.3"
    -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
  - >
    cmake -DJUCE_VERSION="5.4.7"
    -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
  - >
    cmake -DJUCE_VERSION="6.0.5"
    -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
  - >
    cmake -DJUCE_VERSION="6.1.6"
    -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
  - >
    cmake -DJUCE_VERSION="7.0.7"
    -DJucer2CMake_EXE="prefix/FRUT/bin/Jucer2CMake.exe"
    -P ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
  - git diff --quiet

  - mkdir %APPVEYOR_BUILD_FOLDER%\ci\AllJuceProjects\build
  - cd %APPVEYOR_BUILD_FOLDER%\ci\AllJuceProjects\build

  # Configure all JUCE 4.2.0 projects
  - >
    cmake .. -G "%GENERATOR%" -DJUCE_VERSION="4.2.0"
    -DJUCER_AAX_SDK_FOLDER="%APPVEYOR_BUILD_FOLDER%/ci/fake-SDKs/AAX"
    -DJUCER_VST3_SDK_FOLDER="%APPVEYOR_BUILD_FOLDER%/ci/fake-SDKs/VST3"
    -DJUCER_VST_SDK_FOLDER="%APPVEYOR_BUILD_FOLDER%/ci/fake-SDKs/VST"

  # Configure all JUCE 4.3.1 projects
  - >
    cmake .. -G "%GENERATOR%" -DJUCE_VERSION="4.3.1"
    -DJUCER_AAX_SDK_FOLDER="%APPVEYOR_BUILD_FOLDER%/ci/fake-SDKs/AAX"
    -DJUCER_VST3_SDK_FOLDER="%APPVEYOR_BUILD_FOLDER%/ci/fake-SDKs/VST3"

  # Configure all JUCE 5.0.0 projects
  - >
    cmake .. -G "%GENERATOR%" -DJUCE_VERSION="5.0.0"
    -DJUCER_AAX_SDK_FOLDER="%APPVEYOR_BUILD_FOLDER%/ci/fake-SDKs/AAX"
    -DJUCER_VST3_SDK_FOLDER="%APPVEYOR_BUILD_FOLDER%/ci/fake-SDKs/VST3"

  # Configure all JUCE 5.2.1 projects
  - >
    cmake .. -G "%GENERATOR%" -DJUCE_VERSION="5.2.1"
    -DJUCER_AAX_SDK_FOLDER="%APPVEYOR_BUILD_FOLDER%/ci/fake-SDKs/AAX"
    -DJUCER_VST3_SDK_FOLDER="%APPVEYOR_BUILD_FOLDER%/ci/fake-SDKs/VST3"

  # Configure all JUCE 5.3.1 projects
  - >
    cmake .. -G "%GENERATOR%" -DJUCE_VERSION="5.3.1"
    -DJUCER_VST3_SDK_FOLDER="%APPVEYOR_BUILD_FOLDER%/ci/fake-SDKs/VST3"

  # Configure all JUCE 5.4.3 projects
  - cmake .. -G "%GENERATOR%" -DJUCE_VERSION="5.4.3"

  # Configure all JUCE 5.4.7 projects
  - cmake .. -G "%GENERATOR%" -DJUCE_VERSION="5.4.7"

  # Configure all JUCE 6.0.5 projects
  - cmake .. -G "%GENERATOR%" -DJUCE_VERSION="6.0.5"

  # Configure all JUCE 6.1.6 projects
  - cmake .. -G "%GENERATOR%" -DJUCE_VERSION="6.1.6"

  # Configure all JUCE 7.0.7 projects
  - cmake .. -G "%GENERATOR%" -DJUCE_VERSION="7.0.7"


================================================
FILE: .azure-pipelines.yml
================================================
trigger:
  branches:
    include:
      - main

parameters:
  - name: juceVersions
    type: object
    default: [4.2.0, 4.3.1, 5.0.0, 5.2.1, 5.3.1, 5.4.3, 5.4.7, 6.0.5, 6.1.6, 7.0.7]

jobs:
  - job: iOS
    displayName: iOS / Xcode
    pool:
      vmImage: macOS-13
    steps:
      - template: ci/azure-pipelines/steps-iOS.yml
        parameters:
          juceVersions: ${{ parameters.juceVersions }}

  - job: Linux_CodeBlocks
    displayName: Linux / CodeBlocks - Unix Makefiles
    pool:
      vmImage: ubuntu-20.04
    variables:
      cmakeGenerator: "CodeBlocks - Unix Makefiles"
    steps:
      - script: >
          sudo apt update && sudo apt install libxcursor-dev libxinerama-dev libxrandr-dev
        displayName: Install apt packages
      - script: >
          sudo apt install gcc-8 g++-8
          && sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 10
          && sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 10
        displayName: Install GCC 8 (old versions of JUCE don't build with GCC 9)
      - template: ci/azure-pipelines/steps-Makefiles.yml
        parameters:
          juceVersions: ${{ parameters.juceVersions }}

  - job: Linux_Make
    displayName: Linux / Unix Makefiles
    pool:
      vmImage: ubuntu-20.04
    variables:
      cmakeGenerator: "Unix Makefiles"
    steps:
      - script: >
          sudo apt update && sudo apt install gcc-8 g++-8 libasound2-dev
          libcurl4-openssl-dev libxcursor-dev libxinerama-dev libxrandr-dev
          libwebkit2gtk-4.0-dev
        displayName: Install apt packages
      - script: >
          sudo apt install gcc-8 g++-8
          && sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 10
          && sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 10
        displayName: Install GCC 8 (old versions of JUCE don't build with GCC 9)
      - template: ci/azure-pipelines/steps-Makefiles.yml
        parameters:
          juceVersions: ${{ parameters.juceVersions }}

  - job: macOS_Make
    displayName: macOS / Unix Makefiles
    pool:
      vmImage: macOS-12
    variables:
      cmakeGenerator: "Unix Makefiles"
    steps:
      - template: ci/azure-pipelines/steps-Makefiles.yml
        parameters:
          juceVersions: ${{ parameters.juceVersions }}

  - job: macOS_Xcode
    displayName: macOS / Xcode
    pool:
      vmImage: macOS-12
    steps:
      - template: ci/azure-pipelines/steps-Xcode.yml
        parameters:
          juceVersions: ${{ parameters.juceVersions }}

  - job: Windows_VS2019
    displayName: Windows / Visual Studio 2019
    pool:
      vmImage: windows-2019
    variables:
      cmakeGenerator: "Visual Studio 16 2019"
    steps:
      - template: ci/azure-pipelines/steps-VS.yml
        parameters:
          juceVersions: ${{ parameters.juceVersions }}

  - job: Windows_VS2022
    displayName: Windows / Visual Studio 2022
    pool:
      vmImage: windows-2022
    variables:
      cmakeGenerator: "Visual Studio 17 2022"
    steps:
      - template: ci/azure-pipelines/steps-VS.yml
        parameters:
          juceVersions: ${{ parameters.juceVersions }}


================================================
FILE: .cirrus.yml
================================================
task:
  name: clang-format

  only_if: $CIRRUS_BASE_BRANCH == "main" || $CIRRUS_BRANCH == "main"

  container:
    image: rsmmr/clang:9.0

  test_script:
    - clang-format -version
    - 'git ls-files {Jucer2CMake/src,cmake/tools}/"*."{cpp,h,hpp}
      | xargs -d\\n clang-format -i -style=file -verbose'
    - git diff --exit-code


================================================
FILE: .clang-format
================================================
# Using clang-format 9.0.0

AllowShortFunctionsOnASingleLine: false
AlwaysBreakTemplateDeclarations: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Allman
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 90
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
IndentPPDirectives: BeforeHash
MaxEmptyLinesToKeep: 2
PenaltyReturnTypeOnItsOwnLine: 120
PointerAlignment: Left


================================================
FILE: .github/pull_request_template.md
================================================
Before pressing the "Create pull request" button:
- double-check that docs are up-to-date
- delete this list


================================================
FILE: .gitignore
================================================
*build/
*prefix/
.DS_Store
/ci/tmp/
/cmake/bin/


================================================
FILE: .readthedocs.yaml
================================================
version: 2

sphinx:
  configuration: "docs/conf.py"

python:
  install:
    - requirements: "docs/requirements.txt"


================================================
FILE: CMakeLists.txt
================================================
# Copyright (C) 2018-2021  Alain Martin
#
# This file is part of FRUT.
#
# FRUT 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.
#
# FRUT 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 FRUT.  If not, see <http://www.gnu.org/licenses/>.

cmake_minimum_required(VERSION 3.4)

project(FRUT)


add_subdirectory(Jucer2CMake)


set(JUCE_modules_DIRS "${JUCE_ROOT}/modules")

add_subdirectory(cmake/tools)

install(FILES "${CMAKE_CURRENT_LIST_DIR}/cmake/Reprojucer.cmake" DESTINATION "FRUT/cmake")

install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/cmake/data" DESTINATION "FRUT/cmake")


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
 advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
 address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
 professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at amartin@keytrol.org. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq


================================================
FILE: CONTRIBUTING.md
================================================
# How to contribute to FRUT?

Contributions to FRUT are very welcomed and you can contribute even if you don't know
anything about CMake.


## Just do it!

You can simply convert your existing JUCE projects using `Jucer2CMake` and build them
using CMake (see https://github.com/McMartin/FRUT#getting-started). Then create issues
(https://github.com/McMartin/FRUT/issues/new) to report any unwanted differences with how
your projects are usually built when using Projucer.


## Show your interest

Several existing issues are labeled ["missing feature"][missing-feature-issues] and are
only waiting for you to comment on them to express your interest for these features. If
FRUT is missing another feature that you need and there is no issue for that feature, feel
free to create one!


## Help needed

Some of the issues are also labeled ["help wanted"][help-wanted-issues] because they
concern features that require acquiring third-party SDKs and tools. We need developers who
are familiar with these SDKs and tools to build and test theirs JUCE projects while we are
adding these features to FRUT.


[help-wanted-issues]: https://github.com/McMartin/FRUT/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22
[missing-feature-issues]: https://github.com/McMartin/FRUT/issues?q=is%3Aissue+is%3Aopen+label%3A%22missing+feature%22


================================================
FILE: Jucer2CMake/CMakeLists.txt
================================================
# Copyright (C) 2020-2023  Alain Martin
#
# This file is part of FRUT.
#
# FRUT 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.
#
# FRUT 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 FRUT.  If not, see <http://www.gnu.org/licenses/>.

cmake_minimum_required(VERSION 3.4)


if(NOT DEFINED JUCE_ROOT)
  message(FATAL_ERROR "JUCE_ROOT must be defined")
endif()

get_filename_component(JUCE_ROOT "${JUCE_ROOT}" ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")

if(NOT IS_DIRECTORY "${JUCE_ROOT}")
  message(FATAL_ERROR "No such directory: ${JUCE_ROOT}")
endif()


project(Jucer2CMake)


if(NOT DEFINED CMAKE_CONFIGURATION_TYPES)
  if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
    message(STATUS "Setting CMAKE_BUILD_TYPE to \"Debug\" as it was not specified.")
    set(CMAKE_BUILD_TYPE Debug)
  endif()
endif()


set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 17)


add_library(Jucer2CMake_JUCE STATIC "")

if(APPLE)
  target_sources(Jucer2CMake_JUCE PRIVATE "${JUCE_ROOT}/modules/juce_core/juce_core.mm")
else()
  target_sources(Jucer2CMake_JUCE PRIVATE "${JUCE_ROOT}/modules/juce_core/juce_core.cpp")
endif()

target_include_directories(Jucer2CMake_JUCE PUBLIC "${JUCE_ROOT}/modules")

target_compile_definitions(Jucer2CMake_JUCE PUBLIC
  $<$<CONFIG:Debug>:DEBUG=1>
  $<$<CONFIG:Debug>:_DEBUG=1>
  $<$<NOT:$<CONFIG:Debug>>:NDEBUG=1>
  JUCE_DISABLE_JUCE_VERSION_PRINTING=1
  JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1
  JUCE_MODULE_AVAILABLE_juce_core=1
  JUCE_STANDALONE_APPLICATION=1
  JUCE_USE_CURL=0
)

if(APPLE)
  target_compile_options(Jucer2CMake_JUCE PRIVATE
    -Wno-deprecated-declarations
    -Wno-register
  )

  find_library(Cocoa_framework "Cocoa")
  find_library(Foundation_framework "Foundation")
  find_library(IOKit_framework "IOKit")
  find_library(Security_framework "Security")

  target_link_libraries(Jucer2CMake_JUCE PUBLIC
    ${Cocoa_framework} ${Foundation_framework} ${IOKit_framework} ${Security_framework}
  )
endif()

if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
  target_compile_options(Jucer2CMake_JUCE PUBLIC -pthread)
  target_link_libraries(Jucer2CMake_JUCE PUBLIC dl pthread)
endif()

if(WIN32 AND NOT MSVC)
  target_compile_options(Jucer2CMake_JUCE PRIVATE -Wno-cpp)

  target_link_libraries(Jucer2CMake_JUCE PUBLIC
    -lshlwapi -lversion -lwininet -lwinmm -lws2_32
  )
endif()


option(Jucer2CMake_WRITE_CRLF_LINE_ENDINGS
  "Write CR+LF line endings in generated CMakeLists.txt files"
  OFF
)

set(Jucer2CMake_JUCE_LICENSE "Personal" CACHE STRING
  "JUCE License. Changes the default value for settings that depend on the license."
)
set_property(CACHE Jucer2CMake_JUCE_LICENSE PROPERTY STRINGS
  "Education" "GPL" "Indie" "Personal" "Pro"
)
string(CONCAT is_paid_or_gpl "$<OR:"
  "$<STREQUAL:${Jucer2CMake_JUCE_LICENSE},GPL>,"
  "$<STREQUAL:${Jucer2CMake_JUCE_LICENSE},Indie>,"
  "$<STREQUAL:${Jucer2CMake_JUCE_LICENSE},Pro>>"
)

add_executable(Jucer2CMake "${CMAKE_CURRENT_LIST_DIR}/src/main.cpp")

target_include_directories(Jucer2CMake PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../third-party")

target_compile_definitions(Jucer2CMake PRIVATE
  IS_PAID_OR_GPL=${is_paid_or_gpl}
  WRITE_CRLF_LINE_ENDINGS=$<BOOL:${Jucer2CMake_WRITE_CRLF_LINE_ENDINGS}>
)

target_link_libraries(Jucer2CMake PRIVATE Jucer2CMake_JUCE)

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  target_compile_options(Jucer2CMake PRIVATE
    -Werror
    -Weverything
    -Wno-c++98-compat
    -Wno-c++98-compat-pedantic
    -Wno-exit-time-destructors
    -Wno-padded
  )
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  target_compile_options(Jucer2CMake PRIVATE -Werror -Wall -Wextra)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
  target_compile_options(Jucer2CMake PRIVATE /WX /W4 /wd4512)
endif()

install(TARGETS Jucer2CMake DESTINATION "FRUT/bin")


================================================
FILE: Jucer2CMake/src/argh.hpp
================================================
// Copyright (C) 2021  Alain Martin
//
// This file is part of FRUT.
//
// FRUT 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.
//
// FRUT 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 FRUT.  If not, see <http://www.gnu.org/licenses/>.

#pragma once

#if defined(__clang__)
  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Wsign-conversion"

#elif defined(__GNUC__)
  #pragma GCC diagnostic push

#elif defined(_MSC_VER)
  #pragma warning(push)
  #pragma warning(disable : 4800)

#endif

#include <argh/argh.h>

#if defined(__clang__)
  #pragma clang diagnostic pop
#elif defined(__GNUC__)
  #pragma GCC diagnostic pop
#elif defined(_MSC_VER)
  #pragma warning(pop)
#endif


================================================
FILE: Jucer2CMake/src/juce6.hpp
================================================
// Copyright (C) 2021  Alain Martin
//
// This file is part of FRUT.
//
// FRUT 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.
//
// FRUT 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 FRUT.  If not, see <http://www.gnu.org/licenses/>.

#pragma once

#include "utils.hpp"

#include "juce_core.hpp"

#include <cstdlib>
#include <functional>


namespace Jucer2CMake
{

inline const juce::XmlElement& getRequiredChild(const juce::XmlElement& element,
                                                const juce::StringRef childName)
{
  if (const auto pChild = element.getChildByName(childName))
  {
    return *pChild;
  }

  printError(element.getTagName() + " element doesn't have " + childName
             + " child element.");
  throw ExitException{1};
}


inline bool hasModule(const juce::XmlElement& modules, const juce::StringRef moduleId)
{
  for (auto pModule = modules.getFirstChildElement(); pModule != nullptr;
       pModule = pModule->getNextElement())
  {
    if (pModule->isTextElement())
    {
      continue;
    }

    if (pModule->getStringAttribute("id") == moduleId)
    {
      return true;
    }
  }

  return false;
}


inline bool isJuceOptionEnabled(const juce::XmlElement& juceOptions,
                                const juce::StringRef optionName)
{
  return juceOptions.hasAttribute(optionName)
         && toBoolLikeVar(juceOptions.getStringAttribute(optionName));
}


inline void writeJuce6CMakeLists(const Arguments&, const juce::XmlElement& jucerProject,
                                 juce::MemoryOutputStream& outputStream)
{
  LineWriter wLn{outputStream};

  const auto& projectType = jucerProject.getStringAttribute("projectType");
  const auto& jucerProjectName = jucerProject.getStringAttribute("name");

  // Preamble
  {
    const auto cmakeVersion = projectType == "audioplug" ? "3.15" : "3.12";

    wLn();
    wLn("cmake_minimum_required(VERSION ", cmakeVersion, ")");
    wLn();
    wLn("project(\"", jucerProjectName, "\")");
    wLn();
    wLn();
    wLn("find_package(JUCE CONFIG REQUIRED)");
    wLn();
    wLn();
  }

  const auto& targetName = jucerProjectName;

  const auto& modules = getRequiredChild(jucerProject, "MODULES");
  const auto& juceOptions = getRequiredChild(jucerProject, "JUCEOPTIONS");

  const auto writeProjectSettingIfDefined =
    [&jucerProject, &wLn](juce::StringRef attribute, juce::StringRef keyword) {
      if (jucerProject.hasAttribute(attribute))
      {
        wLn("  ", keyword, " \"", jucerProject.getStringAttribute(attribute), "\"");
      }
    };

  const auto writeKeywordAndList = [&wLn](const juce::StringRef keyword,
                                          const juce::StringArray& values) {
    wLn("  ", keyword);

    for (const auto& item : values)
    {
      wLn("    \"", item, "\"");
    }
  };

  // juce_add_{console_app,gui_app,plugin}
  {
    const auto juceAddFunction = [&projectType]() -> juce::String {
      if (projectType == "guiapp")
        return "juce_add_gui_app";
      if (projectType == "consoleapp")
        return "juce_add_console_app";
      if (projectType == "audioplug")
        return "juce_add_plugin";
      return {};
    }();

    wLn(juceAddFunction, "(", targetName);

    // TODO: PRODUCT_NAME

    wLn("  VERSION \"" + jucerProject.getStringAttribute("version", "1.0.0") + "\"");

    writeProjectSettingIfDefined("bundleIdentifier", "BUNDLE_ID");

    writeProjectSettingIfDefined("companyName", "COMPANY_NAME");
    writeProjectSettingIfDefined("companyCopyright", "COMPANY_COPYRIGHT");
    writeProjectSettingIfDefined("companyWebsite", "COMPANY_WEBSITE");
    writeProjectSettingIfDefined("companyEmail", "COMPANY_EMAIL");

    wLn.needsEmptyLine = true;

    if (projectType == "audioplug")
    {
      const auto formats =
        jucerProject.hasAttribute("pluginFormats")
          ? convertIdsToStrings(
            juce::StringArray::fromTokens(
              jucerProject.getStringAttribute("pluginFormats"), ",", {}),
            {{"buildVST3", "VST3"},
             {"buildAU", "AU"},
             {"buildAUv3", "AUv3"},
             {"buildAAX", "AAX"},
             {"buildStandalone", "Standalone"},
             {"buildUnity", "Unity"},
             {"buildVST", "VST"}})
          : juce::StringArray{"VST3", "AU", "Standalone"};

      if (formats.isEmpty())
      {
        wLn("  # FORMATS");
      }
      else
      {
        writeKeywordAndList("FORMATS", formats);
      }

      writeProjectSettingIfDefined("pluginName", "PLUGIN_NAME");
      writeProjectSettingIfDefined("pluginDesc", "DESCRIPTION");
      writeProjectSettingIfDefined("pluginManufacturerCode", "PLUGIN_MANUFACTURER_CODE");
      writeProjectSettingIfDefined("pluginCode", "PLUGIN_CODE");

      const auto characteristics = juce::StringArray::fromTokens(
        jucerProject.getStringAttribute("pluginCharacteristicsValue"), ",", {});
      if (characteristics.contains("pluginIsSynth"))
      {
        wLn("  IS_SYNTH TRUE");
      }
      if (characteristics.contains("pluginWantsMidiIn"))
      {
        wLn("  NEEDS_MIDI_INPUT TRUE");
      }
      if (characteristics.contains("pluginProducesMidiOut"))
      {
        wLn("  NEEDS_MIDI_OUTPUT TRUE");
      }
      if (characteristics.contains("pluginIsMidiEffectPlugin"))
      {
        wLn("  IS_MIDI_EFFECT TRUE");
      }
      if (characteristics.contains("pluginEditorRequiresKeys"))
      {
        wLn("  EDITOR_WANTS_KEYBOARD_FOCUS TRUE");
      }
      if (characteristics.contains("pluginAAXDisableBypass"))
      {
        wLn("  DISABLE_AAX_BYPASS TRUE");
      }
      if (characteristics.contains("pluginAAXDisableMultiMono"))
      {
        wLn("  DISABLE_AAX_MULTI_MONO TRUE");
      }

      writeProjectSettingIfDefined("aaxIdentifier", "AAX_IDENTIFIER");
      writeProjectSettingIfDefined("pluginAUExportPrefix", "AU_EXPORT_PREFIX");

      if (jucerProject.hasAttribute("pluginAUMainType"))
      {
        wLn("  AU_MAIN_TYPE \"",
            getAUMainTypeConstantFromQuotedFourChars(
              jucerProject.getStringAttribute("pluginAUMainType")),
            "\"");
      }

      if (jucerProject.hasAttribute("pluginAUIsSandboxSafe"))
      {
        wLn("  AU_SANDBOX_SAFE ",
            toBoolLikeVar(jucerProject.getStringAttribute("pluginAUIsSandboxSafe"))
              ? "TRUE"
              : "FALSE");
      }

      writeProjectSettingIfDefined("pluginVSTNumMidiInputs", "VST_NUM_MIDI_INS");
      writeProjectSettingIfDefined("pluginVSTNumMidiOutputs", "VST_NUM_MIDI_OUTS");

      if (jucerProject.hasAttribute("pluginVST3Category"))
      {
        const auto vst3Categories = juce::StringArray::fromTokens(
          jucerProject.getStringAttribute("pluginVST3Category"), ",", {});

        if (vst3Categories.isEmpty())
        {
          wLn("  # VST3_CATEGORIES");
        }
        else
        {
          writeKeywordAndList("VST3_CATEGORIES", vst3Categories);
        }
      }

      // TODO: AAX_CATEGORY

      writeProjectSettingIfDefined("pluginVSTCategory", "VST2_CATEGORY");

      // TODO: COPY_PLUGIN_AFTER_BUILD
      // TODO: VST3_COPY_DIR
      // TODO: AU_COPY_DIR
      // TODO: AAX_COPY_DIR
      // TODO: UNITY_COPY_DIR
      // TODO: VST_COPY_DIR
    }

    wLn.needsEmptyLine = true;

    // TODO: ICON_SMALL
    // TODO: ICON_BIG
    // TODO: CUSTOM_XCASSETS_FOLDER
    // TODO: LAUNCH_STORYBOARD_FILE

    wLn.needsEmptyLine = true;

    // TODO: TARGETED_DEVICE_FAMILY
    // TODO: IPHONE_SCREEN_ORIENTATIONS
    // TODO: IPAD_SCREEN_ORIENTATIONS
    // TODO: FILE_SHARING_ENABLED
    // TODO: DOCUMENT_BROWSER_ENABLED
    // TODO: STATUS_BAR_HIDDEN
    // TODO: REQUIRES_FULL_SCREEN
    // TODO: DOCUMENT_EXTENSIONS
    // TODO: APP_SANDBOX_ENABLED
    // TODO: APP_SANDBOX_INHERIT
    // TODO: APP_SANDBOX_OPTIONS
    // TODO: HARDENED_RUNTIME_ENABLED
    // TODO: HARDENED_RUNTIME_OPTIONS
    // TODO: MICROPHONE_PERMISSION_ENABLED
    // TODO: MICROPHONE_PERMISSION_TEXT
    // TODO: CAMERA_PERMISSION_ENABLED
    // TODO: CAMERA_PERMISSION_TEXT
    // TODO: BLUETOOTH_PERMISSION_ENABLED
    // TODO: BLUETOOTH_PERMISSION_TEXT
    // TODO: SEND_APPLE_EVENTS_PERMISSION_ENABLED
    // TODO: SEND_APPLE_EVENTS_PERMISSION_TEXT
    // TODO: BACKGROUND_AUDIO_ENABLED
    // TODO: BACKGROUND_BLE_ENABLED
    // TODO: APP_GROUPS_ENABLED
    // TODO: APP_GROUP_IDS
    // TODO: ICLOUD_PERMISSIONS_ENABLED
    // TODO: PUSH_NOTIFICATIONS_ENABLED
    // TODO: SUPPRESS_AU_PLIST_RESOURCE_USAGE
    // TODO: PLIST_TO_MERGE

    wLn.needsEmptyLine = true;

    if (hasModule(modules, "juce_core")
        && isJuceOptionEnabled(juceOptions, "JUCE_USE_CURL"))
    {
      wLn("  NEEDS_CURL TRUE");
    }

    // TODO: NEEDS_STORE_KIT

    if (hasModule(modules, "juce_gui_extra")
        && isJuceOptionEnabled(juceOptions, "JUCE_WEB_BROWSER"))
    {
      wLn("  NEEDS_WEB_BROWSER TRUE");
    }

    if (hasModule(modules, "juce_audio_processors")
        && isJuceOptionEnabled(juceOptions, "JUCE_PLUGINHOST_AU"))
    {
      wLn("  PLUGINHOST_AU TRUE");
    }

    wLn.needsEmptyLine = false;
    wLn(")");
    wLn();
  }

  // juce_generate_juce_header
  {
    wLn("juce_generate_juce_header(", targetName, ")");
    wLn();
  }

  const auto kIgnoreCase = false;

  // target_compile_definitions
  {
    const auto scope = projectType == "audioplug" ? "PUBLIC" : "PRIVATE";
    wLn("target_compile_definitions(", targetName);
    wLn("  ", scope);

    juce::StringArray moduleConfigFlags;

    for (auto i = 0, numAttributes = juceOptions.getNumAttributes(); i < numAttributes;
         ++i)
    {
      moduleConfigFlags.add(juceOptions.getAttributeName(i) + "="
                            + juceOptions.getAttributeValue(i));
    }

    if (hasModule(modules, "juce_core") && !juceOptions.hasAttribute("JUCE_USE_CURL"))
    {
      moduleConfigFlags.add("JUCE_USE_CURL=0");
    }
    if (hasModule(modules, "juce_gui_extra")
        && !juceOptions.hasAttribute("JUCE_WEB_BROWSER"))
    {
      moduleConfigFlags.add("JUCE_WEB_BROWSER=0");
    }

    moduleConfigFlags.sort(kIgnoreCase);

    for (const auto& item : moduleConfigFlags)
    {
      wLn("    ", item);
    }

    wLn(")");
    wLn();
  }

  juce::StringArray sources;
  juce::StringArray binarySources;

  std::function<void(const juce::XmlElement&)> processGroup =
    [&processGroup, &sources, &binarySources](const juce::XmlElement& group) {
      for (auto pFileOrGroup = group.getFirstChildElement(); pFileOrGroup != nullptr;
           pFileOrGroup = pFileOrGroup->getNextElement())
      {
        if (pFileOrGroup->isTextElement())
        {
          continue;
        }

        if (pFileOrGroup->hasTagName("FILE"))
        {
          const auto& file = *pFileOrGroup;

          if (file.getStringAttribute("compile").getIntValue() == 1)
          {
            sources.add(file.getStringAttribute("file"));
          }
          if (file.getStringAttribute("resource").getIntValue() == 1)
          {
            binarySources.add(file.getStringAttribute("file"));
          }
        }
        else
        {
          processGroup(*pFileOrGroup);
        }
      }
    };

  processGroup(getRequiredChild(jucerProject, "MAINGROUP"));

  sources.sort(kIgnoreCase);
  binarySources.sort(kIgnoreCase);

  // target_sources
  {
    wLn("target_sources(", targetName);

    writeKeywordAndList("PRIVATE", sources);

    wLn(")");
    wLn();
  }

  // juce_add_binary_data
  if (!binarySources.isEmpty())
  {
    wLn("juce_add_binary_data(", targetName, "_BinaryData");

    writeProjectSettingIfDefined("binaryDataNamespace", "NAMESPACE");

    writeKeywordAndList("SOURCES", binarySources);

    wLn(")");
    wLn();
  }

  // target_link_libraries
  {
    wLn("target_link_libraries(", targetName);
    wLn("  PRIVATE");

    if (!binarySources.isEmpty())
    {
      wLn("    ", targetName, "_BinaryData");
    }

    for (auto pModule = modules.getFirstChildElement(); pModule != nullptr;
         pModule = pModule->getNextElement())
    {
      if (pModule->isTextElement())
      {
        continue;
      }

      wLn("    juce::", pModule->getStringAttribute("id"));
    }

    wLn("  PUBLIC");
    wLn("    juce::juce_recommended_config_flags");
    wLn("    juce::juce_recommended_lto_flags");
    wLn("    juce::juce_recommended_warning_flags");

    wLn(")");
  }
}

} // namespace Jucer2CMake


================================================
FILE: Jucer2CMake/src/juce_core.hpp
================================================
// Copyright (C) 2021-2023  Alain Martin
//
// This file is part of FRUT.
//
// FRUT 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.
//
// FRUT 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 FRUT.  If not, see <http://www.gnu.org/licenses/>.

#pragma once

#if defined(__clang__)
  #pragma clang diagnostic push
  #if __has_warning("-Watomic-implicit-seq-cst")
    #pragma clang diagnostic ignored "-Watomic-implicit-seq-cst"
  #endif
  #pragma clang diagnostic ignored "-Wcast-align"
  #pragma clang diagnostic ignored "-Wcast-qual"
  #pragma clang diagnostic ignored "-Wdocumentation"
  #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
  #pragma clang diagnostic ignored "-Wextra-semi"
  #pragma clang diagnostic ignored "-Wglobal-constructors"
  #pragma clang diagnostic ignored "-Wimplicit-fallthrough"
  #if __has_warning("-Winconsistent-missing-destructor-override")
    #pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override"
  #endif
  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
  #pragma clang diagnostic ignored "-Wold-style-cast"
  #pragma clang diagnostic ignored "-Wsign-conversion"
  #if __has_warning("-Wsuggest-destructor-override")
    #pragma clang diagnostic ignored "-Wsuggest-destructor-override"
  #endif
  #if __has_warning("-Wsuggest-override")
    #pragma clang diagnostic ignored "-Wsuggest-override"
  #endif
  #pragma clang diagnostic ignored "-Wundef"
  #if __has_warning("-Wundefined-func-template")
    #pragma clang diagnostic ignored "-Wundefined-func-template"
  #endif
  #if __has_warning("-Wunused-template")
    #pragma clang diagnostic ignored "-Wunused-template"
  #endif
  #pragma clang diagnostic ignored "-Wweak-vtables"
  #if __has_warning("-Wzero-as-null-pointer-constant")
    #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
  #endif

#elif defined(__GNUC__)
  #pragma GCC diagnostic push
  #if __GNUC__ >= 6
    #pragma GCC diagnostic ignored "-Wmisleading-indentation"
  #endif
  #if __GNUC__ >= 8
    #pragma GCC diagnostic ignored "-Wclass-memaccess"
  #endif

#elif defined(_MSC_VER)
  #pragma warning(push)

#endif

#include <juce_core/juce_core.h>

#if defined(__clang__)
  #pragma clang diagnostic pop
#elif defined(__GNUC__)
  #pragma GCC diagnostic pop
#elif defined(_MSC_VER)
  #pragma warning(pop)
#endif


================================================
FILE: Jucer2CMake/src/main.cpp
================================================
// Copyright (C) 2017-2022  Alain Martin
//
// This file is part of FRUT.
//
// FRUT 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.
//
// FRUT 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 FRUT.  If not, see <http://www.gnu.org/licenses/>.

#include "argh.hpp"
#include "juce6.hpp"
#include "juce_core.hpp"
#include "reprojucer.hpp"
#include "utils.hpp"

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <memory>
#include <utility>


using namespace Jucer2CMake;


namespace
{

Arguments parseArguments(const int argc, const char* const argv[])
{
  const auto knownModes = juce::StringArray{"juce6", "reprojucer"};

  const auto knownFlags = std::map<juce::String, juce::StringArray>{
    {"juce6", {"h", "help"}},
    {"reprojucer", {"h", "help", "relocatable"}},
  };

  const auto knownParams = std::map<juce::String, juce::StringArray>{
    {"juce6", {}},
    {"reprojucer", {"jucer-version", "juce-modules", "user-modules"}},
  };

  argh::parser argumentParser;
  for (const auto& modeAndParams : knownParams)
  {
    for (const auto& param : modeAndParams.second)
    {
      argumentParser.add_param(param.toStdString());
    }
  }
  argumentParser.parse(argc, argv);

  const auto askingForHelp = argumentParser[{"-h", "--help"}];
  auto errorInArguments = false;

  auto mode = juce::String{argumentParser[1]};
  if (argumentParser.size() >= 2 && !knownModes.contains(mode))
  {
    printError("invalid mode \"" + mode + "\"");
    mode = "";
    errorInArguments = true;
  }

  if (!askingForHelp)
  {
    if (argumentParser.size() < 3)
    {
      printError("not enough positional arguments");
      errorInArguments = true;
    }
    else if (argumentParser.size() > 4)
    {
      printError("too many positional arguments");
      errorInArguments = true;
    }
  }

  if (mode.isNotEmpty())
  {
    for (const auto& flag : argumentParser.flags())
    {
      if (knownParams.at(mode).contains(juce::String{flag}))
      {
        printError("expected one argument for \"" + flag + "\"");
        errorInArguments = true;
      }
      else if (!knownFlags.at(mode).contains(juce::String{flag}))
      {
        printError("unknown option \"" + flag + "\"");
        errorInArguments = true;
      }
    }

    for (const auto& paramAndValue : argumentParser.params())
    {
      const auto& param = std::get<0>(paramAndValue);
      if (knownFlags.at(mode).contains(juce::String{param}))
      {
        const auto& value = std::get<1>(paramAndValue);
        printError("unexpected argument \"" + value + "\" for \"" + param + "\"");
        errorInArguments = true;
      }
      else if (!knownParams.at(mode).contains(juce::String{param}))
      {
        printError("unknown option \"" + param + "\"");
        errorInArguments = true;
      }
    }
  }

  const auto noModeUsage =
    askingForHelp ? "usage: Jucer2CMake <mode> <jucer_project_file> [--help] [<args>]\n"
                  : "usage: Jucer2CMake {juce6,reprojucer} <jucer_project_file> "
                    "[--help] [<args>]\n";
  const auto noModeHelpText =
    "\n"
    "Converts a .jucer file into a CMakeLists.txt file.\n"
    "The CMakeLists.txt file is written next to the .jucer file (juce6 mode) or in\n"
    "the current working directory (reprojucer mode).\n"
    "\n"
    "    <mode>                    what the generated CMakeLists.txt uses:\n"
    "      juce6                     - JUCE 6's CMake support\n"
    "      reprojucer                - FRUT's Reprojucer\n"
    "\n"
    "    <jucer_project_file>      path to the .jucer file to convert\n"
    "\n"
    "    -h, --help                show this help message and exit\n";

  const auto juce6Usage = "usage: Jucer2CMake juce6 <jucer_project_file> [--help]\n";
  const auto juce6HelpText =
    "\n"
    "Converts a .jucer file into a CMakeLists.txt file that uses JUCE 6's CMake\n"
    "support.\n"
    "The CMakeLists.txt file is written next to the .jucer file.\n"
    "\n"
    "    <jucer_project_file>      path to the .jucer file to convert\n"
    "\n"
    "    -h, --help                show this help message and exit\n";

  const auto reprojucerUsage =
    "usage: Jucer2CMake reprojucer <jucer_project_file> [<Reprojucer.cmake_file>]\n"
    "                   [--help] [--juce-modules=<path>] [--user-modules=<path>]\n"
    "                   [--relocatable]\n";
  const auto reprojucerHelpText =
    "\n"
    "Converts a .jucer file into a CMakeLists.txt file that uses Reprojucer.cmake.\n"
    "The CMakeLists.txt file is written in the current working directory.\n"
    "\n"
    "    <jucer_project_file>      path to the .jucer file to convert\n"
    "    <Reprojucer.cmake_file>   path to Reprojucer.cmake\n"
    "\n"
    "    -h, --help                show this help message and exit\n"
    "    --jucer-version <version> version of Projucer that last saved the .jucer file\n"
    "    --juce-modules <path>     global path to JUCE modules\n"
    "    --user-modules <path>     global path to user modules\n"
    "    --relocatable             makes the CMakeLists.txt file independent from\n"
    "                              the location of the .jucer file, but requires\n"
    "                              defining a variable when calling cmake\n";

  const auto usage = std::map<juce::String, const char*>{
    {"", noModeUsage}, {"juce6", juce6Usage}, {"reprojucer", reprojucerUsage}};
  const auto helpText = std::map<juce::String, const char*>{
    {"", noModeHelpText}, {"juce6", juce6HelpText}, {"reprojucer", reprojucerHelpText}};

  if (askingForHelp || errorInArguments)
  {
    std::cerr << usage.at(mode) << std::flush;

    if (askingForHelp)
    {
      std::cerr << helpText.at(mode) << std::flush;
    }

    throw ExitException{askingForHelp ? 0 : 1};
  }

  const auto existingFilePath = [&argumentParser](juce::StringRef name, size_t index) {
    if (argumentParser.size() > index)
    {
      auto path = juce::String{argumentParser[index]};
      if (path.isEmpty() || !getChildFileFromWorkingDirectory(path).existsAsFile())
      {
        printError("No such file (" + name + "): '" + path + "'");
        throw ExitException{1};
      }
      return path;
    }
    return juce::String{};
  };

  auto jucerFilePath = existingFilePath("<jucer_project_file>", 2);
  auto reprojucerFilePath = existingFilePath("<Reprojucer.cmake_file>", 3);

  auto jucerVersion = juce::String{argumentParser("--jucer-version", "").str()};

  const auto existingDirectoryPath = [&argumentParser](const std::string& name) {
    if (const auto stream = argumentParser(name))
    {
      auto path = juce::String{stream.str()};
      if (path.isEmpty() || !getChildFileFromWorkingDirectory(path).isDirectory())
      {
        printError("No such directory (" + juce::String{name} + "): '" + path + "'");
        throw ExitException{1};
      }
      return path;
    }
    return juce::String{};
  };

  auto juceModulesPath = existingDirectoryPath("--juce-modules");
  auto userModulesPath = existingDirectoryPath("--user-modules");

  auto outputDir =
    mode == "juce6" ? getChildFileFromWorkingDirectory(jucerFilePath).getParentDirectory()
                    : juce::File::getCurrentWorkingDirectory();

  return {std::move(mode),
          std::move(jucerFilePath),
          std::move(reprojucerFilePath),
          std::move(jucerVersion),
          std::move(juceModulesPath),
          std::move(userModulesPath),
          std::move(outputDir),
          argumentParser["--relocatable"]};
}

} // namespace


int main(int argc, char* argv[])
{
  try
  {
    const auto args = parseArguments(argc, argv);

    const auto jucerFile = getChildFileFromWorkingDirectory(args.jucerFilePath);

    const auto pJucerProject =
      std::unique_ptr<juce::XmlElement>{juce::XmlDocument::parse(jucerFile)};
    if (pJucerProject == nullptr || !pJucerProject->hasTagName("JUCERPROJECT"))
    {
      printError("'" + args.jucerFilePath + "' is not a valid Jucer project.");
      return 1;
    }

    const auto& jucerProject = *pJucerProject;

    juce::MemoryOutputStream outputStream;

    outputStream << "# This file was generated by FRUT's Jucer2CMake from \""
                 << jucerFile.getFileName() << "\"\n";

    if (args.mode == "juce6")
    {
      writeJuce6CMakeLists(args, jucerProject, outputStream);
    }
    else if (args.mode == "reprojucer")
    {
      writeReprojucerCMakeLists(args, jucerProject, outputStream);
    }
    else
    {
      printError("There is a bug in Jucer2CMake's CLI!");
      return 1;
    }

    const auto outputFile = args.outputDir.getChildFile("CMakeLists.txt");

    std::unique_ptr<juce::FileInputStream> fileStream{outputFile.createInputStream()};
    if (fileStream)
    {
      juce::MemoryOutputStream fileContents;
      fileContents.writeFromInputStream(*fileStream, -1);

      if (fileContents.getDataSize() == outputStream.getDataSize()
          && std::memcmp(fileContents.getData(), outputStream.getData(),
                         fileContents.getDataSize())
               == 0)
      {
        std::cout << outputFile.getFullPathName() << " is already up-to-date."
                  << std::endl;
        return 0;
      }
    }

    if (outputFile.replaceWithData(outputStream.getData(), outputStream.getDataSize()))
    {
      std::cout << outputFile.getFullPathName() << " has been successfully generated."
                << std::endl;
    }
    else
    {
      printError("Failed to write to " + outputFile.getFullPathName());
      return 1;
    }
  }
  catch (const ExitException& e)
  {
    return e.returnValue();
  }

  return 0;
}


================================================
FILE: Jucer2CMake/src/reprojucer.hpp
================================================
// Copyright (C) 2017  Matthieu Talbot
// Copyright (C) 2017-2022  Alain Martin
// Copyright (C) 2017  Florian Goltz
// Copyright (C) 2019  Johannes Elliesen
// Copyright (C) 2022  Thiébaud Fuchs
// Copyright (C) 2023  Adrian Ostrowski
//
// This file is part of FRUT.
//
// FRUT 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.
//
// FRUT 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 FRUT.  If not, see <http://www.gnu.org/licenses/>.

#pragma once

#include "argh.hpp"
#include "juce_core.hpp"
#include "utils.hpp"

#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <locale>
#include <map>
#include <memory>
#include <regex>
#include <stdexcept>
#include <string>
#include <tuple>
#include <utility>
#include <vector>


#if !defined(IS_PAID_OR_GPL)
  #error IS_PAID_OR_GPL must be defined
#endif
#if IS_PAID_OR_GPL
static const auto kDefaultLicenseBasedValue = "OFF";
#else
static const auto kDefaultLicenseBasedValue = "ON";
#endif


namespace Jucer2CMake
{

inline juce::String makeValidIdentifier(juce::String s)
{
  if (s.isEmpty())
  {
    return "unknown";
  }

  s = s.replaceCharacters(".,;:/@", "______")
        .retainCharacters(
          "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789");

  if (juce::CharacterFunctions::isDigit(s[0]))
  {
    s = "_" + s;
  }

  return s;
}


// Matches _FRUT_make_valid_configuration_name in Reprojucer.cmake.
inline juce::String makeValidConfigurationName(const juce::String& configurationName)
{
  auto validName = configurationName.toStdString();

  validName = std::regex_replace(validName, std::regex{"[^A-Za-z0-9_]+"}, " ");
  validName = juce::String{validName}.trim().toStdString();
  validName = std::regex_replace(validName, std::regex{"[ ]+"}, "_");

  return validName;
}


inline juce::String cmakePath(const juce::String& path)
{
  return (juce::File::isAbsolutePath(path) ? path : "${CMAKE_CURRENT_LIST_DIR}/" + path)
    .replace("\\", "/");
}


inline juce::String escape(const juce::String& charsToEscape, juce::String value)
{
  auto pos = 0;

  while ((pos = value.indexOfAnyOf(charsToEscape, pos)) != -1)
  {
    value = value.replaceSection(pos, 0, "\\");
    pos += 2;
  }

  return value;
}


inline juce::StringArray parsePreprocessorDefinitions(const juce::String& input)
{
  juce::StringArray definitions;

  for (auto s = input.getCharPointer(); !s.isEmpty();)
  {
    s = s.findEndOfWhitespace();
    juce::String definition;

    while (!s.isEmpty() && !s.isWhitespace() && *s != '=')
    {
      definition << s.getAndAdvance();
    }

    s = s.findEndOfWhitespace();
    juce::String value;

    if (*s == '=')
    {
      ++s;

      while (!s.isEmpty() && *s == ' ')
      {
        ++s;
      }

      while (!s.isEmpty() && !s.isWhitespace())
      {
        if (*s == ',')
        {
          ++s;
          break;
        }

        if (*s == '\\' && (s[1] == ' ' || s[1] == ','))
        {
          ++s;
        }

        value << s.getAndAdvance();
      }
    }

    if (definition.isNotEmpty())
    {
      definitions.add(value.isEmpty() ? definition : definition + '=' + value);
    }
  }

  return definitions;
}


inline juce::StringArray parseSearchPaths(const juce::String& input)
{
  juce::StringArray unquotedPaths;

  for (const auto& path : juce::StringArray::fromTokens(input, ";\r\n", {}))
  {
    if (path.isNotEmpty())
    {
      unquotedPaths.add(path.unquoted());
    }
  }

  return unquotedPaths;
}


inline const juce::XmlElement& getFallbackXmlElement() noexcept
{
  static const juce::XmlElement fallbackXmlElement{":"};
  return fallbackXmlElement;
}


inline const juce::XmlElement& safeGetChildByName(const juce::XmlElement& element,
                                                  const juce::StringRef childName)
{
  if (const auto pChild = element.getChildByName(childName))
  {
    return *pChild;
  }

  return getFallbackXmlElement();
}


inline const juce::XmlElement* getChildByAttributeRecursively(
  const juce::XmlElement& parent, const juce::StringRef attributeName,
  const juce::StringRef attributeValue)
{
  if (const auto pChild = parent.getChildByAttribute(attributeName, attributeValue))
  {
    return pChild;
  }

  for (auto pChild = parent.getFirstChildElement(); pChild != nullptr;
       pChild = pChild->getNextElement())
  {
    if (!pChild->isTextElement())
    {
      if (const auto pGrandChild =
            getChildByAttributeRecursively(*pChild, attributeName, attributeValue))
      {
        return pGrandChild;
      }
    }
  }

  return nullptr;
}


inline std::unique_ptr<juce::XmlElement> parseProjucerSettings()
{
  const auto projucerSettingsDirectory =
#if defined(JUCE_LINUX) && JUCE_LINUX
    juce::File{"~/.config/Projucer"};
#elif defined(JUCE_MAC) && JUCE_MAC
    juce::File{"~/Library/Application Support/Projucer"};
#elif defined(JUCE_WINDOWS) && JUCE_WINDOWS
    juce::File::getSpecialLocation(juce::File::userApplicationDataDirectory)
      .getChildFile("Projucer");
#else
  #error Unknown platform
#endif

  return std::unique_ptr<juce::XmlElement>{juce::XmlDocument::parse(
    projucerSettingsDirectory.getChildFile("Projucer.settings"))};
}


inline void writeUserNotes(LineWriter& wLn, const juce::XmlElement& element)
{
  if (element.hasAttribute("userNotes"))
  {
    wLn("  # NOTES");
    const auto& userNotes = element.getStringAttribute("userNotes");
    for (const auto& line : juce::StringArray::fromLines(userNotes))
    {
      wLn("  #   ", line);
    }
  }
}


inline void writeReprojucerCMakeLists(const Arguments& args,
                                      const juce::XmlElement& jucerProject,
                                      juce::MemoryOutputStream& outputStream)
{
  const auto jucerFile = getChildFileFromWorkingDirectory(args.jucerFilePath);

  const auto jucerVersion = args.jucerVersion.isNotEmpty()
                              ? args.jucerVersion
                              : jucerProject.getStringAttribute("jucerVersion", "latest");
  const auto jucerVersionTokens = juce::StringArray::fromTokens(
    jucerVersion == "latest" ? "1000.0.0" : jucerVersion, ".", {});
  if (jucerVersionTokens.size() != 3)
  {
    printError("'" + jucerVersion + "' is not a valid Jucer version.");
    throw ExitException{1};
  }

  using Version = std::tuple<int, int, int>;

  const auto jucerVersionAsTuple = [&jucerVersionTokens, &args]() {
    try
    {
      return Version{std::stoi(jucerVersionTokens[0].toStdString()),
                     std::stoi(jucerVersionTokens[1].toStdString()),
                     std::stoi(jucerVersionTokens[2].toStdString())};
    }
    catch (const std::invalid_argument&)
    {
      printError("'" + args.jucerFilePath + "' is not a valid Jucer project.");
      throw ExitException{1};
    }
  }();

  if (args.reprojucerFilePath.isNotEmpty()
      && !args.reprojucerFilePath.endsWith("Reprojucer.cmake"))
  {
    printError("'" + args.reprojucerFilePath + "' is not a valid Reprojucer.cmake file.");
    throw ExitException{1};
  }

  auto needsJuceModulesGlobalPath = false;
  auto needsUserModulesGlobalPath = false;

  if (const auto pModules = jucerProject.getChildByName("MODULES"))
  {
    for (auto pModule = pModules->getFirstChildElement(); pModule != nullptr;
         pModule = pModule->getNextElement())
    {
      if (pModule->isTextElement())
      {
        continue;
      }

      if (toBoolLikeVar(pModule->getStringAttribute("useGlobalPath")))
      {
        if (pModule->getStringAttribute("id").startsWith("juce_"))
        {
          needsJuceModulesGlobalPath = true;
        }
        else
        {
          needsUserModulesGlobalPath = true;
        }
      }
    }
  }

  const auto shouldParseProjucerSettings =
    (needsJuceModulesGlobalPath && args.juceModulesPath.isEmpty())
    || (needsUserModulesGlobalPath && args.userModulesPath.isEmpty());

  const auto pProjucerSettings =
    shouldParseProjucerSettings ? parseProjucerSettings() : nullptr;

  const auto pProjucerGlobalPaths = [&pProjucerSettings]() -> juce::XmlElement* {
    if (pProjucerSettings && pProjucerSettings->hasTagName("PROPERTIES"))
    {
      if (const auto pValue =
            pProjucerSettings->getChildByAttribute("name", "PROJECT_DEFAULT_SETTINGS"))
      {
        return pValue->getChildByName("PROJECT_DEFAULT_SETTINGS");
      }
    }
    return nullptr;
  }();

  const auto& juceModulesGlobalPath =
    args.juceModulesPath.isNotEmpty()
      ? args.juceModulesPath
      : needsJuceModulesGlobalPath && pProjucerGlobalPaths
          ? pProjucerGlobalPaths->getStringAttribute("defaultJuceModulePath")
          : juce::String{};

  if (needsJuceModulesGlobalPath && juceModulesGlobalPath.isEmpty())
  {
    printError(
      "At least one JUCE module used in " + args.jucerFilePath
      + " relies on the global \"JUCE Modules\" path set in Projucer. You must "
        "provide this path using --juce-modules=\"<global-JUCE-modules-path>\".");
    throw ExitException{1};
  }

  const auto& userModulesGlobalPath =
    args.userModulesPath.isNotEmpty()
      ? args.userModulesPath
      : needsUserModulesGlobalPath && pProjucerGlobalPaths
          ? pProjucerGlobalPaths->getStringAttribute("defaultUserModulePath")
          : juce::String{};

  if (needsUserModulesGlobalPath && userModulesGlobalPath.isEmpty())
  {
    printError(
      "At least one user module used in " + args.jucerFilePath
      + " relies on the global \"User Modules\" path set in Projucer. You must "
        "provide this path using --user-modules=\"<global-user-modules-path>\".");
    throw ExitException{1};
  }

  LineWriter wLn{outputStream};

  const auto writeUnquoted = [&wLn](const juce::String& cmakeKeyword,
                                    const juce::String& value) {
    if (value.isEmpty())
    {
      wLn("  # ", cmakeKeyword);
    }
    else
    {
      wLn("  ", cmakeKeyword, " ", value);
    }
  };

  const auto writeBracket = [&wLn](const juce::String& cmakeKeyword,
                                   const juce::String& value) {
    if (value.isEmpty())
    {
      wLn("  # ", cmakeKeyword);
    }
    else
    {
      wLn("  ", cmakeKeyword, " [=[", value, "]=]");
    }
  };

  const auto writeQuoted = [&wLn](const juce::String& cmakeKeyword,
                                  const juce::String& value) {
    if (value.isEmpty())
    {
      wLn("  # ", cmakeKeyword);
    }
    else
    {
      wLn("  ", cmakeKeyword, " \"", escape("\\\";", value.trimCharactersAtEnd("\\")),
          "\"");
    }
  };

  const auto writeList = [&wLn](const juce::String& cmakeKeyword,
                                const juce::StringArray& values) {
    if (values.isEmpty())
    {
      wLn("  # ", cmakeKeyword);
    }
    else
    {
      wLn("  ", cmakeKeyword);

      for (const auto& item : values)
      {
        if (item.isNotEmpty())
        {
          wLn("    \"", escape("\\\";", item.trimCharactersAtEnd("\\")), "\"");
        }
      }
    }
  };

  const auto convertSetting =
    [&writeQuoted](const juce::XmlElement& element, const juce::StringRef attributeName,
                   const juce::String& cmakeKeyword,
                   const std::function<juce::String(const juce::String&)>& converterFn) {
      const auto value = converterFn
                           ? converterFn(element.getStringAttribute(attributeName))
                           : element.getStringAttribute(attributeName);

      writeQuoted(cmakeKeyword, value);
    };

  const auto convertSettingIfDefined =
    [&convertSetting](
      const juce::XmlElement& element, const juce::StringRef attributeName,
      const juce::String& cmakeKeyword,
      const std::function<juce::String(const juce::String&)>& converterFn) {
      if (element.hasAttribute(attributeName))
      {
        convertSetting(element, attributeName, cmakeKeyword, converterFn);
      }
    };

  const auto convertSettingWithDefault =
    [&convertSetting](
      const juce::XmlElement& element, const juce::StringRef attributeName,
      const juce::String& cmakeKeyword, const juce::String& defaultValue) {
      if (element.hasAttribute(attributeName))
      {
        convertSetting(element, attributeName, cmakeKeyword, {});
      }
      else
      {
        convertSetting(element, attributeName, cmakeKeyword,
                       [&defaultValue](const juce::String&) { return defaultValue; });
      }
    };

  const auto convertOnOffSetting =
    [&writeUnquoted](
      const juce::XmlElement& element, const juce::StringRef attributeName,
      const juce::String& cmakeKeyword,
      const std::function<juce::String(const juce::String&)>& converterFn) {
      const auto value =
        converterFn
          ? converterFn(element.getStringAttribute(attributeName))
          : juce::String{
            element.hasAttribute(attributeName)
              ? toBoolLikeVar(element.getStringAttribute(attributeName)) ? "ON" : "OFF"
              : ""};

      writeUnquoted(cmakeKeyword, value);
    };

  const auto convertOnOffSettingIfDefined =
    [&convertOnOffSetting](
      const juce::XmlElement& element, const juce::StringRef attributeName,
      const juce::String& cmakeKeyword,
      const std::function<juce::String(const juce::String&)>& converterFn) {
      if (element.hasAttribute(attributeName))
      {
        convertOnOffSetting(element, attributeName, cmakeKeyword, converterFn);
      }
    };

  const auto convertOnOffSettingWithDefault = [&convertOnOffSetting](
                                                const juce::XmlElement& element,
                                                const juce::StringRef attributeName,
                                                const juce::String& cmakeKeyword,
                                                const juce::String& defaultValue) {
    if (element.hasAttribute(attributeName))
    {
      convertOnOffSetting(element, attributeName, cmakeKeyword, {});
    }
    else
    {
      convertOnOffSetting(element, attributeName, cmakeKeyword,
                          [&defaultValue](const juce::String&) { return defaultValue; });
    }
  };

  const auto convertRawStringSetting =
    [&writeBracket](const juce::XmlElement& element, const juce::StringRef attributeName,
                    const juce::String& cmakeKeyword,
                    const std::function<juce::String(const juce::String&)>& converterFn) {
      const auto value = converterFn
                           ? converterFn(element.getStringAttribute(attributeName))
                           : element.getStringAttribute(attributeName);

      writeBracket(cmakeKeyword, value);
    };

  const auto convertRawStringSettingIfDefined =
    [&convertRawStringSetting](
      const juce::XmlElement& element, const juce::StringRef attributeName,
      const juce::String& cmakeKeyword,
      const std::function<juce::String(const juce::String&)>& converterFn) {
      if (element.hasAttribute(attributeName))
      {
        convertRawStringSetting(element, attributeName, cmakeKeyword, converterFn);
      }
    };

  const auto convertSettingAsList =
    [&writeList](
      const juce::XmlElement& element, const juce::StringRef attributeName,
      const juce::String& cmakeKeyword,
      const std::function<juce::StringArray(const juce::String&)>& converterFn) {
      const auto values =
        converterFn
          ? converterFn(element.getStringAttribute(attributeName))
          : juce::StringArray::fromLines(element.getStringAttribute(attributeName));

      writeList(cmakeKeyword, values);
    };

  const auto convertSettingAsListIfDefined =
    [&convertSettingAsList](
      const juce::XmlElement& element, const juce::StringRef attributeName,
      const juce::String& cmakeKeyword,
      const std::function<juce::StringArray(const juce::String&)>& converterFn) {
      if (element.hasAttribute(attributeName))
      {
        convertSettingAsList(element, attributeName, cmakeKeyword, converterFn);
      }
    };

  const auto jucerFileName = jucerFile.getFileName();
  const auto& jucerProjectName = jucerProject.getStringAttribute("name");

  // Preamble
  {
    wLn();
    wLn("cmake_minimum_required(VERSION 3.4)");
    wLn();
    wLn("project(\"", jucerProjectName, "\")");
    wLn();
    wLn();
  }

  // include(Reprojucer)
  {
    if (args.reprojucerFilePath.isNotEmpty())
    {
      const auto relativeReprojucerDirPath =
        getChildFileFromWorkingDirectory(args.reprojucerFilePath)
          .getParentDirectory()
          .getRelativePathFrom(args.outputDir);
      wLn("list(APPEND CMAKE_MODULE_PATH \"", cmakePath(relativeReprojucerDirPath),
          "\")");
    }
    else
    {
      wLn("# list(APPEND CMAKE_MODULE_PATH"
          " \"${CMAKE_CURRENT_LIST_DIR}/<relative_path_to_FRUT>/cmake\")");
    }
    wLn("include(Reprojucer)");
    wLn();
    wLn();
  }

  auto escapedJucerFileName = jucerFileName.toStdString();
  std::replace_if(
    escapedJucerFileName.begin(), escapedJucerFileName.end(),
    [](const std::string::value_type& c) {
      return !(std::isalpha(c, std::locale::classic())
               || std::isdigit(c, std::locale::classic()));
    },
    '_');
  const auto jucerFileCMakeVar = juce::String{escapedJucerFileName} + "_FILE";

  // get_filename_component() or set(*_FILE)
  {
    if (args.relocatable)
    {
      wLn("if(NOT DEFINED ", jucerFileCMakeVar, ")");
      wLn("  message(FATAL_ERROR \"", jucerFileCMakeVar, " must be defined\")");
      wLn("endif()");
      wLn();
      wLn("get_filename_component(", jucerFileCMakeVar);
      wLn("  \"${", jucerFileCMakeVar, "}\" ABSOLUTE");
      wLn("  BASE_DIR \"${CMAKE_BINARY_DIR}\"");
      wLn(")");
    }
    else
    {
      wLn("set(", jucerFileCMakeVar);
      const auto relativeJucerFilePath =
        getChildFileFromWorkingDirectory(args.jucerFilePath)
          .getRelativePathFrom(args.outputDir);
      wLn("  \"", cmakePath(relativeJucerFilePath), "\"");
      wLn(")");
    }
    wLn();
    wLn();
  }

  // set({JUCE,USER}_MODULES_GLOBAL_PATH)
  {
    if (juceModulesGlobalPath.isNotEmpty())
    {
      std::cout << "Using '" << juceModulesGlobalPath
                << "' as global \"JUCE Modules\" path." << std::endl;
      wLn("set(JUCE_MODULES_GLOBAL_PATH \"", cmakePath(juceModulesGlobalPath), "\")");
    }

    if (userModulesGlobalPath.isNotEmpty())
    {
      std::cout << "Using '" << userModulesGlobalPath
                << "' as global \"User Modules\" path." << std::endl;
      wLn("set(USER_MODULES_GLOBAL_PATH \"", cmakePath(userModulesGlobalPath), "\")");
    }

    if (juceModulesGlobalPath.isNotEmpty() || userModulesGlobalPath.isNotEmpty())
    {
      wLn();
      wLn();
    }
  }

  // jucer_project_begin()
  {
    wLn("jucer_project_begin(");
    if (jucerProject.hasAttribute("jucerFormatVersion"))
    {
      writeQuoted("JUCER_FORMAT_VERSION",
                  jucerProject.getStringAttribute("jucerFormatVersion"));
    }
    if (jucerVersion != "latest")
    {
      writeQuoted("JUCER_VERSION", jucerVersion);
    }
    writeQuoted("PROJECT_FILE", "${" + jucerFileCMakeVar + "}");
    convertSetting(jucerProject, "id", "PROJECT_ID", {});
    wLn(")");
    wLn();
  }

  const auto& projectType = jucerProject.getStringAttribute("projectType");

  // jucer_project_settings()
  {
    wLn("jucer_project_settings(");
    convertSetting(jucerProject, "name", "PROJECT_NAME", {});
    convertSettingWithDefault(jucerProject, "version", "PROJECT_VERSION", "1.0.0");

    convertSettingIfDefined(jucerProject, "companyName", "COMPANY_NAME", {});
    convertSettingIfDefined(jucerProject, "companyCopyright", "COMPANY_COPYRIGHT", {});
    convertSettingIfDefined(jucerProject, "companyWebsite", "COMPANY_WEBSITE", {});
    convertSettingIfDefined(jucerProject, "companyEmail", "COMPANY_EMAIL", {});

    convertOnOffSettingIfDefined(jucerProject, "useAppConfig",
                                 "USE_GLOBAL_APPCONFIG_HEADER", {});
    convertOnOffSettingIfDefined(jucerProject, "addUsingNamespaceToJuceHeader",
                                 "ADD_USING_NAMESPACE_JUCE_TO_JUCE_HEADER", {});

    const auto tagLine = juce::String{" # Required for closed source applications"
                                      " without an Indie or Pro JUCE license"};

    if (jucerVersionAsTuple >= Version{5, 0, 0} && jucerVersionAsTuple < Version{6, 0, 0})
    {
      if (jucerProject.hasAttribute("reportAppUsage"))
      {
        convertOnOffSetting(jucerProject, "reportAppUsage", "REPORT_JUCE_APP_USAGE",
                            [&tagLine](const juce::String& value) {
                              return (toBoolLikeVar(value) ? "ON" : "OFF") + tagLine;
                            });
      }
      else
      {
        writeUnquoted("REPORT_JUCE_APP_USAGE", kDefaultLicenseBasedValue + tagLine);
      }
    }

    if (jucerVersionAsTuple >= Version{5, 0, 0})
    {
      if (jucerProject.hasAttribute("displaySplashScreen"))
      {
        convertOnOffSetting(jucerProject, "displaySplashScreen",
                            "DISPLAY_THE_JUCE_SPLASH_SCREEN",
                            [&tagLine](const juce::String& value) {
                              return (toBoolLikeVar(value) ? "ON" : "OFF") + tagLine;
                            });
      }
      else
      {
        writeUnquoted("DISPLAY_THE_JUCE_SPLASH_SCREEN",
                      kDefaultLicenseBasedValue + tagLine);
      }

      convertSettingIfDefined(jucerProject, "splashScreenColour", "SPLASH_SCREEN_COLOUR",
                              {});
    }

    const auto projectTypeDescription = [&projectType]() -> juce::String {
      if (projectType == "guiapp")
        return "GUI Application";

      if (projectType == "consoleapp")
        return "Console Application";

      if (projectType == "library")
        return "Static Library";

      if (projectType == "dll")
        return "Dynamic Library";

      if (projectType == "audioplug")
        return "Audio Plug-in";

      return {};
    }();
    writeQuoted("PROJECT_TYPE", projectTypeDescription);

    const auto defaultCompanyName = [&jucerProject]() {
      const auto& companyNameString = jucerProject.getStringAttribute("companyName");
      return companyNameString.isEmpty() ? "yourcompany" : companyNameString;
    }();

    const auto defaultBundleIdentifier =
      jucerVersionAsTuple >= Version{5, 4, 0}
        ? "com." + makeValidIdentifier(defaultCompanyName) + "."
            + makeValidIdentifier(jucerProjectName)
        : "com.yourcompany." + makeValidIdentifier(jucerProjectName);

    convertSettingWithDefault(jucerProject, "bundleIdentifier", "BUNDLE_IDENTIFIER",
                              defaultBundleIdentifier);

    convertSettingIfDefined(jucerProject, "maxBinaryFileSize", "BINARYDATACPP_SIZE_LIMIT",
                            [](const juce::String& value) -> juce::String {
                              if (value.isEmpty())
                                return "Default";
                              return juce::File::descriptionOfSizeInBytes(
                                value.getIntValue());
                            });
    if (jucerProject.hasAttribute("includeBinaryInJuceHeader"))
    {
      convertOnOffSetting(jucerProject, "includeBinaryInJuceHeader", "INCLUDE_BINARYDATA",
                          {});
    }
    else
    {
      convertOnOffSettingIfDefined(jucerProject, "includeBinaryInAppConfig",
                                   "INCLUDE_BINARYDATA", {});
    }
    convertSettingIfDefined(jucerProject, "binaryDataNamespace", "BINARYDATA_NAMESPACE",
                            {});

    if (jucerProject.hasAttribute("cppLanguageStandard"))
    {
      convertSetting(jucerProject, "cppLanguageStandard", "CXX_LANGUAGE_STANDARD",
                     [](const juce::String& value) -> juce::String {
                       if (value == "11")
                         return "C++11";

                       if (value == "14")
                         return "C++14";

                       if (value == "17")
                         return "C++17";

                       if (value == "20")
                         return "C++20";

                       if (value == "latest")
                         return "Use Latest";

                       return {};
                     });
    }
    else if (jucerVersionAsTuple >= Version{7, 0, 3})
    {
      writeQuoted("CXX_LANGUAGE_STANDARD", "C++17");
    }
    else if (jucerVersionAsTuple > Version{5, 2, 0})
    {
      writeQuoted("CXX_LANGUAGE_STANDARD", "C++14");
    }
    else if (jucerVersionAsTuple > Version{5, 0, 2})
    {
      writeQuoted("CXX_LANGUAGE_STANDARD", "C++11");
    }

    convertSettingAsListIfDefined(jucerProject, "defines", "PREPROCESSOR_DEFINITIONS",
                                  parsePreprocessorDefinitions);
    convertSettingAsListIfDefined(jucerProject, "headerPath", "HEADER_SEARCH_PATHS",
                                  parseSearchPaths);

    convertRawStringSettingIfDefined(jucerProject, "postExportShellCommandPosix",
                                     "POST_EXPORT_SHELL_COMMAND_MACOS_LINUX", {});
    convertRawStringSettingIfDefined(jucerProject, "postExportShellCommandWin",
                                     "POST_EXPORT_SHELL_COMMAND_WINDOWS", {});

    writeUserNotes(wLn, jucerProject);

    wLn(")");
    wLn();

    // jucer_audio_plugin_settings()
    if (projectType == "audioplug")
    {
      wLn("jucer_audio_plugin_settings(");

      const auto vstIsLegacy = jucerVersionAsTuple > Version{5, 3, 2};

      if (jucerVersionAsTuple >= Version{5, 3, 1})
      {
        if (jucerProject.hasAttribute("pluginFormats"))
        {
          convertSettingAsList(
            jucerProject, "pluginFormats", "PLUGIN_FORMATS",
            [&jucerVersionAsTuple, &vstIsLegacy](const juce::String& value) {
              const auto supportsUnity = jucerVersionAsTuple >= Version{5, 3, 2};
              return convertIdsToStrings(
                juce::StringArray::fromTokens(value, ",", {}),
                {{vstIsLegacy ? "" : "buildVST", vstIsLegacy ? "" : "VST"},
                 {"buildVST3", "VST3"},
                 {"buildAU", "AU"},
                 {"buildAUv3", "AUv3"},
                 {"buildRTAS", "RTAS"},
                 {"buildAAX", "AAX"},
                 {"buildStandalone", "Standalone"},
                 {supportsUnity ? "buildUnity" : "", supportsUnity ? "Unity" : ""},
                 {"enableIAA", "Enable IAA"},
                 {vstIsLegacy ? "buildVST" : "", vstIsLegacy ? "VST (Legacy)" : ""}});
            });
        }
        else
        {
          convertSettingAsList(
            jucerProject, "pluginFormats", "PLUGIN_FORMATS",
            [&vstIsLegacy](const juce::String&) {
              return juce::StringArray{vstIsLegacy ? "VST3" : "VST", "AU", "Standalone"};
            });
        }

        if (jucerProject.hasAttribute("pluginCharacteristicsValue"))
        {
          convertSettingAsList(
            jucerProject, "pluginCharacteristicsValue", "PLUGIN_CHARACTERISTICS",
            [](const juce::String& value) {
              return convertIdsToStrings(
                juce::StringArray::fromTokens(value, ",", {}),
                {{"pluginIsSynth", "Plugin is a Synth"},
                 {"pluginWantsMidiIn", "Plugin MIDI Input"},
                 {"pluginProducesMidiOut", "Plugin MIDI Output"},
                 {"pluginIsMidiEffectPlugin", "MIDI Effect Plugin"},
                 {"pluginEditorRequiresKeys", "Plugin Editor Requires Keyboard Focus"},
                 {"pluginRTASDisableBypass", "Disable RTAS Bypass"},
                 {"pluginAAXDisableBypass", "Disable AAX Bypass"},
                 {"pluginRTASDisableMultiMono", "Disable RTAS Multi-Mono"},
                 {"pluginAAXDisableMultiMono", "Disable AAX Multi-Mono"}});
            });
        }
        else
        {
          wLn("  # PLUGIN_CHARACTERISTICS");
        }
      }
      else
      {
        convertOnOffSettingWithDefault(jucerProject, "buildVST", "BUILD_VST", "ON");
        convertOnOffSettingWithDefault(jucerProject, "buildVST3", "BUILD_VST3", "OFF");
        convertOnOffSettingWithDefault(jucerProject, "buildAU", "BUILD_AUDIOUNIT", "ON");
        convertOnOffSettingWithDefault(jucerProject, "buildAUv3", "BUILD_AUDIOUNIT_V3",
                                       "OFF");
        convertOnOffSettingWithDefault(jucerProject, "buildRTAS", "BUILD_RTAS", "OFF");
        convertOnOffSettingWithDefault(jucerProject, "buildAAX", "BUILD_AAX", "OFF");
        if (jucerVersionAsTuple >= Version{5, 0, 0})
        {
          convertOnOffSettingWithDefault(jucerProject, "buildStandalone",
                                         "BUILD_STANDALONE_PLUGIN", "OFF");
          convertOnOffSettingWithDefault(jucerProject, "enableIAA",
                                         "ENABLE_INTER_APP_AUDIO", "OFF");
        }
      }

      convertSettingWithDefault(jucerProject, "pluginName", "PLUGIN_NAME",
                                jucerProjectName);
      convertSettingWithDefault(jucerProject, "pluginDesc", "PLUGIN_DESCRIPTION",
                                jucerProjectName);

      convertSettingWithDefault(jucerProject, "pluginManufacturer", "PLUGIN_MANUFACTURER",
                                defaultCompanyName);
      convertSettingWithDefault(jucerProject, "pluginManufacturerCode",
                                "PLUGIN_MANUFACTURER_CODE", "Manu");

      const auto defaultPluginCode = [&jucerProject]() {
        const auto& projectId = jucerProject.getStringAttribute("id");
        const auto s = makeValidIdentifier(projectId + projectId) + "xxxx";
        return s.substring(0, 1).toUpperCase() + s.substring(1, 4).toLowerCase();
      }();
      convertSettingWithDefault(jucerProject, "pluginCode", "PLUGIN_CODE",
                                defaultPluginCode);

      convertSetting(jucerProject, "pluginChannelConfigs",
                     "PLUGIN_CHANNEL_CONFIGURATIONS", {});

      const auto pluginCharacteristics = juce::StringArray::fromTokens(
        jucerProject.getStringAttribute("pluginCharacteristicsValue"), ",", {});

      const auto isSynthAudioPlugin =
        jucerVersionAsTuple >= Version{5, 3, 1}
          ? pluginCharacteristics.contains("pluginIsSynth")
          : toBoolLikeVar(jucerProject.getStringAttribute("pluginIsSynth"));

      if (jucerVersionAsTuple < Version{5, 3, 1})
      {
        wLn(juce::String{"  PLUGIN_IS_A_SYNTH "} + (isSynthAudioPlugin ? "ON" : "OFF"));
        convertOnOffSettingWithDefault(jucerProject, "pluginWantsMidiIn",
                                       "PLUGIN_MIDI_INPUT", "OFF");
        convertOnOffSettingWithDefault(jucerProject, "pluginProducesMidiOut",
                                       "PLUGIN_MIDI_OUTPUT", "OFF");
        convertOnOffSettingWithDefault(jucerProject, "pluginIsMidiEffectPlugin",
                                       "MIDI_EFFECT_PLUGIN", "OFF");
        convertOnOffSettingWithDefault(jucerProject, "pluginEditorRequiresKeys",
                                       "KEY_FOCUS", "OFF");
      }

      if (jucerVersionAsTuple >= Version{5, 3, 1})
      {
        convertSettingWithDefault(jucerProject, "aaxIdentifier", "PLUGIN_AAX_IDENTIFIER",
                                  defaultBundleIdentifier);
      }
      convertSettingWithDefault(jucerProject, "pluginAUExportPrefix",
                                "PLUGIN_AU_EXPORT_PREFIX",
                                makeValidIdentifier(jucerProjectName) + "AU");
      if (jucerVersionAsTuple >= Version{5, 3, 1})
      {
        if (jucerProject.hasAttribute("pluginAUMainType"))
        {
          convertSetting(jucerProject, "pluginAUMainType", "PLUGIN_AU_MAIN_TYPE",
                         getAUMainTypeConstantFromQuotedFourChars);
        }
        else
        {
          convertSetting(jucerProject, "pluginAUMainType", "PLUGIN_AU_MAIN_TYPE",
                         [&pluginCharacteristics](const juce::String&) -> juce::String {
                           if (pluginCharacteristics.contains("pluginIsMidiEffectPlugin"))
                             return "kAudioUnitType_MIDIProcessor"; // 'aumi'

                           if (pluginCharacteristics.contains("pluginIsSynth"))
                             return "kAudioUnitType_MusicDevice"; // 'aumu'

                           if (pluginCharacteristics.contains("pluginWantsMidiIn"))
                             return "kAudioUnitType_MusicEffect"; // 'aumf'

                           return "kAudioUnitType_Effect"; // 'aufx'
                         });
        }
      }
      else
      {
        convertSetting(jucerProject, "pluginAUMainType", "PLUGIN_AU_MAIN_TYPE", {});
      }
      convertOnOffSettingIfDefined(jucerProject, "pluginAUIsSandboxSafe",
                                   "PLUGIN_AU_IS_SANDBOX_SAFE", {});

      if (jucerProject.hasAttribute("pluginVSTNumMidiInputs")
          || (jucerVersionAsTuple >= Version{5, 4, 2}
              && pluginCharacteristics.contains("pluginWantsMidiIn")))
      {
        convertSettingWithDefault(jucerProject, "pluginVSTNumMidiInputs",
                                  "PLUGIN_VST_NUM_MIDI_INPUTS", "16");
      }
      if (jucerProject.hasAttribute("pluginVSTNumMidiOutputs")
          || (jucerVersionAsTuple >= Version{5, 4, 2}
              && pluginCharacteristics.contains("pluginProducesMidiOut")))
      {
        convertSettingWithDefault(jucerProject, "pluginVSTNumMidiOutputs",
                                  "PLUGIN_VST_NUM_MIDI_OUTPUTS", "16");
      }

      if (!vstIsLegacy)
      {
        convertSettingWithDefault(
          jucerProject, "pluginVSTCategory",
          jucerVersionAsTuple > Version{5, 3, 0} ? "PLUGIN_VST_CATEGORY" : "VST_CATEGORY",
          jucerVersionAsTuple >= Version{5, 3, 1}
            ? (isSynthAudioPlugin ? "kPlugCategSynth" : "kPlugCategEffect")
            : "");
      }

      if (jucerProject.hasAttribute("pluginVST3Category")
          || jucerVersionAsTuple >= Version{5, 3, 1})
      {
        if (jucerProject.hasAttribute("pluginVST3Category"))
        {
          convertSettingAsList(
            jucerProject, "pluginVST3Category", "PLUGIN_VST3_CATEGORY",
            [](const juce::String& value) {
              auto vst3Categories = juce::StringArray::fromTokens(value, ",", {});
              if (vst3Categories.contains("Instrument"))
              {
                vst3Categories.move(vst3Categories.indexOf("Instrument"), 0);
              }
              if (vst3Categories.contains("Fx"))
              {
                vst3Categories.move(vst3Categories.indexOf("Fx"), 0);
              }
              return vst3Categories;
            });
        }
        else
        {
          convertSettingAsList(jucerProject, "pluginVST3Category", "PLUGIN_VST3_CATEGORY",
                               [isSynthAudioPlugin](const juce::String&) {
                                 return isSynthAudioPlugin
                                          ? juce::StringArray{"Instrument", "Synth"}
                                          : juce::StringArray{"Fx"};
                               });
        }
      }

      if (jucerVersionAsTuple >= Version{5, 3, 1})
      {
        if (jucerProject.hasAttribute("pluginRTASCategory"))
        {
          convertSettingAsList(jucerProject, "pluginRTASCategory", "PLUGIN_RTAS_CATEGORY",
                               [](const juce::String& value) {
                                 return convertIdsToStrings(
                                   juce::StringArray::fromTokens(value, ",", {}),
                                   {{"0", "ePlugInCategory_None"},
                                    {"1", "ePlugInCategory_EQ"},
                                    {"2", "ePlugInCategory_Dynamics"},
                                    {"4", "ePlugInCategory_PitchShift"},
                                    {"8", "ePlugInCategory_Reverb"},
                                    {"16", "ePlugInCategory_Delay"},
                                    {"32", "ePlugInCategory_Modulation"},
                                    {"64", "ePlugInCategory_Harmonic"},
                                    {"128", "ePlugInCategory_NoiseReduction"},
                                    {"256", "ePlugInCategory_Dither"},
                                    {"512", "ePlugInCategory_SoundField"},
                                    {"1024", "ePlugInCategory_HWGenerators"},
                                    {"2048", "ePlugInCategory_SWGenerators"},
                                    {"4096", "ePlugInCategory_WrappedPlugin"},
                                    {"8192", "ePlugInCategory_Effect"}});
                               });
        }
        else
        {
          convertSettingAsList(jucerProject, "pluginRTASCategory", "PLUGIN_RTAS_CATEGORY",
                               [isSynthAudioPlugin](const juce::String&) {
                                 return juce::StringArray{
                                   isSynthAudioPlugin ? "ePlugInCategory_SWGenerators"
                                                      : "ePlugInCategory_None"};
                               });
        }

        if (jucerProject.hasAttribute("pluginAAXCategory"))
        {
          convertSettingAsList(jucerProject, "pluginAAXCategory", "PLUGIN_AAX_CATEGORY",
                               [](const juce::String& value) {
                                 return convertIdsToStrings(
                                   juce::StringArray::fromTokens(value, ",", {}),
                                   {{"0", "AAX_ePlugInCategory_None"},
                                    {"1", "AAX_ePlugInCategory_EQ"},
                                    {"2", "AAX_ePlugInCategory_Dynamics"},
                                    {"4", "AAX_ePlugInCategory_PitchShift"},
                                    {"8", "AAX_ePlugInCategory_Reverb"},
                                    {"16", "AAX_ePlugInCategory_Delay"},
                                    {"32", "AAX_ePlugInCategory_Modulation"},
                                    {"64", "AAX_ePlugInCategory_Harmonic"},
                                    {"128", "AAX_ePlugInCategory_NoiseReduction"},
                                    {"256", "AAX_ePlugInCategory_Dither"},
                                    {"512", "AAX_ePlugInCategory_SoundField"},
                                    {"1024", "AAX_ePlugInCategory_HWGenerators"},
                                    {"2048", "AAX_ePlugInCategory_SWGenerators"},
                                    {"4096", "AAX_ePlugInCategory_WrappedPlugin"},
                                    {"8192", "AAX_EPlugInCategory_Effect"}});
                               });
        }
        else
        {
          convertSettingAsList(jucerProject, "pluginAAXCategory", "PLUGIN_AAX_CATEGORY",
                               [isSynthAudioPlugin](const juce::String&) {
                                 return juce::StringArray{
                                   isSynthAudioPlugin ? "AAX_ePlugInCategory_SWGenerators"
                                                      : "AAX_ePlugInCategory_None"};
                               });
        }
      }
      else
      {
        convertSetting(jucerProject, "pluginRTASCategory", "PLUGIN_RTAS_CATEGORY", {});
        convertSetting(jucerProject, "pluginAAXCategory", "PLUGIN_AAX_CATEGORY", {});
      }

      if (vstIsLegacy)
      {
        convertSettingWithDefault(
          jucerProject, "pluginVSTCategory", "PLUGIN_VST_LEGACY_CATEGORY",
          isSynthAudioPlugin ? "kPlugCategSynth" : "kPlugCategEffect");
      }

      if (jucerVersionAsTuple < Version{5, 3, 1})
      {
        convertSetting(jucerProject, "aaxIdentifier", "PLUGIN_AAX_IDENTIFIER", {});
      }

      wLn(")");
      wLn();
    }
  }

  // jucer_project_files()
  {
    const auto projectHasCompilerFlagSchemes =
      jucerProject.getStringAttribute("compilerFlagSchemes").isNotEmpty();

    struct File
    {
      bool compile;
      bool xcodeResource;
      bool binaryResource;
      juce::String path;
      juce::String compilerFlagScheme;
    };

    const auto writeFiles = [&projectHasCompilerFlagSchemes,
                             &wLn](const juce::String& fullGroupName,
                                   const std::vector<File>& files) {
      if (!files.empty())
      {
        const auto longestPathLength =
          std::max_element(files.begin(), files.end(),
                           [](const File& lhs, const File& rhs) {
                             return lhs.path.length() < rhs.path.length();
                           })
            ->path.length();
        const auto nineSpaces = "         ";

        wLn("jucer_project_files(\"", fullGroupName, "\"");
        if (projectHasCompilerFlagSchemes)
        {
          wLn("# Compile   Xcode     Binary    File",
              juce::String::repeatedString(" ", longestPathLength) + "Compiler Flag");
          wLn("#           Resource  Resource",
              juce::String::repeatedString(" ", longestPathLength + 6) + "Scheme");
        }
        else
        {
          wLn("# Compile   Xcode     Binary    File");
          wLn("#           Resource  Resource");
        }

        for (const auto& file : files)
        {
          const auto compilerFlagScheme =
            file.compilerFlagScheme.isEmpty()
              ? ""
              : juce::String::repeatedString(" ",
                                             longestPathLength - file.path.length() + 2)
                  + "\"" + file.compilerFlagScheme + "\"";
          wLn("  ", (file.compile ? "x" : "."), nineSpaces,
              (file.xcodeResource ? "x" : "."), nineSpaces,
              (file.binaryResource ? "x" : "."), nineSpaces, "\"", file.path, "\"",
              compilerFlagScheme);
        }

        wLn(")");
        wLn();
      }
    };

    juce::StringArray groupNames;

    std::function<void(const juce::XmlElement&)> processGroup =
      [&groupNames, &processGroup, &writeFiles](const juce::XmlElement& group) {
        groupNames.add(group.getStringAttribute("name"));

        const auto fullGroupName = groupNames.joinIntoString("/");

        std::vector<File> files;

        for (auto pFileOrGroup = group.getFirstChildElement(); pFileOrGroup != nullptr;
             pFileOrGroup = pFileOrGroup->getNextElement())
        {
          if (pFileOrGroup->isTextElement())
          {
            continue;
          }

          if (pFileOrGroup->hasTagName("FILE"))
          {
            const auto& file = *pFileOrGroup;

            files.push_back({file.getStringAttribute("compile").getIntValue() == 1,
                             file.getStringAttribute("xcodeResource").getIntValue() == 1,
                             file.getStringAttribute("resource").getIntValue() == 1,
                             file.getStringAttribute("file"),
                             file.getStringAttribute("compilerFlagScheme")});
          }
          else
          {
            writeFiles(fullGroupName, files);
            files.clear();

            processGroup(*pFileOrGroup);
          }
        }

        writeFiles(fullGroupName, files);

        groupNames.strings.removeLast();
      };

    processGroup(safeGetChildByName(jucerProject, "MAINGROUP"));
  }

  // jucer_project_module()
  {
    const auto& modulePaths = [&jucerProject]() -> const juce::XmlElement& {
      const auto& exportFormats = safeGetChildByName(jucerProject, "EXPORTFORMATS");
      for (auto pExporter = exportFormats.getFirstChildElement(); pExporter != nullptr;
           pExporter = pExporter->getNextElement())
      {
        if (!pExporter->isTextElement())
        {
          return safeGetChildByName(*pExporter, "MODULEPATHS");
        }
      }
      return getFallbackXmlElement();
    }();

    const auto juceModules = getChildFileFromWorkingDirectory(juceModulesGlobalPath);
    const auto userModules = getChildFileFromWorkingDirectory(userModulesGlobalPath);

    const auto& modules = safeGetChildByName(jucerProject, "MODULES");
    for (auto pModule = modules.getFirstChildElement(); pModule != nullptr;
         pModule = pModule->getNextElement())
    {
      if (pModule->isTextElement())
      {
        continue;
      }

      const auto& module = *pModule;
      const auto& moduleName = module.getStringAttribute("id");

      const auto useGlobalPath =
        toBoolLikeVar(module.getStringAttribute("useGlobalPath"));
      const auto isJuceModule = moduleName.startsWith("juce_");

      const auto modulePath = [&modulePaths, &moduleName]() -> juce::String {
        if (const auto pModulePath = modulePaths.getChildByAttribute("id", moduleName))
        {
          return pModulePath->getStringAttribute("path");
        }
        return {};
      }();

      wLn("jucer_project_module(");
      wLn("  ", moduleName);
      wLn("  PATH \"",
          useGlobalPath ? (isJuceModule ? "${JUCE_MODULES_GLOBAL_PATH}"
                                        : "${USER_MODULES_GLOBAL_PATH}")
                        : modulePath.replace("\\", "/"),
          "\"");

      const auto moduleHeader =
        (useGlobalPath ? (isJuceModule ? juceModules : userModules)
                       : jucerFile.getParentDirectory().getChildFile(modulePath))
          .getChildFile(moduleName)
          .getChildFile(moduleName + ".h");
      if (!moduleHeader.existsAsFile())
      {
        std::cerr << "warning: Couldn't a find module header for " << moduleName
                  << " module at \"" << moduleHeader.getFullPathName() << "\"."
                  << std::endl;
      }
      juce::StringArray moduleHeaderLines;
      moduleHeader.readLines(moduleHeaderLines);

      const auto& modulesOptions = safeGetChildByName(jucerProject, "JUCEOPTIONS");

      for (const auto& line : moduleHeaderLines)
      {
        if (line.startsWith("/** Config: "))
        {
          const auto moduleOption = line.substring(12).trim();
          const auto& optionValue = modulesOptions.getStringAttribute(moduleOption);

          if (optionValue == "1" || optionValue == "enabled")
          {
            writeUnquoted(moduleOption, "ON");
          }
          else if (optionValue == "0" || optionValue == "disabled")
          {
            writeUnquoted(moduleOption, "OFF");
          }
          else
          {
            writeUnquoted(moduleOption, "");
          }
        }
      }

      wLn(")");
      wLn();
    }
  }

  // jucer_appconfig_header()
  {
    const auto appConfigFile =
      jucerFile.getSiblingFile("JuceLibraryCode").getChildFile("AppConfig.h");

    juce::StringArray appConfigLines;
    appConfigLines.addLines(appConfigFile.loadFileAsString());

    if (!appConfigLines.isEmpty())
    {
      juce::StringArray userCodeSectionLines;

      for (auto i = 0; i < appConfigLines.size(); ++i)
      {
        if (appConfigLines[i].contains("[BEGIN_USER_CODE_SECTION]"))
        {
          for (auto j = i + 1; j < appConfigLines.size()
                               && !appConfigLines[j].contains("[END_USER_CODE_SECTION]");
               ++j)
          {
            userCodeSectionLines.add(appConfigLines[j]);
          }

          break;
        }
      }

      const auto kDefaultProjucerUserCodeSectionCommentLines = juce::StringArray{
        "",
        "// (You can add your own code in this section, and the Projucer will not "
        "overwrite it)",
        ""};

      if (userCodeSectionLines != kDefaultProjucerUserCodeSectionCommentLines)
      {
        wLn("jucer_appconfig_header(");
        wLn("  USER_CODE_SECTION");
        wLn("\"", escape("\\\"", userCodeSectionLines.joinIntoString("\n")), "\"");
        wLn(")");
        wLn();
      }
    }
  }

  // jucer_export_target() and jucer_export_target_configuration()
  {
    const auto supportedExporters =
      juce::StringArray{"XCODE_MAC",       "XCODE_IPHONE", "VS2022",
                        "VS2019",          "VS2017",       "VS2015",
                        "VS2013",          "LINUX_MAKE",   "CODEBLOCKS_WINDOWS",
                        "CODEBLOCKS_LINUX"};
    const auto exporterNames = std::map<juce::String, const char*>{
      {"XCODE_MAC",
       jucerVersionAsTuple < Version{6, 0, 2} ? "Xcode (MacOSX)" : "Xcode (macOS)"},
      {"XCODE_IPHONE", "Xcode (iOS)"},
      {"VS2022", "Visual Studio 2022"},
      {"VS2019", "Visual Studio 2019"},
      {"VS2017", "Visual Studio 2017"},
      {"VS2015", "Visual Studio 2015"},
      {"VS2013", "Visual Studio 2013"},
      {"LINUX_MAKE", "Linux Makefile"},
      {"CODEBLOCKS_WINDOWS", "Code::Blocks (Windows)"},
      {"CODEBLOCKS_LINUX", "Code::Blocks (Linux)"},
    };

    juce::StringPairArray configurationNamesMapping;

    const auto& exportFormats = safeGetChildByName(jucerProject, "EXPORTFORMATS");
    for (auto pExporter = exportFormats.getFirstChildElement(); pExporter != nullptr;
         pExporter = pExporter->getNextElement())
    {
      if (pExporter->isTextElement())
      {
        continue;
      }

      const auto& exporter = *pExporter;
      const auto& exporterType = exporter.getTagName();

      if (!supportedExporters.contains(exporterType))
      {
        continue;
      }

      const auto exporterName = exporterNames.at(exporterType);
      const auto& configurations = safeGetChildByName(exporter, "CONFIGURATIONS");

      wLn("jucer_export_target(");
      wLn("  \"", exporterName, "\"");

      const auto isXcodeExporter =
        exporterType == "XCODE_MAC" || exporterType == "XCODE_IPHONE";

      const auto isVSExporter = exporterType == "VS2022" || exporterType == "VS2019"
                                || exporterType == "VS2017" || exporterType == "VS2015"
                                || exporterType == "VS2013";

      juce::StringArray needTargetFolder;

      if (jucerProject.hasAttribute("headerPath"))
      {
        needTargetFolder.add("HEADER_SEARCH_PATHS");
      }

      if (isXcodeExporter)
      {
        if (exporter.hasAttribute("frameworkSearchPaths"))
        {
          needTargetFolder.add("FRAMEWORK_SEARCH_PATHS");
        }
        if (exporter.hasAttribute("prebuildCommand"))
        {
          needTargetFolder.add("PREBUILD_SHELL_SCRIPT");
        }
        if (exporter.hasAttribute("postbuildCommand"))
        {
          needTargetFolder.add("POSTBUILD_SHELL_SCRIPT");
        }
      }

      for (auto pConfiguration = configurations.getFirstChildElement();
           pConfiguration != nullptr; pConfiguration = pConfiguration->getNextElement())
      {
        if (pConfiguration->isTextElement())
        {
          continue;
        }

        if (pConfiguration->hasAttribute("headerPath"))
        {
          needTargetFolder.add("HEADER_SEARCH_PATHS");
        }
        if (pConfiguration->hasAttribute("libraryPath"))
        {
          needTargetFolder.add("EXTRA_LIBRARY_SEARCH_PATHS");
        }

        if (isVSExporter)
        {
          if (pConfiguration->hasAttribute("prebuildCommand"))
          {
            needTargetFolder.add("PREBUILD_COMMAND");
          }
          if (pConfiguration->hasAttribute("postbuildCommand"))
          {
            needTargetFolder.add("POSTBUILD_COMMAND");
          }
        }
      }

      const auto kIgnoreCase = false;
      needTargetFolder.removeDuplicates(kIgnoreCase);
      if (!needTargetFolder.isEmpty())
      {
        wLn("  TARGET_PROJECT_FOLDER \"", exporter.getStringAttribute("targetFolder"),
            "\" # used by ", needTargetFolder.joinIntoString(", "));
      }

      const auto isAudioPlugin = projectType == "audioplug";
      const auto pluginFormats = juce::StringArray::fromTokens(
        jucerProject.getStringAttribute("pluginFormats"), ",", {});
      const auto hasJuceAudioProcessorsModule =
        safeGetChildByName(jucerProject, "MODULES")
          .getChildByAttribute("id", "juce_audio_processors")
        != nullptr;

      const auto hasVst2Interface = jucerVersionAsTuple > Version{4, 2, 3};
      const auto isVstAudioPlugin =
        isAudioPlugin
        && (pluginFormats.contains("buildVST")
            || toBoolLikeVar(jucerProject.getStringAttribute("buildVST")));
      const auto& pluginHostVstOption = safeGetChildByName(jucerProject, "JUCEOPTIONS")
                                          .getStringAttribute("JUCE_PLUGINHOST_VST");
      const auto isVstPluginHost =
        hasJuceAudioProcessorsModule
        && (pluginHostVstOption == "enabled" || pluginHostVstOption == "1");

      if (!hasVst2Interface && (isVstAudioPlugin || isVstPluginHost))
      {
        convertSetting(exporter, "vstFolder", "VST_SDK_FOLDER", {});
      }

      const auto vstIsLegacy = jucerVersionAsTuple > Version{5, 3, 2};

      if (vstIsLegacy && (isVstAudioPlugin || isVstPluginHost))
      {
        convertSetting(exporter, "vstLegacyFolder", "VST_LEGACY_SDK_FOLDER", {});
      }

      const auto supportsVst3 = exporterType == "XCODE_MAC" || isVSExporter;
      const auto isVst3AudioPlugin =
        isAudioPlugin
        && (pluginFormats.contains("buildVST3")
            || toBoolLikeVar(jucerProject.getStringAttribute("buildVST3")));
      const auto& pluginHostVst3Option = safeGetChildByName(jucerProject, "JUCEOPTIONS")
                                           .getStringAttribute("JUCE_PLUGINHOST_VST3");
      const auto isVst3PluginHost =
        hasJuceAudioProcessorsModule
        && (pluginHostVst3Option == "enabled" || pluginHostVst3Option == "1");

      if (supportsVst3 && (isVst3AudioPlugin || isVst3PluginHost))
      {
        convertSetting(exporter, "vst3Folder", "VST3_SDK_FOLDER", {});
      }

      const auto supportsAaxRtas = exporterType == "XCODE_MAC" || isVSExporter;

      if (supportsAaxRtas && isAudioPlugin)
      {
        if (pluginFormats.contains("buildAAX")
            || toBoolLikeVar(jucerProject.getStringAttribute("buildAAX")))
        {
          convertSetting(exporter, "aaxFolder", "AAX_SDK_FOLDER", {});
        }

        if (pluginFormats.contains("buildRTAS")
            || toBoolLikeVar(jucerProject.getStringAttribute("buildRTAS")))
        {
          convertSetting(exporter, "rtasFolder", "RTAS_SDK_FOLDER", {});
        }
      }

      convertSettingAsListIfDefined(exporter, "extraDefs",
                                    "EXTRA_PREPROCESSOR_DEFINITIONS",
                                    parsePreprocessorDefinitions);
      convertSettingAsListIfDefined(exporter, "extraCompilerFlags",
                                    "EXTRA_COMPILER_FLAGS",
                                    [](const juce::String& value) {
                                      return juce::StringArray::fromTokens(value, false);
                                    });

      const auto compilerFlagSchemesArray = juce::StringArray::fromTokens(
        jucerProject.getStringAttribute("compilerFlagSchemes"), ",", {});
      // Use a juce::HashMap like Projucer does, in order to get the same ordering.
      juce::HashMap<juce::String, std::tuple<>> compilerFlagSchemesMap;
      for (const auto& scheme : compilerFlagSchemesArray)
      {
        compilerFlagSchemesMap.set(scheme, {});
      }
      for (juce::HashMap<juce::String, std::tuple<>>::Iterator i(compilerFlagSchemesMap);
           i.next();)
      {
        convertSettingIfDefined(exporter, i.getKey(), "COMPILER_FLAGS_FOR_" + i.getKey(),
                                {});
      }

      convertSettingAsListIfDefined(exporter, "extraLinkerFlags", "EXTRA_LINKER_FLAGS",
                                    [](const juce::String& value) {
                                      return juce::StringArray::fromTokens(value, false);
                                    });
      convertSettingAsListIfDefined(exporter, "externalLibraries",
                                    "EXTERNAL_LIBRARIES_TO_LINK", {});

      convertOnOffSettingIfDefined(exporter, "enableGNUExtensions",
                                   "GNU_COMPILER_EXTENSIONS", {});

      const auto convertIcon =
        [&jucerProject](const juce::String& fileId) -> juce::String {
        if (fileId.isNotEmpty())
        {
          if (const auto pFile = getChildByAttributeRecursively(
                safeGetChildByName(jucerProject, "MAINGROUP"), "id", fileId))
          {
            return pFile->getStringAttribute("file");
          }
        }

        return "<None>";
      };

      convertSettingIfDefined(exporter, "smallIcon", "ICON_SMALL", convertIcon);
      convertSettingIfDefined(exporter, "bigIcon", "ICON_LARGE", convertIcon);

      if (exporterType == "XCODE_IPHONE")
      {
        convertSettingIfDefined(exporter, "customXcassetsFolder",
                                "CUSTOM_XCASSETS_FOLDER", {});
        convertSettingIfDefined(exporter, "customLaunchStoryboard",
                                "CUSTOM_LAUNCH_STORYBOARD", {});
      }

      if (isXcodeExporter)
      {
        convertSettingAsListIfDefined(
          exporter, "customXcodeResourceFolders", "CUSTOM_XCODE_RESOURCE_FOLDERS",
          [](const juce::String& value) {
            auto folders = juce::StringArray::fromLines(value);
            folders.trim();
            return folders;
          });

        if (isAudioPlugin)
        {
          convertOnOffSettingIfDefined(exporter, "duplicateAppExResourcesFolder",
                                       "ADD_DUPLICATE_RESOURCES_FOLDER_TO_APP_EXTENSION",
                                       {});
        }
      }

      if (exporterType == "XCODE_IPHONE")
      {
        convertSettingIfDefined(exporter, "iosDeviceFamily", "DEVICE_FAMILY",
                                [](const juce::String& value) -> juce::String {
                                  if (value == "1")
                                    return "iPhone";

                                  if (value == "2")
                                    return "iPad";

                                  if (value == "1,2")
                                    return "Universal";

                                  return value;
                                });

        const auto screenOrientationFn = [](const juce::String& value) -> juce::String {
          if (value == "portraitlandscape")
            return "Portrait and Landscape";

          if (value == "portrait")
            return "Portrait";

          if (value == "landscape")
            return "Landscape";

          return value;
        };
        const auto screenOrientationsFn = [](const juce::String& value) {
          return convertIdsToStrings(
            juce::StringArray::fromTokens(value, ",", {}),
            {{"UIInterfaceOrientationPortrait", "Portrait"},
             {"UIInterfaceOrientationPortraitUpsideDown", "Portrait Upside Down"},
             {"UIInterfaceOrientationLandscapeLeft", "Landscape Left"},
             {"UIInterfaceOrientationLandscapeRight", "Landscape Right"}});
        };
        if (exporter.hasAttribute("iosScreenOrientation"))
        {
          const auto value = exporter.getStringAttribute("iosScreenOrientation");
          const auto screenOrientations = screenOrientationsFn(value);
          if (!screenOrientations.isEmpty())
          {
            writeList("IPHONE_SCREEN_ORIENTATION", screenOrientations);
          }
          else
          {
            writeQuoted("IPHONE_SCREEN_ORIENTATION", screenOrientationFn(value));
          }
        }
        if (exporter.hasAttribute("iPadScreenOrientation"))
        {
          const auto value = exporter.getStringAttribute("iPadScreenOrientation");
          const auto screenOrientations = screenOrientationsFn(value);
          if (!screenOrientations.isEmpty())
          {
            writeList("IPAD_SCREEN_ORIENTATION", screenOrientations);
          }
          else
          {
            writeQuoted("IPAD_SCREEN_ORIENTATION", screenOrientationFn(value));
          }
        }

        convertOnOffSettingIfDefined(exporter, "UIFileSharingEnabled",
                                     "FILE_SHARING_ENABLED", {});
        convertOnOffSettingIfDefined(exporter, "UISupportsDocumentBrowser",
                                     "SUPPORT_DOCUMENT_BROWSER", {});
        convertOnOffSettingIfDefined(exporter, "UIStatusBarHidden", "STATUS_BAR_HIDDEN",
                                     {});
        convertOnOffSettingIfDefined(exporter, "UIRequiresFullScreen",
                                     "REQUIRES_FULL_SCREEN", {});
      }

      if (exporterType == "XCODE_MAC")
      {
        if (projectType == "guiapp")
        {
          convertSettingAsListIfDefined(
            exporter, "documentExtensions", "DOCUMENT_FILE_EXTENSIONS",
            [](const juce::String& value) {
              return juce::StringArray::fromTokens(value, ",", {});
            });
        }
      }

      convertOnOffSettingIfDefined(exporter, "useLegacyBuildSystem",
                                   "USE_LEGACY_BUILD_SYSTEM", {});

      if (exporterType == "XCODE_MAC")
      {
        convertSettingAsListIfDefined(exporter, "xcodeValidArchs", "VALID_ARCHITECTURES",
                                      [](const juce::String& value) {
                                        return juce::StringArray::fromTokens(value, ",",
                                                                             {});
                                      });

        convertOnOffSettingIfDefined(exporter, "appSandbox", "USE_APP_SANDBOX", {});
        convertOnOffSettingIfDefined(exporter, "appSandboxInheritance",
                                     "APP_SANDBOX_INHERITANCE", {});
        convertSettingAsListIfDefined(
          exporter, "appSandboxOptions", "APP_SANDBOX_OPTIONS",
          [](const juce::String& value) {
            return convertIdsToStrings(
              juce::StringArray::fromTokens(value, ",", {}),
              {{"com.apple.security.network.server",
                "Network: Incoming Connections (Server)"},
               {"com.apple.security.network.client",
                "Network: Outgoing Connections (Client)"},
               {"com.apple.security.device.camera", "Hardware: Camera"},
               {"com.apple.security.device.microphone", "Hardware: Microphone"},
               {"com.apple.security.device.usb", "Hardware: USB"},
               {"com.apple.security.print", "Hardware: Printing"},
               {"com.apple.security.device.bluetooth", "Hardware: Bluetooth"},
               {"com.apple.security.personal-information.addressbook",
                "App Data: Contacts"},
               {"com.apple.security.personal-information.location", "App Data: Location"},
               {"com.apple.security.personal-information.calendars",
                "App Data: Calendar"},
               {"com.apple.security.files.user-selected.read-only",
                "File Access: User Selected File (Read Only)"},
               {"com.apple.security.files.user-selected.read-write",
                "File Access: User Selected File (Read/Write)"},
               {"com.apple.security.files.downloads.read-only",
                "File Access: Downloads Folder (Read Only)"},
               {"com.apple.security.files.downloads.read-write",
                "File Access: Downloads Folder (Read/Write)"},
               {"com.apple.security.files.pictures.read-only",
                "File Access: Pictures Folder (Read Only)"},
               {"com.apple.security.files.pictures.read-write",
                "File Access: Pictures Folder (Read/Write)"},
               {"com.apple.security.assets.music.read-only",
                "File Access: Music Folder (Read Only)"},
               {"com.apple.security.assets.music.read-write",
                "File Access: Music Folder (Read/Write)"},
               {"com.apple.security.assets.movies.read-only",
                "File Access: Movies Folder (Read Only)"},
               {"com.apple.security.assets.movies.read-write",
                "File Access: Movies Folder (Read/Write)"},
               {"com.apple.security.temporary-exception.audio-unit-host",
                "Temporary Exception: Audio Unit Hosting"},
               {"com.apple.security.temporary-exception.mach-lookup.global-name",
                "Temporary Exception: Global Mach Service"},
               {"com.apple.security.temporary-exception.mach-register.global-name",
                "Temporary Exception: Global Mach Service Dynamic Registration"},
               {"com.apple.security.temporary-exception.files.home-relative-path.read-"
                "only",
                "Temporary Exception: Home Directory File Access (Read Only)"},
               {"com.apple.security.temporary-exception.files.home-relative-path.read-"
                "write",
                "Temporary Exception: Home Directory File Access (Read/Write)"},
               {"com.apple.security.temporary-exception.files.absolute-path.read-only",
                "Temporary Exception: Absolute Path File Access (Read Only)"},
               {"com.apple.security.temporary-exception.files.absolute-path.read-write",
                "Temporary Exception: Absolute Path File Access (Read/Write)"},
               {"com.apple.security.temporary-exception.iokit-user-client-class",
                "Temporary Exception: IOKit User Client Class"},
               {"com.apple.security.temporary-exception.shared-preference.read-only",
                "Temporary Exception: Shared Preference Domain (Read Only)"},
               {"com.apple.security.temporary-exception.shared-preference.read-write",
                "Temporary Exception: Shared Preference Domain (Read/Write)"}});
          });

        convertOnOffSettingIfDefined(exporter, "hardenedRuntime", "USE_HARDENED_RUNTIME",
                                     {});
        if (jucerVersionAsTuple >= Version{5, 4, 4})
        {
          convertSettingAsListIfDefined(
            exporter, "hardenedRuntimeOptions", "HARDENED_RUNTIME_OPTIONS",
            [](const juce::String& value) {
              return convertIdsToStrings(
                juce::StringArray::fromTokens(value, ",", {}),
                {{"com.apple.security.cs.allow-jit",
                  "Runtime Exceptions: Allow Execution of JIT-compiled Code"},
                 {"com.apple.security.cs.allow-unsigned-executable-memory",
                  "Runtime Exceptions: Allow Unsigned Executable Memory"},
                 {"com.apple.security.cs.allow-dyld-environment-variables",
                  "Runtime Exceptions: Allow DYLD Environment Variables"},
                 {"com.apple.security.cs.disable-library-validation",
                  "Runtime Exceptions: Disable Library Validation"},
                 {"com.apple.security.cs.disable-executable-page-protection",
                  "Runtime Exceptions: Disable Executable Memory Protection"},
                 {"com.apple.security.cs.debugger", "Runtime Exceptions: Debugging Tool"},
                 {"com.apple.security.device.audio-input",
                  "Resource Access: Audio Input"},
                 {"com.apple.security.device.camera", "Resource Access: Camera"},
                 {"com.apple.security.personal-information.location",
                  "Resource Access: Location"},
                 {"com.apple.security.personal-information.addressbook",
                  "Resource Access: Address Book"},
                 {"com.apple.security.personal-information.calendars",
                  "Resource Access: Calendar"},
                 {"com.apple.security.personal-information.photos-library",
                  "Resource Access: Photos Library"},
                 {"com.apple.security.automation.apple-events",
                  "Resource Access: Apple Events"}});
            });
        }
        else
        {
          convertSettingAsListIfDefined(
            exporter, "hardenedRuntimeOptions", "HARDENED_RUNTIME_OPTIONS",
            [](const juce::String& value) {
              return convertIdsToStrings(
                juce::StringArray::fromTokens(value, ",", {}),
                {{"com.apple.security.cs.allow-jit",
                  "Allow Execution of JIT-compiled Code"},
                 {"com.apple.security.cs.allow-unsigned-executable-memory",
                  "Allow Unsigned Executable Memory"},
                 {"com.apple.security.cs.allow-dyld-environment-variables",
                  "Allow DYLD Environment Variables"},
                 {"com.apple.security.cs.disable-library-validation",
                  "Disable Library Validation"},
                 {"com.apple.security.cs.disable-executable-page-protection",
                  "Disable Executable Memory Protection"},
                 {"com.apple.security.cs.debugger", "Debugging Tool"},
                 {"com.apple.security.device.audio-input", "Audio Input"},
                 {"com.apple.security.device.camera", "Camera"},
                 {"com.apple.security.personal-information.location", "Location"},
                 {"com.apple.security.personal-information.addressbook", "Address Book"},
                 {"com.apple.security.personal-information.calendars", "Calendar"},
                 {"com.apple.security.personal-information.photos-library",
                  "Photos Library"},
                 {"com.apple.security.automation.apple-events", "Apple Events"}});
            });
        }
      }

      if (isXcodeExporter)
      {
        convertOnOffSettingIfDefined(exporter, "microphonePermissionNeeded",
                                     "MICROPHONE_ACCESS", {});
        convertSettingIfDefined(exporter, "microphonePermissionsText",
                                "MICROPHONE_ACCESS_TEXT", {});
        convertOnOffSettingIfDefined(exporter, "cameraPermissionNeeded", "CAMERA_ACCESS",
                                     {});
        convertSettingIfDefined(exporter, "cameraPermissionText", "CAMERA_ACCESS_TEXT",
                                {});
        convertOnOffSettingIfDefined(exporter, "iosBluetoothPermissionNeeded",
                                     "BLUETOOTH_ACCESS", {});
        convertSettingIfDefined(exporter, "iosBluetoothPermissionText",
                                "BLUETOOTH_ACCESS_TEXT", {});
      }

      if (exporterType == "XCODE_MAC")
      {
        convertOnOffSettingIfDefined(exporter, "sendAppleEventsPermissionNeeded",
                                     "SEND_APPLE_EVENTS", {});
        convertSettingIfDefined(exporter, "sendAppleEventsPermissionText",
                                "SEND_APPLE_EVENTS_TEXT", {});
      }

      if (isXcodeExporter)
      {
        convertOnOffSettingIfDefined(exporter, "iosInAppPurchasesValue",
                                     "IN_APP_PURCHASES_CAPABILITY", {});
      }

      if (exporterType == "XCODE_IPHONE")
      {
        convertOnOffSettingIfDefined(exporter, "iosContentSharing", "CONTENT_SHARING",
                                     {});
        convertOnOffSettingIfDefined(exporter, "iosBackgroundAudio",
                                     "AUDIO_BACKGROUND_CAPABILITY", {});
        convertOnOffSettingIfDefined(exporter, "iosBackgroundBle",
                                     "BLUETOOTH_MIDI_BACKGROUND_CAPABILITY", {});
        convertOnOffSettingIfDefined(exporter, "iosAppGroups", "APP_GROUPS_CAPABILITY",
                                     {});
        convertOnOffSettingIfDefined(exporter, "iCloudPermissions", "ICLOUD_PERMISSIONS",
                                     {});
      }

      if (isXcodeExporter)
      {
        convertOnOffSettingIfDefined(exporter, "iosPushNotifications",
                                     "PUSH_NOTIFICATIONS_CAPABILITY", {});

        convertSettingIfDefined(exporter, "customPList", "CUSTOM_PLIST", {});
        convertOnOffSettingIfDefined(exporter, "PListPreprocess", "PLIST_PREPROCESS", {});
        convertOnOffSettingIfDefined(exporter, "pListPreprocess", "PLIST_PREPROCESS", {});
        const auto convertPrefixHeader = [&jucerFile,
                                          &exporter](const juce::String& value) {
          if (value.isEmpty())
            return juce::String{};

          const auto jucerFileDir = jucerFile.getParentDirectory();
          const auto targetProjectDir =
            jucerFileDir.getChildFile(exporter.getStringAttribute("targetFolder"));

          return targetProjectDir.getChildFile(value).getRelativePathFrom(jucerFileDir);
        };
        convertSettingIfDefined(exporter, "PListPrefixHeader", "PLIST_PREFIX_HEADER",
                                convertPrefixHeader);
        convertSettingIfDefined(exporter, "pListPrefixHeader", "PLIST_PREFIX_HEADER",
                                convertPrefixHeader);

        convertOnOffSettingIfDefined(exporter, "suppressPlistResourceUsage",
                                     "SUPPRESS_AUDIOUNIT_PLIST_RESOURCE_USAGE_KEY", {});

        convertSettingAsListIfDefined(
          exporter, "extraFrameworks",
          jucerVersionAsTuple > Version{5, 3, 2} ? "EXTRA_SYSTEM_FRAMEWORKS"
                                                 : "EXTRA_FRAMEWORKS",
          [](const juce::String& value) {
            auto frameworks = juce::StringArray::fromTokens(value, ",;", "\"'");
            frameworks.trim();
            return frameworks;
          });
        convertSettingAsListIfDefined(exporter, "frameworkSearchPaths",
                                      "FRAMEWORK_SEARCH_PATHS", {});
        convertSettingAsListIfDefined(exporter, "extraCustomFrameworks",
                                      "EXTRA_CUSTOM_FRAMEWORKS", {});
        convertSettingAsListIfDefined(exporter, "embeddedFrameworks",
                                      "EMBEDDED_FRAMEWORKS", {});
        convertSettingAsListIfDefined(exporter, "xcodeSubprojects", "XCODE_SUBPROJECTS",
                                      {});
        convertRawStringSettingIfDefined(exporter, "prebuildCommand",
                                         "PREBUILD_SHELL_SCRIPT", {});
        convertRawStringSettingIfDefined(exporter, "postbuildCommand",
                                         "POSTBUILD_SHELL_SCRIPT", {});
        convertSettingIfDefined(exporter, "bundleIdentifier",
                                "EXPORTER_BUNDLE_IDENTIFIER", {});
        convertSettingIfDefined(exporter, "iosDevelopmentTeamID", "DEVELOPMENT_TEAM_ID",
                                {});
      }

      if (exporterType == "XCODE_IPHONE")
      {
        convertSettingAsListIfDefined(
          exporter, "iosAppGroupsId", "APP_GROUP_ID", [](const juce::String& value) {
            auto groups = juce::StringArray::fromTokens(value, ";", {});
            groups.trim();
            return groups;
          });
      }

      if (isXcodeExporter)
      {
        convertOnOffSettingIfDefined(exporter, "keepCustomXcodeSchemes",
                                     "KEEP_CUSTOM_XCODE_SCHEMES", {});
        convertOnOffSettingIfDefined(exporter, "useHeaderMap", "USE_HEADERMAP", {});
      }

      if (isVSExporter)
      {
        convertSettingIfDefined(exporter, "msvcManifestFile", "MANIFEST_FILE", {});

        if (exporter.hasAttribute("toolset"))
        {
          const auto& toolset = exporter.getStringAttribute("toolset");
          if (toolset.isEmpty())
          {
            wLn("  # PLATFORM_TOOLSET \"(default)\"");
          }
          else
          {
            wLn("  # PLATFORM_TOOLSET \"", toolset, "\"");
          }
        }

        convertSettingIfDefined(
          exporter, "IPPLibrary", "USE_IPP_LIBRARY",
          [&jucerVersionAsTuple](const juce::String& value) -> juce::String {
            if (value.isEmpty())
              return "No";

            if (value == "true")
              return jucerVersionAsTuple >= Version{5, 2, 1} ? "Yes (Default Mode)"
                                                             : "Yes (Default Linking)";

            if (value == "Parallel_Static")
              return "Multi-Threaded Static Library";

            if (value == "Sequential")
              return "Single-Threaded Static Library";

            if (value == "Parallel_Dynamic")
              return "Multi-Threaded DLL";

            if (value == "Sequential_Dynamic")
              return "Single-Threaded DLL";

            return {};
          });

        convertSettingIfDefined(exporter, "IPP1ALibrary", "USE_IPP_LIBRARY_ONE_API",
                                [](const juce::String& value) -> juce::String {
                                  if (value.isEmpty())
                                    return "No";

                                  if (value == "true")
                                    return "Yes (Default Linking)";

                                  if (value == "Static_Library")
                                    return "Static Library";

                                  if (value == "Dynamic_Library")
                                    return "Dynamic Library";

                                  return value;
                                });

        convertSettingIfDefined(exporter, "MKL1ALibrary", "USE_MKL_LIBRARY_ONE_API",
                                [](const juce::String& value) -> juce::String {
                                  return value.isEmpty() ? "No" : value;
                                });

        convertSettingIfDefined(exporter, "windowsTargetPlatformVersion",
                                "WINDOWS_TARGET_PLATFORM", {});

        if (exporterType == "VS2017")
        {
          convertSettingIfDefined(exporter, "cppLanguageStandard", "CXX_STANDARD_TO_USE",
                                  [](const juce::String& value) -> juce::String {
                                    if (value.isEmpty())
                                      return "(default)";
                                    if (value == "stdcpp14")
                                      return "C++14";
                                    if (value == "stdcpplatest")
                                      return "Latest C++ Standard";
                                    return {};
                                  });
        }
      }

      if (exporterType == "LINUX_MAKE")
      {
        convertSettingIfDefined(exporter, "cppLanguageStandard", "CXX_STANDARD_TO_USE",
                                [](const juce::String& value) -> juce::String {
                                  if (value == "-std=c++03")
                                    return "C++03";

                                  if (value == "-std=c++11")
                                    return "C++11";

                                  if (value == "-std=c++14")
                                    return "C++14";

                                  return {};
                                });

        convertSettingAsListIfDefined(
          exporter, "linuxExtraPkgConfig", "PKGCONFIG_LIBRARIES",
          [](const juce::String& value) {
            return juce::StringArray::fromTokens(value, " ", "\"'");
          });
      }

      if (exporterType == "CODEBLOCKS_WINDOWS")
      {
        const auto windowsTargets = std::map<juce::String, const char*>{
          {"0x0400", "Windows NT 4.0"}, {"0x0500", "Windows 2000"},
          {"0x0501", "Windows XP"},     {"0x0502", "Windows Server 2003"},
          {"0x0600", "Windows Vista"},  {"0x0601", "Windows 7"},
          {"0x0602", "Windows 8"},      {"0x0603", "Windows 8.1"},
          {"0x0A00", "Windows 10"},
        };

        convertSettingIfDefined(
          exporter, "codeBlocksWindowsTarget", "TARGET_PLATFORM",
          [&windowsTargets](const juce::String& value) -> juce::String {
            auto search = windowsTargets.find(value);
            if (search != windowsTargets.end())
            {
              return search->second;
            }

            return {};
          });
      }

      writeUserNotes(wLn, exporter);

      wLn(")");
      wLn();

      for (auto pConfiguration = configurations.getFirstChildElement();
           pConfiguration != nullptr; pConfiguration = pConfiguration->getNextElement())
      {
        if (pConfiguration->isTextElement())
        {
          continue;
        }

        const auto& configuration = *pConfiguration;

        wLn("jucer_export_target_configuration(");
        wLn("  \"", exporterName, "\"");

        const auto originalName = configuration.getStringAttribute("name");
        if (std::regex_match(originalName.toStdString(), std::regex{"^[A-Za-z0-9_]+$"}))
        {
          writeQuoted("NAME", originalName);
        }
        else
        {
          if (!configurationNamesMapping.containsKey(originalName))
          {
            const auto validNameWithoutSuffix = makeValidConfigurationName(originalName);

            auto numberSuffix = 1;
            auto validName = validNameWithoutSuffix;
            while (configurationNamesMapping.getAllValues().contains(validName))
            {
              validName = validNameWithoutSuffix + "_" + juce::String{numberSuffix++};
            }

            configurationNamesMapping.set(originalName, validName);

            std::cerr << "warning: \"" << originalName
                      << "\" is not a valid CMake build configuration name. It has been "
                         "changed to \""
                      << validName << "\" in the generated CMakeLists.txt file."
                      << std::endl;
          }

          wLn("  NAME \"", configurationNamesMapping[originalName], "\" # originally \"",
              originalName, "\" in ", jucerFileName);
        }

        const auto isDebug = toBoolLikeVar(configuration.getStringAttribute("isDebug"));
        writeUnquoted("DEBUG_MODE", (isDebug ? "ON" : "OFF"));

        convertSettingIfDefined(configuration, "targetName", "BINARY_NAME", {});
        convertSettingIfDefined(configuration, "binaryPath", "BINARY_LOCATION", {});

        convertSettingAsListIfDefined(configuration, "headerPath", "HEADER_SEARCH_PATHS",
                                      parseSearchPaths);
        convertSettingAsListIfDefined(configuration, "libraryPath",
                                      "EXTRA_LIBRARY_SEARCH_PATHS", parseSearchPaths);

        convertSettingAsListIfDefined(configuration, "defines",
                                      "PREPROCESSOR_DEFINITIONS",
                                      parsePreprocessorDefinitions);

        convertOnOffSettingIfDefined(configuration, "linkTimeOptimisation",
                                     "LINK_TIME_OPTIMISATION", {});

        if (!configuration.hasAttribute("linkTimeOptimisation") && isVSExporter
            && !isDebug && jucerVersionAsTuple >= Version{5, 2, 0})
        {
          convertOnOffSettingIfDefined(configuration, "wholeProgramOptimisation",
                                       "LINK_TIME_OPTIMISATION",
                                       [](const juce::String& value) {
                                         if (value.getIntValue() == 0)
                                           return "ON";

                                         return "OFF";
                                       });
        }

        if (isXcodeExporter || isVSExporter)
        {
          convertOnOffSettingIfDefined(configuration, "usePrecompiledHeaderFile",
                                       "USE_PRECOMPILED_HEADER", {});

          convertSettingIfDefined(configuration, "precompiledHeaderFile",
                                  "PRECOMPILED_HEADER_FILE", {});
        }

        if (isXcodeExporter)
        {
          convertSettingIfDefined(configuration, "recommendedWarnings",
                                  "ADD_RECOMMENDED_COMPILER_WARNING_FLAGS",
                                  [](const juce::String& value) -> juce::String {
                                    if (value == "LLVM")
                                      return "Enabled";

                                    if (value.isEmpty())
                                      return "Disabled";

                                    return {};
                                  });
        }
        else if (exporterType == "CODEBLOCKS_LINUX"
                 || exporterType == "CODEBLOCKS_WINDOWS" || exporterType == "LINUX_MAKE")
        {
          convertSettingIfDefined(configuration, "recommendedWarnings",
                                  "ADD_RECOMMENDED_COMPILER_WARNING_FLAGS",
                                  [](const juce::String& value) -> juce::String {
                                    if (value == "GCC")
                                      return "GCC";

                                    if (value == "GCC-7")
                                      return "GCC 7 and below";

                                    if (value == "LLVM")
                                      return "LLVM";

                                    if (value.isEmpty())
                                      return "Disabled";

                                    return {};
                                  });
        }

        convertSettingIfDefined(
          configuration, "optimisation", "OPTIMISATION",
          [&isVSExporter](const juce::String& value) -> juce::String {
            if (isVSExporter)
            {
              switch (value.getIntValue())
              {
              case 1:
                return "No optimisation";
              case 2:
                return "Minimise size";
              case 3:
                return "Maximise speed";
              }

              return {};
            }

            switch (value.getIntValue())
            {
            case 1:
              return "-O0 (no optimisation)";
            case 2:
              return "-Os (minimise code size)";
            case 3:
              return "-O3 (fastest with safe optimisations)";
            case 4:
              return "-O1 (fast)";
            case 5:
              return "-O2 (faster)";
            case 6:
              return "-Ofast (uses aggressive optimisations)";
            }

            return {};
          });

        if (isXcodeExporter)
        {
          convertOnOffSettingIfDefined(configuration, "enablePluginBinaryCopyStep",
                                       "ENABLE_PLUGIN_COPY_STEP", {});

          if (!vstIsLegacy)
          {
            if (configuration.hasAttribute("xcodeVstBinaryLocation"))
            {
              convertSetting(configuration, "xcodeVstBinaryLocation",
                             "VST_BINARY_LOCATION", {});
            }
            else
            {
              convertSettingIfDefined(configuration, "vstBinaryLocation",
                                      "VST_BINARY_LOCATION", {});
            }
          }

          const auto binaryLocationTuples = {
            std::make_tuple("xcodeVst3BinaryLocation", "vst3BinaryLocation",
                            "VST3_BINARY_LOCATION"),
            std::make_tuple("xcodeAudioUnitBinaryLocation", "auBinaryLocation",
                            "AU_BINARY_LOCATION"),
            std::make_tuple("xcodeRtasBinaryLocation", "rtasBinaryLocation",
                            "RTAS_BINARY_LOCATION"),
            std::make_tuple("xcodeAaxBinaryLocation", "aaxBinaryLocation",
                            "AAX_BINARY_LOCATION"),
          };

          for (const auto& binaryLocationTuple : binaryLocationTuples)
          {
            const auto& oldProperty = std::get<0>(binaryLocationTuple);
            const auto& newProperty = std::get<1>(binaryLocationTuple);
            const auto& cmakeKeyword = std::get<2>(binaryLocationTuple);

            if (configuration.hasAttribute(oldProperty))
            {
              convertSetting(configuration, oldProperty, cmakeKeyword, {});
            }
            else
            {
              convertSettingIfDefined(configuration, newProperty, cmakeKeyword, {});
            }
          }

          convertSettingIfDefined(configuration, "unityPluginBinaryLocation",
                                  "UNITY_BINARY_LOCATION", {});
          if (vstIsLegacy)
          {
            convertSettingIfDefined(configuration, "vstBinaryLocation",
                                    "VST_LEGACY_BINARY_LOCATION", {});
          }
        }

        if (exporterType == "XCODE_IPHONE")
        {
          convertSettingIfDefined(configuration, "iosBaseSDK", "IOS_BASE_SDK", {});

          if (configuration.hasAttribute("iosDeploymentTarget"))
          {
            convertSetting(configuration, "iosDeploymentTarget", "IOS_DEPLOYMENT_TARGET",
                           {});
          }
          else
          {
            convertSettingIfDefined(configuration, "iosCompatibility",
                                    "IOS_DEPLOYMENT_TARGET", {});
          }
        }

        if (exporterType == "XCODE_MAC")
        {
          const auto sdks = juce::StringArray{
            "10.5 SDK",  "10.6 SDK",  "10.7 SDK",  "10.8 SDK",  "10.9 SDK",
            "10.10 SDK", "10.11 SDK", "10.12 SDK", "10.13 SDK", "10.14 SDK",
            "10.15 SDK", "10.16 SDK", "11.0 SDK",  "11.1 SDK",
          };

          if (configuration.hasAttribute("macOSBaseSDK"))
          {
            convertSetting(configuration, "macOSBaseSDK", "MACOS_BASE_SDK", {});
          }
          else
          {
            convertSettingIfDefined(
              configuration, "osxSDK",
              jucerVersionAsTuple < Version{6, 0, 2} ? "OSX_BASE_SDK_VERSION"
                                                     : "MACOS_BASE_SDK_VERSION",
              [&jucerVersionAsTuple, &sdks](const juce::String& value) -> juce::String {
                if (value == "default")
                  return jucerVersionAsTuple < Version{5, 2, 1} ? "Use Default"
                                                                : "Default";

                if (sdks.contains(value))
                  return value;

                return {};
              });
          }

          if (configuration.hasAttribute("macOSDeploymentTarget"))
          {
            convertSetting(configuration, "macOSDeploymentTarget",
                           "MACOS_DEPLOYMENT_TARGET", {});
          }
          else
          {
            convertSettingIfDefined(
              configuration, "osxCompatibility",
              jucerVersionAsTuple < Version{6, 0, 2} ? "OSX_DEPLOYMENT_TARGET"
                                                     : "MACOS_DEPLOYMENT_TARGET",
              [&jucerVersionAsTuple, &sdks](const juce::String& value) -> juce::String {
                if (value == "default")
                  return jucerVersionAsTuple < Version{5, 2, 1} ? "Use Default"
                                                                : "Default";

                if (sdks.contains(value))
                  return value.substring(0, value.length() - 4);

                return {};
              });
          }

          if (jucerVersionAsTuple < Version{6, 0, 2})
          {
            convertSettingIfDefined(
              configuration, "osxArchitecture", "OSX_ARCHITECTURE",
              [&jucerVersionAsTuple](const juce::String& value) -> juce::String {
                if (value == "default")
                  return jucerVersionAsTuple < Version{5, 2, 1} ? "Use Default"
                                                                : "Default";

                if (value == "Native")
                  return "Native architecture of build machine";

                if (value == "32BitUniversal")
                  return "Universal Binary (32-bit)";

                if (value == "64BitUniversal")
                  return "Universal Binary (32/64-bit)";

                if (value == "64BitIntel")
                  return "64-bit Intel";

                return {};
              });
          }
          else
          {
            convertSettingIfDefined(configuration, "osxArchitecture",
                                    "MACOS_ARCHITECTURE",
                                    [](const juce::String& value) -> juce::String {
                                      if (value == "Native")
                                        return "Native architecture of build machine";

                                      if (value == "32BitUniversal")
                                        return "Standard 32-bit";

                                      if (value == "64BitUniversal")
                                        return "Standard 32/64-bit";

                                      if (value == "64BitIntel")
                                        return "Standard 64-bit";

                                      return {};
                                    });
          }
        }

        if (isXcodeExporter)
        {
          convertSettingAsListIfDefined(
            configuration, "customXcodeFlags", "CUSTOM_XCODE_FLAGS",
            [](const juce::String& value) {
              auto customFlags = juce::StringArray::fromTokens(value, ",", "\"'");
              customFlags.removeEmptyStrings();

              for (auto& flag : customFlags)
              {
                flag = flag.upToFirstOccurrenceOf("=", false, false).trim() + " = "
                       + flag.fromFirstOccurrenceOf("=", false, false).trim();
              }

              return customFlags;
            });

          convertSettingAsListIfDefined(configuration, "plistPreprocessorDefinitions",
                                        "PLIST_PREPROCESSOR_DEFINITIONS",
                                        parsePreprocessorDefinitions);

          convertSettingIfDefined(configuration, "cppLanguageStandard",
                                  "CXX_LANGUAGE_STANDARD",
                                  [](const juce::String& value) -> juce::String {
                                    if (value.isEmpty())
                                      return "Use Default";

                                    if (value == "c++98")
                                      return "C++98";

                                    if (value == "gnu++98")
                                      return "GNU++98";

                                    if (value == "c++11")
                                      return "C++11";

                                    if (value == "gnu++11")
                                      return "GNU++11";

                                    if (value == "c++14")
                                      return "C++14";

                                    if (value == "gnu++14")
                                      return "GNU++14";

                                    return {};
                                  });

          convertSettingIfDefined(
            configuration, "cppLibType", "CXX_LIBRARY",
            [&jucerVersionAsTuple](const juce::String& value) -> juce::String {
              if (value.isEmpty())
                return jucerVersionAsTuple < Version{5, 2, 1} ? "Use Default" : "Default";

              if (value == "libc++")
                return "LLVM libc++";

              if (value == "libstdc++")
                return "GNU libstdc++";

              return {};
            });

          convertSettingIfDefined(configuration, "codeSigningIdentity",
                                  "CODE_SIGNING_IDENTITY", {});
          convertOnOffSettingIfDefined(configuration, "fastMath", "RELAX_IEEE_COMPLIANCE",
                                       {});
          convertOnOffSettingIfDefined(configuration, "stripLocalSymbols",
                                       "STRIP_LOCAL_SYMBOLS", {});
        }

        if (isVSExporter)
        {
          convertOnOffSettingIfDefined(configuration, "enablePluginBinaryCopyStep",
                                       "ENABLE_PLUGIN_COPY_STEP", {});

          if (!vstIsLegacy)
          {
            convertSettingIfDefined(configuration, "vstBinaryLocation",
                                    "VST_BINARY_LOCATION", {});
          }
          convertSettingIfDefined(configuration, "vst3BinaryLocation",
                                  "VST3_BINARY_LOCATION", {});
          convertSettingIfDefined(configuration, "rtasBinaryLocation",
                                  "RTAS_BINARY_LOCATION", {});
          convertSettingIfDefined(configuration, "aaxBinaryLocation",
                                  "AAX_BINARY_LOCATION", {});
          convertSettingIfDefined(configuration, "unityPluginBinaryLocation",
                                  "UNITY_BINARY_LOCATION", {});
          if (vstIsLegacy)
          {
            convertSettingIfDefined(configuration, "vstBinaryLocation",
                                    "VST_LEGACY_BINARY_LOCATION", {});
          }

          convertSettingIfDefined(configuration, "winWarningLevel", "WARNING_LEVEL",
                                  [](const juce::String& value) -> juce::String {
                                    switch (value.getIntValue())
                                    {
                                    case 2:
                                      return "Low";
                                    case 3:
                                      return "Medium";
                                    case 4:
                                      return "High";
                                    }

                                    return "High";
                                  });

          convertOnOffSettingIfDefined(configuration, "warningsAreErrors",
                                       "TREAT_WARNINGS_AS_ERRORS", {});

          convertSettingIfDefined(
            configuration, "useRuntimeLibDLL", "RUNTIME_LIBRARY",
            [&jucerVersionAsTuple](const juce::String& value) -> juce::String {
              if (value.isEmpty())
                return jucerVersionAsTuple < Version{5, 2, 1} ? "(Default)" : "Default";

              if (value == "0")
                return "Use static runtime";

              if (value == "1")
                return "Use DLL runtime";

              return {};
            });

          if (jucerVersionAsTuple < Version{5, 2, 0})
          {
            convertSettingIfDefined(configuration, "wholeProgramOptimisation",
                                    "WHOLE_PROGRAM_OPTIMISATION",
                                    [](const juce::String& value) -> juce::String {
                                      if (value.isEmpty())
                                        return "Enable when possible";

                                      if (value.getIntValue() > 0)
                                        return "Always disable";

                                      return {};
                                    });
          }

          convertOnOffSettingIfDefined(configuration, "multiProcessorCompilation",
                                       "MULTI_PROCESSOR_COMPILATION", {});
          convertOnOffSettingIfDefined(configuration, "enableIncrementalLinking",
                                       "INCREMENTAL_LINKING", {});

          if (!isDebug)
          {
            convertOnOffSettingIfDefined(configuration, "alwaysGenerateDebugSymbols",
                                         "FORCE_GENERATION_OF_DEBUG_SYMBOLS", {});
          }

          convertSettingIfDefined(configuration, "prebuildCommand", "PREBUILD_COMMAND",
                                  {});
          convertSettingIfDefined(configuration, "postbuildCommand", "POSTBUILD_COMMAND",
                                  {});
          convertOnOffSettingIfDefined(configuration, "generateManifest",
                                       "GENERATE_MANIFEST", {});

          convertSettingIfDefined(configuration, "characterSet", "CHARACTER_SET",
                                  [](const juce::String& value) -> juce::String {
                                    if (value.isEmpty())
                                      return "Default";

                                    return value;
                                  });

          if (configuration.hasAttribute("winArchitecture"))
          {
            const auto& winArchitecture =
              configuration.getStringAttribute("winArchitecture");
            if (winArchitecture.isEmpty())
            {
              wLn("  # ARCHITECTURE");
            }
            else
            {
              wLn("  # ARCHITECTURE \"", winArchitecture, "\"");
            }
          }

          convertSettingIfDefined(
            configuration, "debugInformationFormat", "DEBUG_INFORMATION_FORMAT",
            [](const juce::String& value) -> juce::String {
              if (value == "None")
                return "None";

              if (value == "OldStyle")
                return "C7 Compatible (/Z7)";

              if (value == "ProgramDatabase")
                return "Program Database (/Zi)";

              if (value == "EditAndContinue")
                return "Program Database for Edit And Continue (/ZI)";

              return {};
            });

          convertOnOffSettingIfDefined(configuration, "fastMath", "RELAX_IEEE_COMPLIANCE",
                                       {});
        }

        if (exporterType == "LINUX_MAKE")
        {
          convertSettingIfDefined(configuration, "linuxArchitecture", "ARCHITECTURE",
                                  [](const juce::String& value) -> juce::String {
                                    if (value.isEmpty())
                                      return "<None>";

                                    if (value == "-march=native")
                                      return "Native";

                                    if (value == "-m32")
                                      return "32-bit (-m32)";

                                    if (value == "-m64")
                                      return "64-bit (-m64)";

                                    if (value == "-march=armv6")
                                      return "ARM v6";

                                    if (value == "-march=armv7")
                                      return "ARM v7";

                                    return {};
                                  });

          convertOnOffSettingIfDefined(configuration, "enablePluginBinaryCopyStep",
                                       "ENABLE_PLUGIN_COPY_STEP", {});

          convertSettingIfDefined(configuration, "vst3BinaryLocation",
                                  "VST3_BINARY_LOCATION", {});
          convertSettingIfDefined(configuration, "unityPluginBinaryLocation",
                                  "UNITY_BINARY_LOCATION", {});
          convertSettingIfDefined(configuration, "vstBinaryLocation",
                                  "VST_LEGACY_BINARY_LOCATION", {});
        }

        const auto codeBlocksArchitecture =
          [](const juce::String& value) -> juce::String {
          if (value == "-m32")
            return "32-bit (-m32)";

          if (value == "-m64" || value.isEmpty())
            return "64-bit (-m64)";

          if (value == "-march=armv6")
            return "ARM v6";

          if (value == "-march=armv7")
            return "ARM v7";

          return {};
        };

        if (exporterType == "CODEBLOCKS_WINDOWS")
        {
          if (configuration.hasAttribute("windowsCodeBlocksArchitecture")
              || (jucerVersionAsTuple >= Version{5, 0, 0}
                  && jucerVersionAsTuple < Version{5, 2, 1}))
          {
            convertSetting(configuration, "windowsCodeBlocksArchitecture", "ARCHITECTURE",
                           codeBlocksArchitecture);
          }
        }

        if (exporterType == "CODEBLOCKS_LINUX")
        {
          if (configuration.hasAttribute("linuxCodeBlocksArchitecture")
              || (jucerVersionAsTuple >= Version{5, 0, 0}
                  && jucerVersionAsTuple < Version{5, 2, 1}))
          {
            convertSetting(configuration, "linuxCodeBlocksArchitecture", "ARCHITECTURE",
                           codeBlocksArchitecture);
          }
        }

        writeUserNotes(wLn, configuration);

        wLn(")");
        wLn();
      }
    }
  }

  wLn("jucer_project_end()");
}


} // namespace Jucer2CMake


================================================
FILE: Jucer2CMake/src/utils.hpp
================================================
// Copyright (C) 2021-2022  Alain Martin
//
// This file is part of FRUT.
//
// FRUT 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.
//
// FRUT 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 FRUT.  If not, see <http://www.gnu.org/licenses/>.

#pragma once

#include "juce_core.hpp"

#include <iostream>
#include <utility>


namespace Jucer2CMake
{

struct Arguments
{
  juce::String mode;
  juce::String jucerFilePath;
  juce::String reprojucerFilePath;
  juce::String jucerVersion;
  juce::String juceModulesPath;
  juce::String userModulesPath;
  juce::File outputDir;
  bool relocatable;
};


struct ExitException
{
public:
  ExitException(const int returnValue)
    : mReturnValue{returnValue}
  {
  }

  int returnValue() const
  {
    return mReturnValue;
  }

private:
  const int mReturnValue;
};


#if !defined(WRITE_CRLF_LINE_ENDINGS)
  #error WRITE_CRLF_LINE_ENDINGS must be defined
#endif
#if WRITE_CRLF_LINE_ENDINGS
static const auto kNewLine = "\r\n";
#else
static const auto kNewLine = '\n';
#endif


struct LineWriter
{
  explicit LineWriter(juce::MemoryOutputStream& stream)
    : mStream(stream)
  {
  }

  LineWriter(const LineWriter&) = delete;
  LineWriter& operator=(const LineWriter&) = delete;

  template <typename... Args>
  void operator()(Args&&... args)
  {
    if (needsEmptyLine)
    {
      writeToStream(mStream, kNewLine);
      needsEmptyLine = false;
    }

    writeToStream(mStream, std::forward<Args>(args)..., kNewLine);
  }

  bool needsEmptyLine = false;

private:
  template <class Head>
  void writeToStream(juce::MemoryOutputStream& stream, Head&& head)
  {
    stream << std::forward<Head>(head);
  }

  template <class Head, class... Tail>
  void writeToStream(juce::MemoryOutputStream& stream, Head&& head, Tail&&... tail)
  {
    stream << std::forward<Head>(head);
    writeToStream(stream, std::forward<Tail>(tail)...);
  }

  juce::MemoryOutputStream& mStream;
};


inline juce::StringArray convertIdsToStrings(
  const juce::StringArray& ids,
  const std::vector<std::pair<juce::String, const char*>>& idsToStrings)
{
  juce::StringArray strings;
  for (const auto& idToString : idsToStrings)
  {
    if (ids.contains(idToString.first))
    {
      strings.add(idToString.second);
    }
  }
  return strings;
}


inline juce::String getAUMainTypeConstantFromQuotedFourChars(
  const juce::String& quotedFourChars)
{
  // clang-format off
  if (quotedFourChars == "'aufx'") return "kAudioUnitType_Effect";
  if (quotedFourChars == "'aufc'") return "kAudioUnitType_FormatConverter";
  if (quotedFourChars == "'augn'") return "kAudioUnitType_Generator";
  if (quotedFourChars == "'aumi'") return "kAudioUnitType_MIDIProcessor";
  if (quotedFourChars == "'aumx'") return "kAudioUnitType_Mixer";
  if (quotedFourChars == "'aumu'") return "kAudioUnitType_MusicDevice";
  if (quotedFourChars == "'aumf'") return "kAudioUnitType_MusicEffect";
  if (quotedFourChars == "'auol'") return "kAudioUnitType_OfflineEffect";
  if (quotedFourChars == "'auou'") return "kAudioUnitType_Output";
  if (quotedFourChars == "'aupn'") return "kAudioUnitType_Panner";
  // clang-format on
  return quotedFourChars;
}


inline juce::File getChildFileFromWorkingDirectory(
  const juce::StringRef relativeOrAbsolutePath)
{
  return juce::File::getCurrentWorkingDirectory().getChildFile(relativeOrAbsolutePath);
}


inline void printError(const juce::String& error)
{
  std::cerr << "error: " << error << std::endl;
}


// Matches juce::var::VariantType_String::toBool. This means that `toBoolLikeVar(s)` and
// `bool{juce::var{s}}` are equivalent.
inline bool toBoolLikeVar(const juce::String& s)
{
  return s.getIntValue() != 0 || s.trim().equalsIgnoreCase("true")
         || s.trim().equalsIgnoreCase("yes");
}

} // namespace Jucer2CMake


================================================
FILE: Jucer2CMake/tests/.gitignore
================================================
/*/Builds/
/*/JuceLibraryCode/


================================================
FILE: Jucer2CMake/tests/apply-Jucer2CMake-juce6-to-test-jucers.cmake
================================================
# Copyright (C) 2021  Alain Martin
#
# This file is part of FRUT.
#
# FRUT 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.
#
# FRUT 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 FRUT.  If not, see <http://www.gnu.org/licenses/>.

if(NOT DEFINED Jucer2CMake_EXE)
  message(FATAL_ERROR "Jucer2CMake_EXE must be defined")
endif()

if(NOT EXISTS ${Jucer2CMake_EXE})
  message(FATAL_ERROR "No such file: ${Jucer2CMake_EXE}")
endif()

get_filename_component(Jucer2CMake_EXE "${Jucer2CMake_EXE}" ABSOLUTE)


file(GLOB_RECURSE jucer_files "${CMAKE_CURRENT_LIST_DIR}/*.jucer")

foreach(jucer_file IN LISTS jucer_files)
  set(command "${Jucer2CMake_EXE}" "juce6" "${jucer_file}")
  execute_process(COMMAND ${command} RESULT_VARIABLE result)

  if(NOT result EQUAL 0)
    string(REPLACE ";" " " command_string "${command}")
    message(FATAL_ERROR "Failed to run `${command_string}`")
  endif()
endforeach()


================================================
FILE: Jucer2CMake/tests/audioplug6/CMakeLists.txt
================================================
# This file was generated by FRUT's Jucer2CMake from "audioplug6.jucer"

cmake_minimum_required(VERSION 3.15)

project("audioplug6")


find_package(JUCE CONFIG REQUIRED)


juce_add_plugin(audioplug6
  VERSION "1.0.0"

  FORMATS
    "VST3"
    "Standalone"
  PLUGIN_NAME "PluginName"
  DESCRIPTION "The description"
  PLUGIN_MANUFACTURER_CODE "Manu"
  PLUGIN_CODE "Code"
  IS_SYNTH TRUE
  NEEDS_MIDI_INPUT TRUE
  NEEDS_MIDI_OUTPUT TRUE
  IS_MIDI_EFFECT TRUE
  EDITOR_WANTS_KEYBOARD_FOCUS TRUE
  DISABLE_AAX_BYPASS TRUE
  DISABLE_AAX_MULTI_MONO TRUE
  AAX_IDENTIFIER "org.myorg.myAAXplugin"
  AU_EXPORT_PREFIX "prefixAU"
  AU_MAIN_TYPE "kAudioUnitType_MIDIProcessor"
  AU_SANDBOX_SAFE FALSE
  VST_NUM_MIDI_INS "9"
  VST_NUM_MIDI_OUTS "8"
  VST3_CATEGORIES
    "Drum"
    "Mastering"
  VST2_CATEGORY "kPlugCategUnknown"
)

juce_generate_juce_header(audioplug6)

target_compile_definitions(audioplug6
  PUBLIC
    JUCE_STRICT_REFCOUNTEDPOINTER=1
    JUCE_USE_CURL=0
    JUCE_VST3_CAN_REPLACE_VST2=0
    JUCE_WEB_BROWSER=0
)

target_sources(audioplug6
  PRIVATE
    "Source/PluginEditor.cpp"
    "Source/PluginProcessor.cpp"
)

target_link_libraries(audioplug6
  PRIVATE
    juce::juce_audio_basics
    juce::juce_audio_devices
    juce::juce_audio_formats
    juce::juce_audio_plugin_client
    juce::juce_audio_processors
    juce::juce_audio_utils
    juce::juce_core
    juce::juce_data_structures
    juce::juce_events
    juce::juce_graphics
    juce::juce_gui_basics
    juce::juce_gui_extra
  PUBLIC
    juce::juce_recommended_config_flags
    juce::juce_recommended_lto_flags
    juce::juce_recommended_warning_flags
)


================================================
FILE: Jucer2CMake/tests/audioplug6/Source/PluginEditor.cpp
================================================
/*
  ==============================================================================

    This file contains the basic framework code for a JUCE plugin editor.

  ==============================================================================
*/

#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================
Audioplug6AudioProcessorEditor::Audioplug6AudioProcessorEditor (Audioplug6AudioProcessor& p)
    : AudioProcessorEditor (&p), audioProcessor (p)
{
    // Make sure that before the constructor has finished, you've set the
    // editor's size to whatever you need it to be.
    setSize (400, 300);
}

Audioplug6AudioProcessorEditor::~Audioplug6AudioProcessorEditor()
{
}

//==============================================================================
void Audioplug6AudioProcessorEditor::paint (juce::Graphics& g)
{
    // (Our component is opaque, so we must completely fill the background with a solid colour)
    g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));

    g.setColour (juce::Colours::white);
    g.setFont (15.0f);
    g.drawFittedText ("Hello World!", getLocalBounds(), juce::Justification::centred, 1);
}

void Audioplug6AudioProcessorEditor::resized()
{
    // This is generally where you'll want to lay out the positions of any
    // subcomponents in your editor..
}


================================================
FILE: Jucer2CMake/tests/audioplug6/Source/PluginEditor.h
================================================
/*
  ==============================================================================

    This file contains the basic framework code for a JUCE plugin editor.

  ==============================================================================
*/

#pragma once

#include <JuceHeader.h>
#include "PluginProcessor.h"

//==============================================================================
/**
*/
class Audioplug6AudioProcessorEditor  : public juce::AudioProcessorEditor
{
public:
    Audioplug6AudioProcessorEditor (Audioplug6AudioProcessor&);
    ~Audioplug6AudioProcessorEditor() override;

    //==============================================================================
    void paint (juce::Graphics&) override;
    void resized() override;

private:
    // This reference is provided as a quick way for your editor to
    // access the processor object that created it.
    Audioplug6AudioProcessor& audioProcessor;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Audioplug6AudioProcessorEditor)
};


================================================
FILE: Jucer2CMake/tests/audioplug6/Source/PluginProcessor.cpp
================================================
/*
  ==============================================================================

    This file contains the basic framework code for a JUCE plugin processor.

  ==============================================================================
*/

#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================
Audioplug6AudioProcessor::Audioplug6AudioProcessor()
#ifndef JucePlugin_PreferredChannelConfigurations
     : AudioProcessor (BusesProperties()
                     #if ! JucePlugin_IsMidiEffect
                      #if ! JucePlugin_IsSynth
                       .withInput  ("Input",  juce::AudioChannelSet::stereo(), true)
                      #endif
                       .withOutput ("Output", juce::AudioChannelSet::stereo(), true)
                     #endif
                       )
#endif
{
}

Audioplug6AudioProcessor::~Audioplug6AudioProcessor()
{
}

//==============================================================================
const juce::String Audioplug6AudioProcessor::getName() const
{
    return JucePlugin_Name;
}

bool Audioplug6AudioProcessor::acceptsMidi() const
{
   #if JucePlugin_WantsMidiInput
    return true;
   #else
    return false;
   #endif
}

bool Audioplug6AudioProcessor::producesMidi() const
{
   #if JucePlugin_ProducesMidiOutput
    return true;
   #else
    return false;
   #endif
}

bool Audioplug6AudioProcessor::isMidiEffect() const
{
   #if JucePlugin_IsMidiEffect
    return true;
   #else
    return false;
   #endif
}

double Audioplug6AudioProcessor::getTailLengthSeconds() const
{
    return 0.0;
}

int Audioplug6AudioProcessor::getNumPrograms()
{
    return 1;   // NB: some hosts don't cope very well if you tell them there are 0 programs,
                // so this should be at least 1, even if you're not really implementing programs.
}

int Audioplug6AudioProcessor::getCurrentProgram()
{
    return 0;
}

void Audioplug6AudioProcessor::setCurrentProgram (int index)
{
}

const juce::String Audioplug6AudioProcessor::getProgramName (int index)
{
    return {};
}

void Audioplug6AudioProcessor::changeProgramName (int index, const juce::String& newName)
{
}

//==============================================================================
void Audioplug6AudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
    // Use this method as the place to do any pre-playback
    // initialisation that you need..
}

void Audioplug6AudioProcessor::releaseResources()
{
    // When playback stops, you can use this as an opportunity to free up any
    // spare memory, etc.
}

#ifndef JucePlugin_PreferredChannelConfigurations
bool Audioplug6AudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
{
  #if JucePlugin_IsMidiEffect
    juce::ignoreUnused (layouts);
    return true;
  #else
    // This is the place where you check if the layout is supported.
    // In this template code we only support mono or stereo.
    if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
     && layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
        return false;

    // This checks if the input layout matches the output layout
   #if ! JucePlugin_IsSynth
    if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
        return false;
   #endif

    return true;
  #endif
}
#endif

void Audioplug6AudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
    juce::ScopedNoDenormals noDenormals;
    auto totalNumInputChannels  = getTotalNumInputChannels();
    auto totalNumOutputChannels = getTotalNumOutputChannels();

    // In case we have more outputs than inputs, this code clears any output
    // channels that didn't contain input data, (because these aren't
    // guaranteed to be empty - they may contain garbage).
    // This is here to avoid people getting screaming feedback
    // when they first compile a plugin, but obviously you don't need to keep
    // this code if your algorithm always overwrites all the output channels.
    for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
        buffer.clear (i, 0, buffer.getNumSamples());

    // This is the place where you'd normally do the guts of your plugin's
    // audio processing...
    // Make sure to reset the state if your inner loop is processing
    // the samples and the outer loop is handling the channels.
    // Alternatively, you can process the samples with the channels
    // interleaved by keeping the same state.
    for (int channel = 0; channel < totalNumInputChannels; ++channel)
    {
        auto* channelData = buffer.getWritePointer (channel);

        // ..do something to the data...
    }
}

//==============================================================================
bool Audioplug6AudioProcessor::hasEditor() const
{
    return true; // (change this to false if you choose to not supply an editor)
}

juce::AudioProcessorEditor* Audioplug6AudioProcessor::createEditor()
{
    return new Audioplug6AudioProcessorEditor (*this);
}

//==============================================================================
void Audioplug6AudioProcessor::getStateInformation (juce::MemoryBlock& destData)
{
    // You should use this method to store your parameters in the memory block.
    // You could do that either as raw data, or use the XML or ValueTree classes
    // as intermediaries to make it easy to save and load complex data.
}

void Audioplug6AudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
    // You should use this method to restore your parameters from this memory block,
    // whose contents will have been created by the getStateInformation() call.
}

//==============================================================================
// This creates new instances of the plugin..
juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{
    return new Audioplug6AudioProcessor();
}


================================================
FILE: Jucer2CMake/tests/audioplug6/Source/PluginProcessor.h
================================================
/*
  ==============================================================================

    This file contains the basic framework code for a JUCE plugin processor.

  ==============================================================================
*/

#pragma once

#include <JuceHeader.h>

//==============================================================================
/**
*/
class Audioplug6AudioProcessor  : public juce::AudioProcessor
{
public:
    //==============================================================================
    Audioplug6AudioProcessor();
    ~Audioplug6AudioProcessor() override;

    //==============================================================================
    void prepareToPlay (double sampleRate, int samplesPerBlock) override;
    void releaseResources() override;

   #ifndef JucePlugin_PreferredChannelConfigurations
    bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
   #endif

    void processBlock (juce::AudioBuffer<float>&, juce::MidiBuffer&) override;

    //==============================================================================
    juce::AudioProcessorEditor* createEditor() override;
    bool hasEditor() const override;

    //==============================================================================
    const juce::String getName() const override;

    bool acceptsMidi() const override;
    bool producesMidi() const override;
    bool isMidiEffect() const override;
    double getTailLengthSeconds() const override;

    //==============================================================================
    int getNumPrograms() override;
    int getCurrentProgram() override;
    void setCurrentProgram (int index) override;
    const juce::String getProgramName (int index) override;
    void changeProgramName (int index, const juce::String& newName) override;

    //==============================================================================
    void getStateInformation (juce::MemoryBlock& destData) override;
    void setStateInformation (const void* data, int sizeInBytes) override;

private:
    //==============================================================================
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Audioplug6AudioProcessor)
};


================================================
FILE: Jucer2CMake/tests/audioplug6/audioplug6.jucer
================================================
<?xml version="1.0" encoding="UTF-8"?>

<JUCERPROJECT id="CCxcbs" name="audioplug6" projectType="audioplug" useAppConfig="0"
              addUsingNamespaceToJuceHeader="0" jucerFormatVersion="1" pluginFormats="buildStandalone,buildVST3"
              pluginName="PluginName" pluginManufacturerCode="Manu" pluginCode="Code"
              pluginDesc="The description" pluginCharacteristicsValue="pluginAAXDisableBypass,pluginAAXDisableMultiMono,pluginEditorRequiresKeys,pluginIsMidiEffectPlugin,pluginIsSynth,pluginProducesMidiOut,pluginWantsMidiIn"
              aaxIdentifier="org.myorg.myAAXplugin" pluginVSTNumMidiInputs="9"
              pluginVSTNumMidiOutputs="8" pluginVSTCategory="kPlugCategUnknown"
              pluginVST3Category="Drum,Mastering" pluginAUMainType="'aumi'"
              pluginAUExportPrefix="prefixAU" pluginAUIsSandboxSafe="0">
  <MAINGROUP id="FPb8mq" name="audioplug6">
    <GROUP id="{EEC7BF3A-C246-BD0C-A80F-13D54B92FB0B}" name="Source">
      <FILE id="wqYbDN" name="PluginProcessor.cpp" compile="1" resource="0"
            file="Source/PluginProcessor.cpp"/>
      <FILE id="H1CABy" name="PluginProcessor.h" compile="0" resource="0"
            file="Source/PluginProcessor.h"/>
      <FILE id="peExFn" name="PluginEditor.cpp" compile="1" resource="0"
            file="Source/PluginEditor.cpp"/>
      <FILE id="rL5dke" name="PluginEditor.h" compile="0" resource="0" file="Source/PluginEditor.h"/>
    </GROUP>
  </MAINGROUP>
  <JUCEOPTIONS JUCE_STRICT_REFCOUNTEDPOINTER="1" JUCE_VST3_CAN_REPLACE_VST2="0"
               JUCE_WEB_BROWSER="0"/>
  <EXPORTFORMATS>
    <LINUX_MAKE targetFolder="Builds/LinuxMakefile">
      <CONFIGURATIONS>
        <CONFIGURATION isDebug="1" name="Debug"/>
        <CONFIGURATION isDebug="0" name="Release"/>
      </CONFIGURATIONS>
      <MODULEPATHS>
        <MODULEPATH id="juce_audio_basics"/>
        <MODULEPATH id="juce_audio_devices"/>
        <MODULEPATH id="juce_audio_formats"/>
        <MODULEPATH id="juce_audio_plugin_client"/>
        <MODULEPATH id="juce_audio_processors"/>
        <MODULEPATH id="juce_audio_utils"/>
        <MODULEPATH id="juce_core"/>
        <MODULEPATH id="juce_data_structures"/>
        <MODULEPATH id="juce_events"/>
        <MODULEPATH id="juce_graphics"/>
        <MODULEPATH id="juce_gui_basics"/>
        <MODULEPATH id="juce_gui_extra"/>
      </MODULEPATHS>
    </LINUX_MAKE>
    <VS2019 targetFolder="Builds/VisualStudio2019">
      <CONFIGURATIONS>
        <CONFIGURATION isDebug="1" name="Debug"/>
        <CONFIGURATION isDebug="0" name="Release"/>
      </CONFIGURATIONS>
      <MODULEPATHS>
        <MODULEPATH id="juce_audio_basics"/>
        <MODULEPATH id="juce_audio_devices"/>
        <MODULEPATH id="juce_audio_formats"/>
        <MODULEPATH id="juce_audio_plugin_client"/>
        <MODULEPATH id="juce_audio_processors"/>
        <MODULEPATH id="juce_audio_utils"/>
        <MODULEPATH id="juce_core"/>
        <MODULEPATH id="juce_data_structures"/>
        <MODULEPATH id="juce_events"/>
        <MODULEPATH id="juce_graphics"/>
        <MODULEPATH id="juce_gui_basics"/>
        <MODULEPATH id="juce_gui_extra"/>
      </MODULEPATHS>
    </VS2019>
    <XCODE_MAC targetFolder="Builds/MacOSX">
      <CONFIGURATIONS>
        <CONFIGURATION isDebug="1" name="Debug"/>
        <CONFIGURATION isDebug="0" name="Release"/>
      </CONFIGURATIONS>
      <MODULEPATHS>
        <MODULEPATH id="juce_audio_basics"/>
        <MODULEPATH id="juce_audio_devices"/>
        <MODULEPATH id="juce_audio_formats"/>
        <MODULEPATH id="juce_audio_plugin_client"/>
        <MODULEPATH id="juce_audio_processors"/>
        <MODULEPATH id="juce_audio_utils"/>
        <MODULEPATH id="juce_core"/>
        <MODULEPATH id="juce_data_structures"/>
        <MODULEPATH id="juce_events"/>
        <MODULEPATH id="juce_graphics"/>
        <MODULEPATH id="juce_gui_basics"/>
        <MODULEPATH id="juce_gui_extra"/>
      </MODULEPATHS>
    </XCODE_MAC>
    <XCODE_IPHONE targetFolder="Builds/iOS">
      <CONFIGURATIONS>
        <CONFIGURATION isDebug="1" name="Debug"/>
        <CONFIGURATION isDebug="0" name="Release"/>
      </CONFIGURATIONS>
      <MODULEPATHS>
        <MODULEPATH id="juce_audio_basics"/>
        <MODULEPATH id="juce_audio_devices"/>
        <MODULEPATH id="juce_audio_formats"/>
        <MODULEPATH id="juce_audio_plugin_client"/>
        <MODULEPATH id="juce_audio_processors"/>
        <MODULEPATH id="juce_audio_utils"/>
        <MODULEPATH id="juce_core"/>
        <MODULEPATH id="juce_data_structures"/>
        <MODULEPATH id="juce_events"/>
        <MODULEPATH id="juce_graphics"/>
        <MODULEPATH id="juce_gui_basics"/>
        <MODULEPATH id="juce_gui_extra"/>
      </MODULEPATHS>
    </XCODE_IPHONE>
  </EXPORTFORMATS>
  <MODULES>
    <MODULE id="juce_audio_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
    <MODULE id="juce_audio_devices" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
    <MODULE id="juce_audio_formats" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
    <MODULE id="juce_audio_plugin_client" showAllCode="1" useLocalCopy="0"
            useGlobalPath="1"/>
    <MODULE id="juce_audio_processors" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
    <MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
    <MODULE id="juce_core" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
    <MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
    <MODULE id="juce_events" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
    <MODULE id="juce_graphics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
    <MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
    <MODULE id="juce_gui_extra" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
  </MODULES>
</JUCERPROJECT>


================================================
FILE: Jucer2CMake/tests/audioplug6-default/CMakeLists.txt
================================================
# This file was generated by FRUT's Jucer2CMake from "audioplug6.jucer"

cmake_minimum_required(VERSION 3.15)

project("audioplug6")


find_package(JUCE CONFIG REQUIRED)


juce_add_plugin(audioplug6
  VERSION "1.0.0"

  FORMATS
    "VST3"
    "AU"
    "Standalone"
)

juce_generate_juce_header(audioplug6)

target_compile_definitions(audioplug6
  PUBLIC
    JUCE_STRICT_REFCOUNTEDPOINTER=1
    JUCE_USE_CURL=0
    JUCE_VST3_CAN_REPLACE_VST2=0
    JUCE_WEB_BROWSER=0
)

target_sources(audioplug6
  PRIVATE
    "Source/PluginEditor.cpp"
    "Source/PluginProcessor.cpp"
)

target_link_libraries(audioplug6
  PRIVATE
    juce::juce_audio_basics
    juce::juce_audio_devices
    juce::juce_audio_formats
    juce::juce_audio_plugin_client
    juce::juce_audio_processors
    juce::juce_audio_utils
    juce::juce_core
    juce::juce_data_structures
    juce::juce_events
    juce::juce_graphics
    juce::juce_gui_basics
    juce::juce_gui_extra
  PUBLIC
    juce::juce_recommended_config_flags
    juce::juce_recommended_lto_flags
    juce::juce_recommended_warning_flags
)


================================================
FILE: Jucer2CMake/tests/audioplug6-default/Source/PluginEditor.cpp
================================================
/*
  ==============================================================================

    This file contains the basic framework code for a JUCE plugin editor.

  ==============================================================================
*/

#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================
Audioplug6AudioProcessorEditor::Audioplug6AudioProcessorEditor (Audioplug6AudioProcessor& p)
    : AudioProcessorEditor (&p), audioProcessor (p)
{
    // Make sure that before the constructor has finished, you've set the
    // editor's size to whatever you need it to be.
    setSize (400, 300);
}

Audioplug6AudioProcessorEditor::~Audioplug6AudioProcessorEditor()
{
}

//==============================================================================
void Audioplug6AudioProcessorEditor::paint (juce::Graphics& g)
{
    // (Our component is opaque, so we must completely fill the background with a solid colour)
    g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));

    g.setColour (juce::Colours::white);
    g.setFont (15.0f);
    g.drawFittedText ("Hello World!", getLocalBounds(), juce::Justification::centred, 1);
}

void Audioplug6AudioProcessorEditor::resized()
{
    // This is generally where you'll want to lay out the positions of any
    // subcomponents in your editor..
}


================================================
FILE: Jucer2CMake/tests/audioplug6-default/Source/PluginEditor.h
================================================
/*
  ==============================================================================

    This file contains the basic framework code for a JUCE plugin editor.

  ==============================================================================
*/

#pragma once

#include <JuceHeader.h>
#include "PluginProcessor.h"

//==============================================================================
/**
*/
class Audioplug6AudioProcessorEditor  : public juce::AudioProcessorEditor
{
public:
    Audioplug6AudioProcessorEditor (Audioplug6AudioProcessor&);
    ~Audioplug6AudioProcessorEditor() override;

    //==============================================================================
    void paint (juce::Graphics&) override;
    void resized() override;

private:
    // This reference is provided as a quick way for your editor to
    // access the processor object that created it.
    Audioplug6AudioProcessor& audioProcessor;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Audioplug6AudioProcessorEditor)
};


================================================
FILE: Jucer2CMake/tests/audioplug6-default/Source/PluginProcessor.cpp
================================================
/*
  ==============================================================================

    This file contains the basic framework code for a JUCE plugin processor.

  ==============================================================================
*/

#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================
Audioplug6AudioProcessor::Audioplug6AudioProcessor()
#ifndef JucePlugin_PreferredChannelConfigurations
     : AudioProcessor (BusesProperties()
                     #if ! JucePlugin_IsMidiEffect
                      #if ! JucePlugin_IsSynth
                       .withInput  ("Input",  juce::AudioChannelSet::stereo(), true)
                      #endif
                       .withOutput ("Output", juce::AudioChannelSet::stereo(), true)
                     #endif
                       )
#endif
{
}

Audioplug6AudioProcessor::~Audioplug6AudioProcessor()
{
}

//==============================================================================
const juce::String Audioplug6AudioProcessor::getName() const
{
    return JucePlugin_Name;
}

bool Audioplug6AudioProcessor::acceptsMidi() const
{
   #if JucePlugin_WantsMidiInput
    return true;
   #else
    return false;
   #endif
}

bool Audioplug6AudioProcessor::producesMidi() const
{
   #if JucePlugin_ProducesMidiOutput
    return true;
   #else
    return false;
   #endif
}

bool Audioplug6AudioProcessor::isMidiEffect() const
{
   #if JucePlugin_IsMidiEffect
    return true;
   #else
    return false;
   #endif
}

double Audioplug6AudioProcessor::getTailLengthSeconds() const
{
    return 0.0;
}

int Audioplug6AudioProcessor::getNumPrograms()
{
    return 1;   // NB: some hosts don't cope very well if you tell them there are 0 programs,
                // so this should be at least 1, even if you're not really implementing programs.
}

int Audioplug6AudioProcessor::getCurrentProgram()
{
    return 0;
}

void Audioplug6AudioProcessor::setCurrentProgram (int index)
{
}

const juce::String Audioplug6AudioProcessor::getProgramName (int index)
{
    return {};
}

void Audioplug6AudioProcessor::changeProgramName (int index, const juce::String& newName)
{
}

//==============================================================================
void Audioplug6AudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
    // Use this method as the place to do any pre-playback
    // initialisation that you need..
}

void Audioplug6AudioProcessor::releaseResources()
{
    // When playback stops, you can use this as an opportunity to free up any
    // spare memory, etc.
}

#ifndef JucePlugin_PreferredChannelConfigurations
bool Audioplug6AudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
{
  #if JucePlugin_IsMidiEffect
    juce::ignoreUnused (layouts);
    return true;
  #else
    // This is the place where you check if the layout is supported.
    // In this template code we only support mono or stereo.
    if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
     && layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
        return false;

    // This checks if the input layout matches the output layout
   #if ! JucePlugin_IsSynth
    if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
        return false;
   #endif

    return true;
  #endif
}
#endif

void Audioplug6AudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
    juce::ScopedNoDenormals noDenormals;
    auto totalNumInputChannels  = getTotalNumInputChannels();
    auto totalNumOutputChannels = getTotalNumOutputChannels();

    // In case we have more outputs than inputs, this code clears any output
    // channels that didn't contain input data, (because these aren't
    // guaranteed to be empty - they may contain garbage).
    // This is here to avoid people getting screaming feedback
    // when they first compile a plugin, but obviously you don't need to keep
    // this code if your algorithm always overwrites all the output channels.
    for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
        buffer.clear (i, 0, buffer.getNumSamples());

    // This is the place where you'd normally do the guts of your plugin's
    // audio processing...
    // Make sure to reset the state if your inner loop is processing
    // the samples and the outer loop is handling the channels.
    // Alternatively, you can process the samples with the channels
    // interleaved by keeping the same state.
    for (int channel = 0; channel < totalNumInputChannels; ++channel)
    {
        auto* channelData = buffer.getWritePointer (channel);

        // ..do something to the data...
    }
}

//==============================================================================
bool Audioplug6AudioProcessor::hasEditor() const
{
    return true; // (change this to false if you choose to not supply an editor)
}

juce::AudioProcessorEditor* Audioplug6AudioProcessor::createEditor()
{
    return new Audioplug6AudioProcessorEditor (*this);
}

//==============================================================================
void Audioplug6AudioProcessor::getStateInformation (juce::MemoryBlock& destData)
{
    // You should use this method to store your parameters in the memory block.
    // You could do that either as raw data, or use the XML or ValueTree classes
    // as intermediaries to make it easy to save and load complex data.
}

void Audioplug6AudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
    // You should use this method to restore your parameters from this memory block,
    // whose contents will have been created by the getStateInformation() call.
}

//==============================================================================
// This creates new instances of the plugin..
juce::AudioProcessor* JUCE_CALLTYP
Download .txt
gitextract_b0ewfza2/

├── .appveyor.yml
├── .azure-pipelines.yml
├── .cirrus.yml
├── .clang-format
├── .github/
│   └── pull_request_template.md
├── .gitignore
├── .readthedocs.yaml
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Jucer2CMake/
│   ├── CMakeLists.txt
│   ├── src/
│   │   ├── argh.hpp
│   │   ├── juce6.hpp
│   │   ├── juce_core.hpp
│   │   ├── main.cpp
│   │   ├── reprojucer.hpp
│   │   └── utils.hpp
│   └── tests/
│       ├── .gitignore
│       ├── apply-Jucer2CMake-juce6-to-test-jucers.cmake
│       ├── audioplug6/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   ├── PluginEditor.cpp
│       │   │   ├── PluginEditor.h
│       │   │   ├── PluginProcessor.cpp
│       │   │   └── PluginProcessor.h
│       │   └── audioplug6.jucer
│       ├── audioplug6-default/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   ├── PluginEditor.cpp
│       │   │   ├── PluginEditor.h
│       │   │   ├── PluginProcessor.cpp
│       │   │   └── PluginProcessor.h
│       │   └── audioplug6.jucer
│       ├── consoleapp6/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   └── Main.cpp
│       │   └── consoleapp6.jucer
│       ├── consoleapp6-default/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   └── Main.cpp
│       │   └── consoleapp6.jucer
│       ├── guiapp6/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   ├── Main.cpp
│       │   │   ├── MainComponent.cpp
│       │   │   └── MainComponent.h
│       │   └── guiapp6.jucer
│       └── guiapp6-default/
│           ├── CMakeLists.txt
│           ├── Source/
│           │   ├── Main.cpp
│           │   ├── MainComponent.cpp
│           │   └── MainComponent.h
│           └── guiapp6.jucer
├── LICENSE
├── README.rst
├── ci/
│   ├── AllJuceProjects/
│   │   └── CMakeLists.txt
│   ├── apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake
│   ├── apply-Jucer2CMake-reprojucer-to-test-jucers.cmake
│   ├── azure-pipelines/
│   │   ├── steps-Makefiles.yml
│   │   ├── steps-VS.yml
│   │   ├── steps-Xcode.yml
│   │   └── steps-iOS.yml
│   └── fake-SDKs/
│       ├── AAX/
│       │   └── Interfaces/
│       │       └── AAX_Exports.cpp
│       ├── VST/
│       │   ├── pluginterfaces/
│       │   │   └── vst2.x/
│       │   │       └── aeffect.h
│       │   └── public.sdk/
│       │       └── source/
│       │           └── vst2.x/
│       │               └── audioeffectx.h
│       └── VST3/
│           └── base/
│               └── source/
│                   └── baseiids.cpp
├── cmake/
│   ├── Reprojucer.cmake
│   ├── data/
│   │   ├── AppConfig-4.h.in
│   │   ├── AppConfig-5.h.in
│   │   ├── AppConfig.h.in
│   │   ├── Info.plist.in
│   │   ├── JuceHeader.h.in
│   │   ├── JuceLibraryCode-Wrapper.cpp.in
│   │   ├── JucePluginDefines.h.in
│   │   ├── LaunchScreen.storyboard
│   │   ├── PkgInfo
│   │   ├── UnityScript.cs.in
│   │   ├── failed-to.md.in
│   │   ├── juce_runtime_arch_detection.cpp
│   │   ├── resources.rc.in
│   │   ├── script.in
│   │   └── target.entitlements.in
│   └── tools/
│       ├── BinaryDataBuilder/
│       │   ├── CMakeLists.txt
│       │   ├── extras/
│       │   │   └── Projucer/
│       │   │       └── Source/
│       │   │           ├── Project/
│       │   │           │   └── jucer_Project.h
│       │   │           ├── Project Saving/
│       │   │           │   ├── jucer_ResourceFile.cpp
│       │   │           │   └── jucer_ResourceFile.h
│       │   │           ├── Utility/
│       │   │           │   ├── jucer_CodeHelpers.cpp
│       │   │           │   ├── jucer_CodeHelpers.h
│       │   │           │   ├── jucer_FileHelpers.cpp
│       │   │           │   ├── jucer_FileHelpers.h
│       │   │           │   ├── jucer_MiscUtilities.cpp
│       │   │           │   └── jucer_MiscUtilities.h
│       │   │           └── jucer_Headers.h
│       │   ├── main.cpp
│       │   └── modules/
│       │       └── juce_gui_extra/
│       │           ├── code_editor/
│       │           │   ├── juce_CPlusPlusCodeTokeniser.cpp
│       │           │   ├── juce_CPlusPlusCodeTokeniser.h
│       │           │   └── juce_CPlusPlusCodeTokeniserFunctions.h
│       │           ├── juce_gui_extra.cpp
│       │           └── juce_gui_extra.h
│       ├── CMakeLists.txt
│       ├── IconBuilder/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   ├── Project Saving/
│       │   │   │   ├── jucer_ProjectExport_MSVC.h
│       │   │   │   ├── jucer_ProjectExport_XCode.h
│       │   │   │   ├── jucer_ProjectExporter.cpp
│       │   │   │   └── jucer_ProjectExporter.h
│       │   │   ├── Utility/
│       │   │   │   ├── jucer_FileHelpers.cpp
│       │   │   │   └── jucer_FileHelpers.h
│       │   │   └── jucer_Headers.h
│       │   └── main.cpp
│       ├── PListMerger/
│       │   ├── CMakeLists.txt
│       │   └── main.cpp
│       ├── XcassetsBuilder/
│       │   ├── CMakeLists.txt
│       │   ├── Source/
│       │   │   ├── ProjectSaving/
│       │   │   │   ├── jucer_ProjectExport_Xcode.h
│       │   │   │   ├── jucer_ProjectExporter.cpp
│       │   │   │   └── jucer_ProjectExporter.h
│       │   │   ├── Utility/
│       │   │   │   ├── jucer_FileHelpers.cpp
│       │   │   │   └── jucer_FileHelpers.h
│       │   │   └── jucer_Headers.h
│       │   └── main.cpp
│       ├── juce_core.cmake
│       └── juce_gui_basics.cmake
├── docs/
│   ├── Reprojucer.cmake/
│   │   ├── command/
│   │   │   ├── jucer_appconfig_header.rst
│   │   │   ├── jucer_audio_plugin_settings.rst
│   │   │   ├── jucer_export_target.rst
│   │   │   ├── jucer_export_target_configuration.rst
│   │   │   ├── jucer_project_begin.rst
│   │   │   ├── jucer_project_end.rst
│   │   │   ├── jucer_project_files.rst
│   │   │   ├── jucer_project_module.rst
│   │   │   └── jucer_project_settings.rst
│   │   └── index.rst
│   ├── conf.py
│   ├── index.rst
│   └── requirements.txt
├── generated/
│   ├── JUCE-4.2.0/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   ├── AUv3Synth/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AnimationAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AudioAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── BouncingBallWavetableDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── ComponentTutorialExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── Demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── HelloWorld/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MPETest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MidiTest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── NetworkGraphicsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCMonitor/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCReceiver/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCSender/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OpenGLAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PluckedStringsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PlugInSamples/
│   │   │   │   ├── Arpeggiator/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── GainPlugIn/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── MultiOutSynth/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── NoiseGate/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── Surround/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── SimpleFFTExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── audio plugin demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   └── audio plugin host/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       ├── binarybuilder/
│   │       │   └── CMakeLists.txt
│   │       └── windows dll/
│   │           └── CMakeLists.txt
│   ├── JUCE-4.3.1/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   ├── AUv3Synth/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AnimationAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AudioAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── BLOCKS/
│   │   │   │   ├── BlocksDrawing/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── BlocksMonitor/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── BlocksSynth/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── BouncingBallWavetableDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── ComponentTutorialExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── Demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── HelloWorld/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MPETest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MidiTest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── NetworkGraphicsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCMonitor/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCReceiver/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCSender/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OpenGLAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PluckedStringsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PlugInSamples/
│   │   │   │   ├── Arpeggiator/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── GainPlugIn/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── MultiOutSynth/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── NoiseGate/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── Surround/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── SimpleFFTExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── audio plugin demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   └── audio plugin host/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       ├── binarybuilder/
│   │       │   └── CMakeLists.txt
│   │       └── windows dll/
│   │           └── CMakeLists.txt
│   ├── JUCE-5.0.0/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   ├── AUv3Synth/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AnimationAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AudioAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── BLOCKS/
│   │   │   │   ├── BlocksDrawing/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── BlocksMonitor/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── BlocksSynth/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── BouncingBallWavetableDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── ComponentTutorialExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── Demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── HelloWorld/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MPETest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MidiTest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── NetworkGraphicsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCMonitor/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCReceiver/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCSender/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OpenGLAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PluckedStringsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PlugInSamples/
│   │   │   │   ├── Arpeggiator/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── GainPlugIn/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── InterAppAudioEffect/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── MultiOutSynth/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── NoiseGate/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── Surround/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── SimpleFFTExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── audio plugin demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   └── audio plugin host/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       ├── binarybuilder/
│   │       │   └── CMakeLists.txt
│   │       └── windows dll/
│   │           └── CMakeLists.txt
│   ├── JUCE-5.2.1/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   ├── AUv3Synth/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AnalyticsCollection/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AnimationAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── AudioAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── BLOCKS/
│   │   │   │   ├── BlocksDrawing/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── BlocksMonitor/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── BlocksSynth/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── BouncingBallWavetableDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── ComponentTutorialExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── DSP module plugin demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── DSPDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── Demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── HelloWorld/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── InAppPurchase/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MPETest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── MidiTest/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── NetworkGraphicsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCMonitor/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCReceiver/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OSCSender/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── OpenGLAppExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PluckedStringsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── PlugInSamples/
│   │   │   │   ├── Arpeggiator/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── GainPlugIn/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── InterAppAudioEffect/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── MultiOutSynth/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   ├── NoiseGate/
│   │   │   │   │   └── CMakeLists.txt
│   │   │   │   └── Surround/
│   │   │   │       └── CMakeLists.txt
│   │   │   ├── PushNotificationsDemo/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── SimpleFFTExample/
│   │   │   │   └── CMakeLists.txt
│   │   │   ├── audio plugin demo/
│   │   │   │   └── CMakeLists.txt
│   │   │   └── audio plugin host/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       ├── binarybuilder/
│   │       │   └── CMakeLists.txt
│   │       └── windows dll/
│   │           └── CMakeLists.txt
│   ├── JUCE-5.3.1/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   └── DemoRunner/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── AudioPluginHost/
│   │       │   └── CMakeLists.txt
│   │       ├── BinaryBuilder/
│   │       │   └── CMakeLists.txt
│   │       ├── NetworkGraphicsDemo/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       └── WindowsDLL/
│   │           └── CMakeLists.txt
│   ├── JUCE-5.4.3/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   └── DemoRunner/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── AudioPluginHost/
│   │       │   └── CMakeLists.txt
│   │       ├── BinaryBuilder/
│   │       │   └── CMakeLists.txt
│   │       ├── NetworkGraphicsDemo/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       └── WindowsDLL/
│   │           └── CMakeLists.txt
│   ├── JUCE-5.4.7/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   └── DemoRunner/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── AudioPluginHost/
│   │       │   └── CMakeLists.txt
│   │       ├── BinaryBuilder/
│   │       │   └── CMakeLists.txt
│   │       ├── NetworkGraphicsDemo/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       └── WindowsDLL/
│   │           └── CMakeLists.txt
│   ├── JUCE-6.0.5/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   └── DemoRunner/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── AudioPluginHost/
│   │       │   └── CMakeLists.txt
│   │       ├── BinaryBuilder/
│   │       │   └── CMakeLists.txt
│   │       ├── NetworkGraphicsDemo/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       └── WindowsDLL/
│   │           └── CMakeLists.txt
│   ├── JUCE-6.1.6/
│   │   ├── CMakeLists.txt
│   │   ├── README.rst
│   │   ├── examples/
│   │   │   └── DemoRunner/
│   │   │       └── CMakeLists.txt
│   │   └── extras/
│   │       ├── AudioPerformanceTest/
│   │       │   └── CMakeLists.txt
│   │       ├── AudioPluginHost/
│   │       │   └── CMakeLists.txt
│   │       ├── BinaryBuilder/
│   │       │   └── CMakeLists.txt
│   │       ├── NetworkGraphicsDemo/
│   │       │   └── CMakeLists.txt
│   │       ├── Projucer/
│   │       │   └── CMakeLists.txt
│   │       ├── UnitTestRunner/
│   │       │   └── CMakeLists.txt
│   │       └── WindowsDLL/
│   │           └── CMakeLists.txt
│   └── JUCE-7.0.7/
│       ├── CMakeLists.txt
│       ├── README.rst
│       ├── examples/
│       │   └── DemoRunner/
│       │       └── CMakeLists.txt
│       └── extras/
│           ├── AudioPerformanceTest/
│           │   └── CMakeLists.txt
│           ├── AudioPluginHost/
│           │   └── CMakeLists.txt
│           ├── BinaryBuilder/
│           │   └── CMakeLists.txt
│           ├── NetworkGraphicsDemo/
│           │   └── CMakeLists.txt
│           ├── Projucer/
│           │   └── CMakeLists.txt
│           ├── UnitTestRunner/
│           │   └── CMakeLists.txt
│           └── WindowsDLL/
│               └── CMakeLists.txt
├── tests/
│   ├── diff-compiler-args.cmake
│   ├── issue-246/
│   │   ├── CMakeLists.txt
│   │   └── main.cpp
│   ├── test-projects/
│   │   ├── entitlements-generation/
│   │   │   ├── .gitignore
│   │   │   ├── guiapp-MacOSX/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   └── binary_dir/
│   │   │   │       ├── AllSettings.entitlements
│   │   │   │       ├── PushNotificationsCapability.entitlements
│   │   │   │       ├── UseAppSandbox_Inheritance.entitlements
│   │   │   │       ├── UseAppSandbox_NoOptions.entitlements
│   │   │   │       ├── UseAppSandbox_OneOption.entitlements
│   │   │   │       ├── UseAppSandbox_SeveralOptions.entitlements
│   │   │   │       ├── UseHardenedRuntime_NoOptions.entitlements
│   │   │   │       ├── UseHardenedRuntime_OneOption.entitlements
│   │   │   │       ├── UseHardenedRuntime_SeveralOptions.entitlements
│   │   │   │       └── default.entitlements
│   │   │   ├── guiapp-iOS/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   └── binary_dir/
│   │   │   │       ├── AppGroupsCapability-empty.entitlements
│   │   │   │       ├── AppGroupsCapability-one_ID.entitlements
│   │   │   │       ├── AppGroupsCapability-three_IDs.entitlements
│   │   │   │       ├── PushNotificationsCapability.entitlements
│   │   │   │       ├── default.entitlements
│   │   │   │       └── iCloudPermissions.entitlements
│   │   │   ├── plugin-MacOSX/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   └── binary_dir/
│   │   │   │       ├── AUv3-AllSettings.entitlements
│   │   │   │       ├── AUv3-PushNotificationsCapability.entitlements
│   │   │   │       ├── AUv3-UseAppSandbox_Inheritance.entitlements
│   │   │   │       ├── AUv3-UseAppSandbox_NoOptions.entitlements
│   │   │   │       ├── AUv3-UseAppSandbox_OneOption.entitlements
│   │   │   │       ├── AUv3-UseAppSandbox_SeveralOptions.entitlements
│   │   │   │       ├── AUv3-UseHardenedRuntime_NoOptions.entitlements
│   │   │   │       ├── AUv3-UseHardenedRuntime_OneOption.entitlements
│   │   │   │       ├── AUv3-UseHardenedRuntime_SeveralOptions.entitlements
│   │   │   │       ├── AUv3-default.entitlements
│   │   │   │       ├── AllSettings.entitlements
│   │   │   │       ├── PushNotificationsCapability.entitlements
│   │   │   │       ├── UseAppSandbox_Inheritance.entitlements
│   │   │   │       ├── UseAppSandbox_NoOptions.entitlements
│   │   │   │       ├── UseAppSandbox_OneOption.entitlements
│   │   │   │       ├── UseAppSandbox_SeveralOptions.entitlements
│   │   │   │       ├── UseHardenedRuntime_NoOptions.entitlements
│   │   │   │       ├── UseHardenedRuntime_OneOption.entitlements
│   │   │   │       ├── UseHardenedRuntime_SeveralOptions.entitlements
│   │   │   │       └── default.entitlements
│   │   │   └── plugin-iOS/
│   │   │       ├── CMakeLists.txt
│   │   │       └── binary_dir/
│   │   │           ├── AUv3-EnableIAA.entitlements
│   │   │           ├── AUv3-PushNotificationsCapability.entitlements
│   │   │           ├── AUv3-default.entitlements
│   │   │           ├── EnableIAA.entitlements
│   │   │           ├── PushNotificationsCapability.entitlements
│   │   │           └── default.entitlements
│   │   ├── no-modules/
│   │   │   ├── consoleapp420/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── Builds/
│   │   │   │   │   ├── CodeBlocksLinux/
│   │   │   │   │   │   └── consoleapp420.cbp
│   │   │   │   │   ├── CodeBlocksWindows/
│   │   │   │   │   │   └── consoleapp420.cbp
│   │   │   │   │   ├── LinuxMakefile/
│   │   │   │   │   │   └── Makefile
│   │   │   │   │   ├── MacOSX/
│   │   │   │   │   │   ├── RecentFilesMenuTemplate.nib
│   │   │   │   │   │   └── consoleapp420.xcodeproj/
│   │   │   │   │   │       └── project.pbxproj
│   │   │   │   │   ├── VisualStudio2013/
│   │   │   │   │   │   ├── consoleapp420.sln
│   │   │   │   │   │   ├── consoleapp420.vcxproj
│   │   │   │   │   │   ├── consoleapp420.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   └── VisualStudio2015/
│   │   │   │   │       ├── consoleapp420.sln
│   │   │   │   │       ├── consoleapp420.vcxproj
│   │   │   │   │       ├── consoleapp420.vcxproj.filters
│   │   │   │   │       └── resources.rc
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── JuceLibraryCode/
│   │   │   │   │   ├── AppConfig.h
│   │   │   │   │   ├── JuceHeader.h
│   │   │   │   │   └── ReadMe.txt
│   │   │   │   ├── Source/
│   │   │   │   │   └── foo.cpp
│   │   │   │   └── consoleapp420.jucer
│   │   │   ├── consoleapp431/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── Builds/
│   │   │   │   │   ├── CodeBlocksLinux/
│   │   │   │   │   │   └── consoleapp431.cbp
│   │   │   │   │   ├── CodeBlocksWindows/
│   │   │   │   │   │   └── consoleapp431.cbp
│   │   │   │   │   ├── LinuxMakefile/
│   │   │   │   │   │   └── Makefile
│   │   │   │   │   ├── MacOSX/
│   │   │   │   │   │   ├── RecentFilesMenuTemplate.nib
│   │   │   │   │   │   └── consoleapp431.xcodeproj/
│   │   │   │   │   │       └── project.pbxproj
│   │   │   │   │   ├── VisualStudio2013/
│   │   │   │   │   │   ├── consoleapp431.sln
│   │   │   │   │   │   ├── consoleapp431.vcxproj
│   │   │   │   │   │   ├── consoleapp431.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   └── VisualStudio2015/
│   │   │   │   │       ├── consoleapp431.sln
│   │   │   │   │       ├── consoleapp431.vcxproj
│   │   │   │   │       ├── consoleapp431.vcxproj.filters
│   │   │   │   │       └── resources.rc
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── JuceLibraryCode/
│   │   │   │   │   ├── AppConfig.h
│   │   │   │   │   ├── JuceHeader.h
│   │   │   │   │   └── ReadMe.txt
│   │   │   │   ├── Source/
│   │   │   │   │   └── foo.cpp
│   │   │   │   └── consoleapp431.jucer
│   │   │   ├── consoleapp500/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── Builds/
│   │   │   │   │   ├── CodeBlocksLinux/
│   │   │   │   │   │   └── consoleapp500.cbp
│   │   │   │   │   ├── CodeBlocksWindows/
│   │   │   │   │   │   └── consoleapp500.cbp
│   │   │   │   │   ├── LinuxMakefile/
│   │   │   │   │   │   └── Makefile
│   │   │   │   │   ├── MacOSX/
│   │   │   │   │   │   ├── RecentFilesMenuTemplate.nib
│   │   │   │   │   │   └── consoleapp500.xcodeproj/
│   │   │   │   │   │       └── project.pbxproj
│   │   │   │   │   ├── VisualStudio2013/
│   │   │   │   │   │   ├── consoleapp500.sln
│   │   │   │   │   │   ├── consoleapp500_ConsoleApp.vcxproj
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   ├── VisualStudio2015/
│   │   │   │   │   │   ├── consoleapp500.sln
│   │   │   │   │   │   ├── consoleapp500_ConsoleApp.vcxproj
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   └── VisualStudio2017/
│   │   │   │   │       ├── consoleapp500.sln
│   │   │   │   │       ├── consoleapp500_ConsoleApp.vcxproj
│   │   │   │   │       └── resources.rc
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── JuceLibraryCode/
│   │   │   │   │   ├── AppConfig.h
│   │   │   │   │   ├── JuceHeader.h
│   │   │   │   │   └── ReadMe.txt
│   │   │   │   ├── Source/
│   │   │   │   │   └── foo.cpp
│   │   │   │   └── consoleapp500.jucer
│   │   │   ├── consoleapp521/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── Builds/
│   │   │   │   │   ├── CodeBlocksLinux/
│   │   │   │   │   │   └── consoleapp521.cbp
│   │   │   │   │   ├── CodeBlocksWindows/
│   │   │   │   │   │   └── consoleapp521.cbp
│   │   │   │   │   ├── LinuxMakefile/
│   │   │   │   │   │   └── Makefile
│   │   │   │   │   ├── MacOSX/
│   │   │   │   │   │   ├── RecentFilesMenuTemplate.nib
│   │   │   │   │   │   └── consoleapp521.xcodeproj/
│   │   │   │   │   │       └── project.pbxproj
│   │   │   │   │   ├── VisualStudio2013/
│   │   │   │   │   │   ├── consoleapp521.sln
│   │   │   │   │   │   ├── consoleapp521_ConsoleApp.vcxproj
│   │   │   │   │   │   ├── consoleapp521_ConsoleApp.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   ├── VisualStudio2015/
│   │   │   │   │   │   ├── consoleapp521.sln
│   │   │   │   │   │   ├── consoleapp521_ConsoleApp.vcxproj
│   │   │   │   │   │   ├── consoleapp521_ConsoleApp.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   └── VisualStudio2017/
│   │   │   │   │       ├── consoleapp521.sln
│   │   │   │   │       ├── consoleapp521_ConsoleApp.vcxproj
│   │   │   │   │       ├── consoleapp521_ConsoleApp.vcxproj.filters
│   │   │   │   │       └── resources.rc
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── JuceLibraryCode/
│   │   │   │   │   ├── AppConfig.h
│   │   │   │   │   ├── JuceHeader.h
│   │   │   │   │   └── ReadMe.txt
│   │   │   │   ├── Source/
│   │   │   │   │   └── foo.cpp
│   │   │   │   └── consoleapp521.jucer
│   │   │   ├── consoleapp531/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── Builds/
│   │   │   │   │   ├── CodeBlocksLinux/
│   │   │   │   │   │   └── consoleapp531.cbp
│   │   │   │   │   ├── CodeBlocksWindows/
│   │   │   │   │   │   └── consoleapp531.cbp
│   │   │   │   │   ├── LinuxMakefile/
│   │   │   │   │   │   └── Makefile
│   │   │   │   │   ├── MacOSX/
│   │   │   │   │   │   ├── RecentFilesMenuTemplate.nib
│   │   │   │   │   │   └── consoleapp531.xcodeproj/
│   │   │   │   │   │       └── project.pbxproj
│   │   │   │   │   ├── VisualStudio2013/
│   │   │   │   │   │   ├── consoleapp531.sln
│   │   │   │   │   │   ├── consoleapp531_ConsoleApp.vcxproj
│   │   │   │   │   │   ├── consoleapp531_ConsoleApp.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   ├── VisualStudio2015/
│   │   │   │   │   │   ├── consoleapp531.sln
│   │   │   │   │   │   ├── consoleapp531_ConsoleApp.vcxproj
│   │   │   │   │   │   ├── consoleapp531_ConsoleApp.vcxproj.filters
│   │   │   │   │   │   └── resources.rc
│   │   │   │   │   └── VisualStudio2017/
│   │   │   │   │       ├── consoleapp531.sln
│   │   │   │   │       ├── consoleapp531_ConsoleApp.vcxproj
│   │   │   │   │       ├── consoleapp531_ConsoleApp.vcxproj.filters
│   │   │   │   │       └── resources.rc
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   ├── JuceLibraryCode/
│   │   │   │   │   ├── AppConfig.h
│   │   │   │   │   ├── JuceHeader.h
│   │   │   │   │   └── ReadMe.txt
│   │   │   │   ├── Source/
│   │   │   │   │   └── foo.cpp
│   │   │   │   └── consoleapp531.jucer
│   │   │   └── consoleapp543/
│   │   │       ├── .gitignore
│   │   │       ├── Builds/
│   │   │       │   ├── CodeBlocksLinux/
│   │   │       │   │   ├── consoleapp543.cbp
│   │   │       │   │   └── resources.rc
│   │   │       │   ├── CodeBlocksWindows/
│   │   │       │   │   ├── consoleapp543.cbp
│   │   │       │   │   └── resources.rc
│   │   │       │   ├── LinuxMakefile/
│   │   │       │   │   └── Makefile
│   │   │       │   ├── MacOSX/
│   │   │       │   │   ├── RecentFilesMenuTemplate.nib
│   │   │       │   │   └── consoleapp543.xcodeproj/
│   │   │       │   │       ├── project.pbxproj
│   │   │       │   │       └── project.xcworkspace/
│   │   │       │   │           └── xcshareddata/
│   │   │       │   │               └── WorkspaceSettings.xcsettings
│   │   │       │   ├── VisualStudio2013/
│   │   │       │   │   ├── consoleapp543.sln
│   │   │       │   │   ├── consoleapp543_ConsoleApp.vcxproj
│   │   │       │   │   ├── consoleapp543_ConsoleApp.vcxproj.filters
│   │   │       │   │   └── resources.rc
│   │   │       │   ├── VisualStudio2015/
│   │   │       │   │   ├── consoleapp543.sln
│   │   │       │   │   ├── consoleapp543_ConsoleApp.vcxproj
│   │   │       │   │   ├── consoleapp543_ConsoleApp.vcxproj.filters
│   │   │       │   │   └── resources.rc
│   │   │       │   └── VisualStudio2017/
│   │   │       │       ├── consoleapp543.sln
│   │   │       │       ├── consoleapp543_ConsoleApp.vcxproj
│   │   │       │       ├── consoleapp543_ConsoleApp.vcxproj.filters
│   │   │       │       └── resources.rc
│   │   │       ├── CMakeLists.txt
│   │   │       ├── JuceLibraryCode/
│   │   │       │   ├── AppConfig.h
│   │   │       │   ├── JuceHeader.h
│   │   │       │   └── ReadMe.txt
│   │   │       ├── Source/
│   │   │       │   └── foo.cpp
│   │   │       └── consoleapp543.jucer
│   │   └── plist-generation/
│   │       ├── .gitignore
│   │       ├── guiapp-MacOSX/
│   │       │   ├── CMakeLists.txt
│   │       │   └── binary_dir/
│   │       │       ├── Info-App-BluetoothUsage-custom.plist
│   │       │       ├── Info-App-BluetoothUsage-default.plist
│   │       │       ├── Info-App-BundleIdentifier.plist
│   │       │       ├── Info-App-CameraUsage-custom.plist
│   │       │       ├── Info-App-CameraUsage-default.plist
│   │       │       ├── Info-App-Copyright-pre-5.2.0.plist
│   │       │       ├── Info-App-Copyright.plist
│   │       │       ├── Info-App-DocumentTypes.plist
│   │       │       ├── Info-App-ExporterBundleIdentifier.plist
│   │       │       ├── Info-App-IconFile.plist
│   │       │       ├── Info-App-MicrophoneUsage-custom.plist
│   │       │       ├── Info-App-MicrophoneUsage-default.plist
│   │       │       ├── Info-App-SendAppleEvents-custom.plist
│   │       │       ├── Info-App-SendAppleEvents-default.plist
│   │       │       ├── Info-App-Version.plist
│   │       │       ├── Info-App-default.plist
│   │       │       └── Info-App-pre-5.2.0.plist
│   │       ├── guiapp-iOS/
│   │       │   ├── CMakeLists.txt
│   │       │   └── binary_dir/
│   │       │       ├── Info-App-AllBackgroundCapabilities.plist
│   │       │       ├── Info-App-AudioBackgroundCapability.plist
│   │       │       ├── Info-App-BluetoothMIDIBackgroundCapability.plist
│   │       │       ├── Info-App-BluetoothUsage-custom.plist
│   │       │       ├── Info-App-BluetoothUsage-default.plist
│   │       │       ├── Info-App-BundleIdentifier.plist
│   │       │       ├── Info-App-CameraUsage-custom.plist
│   │       │       ├── Info-App-CameraUsage-default.plist
│   │       │       ├── Info-App-Copyright.plist
│   │       │       ├── Info-App-ExporterBundleIdentifier.plist
│   │       │       ├── Info-App-FileSharingEnabled.plist
│   │       │       ├── Info-App-MicrophoneUsage-custom.plist
│   │       │       ├── Info-App-MicrophoneUsage-default.plist
│   │       │       ├── Info-App-PushNotificationsCapability.plist
│   │       │       ├── Info-App-RequiresFullScreen-off.plist
│   │       │       ├── Info-App-ScreenOrientations-default.plist
│   │       │       ├── Info-App-ScreenOrientations-different.plist
│   │       │       ├── Info-App-ScreenOrientations-identical.plist
│   │       │       ├── Info-App-StatusBarHidden-pre-6.0.8.plist
│   │       │       ├── Info-App-StatusBarHidden.plist
│   │       │       ├── Info-App-SupportDocumentBrowser.plist
│   │       │       ├── Info-App-Version.plist
│   │       │       ├── Info-App-default.plist
│   │       │       └── Info-App-pre-6.0.8.plist
│   │       ├── plugin-MacOSX/
│   │       │   ├── CMakeLists.txt
│   │       │   └── binary_dir/
│   │       │       ├── Info-AAX-default.plist
│   │       │       ├── Info-AU-default.plist
│   │       │       ├── Info-AU-factoryFunction.plist
│   │       │       ├── Info-AU-pre-5.4.0.plist
│   │       │       ├── Info-AU-sandboxSafe.plist
│   │       │       ├── Info-AUv3_AppExtension-ExporterBundleIdentifier.plist
│   │       │       ├── Info-AUv3_AppExtension-Synth.plist
│   │       │       ├── Info-AUv3_AppExtension-default.plist
│   │       │       ├── Info-AUv3_AppExtension-factoryFunction.plist
│   │       │       ├── Info-AUv3_AppExtension-pre-5.0.0.plist
│   │       │       ├── Info-AUv3_Standalone-pre-5.0.0.plist
│   │       │       ├── Info-RTAS-default.plist
│   │       │       ├── Info-Standalone_Plugin-default.plist
│   │       │       ├── Info-Unity_Plugin-default.plist
│   │       │       ├── Info-VST-default.plist
│   │       │       ├── Info-VST3-default.plist
│   │       │       └── Info-VST3-pre-5.2.0.plist
│   │       └── plugin-iOS/
│   │           ├── CMakeLists.txt
│   │           └── binary_dir/
│   │               ├── Info-AUv3_AppExtension-ExporterBundleIdentifier.plist
│   │               ├── Info-AUv3_AppExtension-Synth.plist
│   │               ├── Info-AUv3_AppExtension-default.plist
│   │               ├── Info-AUv3_AppExtension-factoryFunction.plist
│   │               ├── Info-AUv3_AppExtension-pre-6.0.8.plist
│   │               ├── Info-Standalone_Plugin-IAA.plist
│   │               └── Info-Standalone_Plugin-default.plist
│   └── test-utils/
│       ├── cmake_make_program/
│       │   └── CMakeLists.txt
│       └── simplediff/
│           ├── simplediff.cmake
│           └── test_simplediff.cmake
└── third-party/
    ├── .clang-format
    └── argh/
        ├── LICENSE
        └── argh.h
Download .txt
SYMBOL INDEX (141 symbols across 52 files)

FILE: Jucer2CMake/src/juce6.hpp
  type Jucer2CMake (line 28) | namespace Jucer2CMake
    function hasModule (line 45) | inline bool hasModule(const juce::XmlElement& modules, const juce::Str...
    function isJuceOptionEnabled (line 65) | inline bool isJuceOptionEnabled(const juce::XmlElement& juceOptions,
    function writeJuce6CMakeLists (line 73) | inline void writeJuce6CMakeLists(const Arguments&, const juce::XmlElem...

FILE: Jucer2CMake/src/main.cpp
  function Arguments (line 38) | Arguments parseArguments(const int argc, const char* const argv[])
  function main (line 239) | int main(int argc, char* argv[])

FILE: Jucer2CMake/src/reprojucer.hpp
  type Jucer2CMake (line 55) | namespace Jucer2CMake
    function makeValidIdentifier (line 58) | inline juce::String makeValidIdentifier(juce::String s)
    function makeValidConfigurationName (line 79) | inline juce::String makeValidConfigurationName(const juce::String& con...
    function cmakePath (line 91) | inline juce::String cmakePath(const juce::String& path)
    function escape (line 98) | inline juce::String escape(const juce::String& charsToEscape, juce::St...
    function parsePreprocessorDefinitions (line 112) | inline juce::StringArray parsePreprocessorDefinitions(const juce::Stri...
    function parseSearchPaths (line 165) | inline juce::StringArray parseSearchPaths(const juce::String& input)
    function parseProjucerSettings (line 226) | inline std::unique_ptr<juce::XmlElement> parseProjucerSettings()
    function writeUserNotes (line 245) | inline void writeUserNotes(LineWriter& wLn, const juce::XmlElement& el...
    function writeReprojucerCMakeLists (line 259) | inline void writeReprojucerCMakeLists(const Arguments& args,

FILE: Jucer2CMake/src/utils.hpp
  type Jucer2CMake (line 26) | namespace Jucer2CMake
    type Arguments (line 29) | struct Arguments
    type ExitException (line 42) | struct ExitException
      method ExitException (line 45) | ExitException(const int returnValue)
      method returnValue (line 50) | int returnValue() const
    type LineWriter (line 70) | struct LineWriter
      method LineWriter (line 72) | explicit LineWriter(juce::MemoryOutputStream& stream)
      method LineWriter (line 77) | LineWriter(const LineWriter&) = delete;
      method LineWriter (line 78) | LineWriter& operator=(const LineWriter&) = delete;
      method writeToStream (line 96) | void writeToStream(juce::MemoryOutputStream& stream, Head&& head)
      method writeToStream (line 102) | void writeToStream(juce::MemoryOutputStream& stream, Head&& head, Ta...
    function convertIdsToStrings (line 112) | inline juce::StringArray convertIdsToStrings(
    function getAUMainTypeConstantFromQuotedFourChars (line 128) | inline juce::String getAUMainTypeConstantFromQuotedFourChars(
    function getChildFileFromWorkingDirectory (line 147) | inline juce::File getChildFileFromWorkingDirectory(
    function printError (line 154) | inline void printError(const juce::String& error)
    function toBoolLikeVar (line 162) | inline bool toBoolLikeVar(const juce::String& s)

FILE: Jucer2CMake/tests/audioplug6-default/Source/PluginEditor.h
  function class (line 17) | class Audioplug6AudioProcessorEditor  : public juce::AudioProcessorEditor

FILE: Jucer2CMake/tests/audioplug6/Source/PluginEditor.h
  function class (line 17) | class Audioplug6AudioProcessorEditor  : public juce::AudioProcessorEditor

FILE: Jucer2CMake/tests/consoleapp6-default/Source/Main.cpp
  function main (line 12) | int main (int argc, char* argv[])

FILE: Jucer2CMake/tests/consoleapp6/Source/Main.cpp
  function main (line 12) | int main (int argc, char* argv[])

FILE: Jucer2CMake/tests/guiapp6-default/Source/Main.cpp
  function guiapp6Application (line 17) | guiapp6Application() {}
  function getApplicationName (line 19) | const juce::String getApplicationName() override       { return ProjectI...
  function getApplicationVersion (line 20) | const juce::String getApplicationVersion() override    { return ProjectI...
  function moreThanOneInstanceAllowed (line 21) | bool moreThanOneInstanceAllowed() override             { return true; }
  function initialise (line 24) | void initialise (const juce::String& commandLine) override
  function shutdown (line 31) | void shutdown() override
  function systemRequestedQuit (line 39) | void systemRequestedQuit() override
  function anotherInstanceStarted (line 46) | void anotherInstanceStarted (const juce::String& commandLine) override
  class MainWindow (line 58) | class MainWindow    : public juce::DocumentWindow
    method MainWindow (line 61) | MainWindow (juce::String name)
    method closeButtonPressed (line 80) | void closeButtonPressed() override

FILE: Jucer2CMake/tests/guiapp6-default/Source/MainComponent.h
  function class (line 10) | class MainComponent  : public juce::Component

FILE: Jucer2CMake/tests/guiapp6/Source/Main.cpp
  function guiapp6Application (line 17) | guiapp6Application() {}
  function getApplicationName (line 19) | const juce::String getApplicationName() override       { return ProjectI...
  function getApplicationVersion (line 20) | const juce::String getApplicationVersion() override    { return ProjectI...
  function moreThanOneInstanceAllowed (line 21) | bool moreThanOneInstanceAllowed() override             { return true; }
  function initialise (line 24) | void initialise (const juce::String& commandLine) override
  function shutdown (line 31) | void shutdown() override
  function systemRequestedQuit (line 39) | void systemRequestedQuit() override
  function anotherInstanceStarted (line 46) | void anotherInstanceStarted (const juce::String& commandLine) override
  class MainWindow (line 58) | class MainWindow    : public juce::DocumentWindow
    method MainWindow (line 61) | MainWindow (juce::String name)
    method closeButtonPressed (line 80) | void closeButtonPressed() override

FILE: Jucer2CMake/tests/guiapp6/Source/MainComponent.h
  function class (line 10) | class MainComponent  : public juce::Component

FILE: cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Project Saving/jucer_ResourceFile.cpp
  function String (line 87) | static String getComment()
  function Result (line 100) | Result ResourceFile::writeHeader (MemoryOutputStream& header)
  function Result (line 154) | Result ResourceFile::writeCpp (MemoryOutputStream& cpp, const File& head...
  function Result (line 247) | Result ResourceFile::write (Array<File>& filesCreated, const int maxFile...
  function Result (line 319) | Result ResourceFile::writeHeader<ProjucerVersion::v5_0_0> (MemoryOutputS...
  function Result (line 395) | Result ResourceFile::writeHeader<ProjucerVersion::v5_3_1> (MemoryOutputS...
  function Result (line 451) | Result ResourceFile::writeCpp<ProjucerVersion::v5_3_1> (MemoryOutputStre...

FILE: cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Project Saving/jucer_ResourceFile.h
  type class (line 54) | enum class
  function class (line 63) | class ResourceFile

FILE: cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Project/jucer_Project.h
  function class (line 21) | class Project

FILE: cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_CodeHelpers.cpp
  type CodeHelpers (line 53) | namespace CodeHelpers
    function String (line 55) | String makeValidIdentifier (String s, bool capitalise, bool removeColo...
    function String (line 106) | String makeBinaryDataIdentifierName (const File& file)
    function writeDataAsCppLiteral (line 114) | void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out,
    function calculateHash (line 180) | static unsigned int calculateHash (const String& s, const unsigned int...
    function findBestHashMultiplier (line 190) | static unsigned int findBestHashMultiplier (const StringArray& strings)
    function createStringMatcher (line 219) | void createStringMatcher (OutputStream& out, const String& utf8Pointer...

FILE: cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_CodeHelpers.h
  function namespace (line 53) | namespace CodeHelpers

FILE: cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_FileHelpers.cpp
  type FileHelpers (line 52) | namespace FileHelpers
    function int64 (line 54) | static int64 calculateMemoryHashCode (const void* data, const size_t n...
    function int64 (line 64) | int64 calculateStreamHashCode (InputStream& in)
    function int64 (line 86) | int64 calculateFileHashCode (const File& file)
    function overwriteFileWithNewDataIfDifferent (line 92) | bool overwriteFileWithNewDataIfDifferent (const File& file, const void...
    function overwriteFileWithNewDataIfDifferent (line 104) | bool overwriteFileWithNewDataIfDifferent (const File& file, const Memo...

FILE: cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_FileHelpers.h
  function namespace (line 53) | namespace FileHelpers

FILE: cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_MiscUtilities.cpp
  function String (line 51) | String hexString8Digits (int value)

FILE: cmake/tools/BinaryDataBuilder/main.cpp
  function main (line 30) | int main(int argc, char* argv[])

FILE: cmake/tools/BinaryDataBuilder/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp
  type juce (line 50) | namespace juce

FILE: cmake/tools/BinaryDataBuilder/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h
  function namespace (line 50) | namespace juce

FILE: cmake/tools/BinaryDataBuilder/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h
  function namespace (line 50) | namespace juce
  function writeEscapeChars (line 119) | static void writeEscapeChars (OutputStream& out, const char* utf8, const...

FILE: cmake/tools/IconBuilder/Source/Project Saving/jucer_ProjectExport_MSVC.h
  function writeBMPImage (line 48) | static void writeBMPImage (const Image& image, const int w, const int h,...
  function writeIconFile (line 116) | static void writeIconFile (const Array<Image>& images, MemoryOutputStrea...

FILE: cmake/tools/IconBuilder/Source/Project Saving/jucer_ProjectExport_XCode.h
  function Image (line 51) | static Image fixMacIconImageSize_v4_2_0 (Drawable& image)
  function writeOldIconFormat (line 75) | static void writeOldIconFormat (MemoryOutputStream& out, const Image& im...
  function writeNewIconFormat (line 110) | static void writeNewIconFormat (MemoryOutputStream& out, const Image& im...
  function writeIcnsFile_v4_2_0 (line 121) | void writeIcnsFile_v4_2_0 (const OwnedArray<Drawable>& images, OutputStr...
  function Image (line 190) | static Image fixMacIconImageSize_v5_4_0 (Drawable& image)
  function writeIconData (line 214) | static void writeIconData (MemoryOutputStream& out, const Image& image, ...
  function writeIcnsFile_v5_4_0 (line 225) | void writeIcnsFile_v5_4_0 (const OwnedArray<Drawable>& images, OutputStr...

FILE: cmake/tools/IconBuilder/Source/Project Saving/jucer_ProjectExporter.cpp
  function Image (line 53) | Image ProjectExporter::getBestIconForSize (int size, bool returnNullIfNo...
  function Image (line 83) | Image ProjectExporter::rescaleImageForIcon (Drawable& d, const int size)

FILE: cmake/tools/IconBuilder/Source/Project Saving/jucer_ProjectExporter.h
  function class (line 25) | class ProjectExporter

FILE: cmake/tools/IconBuilder/Source/Utility/jucer_FileHelpers.cpp
  type FileHelpers (line 52) | namespace FileHelpers
    function int64 (line 54) | static int64 calculateMemoryHashCode (const void* data, const size_t n...
    function int64 (line 64) | int64 calculateStreamHashCode (InputStream& in)
    function int64 (line 86) | int64 calculateFileHashCode (const File& file)
    function overwriteFileWithNewDataIfDifferent (line 92) | bool overwriteFileWithNewDataIfDifferent (const File& file, const void...
    function overwriteFileWithNewDataIfDifferent (line 104) | bool overwriteFileWithNewDataIfDifferent (const File& file, const Memo...

FILE: cmake/tools/IconBuilder/Source/Utility/jucer_FileHelpers.h
  function namespace (line 53) | namespace FileHelpers

FILE: cmake/tools/IconBuilder/main.cpp
  function main (line 31) | int main(int argc, char* argv[])

FILE: cmake/tools/PListMerger/main.cpp
  function main (line 27) | int main(int argc, char* argv[])

FILE: cmake/tools/XcassetsBuilder/Source/ProjectSaving/jucer_ProjectExport_Xcode.h
  function getIconImages (line 53) | void getIconImages (OwnedArray<Drawable>& images) const
  function createiOSIconFiles (line 64) | void createiOSIconFiles (File appIconSet) const

FILE: cmake/tools/XcassetsBuilder/Source/ProjectSaving/jucer_ProjectExporter.cpp
  function Image (line 53) | Image ProjectExporter::rescaleImageForIcon (Drawable& d, const int size)

FILE: cmake/tools/XcassetsBuilder/Source/ProjectSaving/jucer_ProjectExporter.h
  function class (line 25) | class ProjectExporter

FILE: cmake/tools/XcassetsBuilder/Source/Utility/jucer_FileHelpers.cpp
  type FileHelpers (line 51) | namespace FileHelpers
    function int64 (line 53) | static int64 calculateMemoryHashCode (const void* data, const size_t n...
    function int64 (line 63) | int64 calculateStreamHashCode (InputStream& in)
    function int64 (line 85) | int64 calculateFileHashCode (const File& file)
    function overwriteFileWithNewDataIfDifferent (line 91) | bool overwriteFileWithNewDataIfDifferent (const File& file, const void...
    function overwriteFileWithNewDataIfDifferent (line 103) | bool overwriteFileWithNewDataIfDifferent (const File& file, const Memo...
    function overwriteFileWithNewDataIfDifferent (line 108) | bool overwriteFileWithNewDataIfDifferent (const File& file, const Stri...

FILE: cmake/tools/XcassetsBuilder/Source/Utility/jucer_FileHelpers.h
  function namespace (line 52) | namespace FileHelpers

FILE: cmake/tools/XcassetsBuilder/main.cpp
  function main (line 27) | int main(int argc, char* argv[])

FILE: tests/issue-246/main.cpp
  function main (line 1) | int main()

FILE: tests/test-projects/no-modules/consoleapp420/JuceLibraryCode/JuceHeader.h
  function namespace (line 25) | namespace ProjectInfo

FILE: tests/test-projects/no-modules/consoleapp420/Source/foo.cpp
  function main (line 1) | int main()

FILE: tests/test-projects/no-modules/consoleapp431/JuceLibraryCode/JuceHeader.h
  function namespace (line 25) | namespace ProjectInfo

FILE: tests/test-projects/no-modules/consoleapp431/Source/foo.cpp
  function main (line 1) | int main()

FILE: tests/test-projects/no-modules/consoleapp500/JuceLibraryCode/JuceHeader.h
  function namespace (line 24) | namespace ProjectInfo

FILE: tests/test-projects/no-modules/consoleapp500/Source/foo.cpp
  function main (line 1) | int main()

FILE: tests/test-projects/no-modules/consoleapp521/JuceLibraryCode/JuceHeader.h
  function namespace (line 24) | namespace ProjectInfo

FILE: tests/test-projects/no-modules/consoleapp521/Source/foo.cpp
  function main (line 1) | int main()

FILE: tests/test-projects/no-modules/consoleapp531/JuceLibraryCode/JuceHeader.h
  function namespace (line 24) | namespace ProjectInfo

FILE: tests/test-projects/no-modules/consoleapp531/Source/foo.cpp
  function main (line 1) | int main()

FILE: tests/test-projects/no-modules/consoleapp543/JuceLibraryCode/JuceHeader.h
  function namespace (line 24) | namespace ProjectInfo

FILE: tests/test-projects/no-modules/consoleapp543/Source/foo.cpp
  function main (line 1) | int main()

FILE: third-party/argh/argh.h
  function namespace (line 11) | namespace argh
  function parse (line 164) | inline void parser::parse(const char * const argv[], int mode)
  function parse (line 173) | inline void parser::parse(int argc, const char* const argv[], int mode /...
Condensed preview — 586 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,738K chars).
[
  {
    "path": ".appveyor.yml",
    "chars": 16818,
    "preview": "branches:\n  only:\n    - main\n\nclone_depth: 50\n\nenvironment:\n  matrix:\n    - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2"
  },
  {
    "path": ".azure-pipelines.yml",
    "chars": 3158,
    "preview": "trigger:\n  branches:\n    include:\n      - main\n\nparameters:\n  - name: juceVersions\n    type: object\n    default: [4.2.0,"
  },
  {
    "path": ".cirrus.yml",
    "chars": 333,
    "preview": "task:\n  name: clang-format\n\n  only_if: $CIRRUS_BASE_BRANCH == \"main\" || $CIRRUS_BRANCH == \"main\"\n\n  container:\n    image"
  },
  {
    "path": ".clang-format",
    "chars": 412,
    "preview": "# Using clang-format 9.0.0\n\nAllowShortFunctionsOnASingleLine: false\nAlwaysBreakTemplateDeclarations: true\nBreakBeforeBin"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 109,
    "preview": "Before pressing the \"Create pull request\" button:\n- double-check that docs are up-to-date\n- delete this list\n"
  },
  {
    "path": ".gitignore",
    "chars": 48,
    "preview": "*build/\n*prefix/\n.DS_Store\n/ci/tmp/\n/cmake/bin/\n"
  },
  {
    "path": ".readthedocs.yaml",
    "chars": 116,
    "preview": "version: 2\n\nsphinx:\n  configuration: \"docs/conf.py\"\n\npython:\n  install:\n    - requirements: \"docs/requirements.txt\"\n"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 1022,
    "preview": "# Copyright (C) 2018-2021  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistribute i"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3351,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1332,
    "preview": "# How to contribute to FRUT?\n\nContributions to FRUT are very welcomed and you can contribute even if you don't know\nanyt"
  },
  {
    "path": "Jucer2CMake/CMakeLists.txt",
    "chars": 4211,
    "preview": "# Copyright (C) 2020-2023  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistribute i"
  },
  {
    "path": "Jucer2CMake/src/argh.hpp",
    "chars": 1151,
    "preview": "// Copyright (C) 2021  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "Jucer2CMake/src/juce6.hpp",
    "chars": 12814,
    "preview": "// Copyright (C) 2021  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "Jucer2CMake/src/juce_core.hpp",
    "chars": 2802,
    "preview": "// Copyright (C) 2021-2023  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "Jucer2CMake/src/main.cpp",
    "chars": 10093,
    "preview": "// Copyright (C) 2017-2022  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "Jucer2CMake/src/reprojucer.hpp",
    "chars": 104930,
    "preview": "// Copyright (C) 2017  Matthieu Talbot\n// Copyright (C) 2017-2022  Alain Martin\n// Copyright (C) 2017  Florian Goltz\n// "
  },
  {
    "path": "Jucer2CMake/src/utils.hpp",
    "chars": 4225,
    "preview": "// Copyright (C) 2021-2022  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "Jucer2CMake/tests/.gitignore",
    "chars": 31,
    "preview": "/*/Builds/\n/*/JuceLibraryCode/\n"
  },
  {
    "path": "Jucer2CMake/tests/apply-Jucer2CMake-juce6-to-test-jucers.cmake",
    "chars": 1346,
    "preview": "# Copyright (C) 2021  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistribute it and"
  },
  {
    "path": "Jucer2CMake/tests/audioplug6/CMakeLists.txt",
    "chars": 1623,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"audioplug6.jucer\"\n\ncmake_minimum_required(VERSION 3.15)\n\nproject(\""
  },
  {
    "path": "Jucer2CMake/tests/audioplug6/Source/PluginEditor.cpp",
    "chars": 1405,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic fr"
  },
  {
    "path": "Jucer2CMake/tests/audioplug6/Source/PluginEditor.h",
    "chars": 1017,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic fr"
  },
  {
    "path": "Jucer2CMake/tests/audioplug6/Source/PluginProcessor.cpp",
    "chars": 6016,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic fr"
  },
  {
    "path": "Jucer2CMake/tests/audioplug6/Source/PluginProcessor.h",
    "chars": 2260,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic fr"
  },
  {
    "path": "Jucer2CMake/tests/audioplug6/audioplug6.jucer",
    "chars": 5871,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<JUCERPROJECT id=\"CCxcbs\" name=\"audioplug6\" projectType=\"audioplug\" useAppConfig"
  },
  {
    "path": "Jucer2CMake/tests/audioplug6-default/CMakeLists.txt",
    "chars": 1071,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"audioplug6.jucer\"\n\ncmake_minimum_required(VERSION 3.15)\n\nproject(\""
  },
  {
    "path": "Jucer2CMake/tests/audioplug6-default/Source/PluginEditor.cpp",
    "chars": 1405,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic fr"
  },
  {
    "path": "Jucer2CMake/tests/audioplug6-default/Source/PluginEditor.h",
    "chars": 1017,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic fr"
  },
  {
    "path": "Jucer2CMake/tests/audioplug6-default/Source/PluginProcessor.cpp",
    "chars": 6016,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic fr"
  },
  {
    "path": "Jucer2CMake/tests/audioplug6-default/Source/PluginProcessor.h",
    "chars": 2260,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic fr"
  },
  {
    "path": "Jucer2CMake/tests/audioplug6-default/audioplug6.jucer",
    "chars": 5175,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<JUCERPROJECT id=\"CCxcbs\" name=\"audioplug6\" projectType=\"audioplug\" useAppConfig"
  },
  {
    "path": "Jucer2CMake/tests/consoleapp6/CMakeLists.txt",
    "chars": 884,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"consoleapp6.jucer\"\n\ncmake_minimum_required(VERSION 3.12)\n\nproject("
  },
  {
    "path": "Jucer2CMake/tests/consoleapp6/Source/Main.cpp",
    "chars": 432,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic st"
  },
  {
    "path": "Jucer2CMake/tests/consoleapp6/consoleapp6.jucer",
    "chars": 2565,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<JUCERPROJECT id=\"zagqOo\" name=\"consoleapp6\" projectType=\"consoleapp\" useAppConf"
  },
  {
    "path": "Jucer2CMake/tests/consoleapp6-default/CMakeLists.txt",
    "chars": 684,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"consoleapp6.jucer\"\n\ncmake_minimum_required(VERSION 3.12)\n\nproject("
  },
  {
    "path": "Jucer2CMake/tests/consoleapp6-default/Source/Main.cpp",
    "chars": 432,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic st"
  },
  {
    "path": "Jucer2CMake/tests/consoleapp6-default/consoleapp6.jucer",
    "chars": 2334,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<JUCERPROJECT id=\"zagqOo\" name=\"consoleapp6\" projectType=\"consoleapp\" useAppConf"
  },
  {
    "path": "Jucer2CMake/tests/guiapp6/CMakeLists.txt",
    "chars": 1107,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"guiapp6.jucer\"\n\ncmake_minimum_required(VERSION 3.12)\n\nproject(\"gui"
  },
  {
    "path": "Jucer2CMake/tests/guiapp6/Source/Main.cpp",
    "chars": 3984,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic st"
  },
  {
    "path": "Jucer2CMake/tests/guiapp6/Source/MainComponent.cpp",
    "chars": 874,
    "preview": "#include \"MainComponent.h\"\n\n//==============================================================================\nMainCompone"
  },
  {
    "path": "Jucer2CMake/tests/guiapp6/Source/MainComponent.h",
    "chars": 802,
    "preview": "#pragma once\n\n#include <JuceHeader.h>\n\n//==============================================================================\n"
  },
  {
    "path": "Jucer2CMake/tests/guiapp6/guiapp6.jucer",
    "chars": 4311,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<JUCERPROJECT id=\"Zvlvys\" name=\"guiapp6\" projectType=\"guiapp\" useAppConfig=\"0\"\n "
  },
  {
    "path": "Jucer2CMake/tests/guiapp6-default/CMakeLists.txt",
    "chars": 733,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"guiapp6.jucer\"\n\ncmake_minimum_required(VERSION 3.12)\n\nproject(\"gui"
  },
  {
    "path": "Jucer2CMake/tests/guiapp6-default/Source/Main.cpp",
    "chars": 3984,
    "preview": "/*\n  ==============================================================================\n\n    This file contains the basic st"
  },
  {
    "path": "Jucer2CMake/tests/guiapp6-default/Source/MainComponent.cpp",
    "chars": 874,
    "preview": "#include \"MainComponent.h\"\n\n//==============================================================================\nMainCompone"
  },
  {
    "path": "Jucer2CMake/tests/guiapp6-default/Source/MainComponent.h",
    "chars": 802,
    "preview": "#pragma once\n\n#include <JuceHeader.h>\n\n//==============================================================================\n"
  },
  {
    "path": "Jucer2CMake/tests/guiapp6-default/guiapp6.jucer",
    "chars": 3052,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<JUCERPROJECT id=\"Zvlvys\" name=\"guiapp6\" projectType=\"guiapp\" useAppConfig=\"0\"\n "
  },
  {
    "path": "LICENSE",
    "chars": 35147,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README.rst",
    "chars": 21083,
    "preview": "|Code_of_Conduct| |AppVeyor| |Azure_Pipelines| |Read_the_Docs|\n\n.. image:: FRUT.svg\n  :target: https://github.com/McMart"
  },
  {
    "path": "ci/AllJuceProjects/CMakeLists.txt",
    "chars": 1127,
    "preview": "# Copyright (C) 2017-2018  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistribute i"
  },
  {
    "path": "ci/apply-Jucer2CMake-reprojucer-to-JUCE-jucers.cmake",
    "chars": 2257,
    "preview": "# Copyright (C) 2017-2020, 2022  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistri"
  },
  {
    "path": "ci/apply-Jucer2CMake-reprojucer-to-test-jucers.cmake",
    "chars": 1683,
    "preview": "# Copyright (C) 2018-2020  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistribute i"
  },
  {
    "path": "ci/azure-pipelines/steps-Makefiles.yml",
    "chars": 3734,
    "preview": "parameters:\n  - name: juceVersions\n    type: object\n\nsteps:\n  - script: cmake --version\n    displayName: CMake version\n\n"
  },
  {
    "path": "ci/azure-pipelines/steps-VS.yml",
    "chars": 2711,
    "preview": "parameters:\n  - name: juceVersions\n    type: object\n\nsteps:\n  - script: cmake --version\n    displayName: CMake version\n\n"
  },
  {
    "path": "ci/azure-pipelines/steps-Xcode.yml",
    "chars": 3608,
    "preview": "parameters:\n  - name: juceVersions\n    type: object\n\nsteps:\n  - script: cmake --version\n    displayName: CMake version\n\n"
  },
  {
    "path": "ci/azure-pipelines/steps-iOS.yml",
    "chars": 1801,
    "preview": "parameters:\n  - name: juceVersions\n    type: object\n\nsteps:\n  - script: cmake --version\n    displayName: CMake version\n\n"
  },
  {
    "path": "ci/fake-SDKs/AAX/Interfaces/AAX_Exports.cpp",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "ci/fake-SDKs/VST/pluginterfaces/vst2.x/aeffect.h",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "ci/fake-SDKs/VST/public.sdk/source/vst2.x/audioeffectx.h",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "ci/fake-SDKs/VST3/base/source/baseiids.cpp",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "cmake/Reprojucer.cmake",
    "chars": 244319,
    "preview": "# Copyright (C) 2016-2024  Alain Martin\n# Copyright (C) 2017 Matthieu Talbot\n# Copyright (C) 2018-2019 Scott Wheeler\n# C"
  },
  {
    "path": "cmake/data/AppConfig-4.h.in",
    "chars": 1045,
    "preview": "/*\n\n    IMPORTANT! This file is auto-generated each time you run cmake on your\n    project - if you alter its contents, "
  },
  {
    "path": "cmake/data/AppConfig-5.h.in",
    "chars": 1730,
    "preview": "/*\n\n    IMPORTANT! This file is auto-generated each time you run cmake on your\n    project - if you alter its contents, "
  },
  {
    "path": "cmake/data/AppConfig.h.in",
    "chars": 1645,
    "preview": "/*\n\n    IMPORTANT! This file is auto-generated each time you run cmake on your\n    project - if you alter its contents, "
  },
  {
    "path": "cmake/data/Info.plist.in",
    "chars": 194,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/"
  },
  {
    "path": "cmake/data/JuceHeader.h.in",
    "chars": 855,
    "preview": "/*\n\n    IMPORTANT! This file is auto-generated each time you run cmake on your\n    project - if you alter its contents, "
  },
  {
    "path": "cmake/data/JuceLibraryCode-Wrapper.cpp.in",
    "chars": 207,
    "preview": "/*\n\n    IMPORTANT! This file is auto-generated each time you run cmake on your\n    project - if you alter its contents, "
  },
  {
    "path": "cmake/data/JucePluginDefines.h.in",
    "chars": 203,
    "preview": "/*\n\n    IMPORTANT! This file is auto-generated each time you run cmake on your\n    project - if you alter its contents, "
  },
  {
    "path": "cmake/data/LaunchScreen.storyboard",
    "chars": 1042,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
  },
  {
    "path": "cmake/data/PkgInfo",
    "chars": 9,
    "preview": "BNDL????\n"
  },
  {
    "path": "cmake/data/UnityScript.cs.in",
    "chars": 6413,
    "preview": "#if UNITY_EDITOR\n\nusing UnityEditor;\nusing UnityEngine;\n\nusing System.Collections.Generic;\nusing System.Runtime.InteropS"
  },
  {
    "path": "cmake/data/failed-to.md.in",
    "chars": 865,
    "preview": "### Failed to @action@ `@tool_name@`\n\n\n#### Versions\n\nCMake: `@CMAKE_VERSION@`\nFRUT: @frut_version@\nJUCE: @juce_version@"
  },
  {
    "path": "cmake/data/juce_runtime_arch_detection.cpp",
    "chars": 2206,
    "preview": "// This file was copied from\n// https://github.com/juce-framework/JUCE/blob/6.0.8/extras/Build/CMake/juce_runtime_arch_d"
  },
  {
    "path": "cmake/data/resources.rc.in",
    "chars": 454,
    "preview": "#ifdef JUCE_USER_DEFINED_RC_FILE\n #include JUCE_USER_DEFINED_RC_FILE\n#else\n\n#undef  WIN32_LEAN_AND_MEAN\n#define WIN32_LE"
  },
  {
    "path": "cmake/data/script.in",
    "chars": 17,
    "preview": "@script_content@\n"
  },
  {
    "path": "cmake/data/target.entitlements.in",
    "chars": 210,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/CMakeLists.txt",
    "chars": 1487,
    "preview": "# Copyright (C) 2016-2020  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Project/jucer_Project.h",
    "chars": 1472,
    "preview": "// Copyright (C) 2016-2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Project Saving/jucer_ResourceFile.cpp",
    "chars": 21577,
    "preview": "// Copyright (C) 2017-2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Project Saving/jucer_ResourceFile.h",
    "chars": 2944,
    "preview": "// Copyright (C) 2017-2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_CodeHelpers.cpp",
    "chars": 8117,
    "preview": "// Copyright (C) 2017-2018  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_CodeHelpers.h",
    "chars": 2522,
    "preview": "// Copyright (C) 2017-2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_FileHelpers.cpp",
    "chars": 3507,
    "preview": "// Copyright (C) 2017-2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_FileHelpers.h",
    "chars": 2315,
    "preview": "// Copyright (C) 2017-2018  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_MiscUtilities.cpp",
    "chars": 1995,
    "preview": "// Copyright (C) 2017-2018  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/extras/Projucer/Source/Utility/jucer_MiscUtilities.h",
    "chars": 1941,
    "preview": "// Copyright (C) 2017-2018  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/extras/Projucer/Source/jucer_Headers.h",
    "chars": 949,
    "preview": "// Copyright (C) 2017-2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/main.cpp",
    "chars": 3251,
    "preview": "// Copyright (C) 2016-2020  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp",
    "chars": 2072,
    "preview": "// Copyright (C) 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h",
    "chars": 2189,
    "preview": "// Copyright (C) 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h",
    "chars": 8723,
    "preview": "// Copyright (C) 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/modules/juce_gui_extra/juce_gui_extra.cpp",
    "chars": 779,
    "preview": "// Copyright (C) 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/BinaryDataBuilder/modules/juce_gui_extra/juce_gui_extra.h",
    "chars": 858,
    "preview": "// Copyright (C) 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/CMakeLists.txt",
    "chars": 2926,
    "preview": "# Copyright (C) 2020-2022  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/IconBuilder/CMakeLists.txt",
    "chars": 1188,
    "preview": "# Copyright (C) 2017-2020  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/IconBuilder/Source/Project Saving/jucer_ProjectExport_MSVC.h",
    "chars": 5260,
    "preview": "// Copyright (C) 2017, 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistri"
  },
  {
    "path": "cmake/tools/IconBuilder/Source/Project Saving/jucer_ProjectExport_XCode.h",
    "chars": 9320,
    "preview": "// Copyright (C) 2017, 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistri"
  },
  {
    "path": "cmake/tools/IconBuilder/Source/Project Saving/jucer_ProjectExporter.cpp",
    "chars": 3660,
    "preview": "// Copyright (C) 2017, 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistri"
  },
  {
    "path": "cmake/tools/IconBuilder/Source/Project Saving/jucer_ProjectExporter.h",
    "chars": 1476,
    "preview": "// Copyright (C) 2017, 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistri"
  },
  {
    "path": "cmake/tools/IconBuilder/Source/Utility/jucer_FileHelpers.cpp",
    "chars": 3508,
    "preview": "// Copyright (C) 2017, 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistri"
  },
  {
    "path": "cmake/tools/IconBuilder/Source/Utility/jucer_FileHelpers.h",
    "chars": 2316,
    "preview": "// Copyright (C) 2017, 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistri"
  },
  {
    "path": "cmake/tools/IconBuilder/Source/jucer_Headers.h",
    "chars": 890,
    "preview": "// Copyright (C) 2017  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/IconBuilder/main.cpp",
    "chars": 4284,
    "preview": "// Copyright (C) 2017-2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/PListMerger/CMakeLists.txt",
    "chars": 1034,
    "preview": "# Copyright (C) 2017-2020  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/PListMerger/main.cpp",
    "chars": 4619,
    "preview": "// Copyright (C) 2017-2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/XcassetsBuilder/CMakeLists.txt",
    "chars": 1211,
    "preview": "# Copyright (C) 2019-2020  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/XcassetsBuilder/Source/ProjectSaving/jucer_ProjectExport_Xcode.h",
    "chars": 11459,
    "preview": "// Copyright (C) 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/XcassetsBuilder/Source/ProjectSaving/jucer_ProjectExporter.cpp",
    "chars": 2817,
    "preview": "// Copyright (C) 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/XcassetsBuilder/Source/ProjectSaving/jucer_ProjectExporter.h",
    "chars": 1357,
    "preview": "// Copyright (C) 2019-2020  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/XcassetsBuilder/Source/Utility/jucer_FileHelpers.cpp",
    "chars": 3652,
    "preview": "// Copyright (C) 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/XcassetsBuilder/Source/Utility/jucer_FileHelpers.h",
    "chars": 2317,
    "preview": "// Copyright (C) 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/XcassetsBuilder/Source/jucer_Headers.h",
    "chars": 890,
    "preview": "// Copyright (C) 2019  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistribute i"
  },
  {
    "path": "cmake/tools/XcassetsBuilder/main.cpp",
    "chars": 2503,
    "preview": "// Copyright (C) 2019-2020  Alain Martin\n//\n// This file is part of FRUT.\n//\n// FRUT is free software: you can redistrib"
  },
  {
    "path": "cmake/tools/juce_core.cmake",
    "chars": 2128,
    "preview": "# Copyright (C) 2017-2020, 2022-2023  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can red"
  },
  {
    "path": "cmake/tools/juce_gui_basics.cmake",
    "chars": 3732,
    "preview": "# Copyright (C) 2017-2023  Alain Martin\n# Copyright (C) 2019  David Holland\n#\n# This file is part of FRUT.\n#\n# FRUT is f"
  },
  {
    "path": "docs/Reprojucer.cmake/command/jucer_appconfig_header.rst",
    "chars": 1321,
    "preview": ".. # Copyright (C) 2017, 2019-2020  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: y"
  },
  {
    "path": "docs/Reprojucer.cmake/command/jucer_audio_plugin_settings.rst",
    "chars": 3446,
    "preview": ".. # Copyright (C) 2017-2020  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: you can"
  },
  {
    "path": "docs/Reprojucer.cmake/command/jucer_export_target.rst",
    "chars": 7092,
    "preview": ".. # Copyright (C) 2017-2022  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: you can"
  },
  {
    "path": "docs/Reprojucer.cmake/command/jucer_export_target_configuration.rst",
    "chars": 6016,
    "preview": ".. # Copyright (C) 2017-2022  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: you can"
  },
  {
    "path": "docs/Reprojucer.cmake/command/jucer_project_begin.rst",
    "chars": 1105,
    "preview": ".. # Copyright (C) 2017-2018, 2020  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: y"
  },
  {
    "path": "docs/Reprojucer.cmake/command/jucer_project_end.rst",
    "chars": 1032,
    "preview": ".. # Copyright (C) 2017-2018  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: you can"
  },
  {
    "path": "docs/Reprojucer.cmake/command/jucer_project_files.rst",
    "chars": 2086,
    "preview": ".. # Copyright (C) 2017-2020  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: you can"
  },
  {
    "path": "docs/Reprojucer.cmake/command/jucer_project_module.rst",
    "chars": 1801,
    "preview": ".. # Copyright (C) 2017-2020  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: you can"
  },
  {
    "path": "docs/Reprojucer.cmake/command/jucer_project_settings.rst",
    "chars": 2935,
    "preview": ".. # Copyright (C) 2017-2020  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: you can"
  },
  {
    "path": "docs/Reprojucer.cmake/index.rst",
    "chars": 4308,
    "preview": ".. # Copyright (C) 2017-2019, 2022  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: y"
  },
  {
    "path": "docs/conf.py",
    "chars": 822,
    "preview": "# Copyright (C) 2018-2019, 2023-2024  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can red"
  },
  {
    "path": "docs/index.rst",
    "chars": 4218,
    "preview": ".. # Copyright (C) 2018-2022  Alain Martin\n.. #\n.. # This file is part of FRUT.\n.. #\n.. # FRUT is free software: you can"
  },
  {
    "path": "docs/requirements.txt",
    "chars": 17,
    "preview": "sphinx-rtd-theme\n"
  },
  {
    "path": "generated/JUCE-4.2.0/CMakeLists.txt",
    "chars": 6894,
    "preview": "# Copyright (C) 2017-2019, 2022  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistri"
  },
  {
    "path": "generated/JUCE-4.2.0/README.rst",
    "chars": 6724,
    "preview": "JUCE 4.2.0\n==========\n\n+--------------------------------------+-------------+-------------+-------------+-------------+-"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/AUv3Synth/CMakeLists.txt",
    "chars": 4827,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AUv3Synth.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"AU"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/AnimationAppExample/CMakeLists.txt",
    "chars": 3863,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AnimationAppExample.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\np"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/AudioAppExample/CMakeLists.txt",
    "chars": 3874,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AudioAppExample.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproje"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/BouncingBallWavetableDemo/CMakeLists.txt",
    "chars": 4525,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BouncingBallWavetableDemo.jucer\"\n\ncmake_minimum_required(VERSION 3"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/ComponentTutorialExample/CMakeLists.txt",
    "chars": 2687,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"ComponentTutorialExample.jucer\"\n\ncmake_minimum_required(VERSION 3."
  },
  {
    "path": "generated/JUCE-4.2.0/examples/Demo/CMakeLists.txt",
    "chars": 9454,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"JuceDemo.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"Juc"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/HelloWorld/CMakeLists.txt",
    "chars": 3866,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"HelloWorld.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"H"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/MPETest/CMakeLists.txt",
    "chars": 4638,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"MPETest.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"MPET"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/MidiTest/CMakeLists.txt",
    "chars": 4941,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"MidiTest.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"Mid"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/NetworkGraphicsDemo/CMakeLists.txt",
    "chars": 5497,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"NetworkGraphicsDemo.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\np"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/OSCMonitor/CMakeLists.txt",
    "chars": 4456,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"OSCMonitor.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"O"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/OSCReceiver/CMakeLists.txt",
    "chars": 4021,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"OSCReceiver.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\""
  },
  {
    "path": "generated/JUCE-4.2.0/examples/OSCSender/CMakeLists.txt",
    "chars": 3794,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"OSCSender.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"OS"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/OpenGLAppExample/CMakeLists.txt",
    "chars": 4082,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"OpenGLAppExample.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproj"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/PluckedStringsDemo/CMakeLists.txt",
    "chars": 3793,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"PluckedStringsDemo.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\npr"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/PlugInSamples/Arpeggiator/CMakeLists.txt",
    "chars": 5052,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"Arpeggiator.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\""
  },
  {
    "path": "generated/JUCE-4.2.0/examples/PlugInSamples/GainPlugIn/CMakeLists.txt",
    "chars": 5047,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"GainPlugIn.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"G"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/PlugInSamples/MultiOutSynth/CMakeLists.txt",
    "chars": 5396,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"MultiOutSynth.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/PlugInSamples/NoiseGate/CMakeLists.txt",
    "chars": 5027,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"NoiseGate.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"No"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/PlugInSamples/Surround/CMakeLists.txt",
    "chars": 6242,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"Surround.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"Sur"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/SimpleFFTExample/CMakeLists.txt",
    "chars": 3659,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"SimpleFFTExample.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproj"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/audio plugin demo/CMakeLists.txt",
    "chars": 5439,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"JuceDemoPlugin.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nprojec"
  },
  {
    "path": "generated/JUCE-4.2.0/examples/audio plugin host/CMakeLists.txt",
    "chars": 5466,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"Plugin Host.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\""
  },
  {
    "path": "generated/JUCE-4.2.0/extras/AudioPerformanceTest/CMakeLists.txt",
    "chars": 4879,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AudioPerformanceTest.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\n"
  },
  {
    "path": "generated/JUCE-4.2.0/extras/Projucer/CMakeLists.txt",
    "chars": 28780,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"Projucer.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"Pro"
  },
  {
    "path": "generated/JUCE-4.2.0/extras/UnitTestRunner/CMakeLists.txt",
    "chars": 4756,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"UnitTestRunner.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nprojec"
  },
  {
    "path": "generated/JUCE-4.2.0/extras/binarybuilder/CMakeLists.txt",
    "chars": 2280,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BinaryBuilder.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject"
  },
  {
    "path": "generated/JUCE-4.2.0/extras/windows dll/CMakeLists.txt",
    "chars": 2571,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"jucedll.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"juce"
  },
  {
    "path": "generated/JUCE-4.3.1/CMakeLists.txt",
    "chars": 7330,
    "preview": "# Copyright (C) 2017-2019, 2022  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistri"
  },
  {
    "path": "generated/JUCE-4.3.1/README.rst",
    "chars": 7390,
    "preview": "JUCE 4.3.1\n==========\n\n+--------------------------------------+-------------+-------------+-------------+-------------+-"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/AUv3Synth/CMakeLists.txt",
    "chars": 4938,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AUv3Synth.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"AU"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/AnimationAppExample/CMakeLists.txt",
    "chars": 3892,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AnimationAppExample.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\np"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/AudioAppExample/CMakeLists.txt",
    "chars": 3947,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AudioAppExample.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproje"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/BLOCKS/BlocksDrawing/CMakeLists.txt",
    "chars": 5100,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BlocksDrawing.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/BLOCKS/BlocksMonitor/CMakeLists.txt",
    "chars": 5095,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BlocksMonitor.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/BLOCKS/BlocksSynth/CMakeLists.txt",
    "chars": 5281,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BlocksSynth.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\""
  },
  {
    "path": "generated/JUCE-4.3.1/examples/BouncingBallWavetableDemo/CMakeLists.txt",
    "chars": 4598,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BouncingBallWavetableDemo.jucer\"\n\ncmake_minimum_required(VERSION 3"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/ComponentTutorialExample/CMakeLists.txt",
    "chars": 2760,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"ComponentTutorialExample.jucer\"\n\ncmake_minimum_required(VERSION 3."
  },
  {
    "path": "generated/JUCE-4.3.1/examples/Demo/CMakeLists.txt",
    "chars": 9907,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"JuceDemo.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"Juc"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/HelloWorld/CMakeLists.txt",
    "chars": 3939,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"HelloWorld.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"H"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/MPETest/CMakeLists.txt",
    "chars": 4711,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"MPETest.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"MPET"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/MidiTest/CMakeLists.txt",
    "chars": 5014,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"MidiTest.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"Mid"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/NetworkGraphicsDemo/CMakeLists.txt",
    "chars": 5570,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"NetworkGraphicsDemo.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\np"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/OSCMonitor/CMakeLists.txt",
    "chars": 4485,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"OSCMonitor.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"O"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/OSCReceiver/CMakeLists.txt",
    "chars": 4094,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"OSCReceiver.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\""
  },
  {
    "path": "generated/JUCE-4.3.1/examples/OSCSender/CMakeLists.txt",
    "chars": 3867,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"OSCSender.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"OS"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/OpenGLAppExample/CMakeLists.txt",
    "chars": 4111,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"OpenGLAppExample.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproj"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/PluckedStringsDemo/CMakeLists.txt",
    "chars": 3866,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"PluckedStringsDemo.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\npr"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/PlugInSamples/Arpeggiator/CMakeLists.txt",
    "chars": 5049,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"Arpeggiator.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\""
  },
  {
    "path": "generated/JUCE-4.3.1/examples/PlugInSamples/GainPlugIn/CMakeLists.txt",
    "chars": 5083,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"GainPlugIn.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"G"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/PlugInSamples/MultiOutSynth/CMakeLists.txt",
    "chars": 5469,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"MultiOutSynth.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/PlugInSamples/NoiseGate/CMakeLists.txt",
    "chars": 5100,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"NoiseGate.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"No"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/PlugInSamples/Surround/CMakeLists.txt",
    "chars": 6296,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"Surround.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"Sur"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/SimpleFFTExample/CMakeLists.txt",
    "chars": 3732,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"SimpleFFTExample.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproj"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/audio plugin demo/CMakeLists.txt",
    "chars": 5522,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"JuceDemoPlugin.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nprojec"
  },
  {
    "path": "generated/JUCE-4.3.1/examples/audio plugin host/CMakeLists.txt",
    "chars": 5952,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"Plugin Host.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\""
  },
  {
    "path": "generated/JUCE-4.3.1/extras/AudioPerformanceTest/CMakeLists.txt",
    "chars": 4952,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AudioPerformanceTest.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\n"
  },
  {
    "path": "generated/JUCE-4.3.1/extras/Projucer/CMakeLists.txt",
    "chars": 29245,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"Projucer.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"Pro"
  },
  {
    "path": "generated/JUCE-4.3.1/extras/UnitTestRunner/CMakeLists.txt",
    "chars": 4785,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"UnitTestRunner.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nprojec"
  },
  {
    "path": "generated/JUCE-4.3.1/extras/binarybuilder/CMakeLists.txt",
    "chars": 2353,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BinaryBuilder.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject"
  },
  {
    "path": "generated/JUCE-4.3.1/extras/windows dll/CMakeLists.txt",
    "chars": 2644,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"jucedll.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"juce"
  },
  {
    "path": "generated/JUCE-5.0.0/CMakeLists.txt",
    "chars": 7982,
    "preview": "# Copyright (C) 2017-2019, 2022  Alain Martin\n#\n# This file is part of FRUT.\n#\n# FRUT is free software: you can redistri"
  },
  {
    "path": "generated/JUCE-5.0.0/README.rst",
    "chars": 8972,
    "preview": "JUCE 5.0.0\n==========\n\n+--------------------------------------------+-------------+-------------+-------------+---------"
  },
  {
    "path": "generated/JUCE-5.0.0/examples/AUv3Synth/CMakeLists.txt",
    "chars": 5325,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AUv3Synth.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\"AU"
  },
  {
    "path": "generated/JUCE-5.0.0/examples/AnimationAppExample/CMakeLists.txt",
    "chars": 4730,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AnimationAppExample.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\np"
  },
  {
    "path": "generated/JUCE-5.0.0/examples/AudioAppExample/CMakeLists.txt",
    "chars": 4777,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"AudioAppExample.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproje"
  },
  {
    "path": "generated/JUCE-5.0.0/examples/BLOCKS/BlocksDrawing/CMakeLists.txt",
    "chars": 5348,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BlocksDrawing.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject"
  },
  {
    "path": "generated/JUCE-5.0.0/examples/BLOCKS/BlocksMonitor/CMakeLists.txt",
    "chars": 5343,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BlocksMonitor.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject"
  },
  {
    "path": "generated/JUCE-5.0.0/examples/BLOCKS/BlocksSynth/CMakeLists.txt",
    "chars": 5529,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BlocksSynth.jucer\"\n\ncmake_minimum_required(VERSION 3.4)\n\nproject(\""
  },
  {
    "path": "generated/JUCE-5.0.0/examples/BouncingBallWavetableDemo/CMakeLists.txt",
    "chars": 5448,
    "preview": "# This file was generated by FRUT's Jucer2CMake from \"BouncingBallWavetableDemo.jucer\"\n\ncmake_minimum_required(VERSION 3"
  }
]

// ... and 386 more files (download for full content)

About this extraction

This page contains the full source code of the McMartin/FRUT GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 586 files (2.4 MB), approximately 671.3k tokens, and a symbol index with 141 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!