master 387fae93ed09 cached
99 files
47.5 MB
73.7k tokens
20 symbols
1 requests
Download .txt
Showing preview only (313K chars total). Download the full file or copy to clipboard to get everything.
Repository: jamesonrader/CUE-Ultrasonic-Transmissions-Protocol
Branch: master
Commit: 387fae93ed09
Files: 99
Total size: 47.5 MB

Directory structure:
gitextract_94ypakwa/

├── .gitignore
├── Android/
│   ├── consumer/
│   │   ├── .gitignore
│   │   ├── app/
│   │   │   ├── .gitignore
│   │   │   ├── build.gradle
│   │   │   ├── proguard-rules.pro
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── AndroidManifest.xml
│   │   │           ├── java/
│   │   │           │   └── com/
│   │   │           │       └── cueaudio/
│   │   │           │           └── engine_consumer/
│   │   │           │               └── MainActivity.java
│   │   │           └── res/
│   │   │               ├── drawable/
│   │   │               │   ├── ic_clear.xml
│   │   │               │   ├── ic_launcher_background.xml
│   │   │               │   ├── ic_notification.xml
│   │   │               │   ├── ic_send.xml
│   │   │               │   ├── ic_start.xml
│   │   │               │   └── ic_stop.xml
│   │   │               ├── drawable-v24/
│   │   │               │   └── ic_launcher_foreground.xml
│   │   │               ├── layout/
│   │   │               │   └── activity_main.xml
│   │   │               ├── menu/
│   │   │               │   └── main.xml
│   │   │               ├── mipmap-anydpi-v26/
│   │   │               │   ├── ic_launcher.xml
│   │   │               │   └── ic_launcher_round.xml
│   │   │               └── values/
│   │   │                   ├── colors.xml
│   │   │                   ├── strings.xml
│   │   │                   └── styles.xml
│   │   ├── build.gradle
│   │   ├── config/
│   │   │   └── debug.keystore
│   │   ├── gradle/
│   │   │   └── wrapper/
│   │   │       ├── gradle-wrapper.jar
│   │   │       └── gradle-wrapper.properties
│   │   ├── gradle.properties
│   │   ├── gradlew
│   │   ├── gradlew.bat
│   │   └── settings.gradle
│   └── engine.aar
├── License.md
├── README.md
├── doc/
│   ├── Android_README.md
│   ├── CUEEngine_JSON_Structure.md
│   ├── iOS_README.md
│   └── licenses/
│       └── 3rd_party/
│           ├── CREDITS-LIBC++.TXT
│           └── NOTICE
└── iOS/
    ├── consumer/
    │   ├── consumer/
    │   │   ├── AppDelegate.h
    │   │   ├── AppDelegate.m
    │   │   ├── Assets.xcassets/
    │   │   │   ├── AppIcon.appiconset/
    │   │   │   │   └── Contents.json
    │   │   │   └── Contents.json
    │   │   ├── Base.lproj/
    │   │   │   ├── LaunchScreen.storyboard
    │   │   │   └── Main.storyboard
    │   │   ├── Info.plist
    │   │   ├── ViewController.h
    │   │   ├── ViewController.m
    │   │   └── main.m
    │   ├── consumer.xcodeproj/
    │   │   └── project.pbxproj
    │   └── engine.xcframework/
    │       ├── Info.plist
    │       ├── LICENSE/
    │       │   └── 3rd_party/
    │       │       ├── CREDITS-LIBC++.TXT
    │       │       └── NOTICE
    │       ├── ios-arm64/
    │       │   └── engine.framework/
    │       │       ├── Headers/
    │       │       │   ├── AudioSession.h
    │       │       │   ├── CUEEngine.h
    │       │       │   ├── CUEErrno.h
    │       │       │   └── CUETrigger.h
    │       │       ├── Info.plist
    │       │       ├── LICENSE/
    │       │       │   └── 3rd_party/
    │       │       │       ├── CREDITS-LIBC++.TXT
    │       │       │       └── NOTICE
    │       │       ├── Modules/
    │       │       │   └── module.modulemap
    │       │       └── engine
    │       └── ios-x86_64-simulator/
    │           └── engine.framework/
    │               ├── Headers/
    │               │   ├── AudioSession.h
    │               │   ├── CUEEngine.h
    │               │   ├── CUEErrno.h
    │               │   └── CUETrigger.h
    │               ├── Info.plist
    │               ├── LICENSE/
    │               │   └── 3rd_party/
    │               │       ├── CREDITS-LIBC++.TXT
    │               │       └── NOTICE
    │               ├── Modules/
    │               │   └── module.modulemap
    │               └── engine
    ├── engine.framework/
    │   ├── Headers/
    │   │   ├── AudioSession.h
    │   │   ├── CUEEngine.h
    │   │   ├── CUEErrno.h
    │   │   └── CUETrigger.h
    │   ├── Info.plist
    │   ├── LICENSE/
    │   │   └── 3rd_party/
    │   │       ├── CREDITS-LIBC++.TXT
    │   │       └── NOTICE
    │   ├── Modules/
    │   │   └── module.modulemap
    │   └── engine
    └── engine.xcframework/
        ├── Info.plist
        ├── LICENSE/
        │   └── 3rd_party/
        │       ├── CREDITS-LIBC++.TXT
        │       └── NOTICE
        ├── ios-arm64/
        │   └── engine.framework/
        │       ├── Headers/
        │       │   ├── AudioSession.h
        │       │   ├── CUEEngine.h
        │       │   ├── CUEErrno.h
        │       │   └── CUETrigger.h
        │       ├── Info.plist
        │       ├── LICENSE/
        │       │   └── 3rd_party/
        │       │       ├── CREDITS-LIBC++.TXT
        │       │       └── NOTICE
        │       ├── Modules/
        │       │   └── module.modulemap
        │       └── engine
        └── ios-x86_64-simulator/
            └── engine.framework/
                ├── Headers/
                │   ├── AudioSession.h
                │   ├── CUEEngine.h
                │   ├── CUEErrno.h
                │   └── CUETrigger.h
                ├── Info.plist
                ├── LICENSE/
                │   └── 3rd_party/
                │       ├── CREDITS-LIBC++.TXT
                │       └── NOTICE
                ├── Modules/
                │   └── module.modulemap
                └── engine

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

================================================
FILE: .gitignore
================================================
# macOS
.DS_Store

#iOS
xcshareddata/
iOS/consumer/build.vars

# xcode
xcuserdata
*.xcuserstate
project.xcworkspace

# Android
Android/wrapper/.cxx/
.gradle/
.idea/
*.iml
*google-services.json

build/

================================================
FILE: Android/consumer/.gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
.idea/


================================================
FILE: Android/consumer/app/.gitignore
================================================
/build


================================================
FILE: Android/consumer/app/build.gradle
================================================
apply plugin: 'com.android.application'
//apply plugin: 'com.google.gms.google-services'

android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'

    defaultConfig {
        applicationId "com.cueaudio.engine_consumer"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }

    signingConfigs {
        debug {
            storeFile file(rootDir.path + '/config/debug.keystore')
            storePassword "android"
            keyAlias "androiddebugkey"
            keyPassword "android"
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            //signingConfig signingConfigs.debug
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    lintOptions {
        abortOnError false
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.0.0'
    implementation 'com.google.android.material:material:1.0.0'
    implementation 'androidx.core:core:1.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'

    implementation (name: 'engine', ext: 'aar')
    //implementation (name: 'engine', ext: 'aar')

    // Import the Firebase BoM
    implementation platform('com.google.firebase:firebase-bom:26.3.0')
    // Add the dependency for the Firebase SDK for Google Analytics
    // When using the BoM, don't specify versions in Firebase dependencies
    implementation 'com.google.firebase:firebase-analytics'
}


================================================
FILE: Android/consumer/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile


================================================
FILE: Android/consumer/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.cueaudio.engine_consumer">

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light"
        tools:ignore="GoogleAppIndexingWarning">

        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:configChanges="orientation"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>


================================================
FILE: Android/consumer/app/src/main/java/com/cueaudio/engine_consumer/MainActivity.java
================================================
package com.cueaudio.engine_consumer;

import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.text.Editable;
import android.text.InputType;
import android.text.Selection;
import android.text.TextWatcher;
import android.text.method.DigitsKeyListener;
import android.text.method.ScrollingMovementMethod;
import android.text.method.TextKeyListener;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.cueaudio.engine.CUEEngine;
import com.cueaudio.engine.CUEReceiverCallbackInterface;
import com.cueaudio.engine.CUETrigger;
import com.cueaudio.engine.CUEEngineError;

import java.util.regex.Pattern;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "AndroidConsumer";

    private static final int REQUEST_RECORD_AUDIO = 13;
    private static final String API_KEY = "H7v7NMMNh6im735w331iLHtqnduxGCTL";
    private static final int NOTIFICATION_ID = 1;

    private TextView outputView;
    private View clearOutput;
    private Switch outputMode;
    private View sendButton;
    private Spinner spinner;
    private TextInputLayout messageLayout;
    private TextInputEditText messageInput;

    private boolean isShown = false;

    /**
     * Used to validate the input.
     */
    private Pattern inputMatcher = null;
    private String[] hints;
    private String[] regex;
    private String[] errors;

    private boolean restartListening = false;

    private int getModeByPosition(int position) {
        int realMode;
        switch( position ) {
            case 0:
            case 1:
                realMode = CUETrigger.MODE_TRIGGER;
                break;
            case 2:
            case 3:
                realMode = CUETrigger.MODE_MULTI_TRIGGER;
                break;
            case 4:
                realMode = CUETrigger.MODE_LL;
                break;
            default:
                realMode = CUETrigger.MODE_DATA;
                break;
        }

        return realMode;
    }

    private boolean getTriggerAsNumberByPosition(int position) {
        if( position == 1 || position == 3 )
            return true;
        else
            return false;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        checkPermission();

        messageLayout = findViewById(R.id.message_layout);
        messageInput = findViewById(R.id.message);
        sendButton = findViewById(R.id.send);
        outputView = findViewById(R.id.outputView);
        outputMode = findViewById(R.id.output_mode);
        clearOutput = findViewById(R.id.clear_output);

        hints = getResources().getStringArray(R.array.message_hints);
        regex = getResources().getStringArray(R.array.message_regex);
        errors = getResources().getStringArray(R.array.message_errors);
        spinner = findViewById(R.id.message_mode);
        final ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                this,
                R.array.message_modes,
                android.R.layout.simple_spinner_item
        );
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                selectMode(position);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        messageInput.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (s != null && s.toString().length() != 0 ) {
                    validateInput(s.toString());
                }
            }
        });

        outputView.setMovementMethod(new ScrollingMovementMethod());
        sendButton.setEnabled(false);
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //noinspection ConstantConditions
                final String input = messageInput.getText().toString();
                final int position = spinner.getSelectedItemPosition();

                int mode = getModeByPosition( position );
                boolean triggerAsNumber = getTriggerAsNumberByPosition( position );

                Log.v(TAG, String.format("triggerAsNumber %b", triggerAsNumber));
                queueInput(input, mode, triggerAsNumber);
            }
        });

        clearOutput.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                outputView.setText(null);
                clearOutput.setVisibility(View.GONE);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        isShown = true;
        if (restartListening) {
            CUEEngine.getInstance().startListening();
        }
    }

    @Override
    protected void onStop() {
        restartListening = CUEEngine.getInstance().isListening();
        CUEEngine.getInstance().stopListening();
        isShown = false;
        super.onStop();
    }

    private void selectMode(int position) {
        refreshKeyboard(messageInput);

        messageInput.setHint(hints[position]);
        messageLayout.setHint(null);
        inputMatcher = Pattern.compile(regex[position]);

        int mode = getModeByPosition(position);
        switch (mode) {
            case CUETrigger.MODE_TRIGGER:
            case CUETrigger.MODE_MULTI_TRIGGER:
            case CUETrigger.MODE_LL:
                messageInput.setInputType(InputType.TYPE_CLASS_NUMBER);
                messageInput.setKeyListener(DigitsKeyListener.getInstance("0123456789."));
                break;
            case CUETrigger.MODE_DATA:
                messageInput.setInputType(InputType.TYPE_CLASS_TEXT);
                messageInput.setKeyListener(TextKeyListener.getInstance());
                break;
        }

        //noinspection ConstantConditions
        validateInput(messageInput.getText().toString());
    }

    private void validateInput(@NonNull String input) {
        final boolean matches = inputMatcher.matcher(input).matches();
        sendButton.setEnabled(matches);
        if (!matches) {
            final int position = spinner.getSelectedItemPosition();
            // HACK: to prevent error message to be cut https://stackoverflow.com/a/55468225/322955
            messageLayout.setError(null);
            messageLayout.setError(errors[position]);
        } else {
            messageLayout.setError(null);
        }
    }

    private void queueInput(@NonNull String input, int mode, boolean triggerAsNumber) {
        int result;

        switch (mode) {
            case CUETrigger.MODE_TRIGGER:
                if(triggerAsNumber) {
                    long number = Long.parseLong(input);
                    result = CUEEngine.getInstance().queueTriggerAsNumber(number);
                    if( result == CUEEngineError.TRIGGER_AS_NUMBER_MAX_NUMBER_EXCEEDED ) {
                        messageLayout.setError(
                            "Triggers as number can not exceed 461 for a CUEEngine g1 or 98611127 for a CUEEngine g2" );
                    } else if ( result < 0 ){
                        messageLayout.setError(
                                "Triggers as number sending: unknown error" );
                    }
                } else {
                    result = CUEEngine.getInstance().queueTrigger(input);
                    if( result == CUEEngineError.NUMBER_OF_SYMBOLS_MISMATCH
                        || result == CUEEngineError.INDEX_VALUE_EXCEEDED ) {
                        messageLayout.setError(
                                "Triggers must be of the format [0-461] for a CUEEngine generation 1 " +
                                "or [0-461].[0-461].[0-461] for a CUEEngine generation 2" );
                    } else if ( result < 0 ){
                        messageLayout.setError(
                                "Triggers as number sending: unknown error" );
                    }
                }
                break;

            case CUETrigger.MODE_MULTI_TRIGGER:
                if(triggerAsNumber) {
                    long number = Long.parseLong(input);
                    result = CUEEngine.getInstance().queueMultiTriggerAsNumber(number);
                    if( result == CUEEngineError.G1_QUEUE_MULTI_TRIGGER_UNSUPPORTED ) {
                        messageLayout.setError("Queue multi-trigger as number: unsupported for CUEEngine generation 1");
                    } else if( result == CUEEngineError.MULTI_TRIGGER_AS_NUMBER_MAX_NUMBER_EXCEEDED ) {
                        messageLayout.setError(
                                "Queue multi-trigger as number can not exceed 9724154565432383" );
                    } else if ( result < 0 ){
                        messageLayout.setError(
                                "Queue multi-trigger as number: unknown error" );
                    }
                } else {
                    result = CUEEngine.getInstance().queueMultiTrigger(input);
                    if( result == CUEEngineError.G1_QUEUE_MULTI_TRIGGER_UNSUPPORTED ) {
                        messageLayout.setError("Queue multi-trigger: unsupported for CUEEngine generation 1");
                    } else if ( result < 0 ){
                        messageLayout.setError(
                                "Queue multi-trigger: unknown error" );
                    }
                }
                break;

            case CUETrigger.MODE_LL:
                result = CUEEngine.getInstance().queueLL(input);
                if ( result == CUEEngineError.G1_QUEUE_LL_UNSUPPORTED ) {
                    messageLayout.setError(
                            "LL triggers sending is unsupported for engine generation 1");
                } else if ( result == CUEEngineError.G2_QUEUE_LL_MODE_LL_ONLY_OR_MODE_BASIC_SHOULD_BE_SET ) {
                    messageLayout.setError(
                            "Can not queue ll: please set config mode to 'basic' or to 'll_only'" );
                } else if ( result == CUEEngineError.G2_LL_IS_ON_IN_BASIC_CAN_NOT_QUEUE ) {
                    Toast.makeText(this,
                            "LL is already on in a config 'basic' mode, can not queue, please wait while it is off",
                            Toast.LENGTH_SHORT).show();
                } else if( result < 0 ) {
                    messageLayout.setError("Queue ll: unknown error");
                }
                break;

            case CUETrigger.MODE_DATA:
                result = CUEEngine.getInstance().queueMessage(input);
                if ( result == CUEEngineError.G1_QUEUE_MESSAGE_UNSUPPORTED ) {
                    messageLayout.setError("Queue message or data: unsupported for CUEEngine generation 1");
                } else if ( result == CUEEngineError.G2_MESSAGE_STRING_SIZE_IN_BYTES_EXCEEDED ) {
                    messageLayout.setError("Text can't contain more then 512 bytes for G2");
                } else if( result < 0 ) {
                    messageLayout.setError("Queue message: unknown error");
                }
                break;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        final boolean listening = CUEEngine.getInstance().isListening();

        final Drawable startIcon = menu.findItem(R.id.menu_start).getIcon();
        final Drawable stopIcon = menu.findItem(R.id.menu_stop).getIcon();
        if (listening) {
            DrawableCompat.setTint(startIcon, getResources().getColor(R.color.menu_active));
            DrawableCompat.setTint(stopIcon, getResources().getColor(R.color.menu_inactive));
        } else {
            DrawableCompat.setTint(startIcon, getResources().getColor(R.color.menu_inactive));
            DrawableCompat.setTint(stopIcon, getResources().getColor(R.color.menu_active));
        }
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        final int id = item.getItemId();
        switch (id) {
            case R.id.menu_start:
                enableListening(true);
                return true;
            case R.id.menu_stop:
                enableListening(false);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void checkPermission() {
        ActivityCompat.requestPermissions(
                this,
                new String[] { android.Manifest.permission.RECORD_AUDIO },
                REQUEST_RECORD_AUDIO
        );
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        //check if permission was granted, and confirm that permission was mic access
        boolean permCondition = requestCode == REQUEST_RECORD_AUDIO &&
                                grantResults.length == 1 &&
                                grantResults[0] == PackageManager.PERMISSION_GRANTED;
        // permission is not granted yet
        if (!permCondition) {
            checkPermission();
            return;
        }

        CUEEngine.getInstance().setupWithAPIKey(this, API_KEY);
        CUEEngine.getInstance().setDefaultGeneration(2);

        CUEEngine.getInstance().setReceiverCallback(new OutputListener());
        enableListening(true);

        final String config = CUEEngine.getInstance().getConfig();
        Log.v(TAG, config);

        CUEEngine.getInstance().setTransmittingEnabled(true);
    }

    private void onTriggerHeard(CUETrigger model) {
        if (!isShown) {
            showNotification(model.getRawIndices());
        }

        if (outputMode.isChecked()) {
            outputView.append(model.toString());
        } else {
            outputView.append(model.toShortString());
        }
        outputView.append("\n");
        outputView.append("\n");
        clearOutput.setVisibility(View.VISIBLE);

        long triggerNum = model.getTriggerAsNumber();
        Log.i("triggerAsNumber: ", Long.toString(triggerNum));


        // scroll to end
        // https://stackoverflow.com/a/43290961
        final Editable editable = (Editable) outputView.getText();
        Selection.setSelection(editable, editable.length());
    }

    private void showNotification(@NonNull String message) {
        final NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        final String channelId = getString(R.string.notification_channel_id);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            final CharSequence name = getString(R.string.notification_channel_name);
            NotificationChannel channel = new NotificationChannel(
                    channelId,
                    name,
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            //noinspection ConstantConditions
            notificationManager.createNotificationChannel(channel);
        }

        final Intent intent = new Intent(this, MainActivity.class);
        final PendingIntent pendingIntent = PendingIntent.getActivity(
                this, 0, intent, 0
        );

        final NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentTitle(getText(R.string.notification_title))
                .setContentText(message)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
                .setContentIntent(pendingIntent)
                .setVibrate(new long[] { 1000, 1000, 1000 })
                .setAutoCancel(true);
        //noinspection ConstantConditions
        notificationManager.notify(NOTIFICATION_ID, builder.build());
    }

    private void enableListening(boolean enable) {
        if (enable) {
            CUEEngine.getInstance().startListening();
        } else {
            CUEEngine.getInstance().stopListening();
        }
        supportInvalidateOptionsMenu();
    }

    private static void refreshKeyboard(@NonNull View view) {
        final InputMethodManager imm =
                (InputMethodManager) view.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
        //noinspection ConstantConditions
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        imm.showSoftInput(view, 0);
    }

    private class OutputListener implements CUEReceiverCallbackInterface {
        @Override
        public void run(@NonNull String json) {
            final CUETrigger model = CUETrigger.parse(json);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    onTriggerHeard(model);
                }
            });
        }
    }
}


================================================
FILE: Android/consumer/app/src/main/res/drawable/ic_clear.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>


================================================
FILE: Android/consumer/app/src/main/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="108dp"
    android:height="108dp"
    android:viewportHeight="108"
    android:viewportWidth="108">
    <path
        android:fillColor="#26A69A"
        android:pathData="M0,0h108v108h-108z" />
    <path
        android:fillColor="#00000000"
        android:pathData="M9,0L9,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,0L19,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M29,0L29,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M39,0L39,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M49,0L49,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M59,0L59,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M69,0L69,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M79,0L79,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M89,0L89,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M99,0L99,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,9L108,9"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,19L108,19"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,29L108,29"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,39L108,39"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,49L108,49"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,59L108,59"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,69L108,69"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,79L108,79"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,89L108,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,99L108,99"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,29L89,29"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,39L89,39"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,49L89,49"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,59L89,59"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,69L89,69"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,79L89,79"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M29,19L29,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M39,19L39,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M49,19L49,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M59,19L59,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M69,19L69,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M79,19L79,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
</vector>


================================================
FILE: Android/consumer/app/src/main/res/drawable/ic_notification.xml
================================================
<vector android:height="24dp" android:viewportHeight="22"
    android:viewportWidth="22" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#FFF" android:fillType="evenOdd" android:pathData="M3.9,6.897a1.089,1.089 0,0 0,-0.038 0.038L0,11l3.862,4.065a1.061,1.061 0,0 0,1.54 0,1.175 1.175,0 0,0 0,-1.62L3.077,11 5.4,8.555a1.175,1.175 0,0 0,0 -1.62,1.059 1.059,0 0,0 -1.5,-0.038zM16.63,6.906a1.133,1.133 0,0 0,-0.021 1.6l2.32,2.386 -2.347,2.583a1.172,1.172 0,0 0,0.027 1.605,1.047 1.047,0 0,0 1.518,-0.017L22,10.892l-3.855,-3.965a1.068,1.068 0,0 0,-1.515 -0.021zM13.2,4.4v13.2a1.1,1.1 0,0 0,2.2 0V4.4a1.1,1.1 0,0 0,-2.2 0zM6.6,4.4v13.2a1.1,1.1 0,0 0,2.2 0V4.4a1.1,1.1 0,1 0,-2.2 0zM9.9,1.1v19.8a1.1,1.1 0,1 0,2.2 0V1.1a1.1,1.1 0,1 0,-2.2 0z"/>
</vector>


================================================
FILE: Android/consumer/app/src/main/res/drawable/ic_send.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z"/>
</vector>


================================================
FILE: Android/consumer/app/src/main/res/drawable/ic_start.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M8,5v14l11,-7z"/>
</vector>


================================================
FILE: Android/consumer/app/src/main/res/drawable/ic_stop.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M6,6h12v12H6z"/>
</vector>


================================================
FILE: Android/consumer/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    android:width="108dp"
    android:height="108dp"
    android:viewportHeight="108"
    android:viewportWidth="108">
    <path
        android:fillType="evenOdd"
        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
        android:strokeColor="#00000000"
        android:strokeWidth="1">
        <aapt:attr name="android:fillColor">
            <gradient
                android:endX="78.5885"
                android:endY="90.9159"
                android:startX="48.7653"
                android:startY="61.0927"
                android:type="linear">
                <item
                    android:color="#44000000"
                    android:offset="0.0" />
                <item
                    android:color="#00000000"
                    android:offset="1.0" />
            </gradient>
        </aapt:attr>
    </path>
    <path
        android:fillColor="#FFFFFF"
        android:fillType="nonZero"
        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
        android:strokeColor="#00000000"
        android:strokeWidth="1" />
</vector>


================================================
FILE: Android/consumer/app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:padding="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/message_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/output_mode"
        android:orientation="horizontal">

        <Spinner
            android:id="@+id/message_mode"
            android:layout_width="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_height="wrap_content"/>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/message_layout"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_marginTop="-16dp"
            android:hint="@null">

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/message"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/message_hint_trigger" />

        </com.google.android.material.textfield.TextInputLayout>

        <ImageButton
            android:id="@+id/send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_send" />

    </LinearLayout>

    <Switch
        android:id="@+id/output_mode"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:checked="false"
        android:layout_marginStart="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/message_container"
        app:layout_constraintBottom_toTopOf="@+id/outputView"
        android:text="@string/output_mode_text"/>

    <TextView android:id="@+id/outputView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:drawable/editbox_background"
        android:layout_marginTop="8sp"
        android:hint="@string/output_hint_text"
        app:layout_constraintTop_toBottomOf="@+id/output_mode"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:scrollbars="vertical"
        android:textSize="15sp" />

    <ImageButton
        android:id="@+id/clear_output"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_clear"
        android:padding="16dp"
        android:visibility="gone"
        tools:visibility="visible"
        app:layout_constraintRight_toRightOf="@+id/outputView"
        app:layout_constraintBottom_toBottomOf="@+id/outputView"
        android:background="?selectableItemBackground"/>

</androidx.constraintlayout.widget.ConstraintLayout>

================================================
FILE: Android/consumer/app/src/main/res/menu/main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/menu_start"
        android:title="@string/menu_start_listening"
        android:icon="@drawable/ic_start"
        app:showAsAction="always"/>

    <item
        android:id="@+id/menu_stop"
        android:title="@string/menu_stop_listening"
        android:icon="@drawable/ic_stop"
        app:showAsAction="always"/>

</menu>

================================================
FILE: Android/consumer/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/ic_launcher_background" />
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

================================================
FILE: Android/consumer/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/ic_launcher_background" />
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

================================================
FILE: Android/consumer/app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>

    <color name="menu_active">@color/colorAccent</color>
    <color name="menu_inactive">#808080</color>
</resources>


================================================
FILE: Android/consumer/app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">CUE Consumer</string>

    <string name="menu_start_listening">Start listening</string>
    <string name="menu_stop_listening">Stop listening</string>
    <string name="output_mode_text">Output ALL data</string>
    <string name="output_hint_text">Ultrasonic Payload</string>

    <string name="notification_channel_id" translatable="false">triggers</string>
    <string name="notification_channel_name">Triggers</string>
    <string name="notification_title">@string/app_name</string>

    <string name="message_error_trigger">
        Triggers must be of the format [0-461] for a CUEEngine generation 1
        or [0-461].[0-461].[0-461] for a CUEEngine generation 2
    </string>
    <string name="message_error_number">Triggers as number must be of the format [0-98611127]</string>
    <string name="message_error_multi_trigger">Multi triggers must be of the format [0-461].[0-461].[0-461].[0-461].[0-461].[0-461]</string>
    <string name="message_error_number_mt">Multi-triggers as number must be of the format [0-9724154565432383]</string>
    <string name="message_error_ll">LL Triggers must be of the format [0-125].[0-125]...</string>
    <!-- <string name="message_error_raw">RAW must be of the format [0-461].[0-461]...</string> -->

    <string name="message_hint_trigger">e.g. 1 or 1.2.34</string>
    <string name="message_hint_number">0-98611127</string>
    <string name="message_hint_multi_trigger">1.2.3.4.5.6</string>
    <string name="message_hint_number_mt">0-9724154565432383</string>
    <string name="message_hint_ll">1.2.3.4.5....</string>
    <string name="message_hint_data">Hello World!</string>
    <!-- <string name="message_hint_raw">1.23.45.67.8.9</string> -->

    <string name="mode_trigger">Trigger</string>
    <string name="mode_number">Number</string>
    <string name="mode_multi_trigger">MultiTrigger</string>
    <string name="mode_number_mt">NumMultiTrg</string>
    <string name="mode_ll">LL</string>
    <string name="mode_data">Data</string>

    <string-array name="message_errors">
        <item>@string/message_error_trigger</item>
        <item>@string/message_error_number</item>
        <item>@string/message_error_multi_trigger</item>
        <item>@string/message_error_number_mt</item>
        <item>@string/message_error_ll</item>
        <item>@null</item>
        <!-- <item>@string/message_error_raw</item> -->
    </string-array>

    <string-array name="message_modes">
        <item>@string/mode_trigger</item>
        <item>@string/mode_number</item>
        <item>@string/mode_multi_trigger</item>
        <item>@string/mode_number_mt</item>
        <item>@string/mode_ll</item>
        <item>@string/mode_data</item>
    </string-array>

    <string-array name="message_hints">
        <item>@string/message_hint_trigger</item>
        <item>@string/message_hint_number</item>
        <item>@string/message_hint_multi_trigger</item>
        <item>@string/message_hint_number_mt</item>
        <item>@string/message_hint_ll</item>
        <item>@string/message_hint_data</item>
        <!-- <item>@string/message_hint_raw</item> -->
    </string-array>

    <string-array name="message_regex">
        <!-- Trigger -->
        <item>^([0-9]|[1-9][0-9]|[1-3][0-9]{2}|4[0-5][0-9]|46[01])(\\.([0-9]|[1-9][0-9]|[1-3][0-9]{2}|4[0-5][0-9]|46[01]))*$</item>
 
        <!-- Trigger as Number -->
        <item>^[0-9]+$</item>

        <!-- MultiTrigger  -->
        <item>^([0-9]|[1-9][0-9]|[1-3][0-9]{2}|4[0-5][0-9]|46[01])(\\.([0-9]|[1-9][0-9]|[1-3][0-9]{2}|4[0-5][0-9]|46[01])){5}$</item>

        <!-- MultiTrigger as Number  -->
        <item>^[0-9]+$</item>

        <!-- LL -->
        <item>^([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-5])(\\.([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-5]))*$</item>

        <!-- Data -->
        <item>^.*$</item>

        <!-- <item>^(\\b(\\d{1,3})\\.?\\b)+$</item> -->
    </string-array>

</resources>


================================================
FILE: Android/consumer/app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>


================================================
FILE: Android/consumer/build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.0'
        classpath 'com.google.gms:google-services:4.3.4'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        flatDir {
            dirs 'libs'
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: Android/consumer/gradle/wrapper/gradle-wrapper.properties
================================================
#Wed Aug 21 13:46:46 BST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip


================================================
FILE: Android/consumer/gradle.properties
================================================
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true


================================================
FILE: Android/consumer/gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: Android/consumer/gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: Android/consumer/settings.gradle
================================================
include ':app'


================================================
FILE: Android/engine.aar
================================================
[File too large to display: 22.9 MB]

================================================
FILE: License.md
================================================
For a better formatted version, see [HERE](./doc/licenses/License.pdf)

# End User License Agreement

This End User License Agreement (“Agreement”) is a binding agreement between you (“End User” or “you”) and CUE Audio, LLC, a Delaware limited liability company (“Company”). This Agreement governs your use of the Company’s software, whether incorporated into a mobile application, integrated into a third-party’s product, software or other medium, or provided on a stand-alone basis, including all related documentation (the “Product”). The Product is licensed, not sold, to you.

BY DOWNLOADING OR USING THE PRODUCT, YOU (A) ACKNOWLEDGE THAT YOU HAVE READ AND UNDERSTAND THIS AGREEMENT; (B) REPRESENT THAT YOU ARE OF LEGAL AGE TO ENTER INTO A BINDING AGREEMENT; AND (C) ACCEPT THIS AGREEMENT AND THE COMPANY’S PRIVACY POLICY AND AGREE THAT YOU ARE LEGALLY BOUND BY SUCH TERMS. IF YOU DO NOT AGREE TO THESE TERMS, DO NOT USE THE PRODUCT AND DELETE IT FROM YOUR MOBILE DEVICE.

License Grant. Subject to the terms of this Agreement, Company grants you a limited, non-exclusive, and nontransferable license to:

download, install, and use the Product for your personal, non-commercial use on a single mobile device owned or otherwise controlled by you (the “Mobile Device”) strictly in accordance with the Product’s documentation; and

on the Mobile Device, access, stream, and use the Content and Services (as defined in Section 5) made available in or otherwise accessible through the Product, strictly in accordance with this Agreement and the Privacy Policy applicable to such Content and Services as set forth in Section 5 (the “Privacy Policy”).

License Restrictions. You shall not: 

copy the Product, except as expressly permitted by this license;

modify, translate, adapt, or otherwise create updates, upgrades, bug fixes, patches, other error corrections, and/or new features (“Updates”) or derivative works, whether or not patentable, of the Product;

reverse engineer, disassemble, decompile, decode, or otherwise attempt to derive or gain access to the source code of the Product or any part thereof;

remove, delete, alter, or obscure any trademarks or any copyright, trademark, patent, or other intellectual property or proprietary rights notices from the Product, or any copy thereof;

rent, lease, lend, sell, sublicense, assign, distribute, publish, transfer, or otherwise make available the Product, or any features or functionality of the Product, to any third party for any reason, including by making the Product available on a network where it is capable of being accessed by more than one device at any time; or

remove, disable, circumvent, or otherwise create or implement any workaround to any copy protection, rights management, or security features in or protecting the Product. 

Reservation of Rights. You acknowledge and agree that the Product is provided under license, and not sold, to you. You do not acquire any ownership interest in the Product under this Agreement, or any other rights thereto other than to use the Product in accordance with the license granted, and subject to all terms, conditions, and restrictions, under this Agreement. Company and its licensors and service providers reserve and shall retain their entire right, title, and interest in and to the Product, including all copyrights, trademarks, and other intellectual property rights therein or relating thereto, subject to rights licensed and expressly granted to you in this Agreement. You agree to safeguard the Product from infringement, misappropriation, theft, misuse, or unauthorized access. 

Collection and Use of Your Information. You acknowledge that when you download, install, or use the Product, Company may use automatic means (including, for example, cookies and web beacons) to collect information about your Mobile Device and about your use of the Product. You also may be required to provide certain information about yourself as a condition to downloading, installing, or using the Product or certain of its features or functionality, and the Product may provide you with opportunities to share information about yourself with others. You represent and warrant that all information you contribute or provide in connection with your use of the Product will be current, complete and accurate, and that you will update it as necessary to maintain its completeness and accuracy. If you choose, or are provided with, a user name, password, or any other piece of information as part of Company’s security procedures, you must treat such information as confidential, and you must not disclose it to any other person or entity, whether such disclosure is made by written or verbal communication, or via social media, blog, or other media-based platform. You also acknowledge that your account is personal to you and agree not to provide any other person with access to the Product or portions of the Product using your user name, password, or other security information. You agree to notify Company immediately of any unauthorized access to or use of your user name or password or any other breach of security. You are responsible for ensuring that you exit your account at the end of each session. You are responsible for the actions of anyone using your account, whether with or without your permission, and you may be held liable for any losses incurred by Company, its members, managers officers, directors, employees, agents, affiliates, successors, and assigns due to someone else’s use of your account, password, or other security information. You should use particular caution when accessing your account from a public or shared network so that others are not able to view or record your password or other personal information. All information Company collects through or in connection with this Product is subject to Company’s Privacy Policy as published at www.cueaudio.com/privacy. By downloading, installing, using, and providing information to or through this Product, you consent to all actions taken by Company with respect to your information in compliance with the Privacy Policy. 

Content and Services. The Product may provide you with access to Company’s website located at https://www.cueaudio.com/ (the “Website”) and products and services accessible thereon, and certain features, functionality, and content accessible on or through the Product may be hosted on the Website (collectively, “Content and Services”). Your access to and use of such Content and Services are governed by the Website’s Privacy Policy, which is incorporated herein by this reference. Your access to and use of such Content and Services may require you to acknowledge your acceptance of such Privacy Policy and/or to register with the Website, and your failure to do so may restrict you from accessing or using certain of the Product’s features and functionality. Any violation of such Privacy Policy will also be deemed a violation of this Agreement.

Consent to Receive Email from Company. You may receive periodic email communications regarding the Product, updates or changes to the Product or this Agreement, or the functionality of the Product, which you cannot opt out of receiving. You may also receive periodic promotions and other offers or materials Company believes might be of interest to you. You can opt out of receiving these promotional messages at any time by (a) following the unsubscribe instructions contained in the email, newsletter, or promotion; or (b) changing the email preferences in your account.

Geographic Restrictions. Company does not represent or warrant that the Content and Services, the Product, or any part thereof, is appropriate or available for use in any particular jurisdiction.  If you choose to access the Content and Services or the Product, you do so on your own initiative and at your own risk, and you are responsible for complying with all local laws, rules, and regulations.  Company may limit the availability of the Content and Services or the Product, in whole or in part, to any person, geographic area, or jurisdiction that Company chooses, at any time and in the Company’s sole discretion.  By using the Product and submitting any information, you consent to the transfer of such information, including personal information, to other countries, such as the United States, which may provide a different level of data security than in your country of residence. 

Updates. Company may from time to time, in its sole discretion, develop and provide Updates for the Product (collectively, including related documentation, “Company Updates”). Company Updates may also modify or delete in their entirety certain features and functionality. You agree that Company has no obligation to provide any Company Updates or to continue to provide or enable any particular features or functionality. Based on your Mobile Device settings, when your Mobile Device is connected to the internet either:

the Product will automatically download and install all available Company Updates; or

you may receive notice of or be prompted to download and install available Company Updates.

You shall promptly download and install all Company Updates and acknowledge and agree that the Product or portions thereof may not properly operate should you fail to do so. You further agree that all Company Updates will be deemed part of the Product and be subject to all terms and conditions of this Agreement.

Third-Party Materials. The Product may display, include, or make available third-party content (including data, information, Products, and other products, services, and/or materials) or provide links to third-party websites or services, including through third-party advertising (“Third-Party Materials”). You acknowledge and agree that Company is not responsible for Third-Party Materials, including their accuracy, completeness, timeliness, validity, copyright compliance, legality, decency, quality, or any other aspect thereof. Company does not assume and will not have any liability or responsibility to you or any other person or entity for any Third-Party Materials. Third-Party Materials and links thereto are provided solely as a convenience to you, and you access and use them entirely at your own risk and subject to such third parties’ terms and conditions.

Term and Termination.

The term of Agreement commences when you download the Product and acknowledge your acceptance and will continue in effect until terminated by you or Company as set forth in this Section 10.

You may terminate this Agreement by permanently deleting the Product and all copies thereof from your Mobile Device.

Company may terminate this Agreement at any time without notice.  Furthermore, Company may terminate this Agreement if it ceases to support the Product, which Company may do in its sole discretion. In addition, this Agreement will terminate immediately and automatically without any notice if you violate any of the terms and conditions of this Agreement.

Upon termination:

all rights granted to you under this Agreement will also terminate; and

you must cease all use of the Product and permanently delete all copies of the Product from your Mobile Device and account.

Termination will not limit any of Company’s rights or remedies at law or in equity.

Disclaimer of Warranties. THE PRODUCT IS PROVIDED TO YOU “AS IS” AND WITH ALL FAULTS AND DEFECTS WITHOUT WARRANTY OF ANY KIND. TO THE MAXIMUM EXTENT PERMITTED UNDER APPLICABLE LAW, COMPANY, ON ITS OWN BEHALF AND ON BEHALF OF ITS AFFILIATES AND ITS AND THEIR RESPECTIVE LICENSORS AND SERVICE PROVIDERS, EXPRESSLY DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE PRODUCT, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, AND WARRANTIES THAT MAY ARISE OUT OF COURSE OF DEALING, COURSE OF PERFORMANCE, USAGE, OR TRADE PRACTICE. WITHOUT LIMITATION TO THE FOREGOING, COMPANY PROVIDES NO WARRANTY OR UNDERTAKING, AND MAKES NO REPRESENTATION OF ANY KIND THAT THE PRODUCT WILL MEET YOUR REQUIREMENTS, ACHIEVE ANY INTENDED RESULTS, BE COMPATIBLE, OR WORK WITH ANY OTHER SOFTWARE, PRODUCTS, SYSTEMS, OR SERVICES, OPERATE WITHOUT INTERRUPTION, MEET ANY PERFORMANCE OR RELIABILITY STANDARDS, OR BE ERROR-FREE, OR THAT ANY ERRORS OR DEFECTS CAN OR WILL BE CORRECTED.

SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY NOT APPLY TO YOU. 

No Reliance on Information.  The information provided on or through the Product or in connection with the Product is made available for your convenience and for general information purposes only and is subject to change without notice. COMPANY DOES NOT WARRANT THE ACCURACY, TIMELINESS, COMPLETENESS, OR USEFULNESS OF THIS INFORMATION OR THAT THE INFORMATION WILL SERVE YOUR PARTICULAR PURPOSES. ALL INFORMATION IS SUBJECT TO CHANGE.  Any reliance you place on such information is strictly at your own risk. Company disclaims all liability and responsibility arising from any reliance placed on such information or materials by you, or by anyone who may be informed of any of its contents. 

Limitation of Liability. TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL COMPANY OR ITS AFFILIATES, OR ANY OF ITS OR THEIR RESPECTIVE LICENSORS OR SERVICE PROVIDERS, HAVE ANY LIABILITY ARISING FROM OR RELATED TO YOUR USE OF OR INABILITY TO USE THE PRODUCT OR THE CONTENT AND SERVICES FOR:

PERSONAL INJURY, PROPERTY DAMAGE, LOST PROFITS, COST OF SUBSTITUTE GOODS OR SERVICES, LOSS OF DATA, LOSS OF GOODWILL, BUSINESS INTERRUPTION, COMPUTER FAILURE OR MALFUNCTION, OR ANY OTHER CONSEQUENTIAL, INCIDENTAL, INDIRECT, EXEMPLARY, SPECIAL, OR PUNITIVE DAMAGES.

DIRECT DAMAGES IN AMOUNTS THAT IN THE AGGREGATE EXCEED THE AMOUNT ACTUALLY PAID BY YOU FOR THE PRODUCT. 

THE FOREGOING LIMITATIONS WILL APPLY WHETHER SUCH DAMAGES ARISE OUT OF BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE AND REGARDLESS OF WHETHER SUCH DAMAGES WERE FORESEEABLE OR COMPANY WAS ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW CERTAIN LIMITATIONS OF LIABILITY SO SOME OR ALL OF THE ABOVE LIMITATIONS OF LIABILITY MAY NOT APPLY TO YOU. 

Indemnification. You agree to indemnify, defend, and hold harmless Company and its members, managers, officers, directors, employees, agents, affiliates, successors, and assigns from and against any and all losses, damages, liabilities, deficiencies, claims, actions, judgments, settlements, interest, awards, penalties, fines, costs, or expenses of whatever kind, including reasonable attorneys’ fees, arising from or relating to your use or misuse of the Product or your breach of this Agreement, including but not limited to the content you submit or make available through this Product.

Export Regulation. The Product may be subject to United States export control laws, including the United States Export Administration Act and its associated regulations. You shall not, directly or indirectly, export, re-export, or release the Product to, or make the Product accessible from, any jurisdiction or country to which export, re-export, or release is prohibited by law, rule, or regulation. You shall comply with all applicable federal laws, regulations, and rules, and complete all required undertakings (including obtaining any necessary export license or other governmental approval), prior to exporting, re-exporting, releasing, or otherwise using or accessing the Product outside the US.

Severability. If any provision of this Agreement is illegal or unenforceable under applicable law, the remainder of the provision will be amended to achieve as closely as possible the effect of the original term and all other provisions of this Agreement will continue in full force and effect.

Governing Law. This Agreement is governed by and construed in accordance with the internal laws of the State of Delaware without giving effect to any choice or conflict of law provision or rule. In the event of a direct conflict between the provisions of this Agreement and any mandatory provision of applicable law, the mandatory provision of applicable law will control; in all other events, the provisions of this Agreement will control. 

Arbitration.  You agree that any dispute, claim, or controversy between you and Company relating in any way to this Agreement or to your use of the Product (whether based in contract, tort, malpractice, negligence, misrepresentation, or any other legal theory, and whether the claims arise during or after the termination of the Agreement) will be resolved by mandatory binding individual arbitration.  Arbitration is more informal than a lawsuit in court. There is no judge or jury, but instead an appointed arbitrator, usually with an experienced background in the area of the dispute. There may be more limited discovery than in court.  An arbitrator can award the same damages and relief as a court (including attorney fees), except that the arbitrator may not award declaratory or injunctive relief to anyone but the parties to the arbitration. This arbitration provision will survive termination of the Agreement.

Either you or Company may demand and/or file arbitration proceedings. Arbitration between you and Company will be conducted under the then-current American Arbitration Association’s (“AAA”) Commercial Dispute Resolution Procedures and the Supplementary Procedures for Consumer Related Disputes (the “AAA Rules”). Arbitration will take place at a location to be agreed upon in Denver, Colorado, provided that if the claim is for $10,000 or less, you may request that the arbitration to be conducted be based on documents submitted to the Arbitrator or through a non-appearance based telephonic hearing; or by an in-person hearing as established by the AAA Rules. Your arbitration fees and costs will be subject to any limitations set forth in the AAA Rules with the remainder (if any) paid by Company.

In the event that Company makes any future change to this arbitration provision, you may reject any such change by sending written notice within thirty (30) days of the change and ceasing all use of the Product deleting the all copies of the Product from your Mobile Device within the same notice period.

Limitation of Time to File Claims. ANY CAUSE OF ACTION, CLAIM, OR DEMAND FOR ARBITRATION YOU MAY HAVE ARISING OUT OF OR RELATING TO THIS AGREEMENT OR THE PRODUCT MUST BE COMMENCED WITHIN ONE (1) YEAR AFTER THE CAUSE OF ACTION FIRST ACCRUES OTHERWISE SUCH CAUSE OF ACTION OR CLAIM WILL BE PERMANENTLY BARRED. If applicable law prohibits a one-year limitation period for asserting claims, any claim must be asserted within the shortest time period permitted by applicable law. 

Entire Agreement. This Agreement and Company’s Privacy Policy constitute the entire agreement between you and Company with respect to the Product and supersede all prior or contemporaneous understandings and agreements, whether written or oral, with respect to the Product. 

Waiver. No failure to exercise, and no delay in exercising, on the part of either party, any right or any power hereunder shall operate as a waiver thereof, nor shall any single or partial exercise of any right or power hereunder preclude further exercise of that or any other right hereunder. In the event of a conflict between this Agreement and any applicable purchase or other terms, the terms of this Agreement shall govern. 


================================================
FILE: README.md
================================================

# High Reliability Acoustic Modem  

## CUE Audio

CUE Audio provides an extremely reliable acoustic modem, permitting data exchange between any two devices with a microphone or speaker. CUE typically operates in the near-ultrasonic frequency band (17.5-19.5kHz) in order to be inaudible to the majority of people but detectable by commonplace microphones. Trusted by many of the world's largest brands and deployed on over nine million devices, with CUE you will have access to the world's most advanced acoustic modem.

Unlike alternative data-over-audio solution, which work only in quiet environments over short distances (a few cm to 3 meters), we've utilized this solution to successfully broadcasted ultrasonic signals in indoor/outdoor environments to crowds of 80,000+ stadium attendees, with a propagation distance of over 150 meters and negligible latency above the speed of sound.

##### Advantages include:

* No reliance on a data connection, including Wi-Fi, Bluetooth, or cellular service.
* Ability to imperceptibly transmit data through online videos, television broadcasts, or any other sound-based media.
* Enhancing the second-screen experience by allowing mobile devices to be informed of not only of what you are watching, but exactly how far along you are in the program. This also allows second-screens to respond to live events, such as touchdowns or breaking news.
* Enabling proximity-awareness in slow zones and dead spots using existing speaker infrastructure.
* Ability to synchronize devices to the nearest eighth of a second.

# Who’s using CUE Audio's library?
###### CUE Audio have been enjoyed by over 5,000,000 users across three continents. Past and current clients include:

<img width="1237" alt="Screenshot 2025-02-26 at 7 55 25 AM" src="https://github.com/user-attachments/assets/17b1db17-4e55-4a26-914e-fd248b297834" />

# Technical Overview
[See PDF here](./doc/cue-technical-overview.pdf)

# Licensing

Please only use the included API Key for applications in development. The public API Key included in this demo is liable to break at any time. Before pushing a product into production, please make sure you have your own API Key by contacting <support+github@connectwithcue.com>. Learn more at <https://cueaudio.com>.


# Example Use Cases

* Triggering commands on the smartphone through a television broadcast, online video, radio commercial, film and movies. Users can be rewarded for tuning in; products can be linked to during a featured commercial; coupons can be distributed, etc.

* Turn $10 household speakers into iBeacons. Any speaker emitting a unique fingerprint at regular intervals can be used to detect proximity and trigger events to achieve the same effect as traditional Bluetooth beacons.

* Location-based “push” notifications. Users can be segmented by proximity to various speakers.
 
* Smartphones in the same room or across the globe can be synchronized and given precisely timed commands in real-time, or minutes, hours, or even days after the trigger was detected.

<p align="center">
  <b>Arbitrary Device Synchronization</b><br>
  <a href="https://youtu.be/ork4Q4eoUg4">Villanova @ Purdue</a> |
  <a href="https://www.youtube.com/watch?v=UkxqUhp2RCk">Iowa @ Purdue</a> |
  <a href="https://www.youtube.com/watch?v=YZZp-idBDpM">Villanova @ Marquette</a>
  <br><br>
  <a href="https://youtu.be/ork4Q4eoUg4"><img src="http://qraider.com/XT/images/purdue.gif"> </a>
</p>
 
* Commands without a data connection. Because the software is triggered by sound, it can perform even where there is no data connection, Wi-Fi, or Bluetooth.
 
* Authorization/ticketing — triggers can be used to verify check-in at an event, or to unlock content on your app.
 
* Indoor location sensing — provide location services more accurate than GPS by making use of the existing speaker infrastructure.

# Integration Guide

For info on the Demo Project, please [view docs here](https://cueaudio.readme.io/docs/demo-project). An API key is not needed to use the demo project, although one is needed to integrate the library into your own project. 

## iOS
[See iOS Documentation](./doc/iOS_README.md)

## Android
[See Android Documentation](./doc/Android_README.md)

## Technical Details
[Engine Callback Structure](https://cueaudio.readme.io/docs/basic-use-cases#structure-of-a-cuetrigger) 

### Note

For testing the demo projects, since CUE is an ultrasonic communications platform, it is best to using two mobile devices (speaker of `device one` --> mic of `device two`) although you can technically test one one device (speaker of `device one` --> mic of `device one`). 


================================================
FILE: doc/Android_README.md
================================================
# CUE Engine -- Android

## Using the Demo Project

To run CUE Audio's ultrasonic engine on Android, simply follow these steps:

(1) Open the `Android/consumer` directory, then open the `consumer` application in Android Studio. 

(2) At the top of `MainActivity.java`, insert your API Key into the following:

`private static final String API_KEY = "myAPIKey"`

(3) Run the project. If your Android Studio gradle settings are not configured, it may be necessary to re-sync your project by selecting `File --> Sync Project with Gradle Files`. 

Now, transmit ultrasonic audio by playing a trigger from the `SampleTones` directory. Upon registering the tone, the device display the binary signal received.

(4) To customize the ultrasonic trigger response, simply modify the following callback within  `MainActivity.java`:

```java
private class OutputListener implements CUEReceiverCallbackInterface {
        @Override
        public void run(@NonNull String json) {
            final CUETrigger model = CUETrigger.parse(json);
            // Use payload
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // Modify UI
                }
            });
        }
    }
```

## Accessing CUEEngine with Custom API Key

1. Add Maven artifactory environment variables to your project's `local.properties` file:

```
com.cueaudio.maven.url=https://cueaudio.jfrog.io/cueaudio
com.cueaudio.maven.repokey=libs-release-local
com.cueaudio.maven.bucket=https://cueaudio.jfrog.io/cueaudio/libs-release-local
com.cueaudio.maven.username=<username>
com.cueaudio.maven.password=<password>
```

2. Import CUEEngine into your project by adding the following to your app's `build.gradle` file:

```
implementation "com.cueaudio:engine:1.+"
```

## Custom Implementation

1) Make sure your app has microphone access granted.

2) Setup the engine using your API key:

```java
CUEEngine.getInstance().setupWithAPIKey(<context>, <apiKey>);
```

You can start and stop listening with the methods:

```java
CUEEngine.getInstance().startListening();
CUEEngine.getInstance().stopListening();
```

3) To decode data from the engine, set the engine's `ReceiverCallback`. This is the block of code that will execute each time an ultrasonic signal is detected. An example is:

```java
private class CUEEngineCallbackInterfaceImpl implements CUEReceiverCallbackInterface {
        private final Gson mGson = new Gson();

        @Override
        public void run(String symbolsJson) {
            try {
                JSONObject obj = new JSONObject(symbolsJson);
                String triggerId = obj.getString("winner-indices");
                Log.i(TAG, "Trigger Detected with SymbolString: " + triggerId);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
```

Then: `CUEEngine.getInstance().setReceiverCallback(new CUEEngineCallbackInterfaceImpl());` 

For details on the structure of the returned JSON, `symbolsJson`, see [here](CUEEngine_JSON_Structure.md).

4) To transmit an ultrasonic trigger from the engine, select from one of the following:

Transmit as an integer between `0` and `98,611,127`:

```java
result = CUEEngine.getInstance().queueTriggerAsNumber(number);
if( result < 0 ) {
    messageLayout.setError("Triggers us number can not exceed 98611127" );
}
```

Transmit as a "trigger" (format "X.X.X" where X is an integer from `0` - `461`):

```java
result = CUEEngine.getInstance().queueTrigger(input);
if( result < 0 ) {
    // handle error
}
```


================================================
FILE: doc/CUEEngine_JSON_Structure.md
================================================
# Structure of CUETrigger

## Basic terms
Each time a CUE audio signal is detected by the device's audio input or microphone, a JSON payload is returned to your application within the `ReceiverCallback` block you provide to the `CUEEngine` shared instance.

There are two types of audio signal formats: a ***trigger*** message and a ***data*** message. The type of audio signal is stated in the `mode` field of the returned JSON.

Within a ***trigger*** audio signal, the `id` is encoded in the `raw-indices` as three  ***symbols*** separated by a `.` character.  E.g. `"42.21.43"`, `"1.2.34"`, etc., where each ***symbol*** is an integer between `0` and `461`.

The ***data*** audio signal is encoded in the `message` field as a byte stream represented by a JSON string.

Example payloads are provided below.

## **Example Payloads**
### Trigger payload
```json
{
    "generation": 2,
    "latency_ms": 960.0,
    "mode": "trigger",
    "noise": 163.40673828125,
    "payload": {"myKey":"myValue"},
    "power": 69682.734375,
    "raw-indices": "1.32.45",
    "trigger-as-number": 228273,
    "winner-indices": "1.32.45"
}
```

### Data payload
```json
{
    "generation": 2,
    "latency_ms": 6375.0,
    "message": "hello world",
    "mode": "data",
    "payload": {}
}
```

## **Description**

### Basic Parameters

- `"mode"`:
    1. `"trigger"`:

		_Intended for transmitting content IDs or small amounts of data over short to long distances. Each `trigger` consists of a three-symbol ID (each symbol ranging from 0 to 461), and can easily transmit throughout a 120,000-person stadium._

        • _payload size_: 26 bits  
        • _latency_: ~1.0 seconds  
    
    2. `"data"`:

		_For transmitting arbitrarily large data payloads over short to medium distances. Transmission occurs at a rate of 26bps. Payload size varies according to signal duration._

        _bandwidth_: 26 bits/sec  
        _latency_: **N/A** (varies according to number of packets in message)

- `"latency_ms"`:

    Time in milliseconds since *start* of the CUE message decoding process


- `"raw-indices"`:

    The "symbol string" or "indices" of the detected trigger (e.g., `"1.2.3"`).

- `"winner-indices"`:
    
    The same as `"raw-indices"`

- `"trigger-as-number"`:

	You can convert a `trigger` back and forth to an `integer` from `0` to `98611127`. Transmit an `integer` by calling:
	
	```objc
	[CUEEngine.sharedInstance queueTriggerAsNumber:number];
	```
	
	```java
	CUEEngine.getInstance().queueTriggerAsNumber(number);
	```
	
	Then, when a `trigger` is received, convert a `trigger` to an integer with the following:
	
	```objc
	long triggerNum = [trigger triggerAsNumber];
	```

### Advanced Parameters

The following parameters are only needed for advanced metrics, such as estimating distance from the audio source. 

- `"power"`:

    Log (base 10) of the median channel strength and noise level


- `"noise"`:

    Log (base 10) of the median background noise level

================================================
FILE: doc/iOS_README.md
================================================
# CUE Engine - iOS

## Using the Demo Project

To run CUE Audio's ultrasonic engine on iOS, simply follow these steps:

(1) Go into `iOS/consumer` and open `consumer.xcodeproj` in Xcode

(2) At the top of `AppDelegate.m`, insert your API Key into the following:

`#define API_KEY @"yourAPIKey"`

(3) Run the project. Transmit ultrasonic audio by playing a trigger from the `SampleTones` directory. Upon registering the tone, the device display the binary signal received.

(4) To customize the ultrasonic trigger response, simply modify the following callback within your `ViewController.m` file:

```objective-c
[CUEEngine.sharedInstance setReceiverCallback:
        ^void( NSString* jsonString )
        {
            //handle engine JSON here
        }
     ];
```

## Accessing CUEEngine with Custom API Key

1. Make sure you have `CocoaPods` and the `CocoaPods Artifactory` plugin installed. You can do so with the following commands using Homebrew:

```
brew install cocoapods
gem install cocoapods-art
```

2. Add credentials to allow you to use the CUEEngine CocoaPod. In ~/.netrc (create this file if necessary) insert your credentials:
```
machine cueaudio.jfrog.io
login <username>
password <pass>
```
3. To use this CocoaPod, execute the command `pod repo-art add cocoapods-local "https://cueaudio.jfrog.io/cueaudio/api/pods/cocoapods-local"` in your project's root directory via the command line.

4. Finally, run `pod install`

5. To update the engine version in the future, run: 

```
pod repo-art update cocoapods-local 
pod install
```

The engine version can then be updated in your `Podfile`. An example of such a podfile is:

```
# Uncomment the next line to define a global platform for your project
platform :ios, '10.3'

plugin 'cocoapods-art', :sources => [
  'cocoapods-local'
]

source 'https://github.com/CocoaPods/Specs.git'

target 'MyProj' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  use_frameworks!

  # Pods for consumer

  project 'MyProj.xcodeproj'
  pod "engine"

end
```

## Custom Implementation 

1. In your `Info.plist` file, make sure you set `Privacy - Microphone Usage Description`.

2. Make sure to enable microphone access in your app.

3. Configure the Audio Session:

`#import <engine/AudioSession.h>`

Then call the method `[AudioSession setup]`. The audio session should always be properly configured if the engine is to function as designed. A good place to call this is in `application didFinishLaunchingWithOptions:`. 

4. Next, setup the engine using your API key:

`[CUEEngine.sharedInstance setupWithAPIKey:API_KEY];`

You can start and stop listening with the methods:

```objective-c
[CUEEngine.sharedInstance startListening];
[CUEEngine.sharedInstance stopListening];
```

5. To decode data from the engine, set the engine's `ReceiverCallback`. This is the block of code that will execute each time an ultrasonic signal is detected. An example is:

```objective-c
[CUEEngine.sharedInstance setReceiverCallback:^(NSString *json) {
        NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        
        //get triggerID
        NSString *symbolString = [jsonDict objectForKey:@"winner-indices"];
        
        NSLog(@"Trigger Detected with SymbolString: %@", symbolString);
    }];
```

For details on the structure of the returned JSON, see [here](CUEEngine_JSON_Structure.md).

6. To transmit an ultrasonic trigger from the engine, select from one of the following:

Transmit as an integer between `0` and `98,611,127`:

```objective-c
result = [CUEEngine.sharedInstance queueTriggerAsNumber:number];
if( result < 0 ) {
    NSLog(@"Triggers us number can not exceed 98611127");
}
```

Transmit as a "trigger" (format "X.X.X" where X is an integer from `0` - `461`):

```objective-c
result = [CUEEngine.sharedInstance queueTrigger:triggerStr];
if( result < 0 ) {
    // handle error
}
```

================================================
FILE: doc/licenses/3rd_party/CREDITS-LIBC++.TXT
================================================
This file is a partial list of people who have contributed to the LLVM/libc++
project.  If you have contributed a patch or made some other contribution to
LLVM/libc++, please submit a patch to this file to add yourself, and it will be
done!

The list is sorted by surname and formatted to allow easy grepping and
beautification by scripts.  The fields are: name (N), email (E), web-address
(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
(S).

N: Saleem Abdulrasool
E: compnerd@compnerd.org
D: Minor patches and Linux fixes.

N: Dan Albert
E: danalbert@google.com
D: Android support and test runner improvements.

N: Dimitry Andric
E: dimitry@andric.com
D: Visibility fixes, minor FreeBSD portability patches.

N: Holger Arnold
E: holgerar@gmail.com
D: Minor fix.

N: Ruben Van Boxem
E: vanboxem dot ruben at gmail dot com
D: Initial Windows patches.

N: David Chisnall
E: theraven at theravensnest dot org
D: FreeBSD and Solaris ports, libcxxrt support, some atomics work.

N: Marshall Clow
E: mclow.lists@gmail.com
E: marshall@idio.com
D: C++14 support, patches and bug fixes.

N: Jonathan B Coe
E: jbcoe@me.com
D: Implementation of propagate_const.

N: Eric Fiselier
E: eric@efcs.ca
D: LFTS support, patches and bug fixes.

N: Bill Fisher
E: william.w.fisher@gmail.com
D: Regex bug fixes.

N: Matthew Dempsky
E: matthew@dempsky.org
D: Minor patches and bug fixes.

N: Google Inc.
D: Copyright owner and contributor of the CityHash algorithm

N: Howard Hinnant
E: hhinnant@apple.com
D: Architect and primary author of libc++

N: Hyeon-bin Jeong
E: tuhertz@gmail.com
D: Minor patches and bug fixes.

N: Argyrios Kyrtzidis
E: kyrtzidis@apple.com
D: Bug fixes.

N: Bruce Mitchener, Jr.
E: bruce.mitchener@gmail.com
D: Emscripten-related changes.

N: Michel Morin
E: mimomorin@gmail.com
D: Minor patches to is_convertible.

N: Andrew Morrow
E: andrew.c.morrow@gmail.com
D: Minor patches and Linux fixes.

N: Michael Park
E: mcypark@gmail.com
D: Implementation of <variant>.

N: Arvid Picciani
E: aep at exys dot org
D: Minor patches and musl port.

N: Bjorn Reese
E: breese@users.sourceforge.net
D: Initial regex prototype

N: Nico Rieck
E: nico.rieck@gmail.com
D: Windows fixes

N: Jon Roelofs
E: jonathan@codesourcery.com
D: Remote testing, Newlib port, baremetal/single-threaded support.

N: Jonathan Sauer
D: Minor patches, mostly related to constexpr

N: Craig Silverstein
E: csilvers@google.com
D: Implemented Cityhash as the string hash function on 64-bit machines

N: Richard Smith
D: Minor patches.

N: Joerg Sonnenberger
E: joerg@NetBSD.org
D: NetBSD port.

N: Stephan Tolksdorf
E: st@quanttec.com
D: Minor <atomic> fix

N: Michael van der Westhuizen
E: r1mikey at gmail dot com

N: Larisse Voufo
D: Minor patches.

N: Klaas de Vries
E: klaas at klaasgaaf dot nl
D: Minor bug fix.

N: Zhang Xiongpang
E: zhangxiongpang@gmail.com
D: Minor patches and bug fixes.

N: Xing Xue
E: xingxue@ca.ibm.com
D: AIX port

N: Zhihao Yuan
E: lichray@gmail.com
D: Standard compatibility fixes.

N: Jeffrey Yasskin
E: jyasskin@gmail.com
E: jyasskin@google.com
D: Linux fixes.


================================================
FILE: doc/licenses/3rd_party/NOTICE
================================================
mbedtls -> https://github.com/ARMmbed/mbedtls
----------------
Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-------------------------------------------------------------------------------


http-parser -> https://github.com/nodejs/http-parser
----------------
Copyright Joyent, Inc. and other Node contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE. 

-------------------------------------------------------------------------------


json -> https://github.com/nlohmann/json
----------------
Copyright (c) 2013-2018 Niels Lohmann

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

-------------------------------------------------------------------------------


kissfft -> https://github.com/mborgerding/kissfft
----------------
Copyright (c) 2003-2010 Mark Borgerding . All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-------------------------------------------------------------------------------


libsamplerate -> https://github.com/erikd/libsamplerate
----------------
Copyright (c) 2012-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-------------------------------------------------------------------------------


zlib -> https://www.zlib.net 
----------------
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
 claim that you wrote the original software. If you use this software
 in a product, an acknowledgment in the product documentation would be
 appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
 misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

Jean-loup Gailly        Mark Adler
jloup@gzip.org          madler@alumni.caltech.edu

-------------------------------------------------------------------------------


yahdlc -> https://github.com/bang-olufsen/yahdlc
----------------
Copyright (c) 2015 Bang & Olufsen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

-------------------------------------------------------------------------------


==============================================================================
libc++ License
==============================================================================

The libc++ library is dual licensed under both the University of Illinois
"BSD-Like" license and the MIT license.  As a user of this code you may choose
to use it under either license.  As a contributor, you agree to allow your code
to be used under both.

Full text of the relevant licenses is included below.

==============================================================================

University of Illinois/NCSA
Open Source License

Copyright (c) 2009-2017 by the contributors listed in CREDITS-LIBC++.TXT

All rights reserved.

Developed by:

    LLVM Team

    University of Illinois at Urbana-Champaign

    http://llvm.org

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimers.

    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimers in the
      documentation and/or other materials provided with the distribution.

    * Neither the names of the LLVM Team, University of Illinois at
      Urbana-Champaign, nor the names of its contributors may be used to
      endorse or promote products derived from this Software without specific
      prior written permission.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.

==============================================================================

Copyright (c) 2009-2014 by the contributors listed in CREDITS-LIBC++.TXT

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: iOS/consumer/consumer/AppDelegate.h
================================================
//
//  AppDelegate.h
//  objC_consumer
//
//  Created by CUEAudio on 01/03/2018.
//  © CUEAudio, 2018 to the last syllable of recorded time, all rights reserved.
//

#import <UIKit/UIKit.h>

#define API_KEY @"H7v7NMMNh6im735w331iLHtqnduxGCTL"

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end



================================================
FILE: iOS/consumer/consumer/AppDelegate.m
================================================
//
//  AppDelegate.m
//  objC_consumer
//
//  Created by CUEAudio on 01/03/2018.
//  © CUEAudio, 2018 to the last syllable of recorded time, all rights reserved.

//π. All rights reserved.
//

#import <AVFoundation/AVFoundation.h>

#import <engine/AudioSession.h>
#import <engine/CUEEngine.h>

#import "AppDelegate.h"

// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

@implementation AppDelegate

- (BOOL)            application: (UIApplication *) application
  didFinishLaunchingWithOptions: (NSDictionary *) launchOptions
{
    if( ! [AudioSession setup] ) {
        NSLog( @"Error setting up AudioSession" );
        return NO;
    }
    
    // Request mic access
    [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
        //if granted, set up engine
        if( granted == YES ) {
            [self setupEngine];
            [self startListening];
        }
    }];
    
    return YES;
}

- (void) setupEngine
{
    [CUEEngine.sharedInstance setupWithAPIKey:API_KEY];
    [CUEEngine.sharedInstance setDefaultGeneration:2];
}

- (void) startListening {
    [CUEEngine.sharedInstance startListening];
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    //to not listen in the background
    [CUEEngine.sharedInstance stopListening];
}

@end

// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


================================================
FILE: iOS/consumer/consumer/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "iphone",
      "size" : "20x20",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "20x20",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "3x"
    },
    {
      "idiom" : "ipad",
      "size" : "20x20",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "20x20",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "29x29",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "40x40",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "76x76",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "76x76",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "83.5x83.5",
      "scale" : "2x"
    },
    {
      "idiom" : "ios-marketing",
      "size" : "1024x1024",
      "scale" : "1x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: iOS/consumer/consumer/Assets.xcassets/Contents.json
================================================
{
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: iOS/consumer/consumer/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="EHf-IW-A2E">
            <objects>
                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="53" y="375"/>
        </scene>
    </scenes>
</document>


================================================
FILE: iOS/consumer/consumer/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="4i9-g3-DXA">
    <device id="retina4_0" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--Consumer-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <pickerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="yXA-GX-efD">
                                <rect key="frame" x="8" y="64" width="100" height="100"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="100" id="wR1-sr-3LL"/>
                                    <constraint firstAttribute="width" constant="100" id="xIB-MK-Ag4"/>
                                </constraints>
                            </pickerView>
                            <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Y7j-OV-FDE">
                                <rect key="frame" x="116" y="99" width="146" height="30"/>
                                <nil key="textColor"/>
                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                <textInputTraits key="textInputTraits"/>
                            </textField>
                            <button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NRj-6o-PiI">
                                <rect key="frame" x="270" y="97" width="42" height="34"/>
                                <state key="normal" title="Send">
                                    <color key="titleColor" red="1" green="0.57637232540000005" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                </state>
                                <connections>
                                    <action selector="transmit:" destination="BYZ-38-t0r" eventType="touchUpInside" id="pCp-ZV-UqZ"/>
                                </connections>
                            </button>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Output all data" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X2r-1U-fmE">
                                <rect key="frame" x="12" y="176" width="113" height="21"/>
                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="fpX-SJ-nUr">
                                <rect key="frame" x="137" y="171" width="51" height="31"/>
                            </switch>
                            <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="LAD-wF-N6a">
                                <rect key="frame" x="12" y="214" width="296" height="342"/>
                                <color key="backgroundColor" red="0.86274509803921573" green="0.86274509803921573" blue="0.86274509803921573" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
                            </textView>
                            <button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vhx-ei-GFa">
                                <rect key="frame" x="261" y="169.5" width="43" height="34"/>
                                <state key="normal" title="Clear">
                                    <color key="titleColor" red="1" green="0.57637232540000005" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                </state>
                                <connections>
                                    <action selector="clearOutput:" destination="BYZ-38-t0r" eventType="touchUpInside" id="9Gn-dF-EXz"/>
                                </connections>
                            </button>
                        </subviews>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="yXA-GX-efD" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="8" id="7yf-W9-FiZ"/>
                            <constraint firstItem="vhx-ei-GFa" firstAttribute="centerY" secondItem="X2r-1U-fmE" secondAttribute="centerY" id="9Gb-oe-zQD"/>
                            <constraint firstItem="NRj-6o-PiI" firstAttribute="leading" secondItem="Y7j-OV-FDE" secondAttribute="trailing" constant="8" id="GLV-Yb-Uyn"/>
                            <constraint firstItem="Y7j-OV-FDE" firstAttribute="centerY" secondItem="yXA-GX-efD" secondAttribute="centerY" id="Oy2-qR-ozX"/>
                            <constraint firstItem="yXA-GX-efD" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="Su9-Oc-rVM"/>
                            <constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="NRj-6o-PiI" secondAttribute="trailing" constant="8" id="UrX-KB-w0A"/>
                            <constraint firstItem="LAD-wF-N6a" firstAttribute="top" secondItem="fpX-SJ-nUr" secondAttribute="bottom" constant="12" id="Xvf-Tl-Ffk"/>
                            <constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="LAD-wF-N6a" secondAttribute="trailing" constant="12" id="ZrS-Fb-Geu"/>
                            <constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="vhx-ei-GFa" secondAttribute="trailing" constant="16" id="fUR-d8-dyG"/>
                            <constraint firstItem="Y7j-OV-FDE" firstAttribute="leading" secondItem="yXA-GX-efD" secondAttribute="trailing" constant="8" id="gZA-7j-pbO"/>
                            <constraint firstItem="LAD-wF-N6a" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="12" id="gfY-rs-ZBr"/>
                            <constraint firstItem="NRj-6o-PiI" firstAttribute="centerY" secondItem="yXA-GX-efD" secondAttribute="centerY" id="joN-zU-iwf"/>
                            <constraint firstItem="X2r-1U-fmE" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="12" id="mge-cK-3G5"/>
                            <constraint firstItem="X2r-1U-fmE" firstAttribute="top" secondItem="yXA-GX-efD" secondAttribute="bottom" constant="12" id="t1D-Cy-Yo9"/>
                            <constraint firstItem="fpX-SJ-nUr" firstAttribute="centerY" secondItem="X2r-1U-fmE" secondAttribute="centerY" id="uNn-aZ-pLh"/>
                            <constraint firstItem="fpX-SJ-nUr" firstAttribute="leading" secondItem="X2r-1U-fmE" secondAttribute="trailing" constant="12" id="uXq-nu-ezS"/>
                            <constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="LAD-wF-N6a" secondAttribute="bottom" constant="12" id="wcS-5F-G5Q"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
                    </view>
                    <navigationItem key="navigationItem" title="Consumer" id="pZd-YX-Cov">
                        <barButtonItem key="rightBarButtonItem" title="Item" id="GCp-tK-qWY"/>
                    </navigationItem>
                    <connections>
                        <outlet property="fullOutputSwitch" destination="fpX-SJ-nUr" id="8EI-m4-33b"/>
                        <outlet property="modePicker" destination="yXA-GX-efD" id="1z6-ij-OSk"/>
                        <outlet property="outputView" destination="LAD-wF-N6a" id="94D-yF-nnW"/>
                        <outlet property="sendButton" destination="NRj-6o-PiI" id="8oy-Ew-XdW"/>
                        <outlet property="textEntryField" destination="Y7j-OV-FDE" id="Rub-3I-431"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="1157" y="-15"/>
        </scene>
        <!--Navigation Controller-->
        <scene sceneID="oIu-li-FyX">
            <objects>
                <navigationController id="4i9-g3-DXA" sceneMemberID="viewController">
                    <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="7ea-X1-WUz">
                        <rect key="frame" x="0.0" y="20" width="320" height="44"/>
                        <autoresizingMask key="autoresizingMask"/>
                    </navigationBar>
                    <connections>
                        <segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="wsh-RJ-AaU"/>
                    </connections>
                </navigationController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="rhU-fe-y79" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="264" y="-14"/>
        </scene>
    </scenes>
</document>


================================================
FILE: iOS/consumer/consumer/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>UIUserInterfaceStyle</key>
	<string>UIStatusBarStyleLightContent</string>
	<key>CFBundleDevelopmentRegion</key>
	<string>$(DEVELOPMENT_LANGUAGE)</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleVersion</key>
	<string>1</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>NSMicrophoneUsageDescription</key>
	<string>To detect ultrasonic transmissions in your local environment</string>
	<key>UIBackgroundModes</key>
	<array>
		<string>audio</string>
	</array>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIMainStoryboardFile</key>
	<string>Main</string>
	<key>UIRequiredDeviceCapabilities</key>
	<array>
		<string>armv7</string>
	</array>
	<key>UIRequiresFullScreen</key>
	<true/>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UISupportedInterfaceOrientations~ipad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
</dict>
</plist>


================================================
FILE: iOS/consumer/consumer/ViewController.h
================================================
//
//  ViewController.h
//  objC_consumer
//
//  Created by CUEAudio on 01/03/2018.
//  © CUEAudio, 2018 to the last syllable of recorded time, all rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end



================================================
FILE: iOS/consumer/consumer/ViewController.m
================================================
//
//  ViewController.m
//  objC_consumer
//
//  Created by CUEAudio on 01/03/2018.
//  © CUEAudio, 2018 to the last syllable of recorded time, all rights reserved.
//

#import "ViewController.h"
#import <UserNotifications/UserNotifications.h>

#import <engine/CUEEngine.h>
#import <engine/CUETrigger.h>
#import <engine/CUEErrno.h>

#define decimalPoint NSLocale.currentLocale.decimalSeparator

@interface ViewController() <UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UITextView *outputView;
@property (weak, nonatomic) IBOutlet UIPickerView *modePicker;
@property (weak, nonatomic) IBOutlet UITextField *textEntryField;
@property (weak, nonatomic) IBOutlet UIButton *sendButton;
@property (weak, nonatomic) IBOutlet UISwitch *fullOutputSwitch;

@property CUEEngineMode selectedMode;
@property BOOL triggerAsNumber;

@property NSArray *modes;
@property UIBarButtonItem *playButton;
@property UIBarButtonItem *pauseButton;

@end

@implementation ViewController

- (void) viewDidLoad
{
    [super viewDidLoad];
    
    [self setupKeyboardGesture];
    [self setupModesArray];
    [self setupTextEntryField];
    [self setupPickerView];
    [self setupPlayPauseButtons];
    [self registerForLocalNotifications];
    [self setupCUEEngineCallback];
}

- (void) setupCUEEngineCallback {
    [CUEEngine.sharedInstance setReceiverCallback:
     ^void( NSString* jsonString )
     {
         NSLog(@"CUEEngine viewDidLoad got-trigger-callback with JSON:\n%@", jsonString);
         CUETrigger *trigger = [[CUETrigger alloc] initWithJsonString:jsonString];
         
         /* * * * * * * * * * *
          * display output
          * * * * * * * * * * */
         
         dispatch_async( dispatch_get_main_queue(), ^{
             
             /* * * * * * * * * * * * *
              * Fill out output string
              * * * * * * * * * * * * */
             
             NSString *outputStr;
             if (self.fullOutputSwitch.isOn) {
                 outputStr = [CUETrigger formatFullData:trigger];
             } else {
                 outputStr = [CUETrigger formatPartialData:trigger];
             }
             
             // If running in background, check to send notification
             [self sendNotificationInBackground:trigger.rawIndices andMode:trigger.mode];
             
             self.outputView.text = [self.outputView.text stringByAppendingString:outputStr];
             
             /* Scroll to bottom */
             NSRange bottomLine = NSMakeRange(self.outputView.text.length - 1, 1);
             [self.outputView scrollRangeToVisible:bottomLine];
             
             /* * * * * * * * * * * * *
             * Get trigger as number
             * * * * * * * * * * * * */
             long triggerNum = [trigger triggerAsNumber];
             NSLog(@"%li", triggerNum);
         } );
         
     }];
}

- (void) setupPlayPauseButtons {
    //disable send button until textEntryField has text
    self.sendButton.enabled = false;
    
    self.playButton = [[UIBarButtonItem alloc]
                       initWithBarButtonSystemItem:UIBarButtonSystemItemPlay
                       target:self action:@selector(playButtonTapped)];
    
    self.pauseButton = [[UIBarButtonItem alloc]
                        initWithBarButtonSystemItem:UIBarButtonSystemItemPause
                        target:self action:@selector(pauseButtonTapped)];
    
    
    self.navigationItem.rightBarButtonItem = self.pauseButton;
}

- (void) setupModesArray {
    self.modes = @[[NSNumber numberWithInteger:CUEEngineModeTrigger],
                   [NSNumber numberWithInteger:CUEEngineModeMultiTrigger],
                   [NSNumber numberWithInteger:CUEEngineModeLL],
                   [NSNumber numberWithInteger:CUEEngineModeData]];
}

#pragma mark Notifications

- (void) registerForLocalNotifications {
    [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNNotificationPresentationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            NSLog(@"Notification Permission Granted");
        }
    }];
}

- (void) sendNotificationInBackground:(NSString *) trigger andMode: (CUEEngineMode) mode {
    UNMutableNotificationContent *content = [UNMutableNotificationContent new];
    content.sound = [UNNotificationSound defaultSound];
    
    // For specific trigger, create pre-set local notification
    if ([trigger isEqualToString:@"1.2.3"]) {
        content.title = @"My Ultrasonic Notification";
        content.body = @"Hello World!";
        
    } else {
        content.title = trigger;
    }
    
    UNTimeIntervalNotificationTrigger *notificationTrigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO];
    NSString *identifier = @"CUELocalNotification";
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier
                                                                          content:content trigger:notificationTrigger];
    
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        if (error != nil) {
            NSLog(@"Something went wrong: %@",error);
        }
    }];
}

#pragma mark Keyboard

- (void) setupKeyboardGesture {
    UITapGestureRecognizer * dismissGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    [self.view addGestureRecognizer:dismissGesture];
}

- (void) dismissKeyboard {
    [self.view endEditing:true];
}

- (IBAction)clearOutput:(id)sender {
    self.outputView.text = @"";
}

# pragma mark Buttons

- (void)playButtonTapped {
    [CUEEngine.sharedInstance startListening];
    self.navigationItem.rightBarButtonItem = self.pauseButton;
}

- (void)pauseButtonTapped {
    [CUEEngine.sharedInstance stopListening];
    self.navigationItem.rightBarButtonItem = self.playButton;
}

- (void)issueAlertWithTitle: (NSString*)title
                 andMessage: (NSString*)message 
{
    UIAlertController *alert = [ UIAlertController
        alertControllerWithTitle:title 
                         message:message
                  preferredStyle:UIAlertControllerStyleAlert
    ];

    [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:NULL]];
    [self presentViewController:alert animated:YES completion:NULL];
}

# pragma mark Transmit

- (IBAction)transmit:(id)sender {
    CUE_ENGINE_ERROR validationResult = 0;
    NSString* title = @"";
    NSString* message = @"";

    [[self view] endEditing:YES];

    switch (self.selectedMode) {
        case CUEEngineModeTrigger: {
            if(self.triggerAsNumber) {
                NSString* num_s = [[self textEntryField] text];
                BOOL isNum = true;
                for( int i = 0; i < [num_s length]; i++) {
                    int c = [num_s characterAtIndex:i];
                    isNum = isdigit(c);
                    if(! isNum) {
                        [self issueAlertWithTitle:@"Invalid format"
                                       andMessage:@"Should be a number in a range: 0-9861112 "
                                                  @"for a CUEEngine generation 2 or 0-461 "
                                                  @"for a CUEEngine generation 1"];
                        return;
                    }
                }
                unsigned long number = (unsigned long) [num_s longLongValue];
                validationResult = [CUEEngine.sharedInstance queueTriggerAsNumber:number];
                if( validationResult == CUE_ENGINE_ERR_TRIGGER_AS_NUMBER_MAX_NUMBER_EXCEEDED ) {
                    [ self issueAlertWithTitle:@"Invalid Format"
                                    andMessage:@"Trigger as number can not exceed 98611127 "
                                               @"for a CUEEngine generation 2 or 461 "
                                               @"for a CUEEngine generation 1"];
                }
            } else {
                NSString* triggerStr = [self.textEntryField.text stringByReplacingOccurrencesOfString:decimalPoint withString:@"."];

                validationResult = [CUEEngine.sharedInstance queueTrigger:triggerStr];
                if(validationResult < 0) {
                    NSString* alertMsg = [
                        NSString stringWithFormat:@"Triggers must be of the format [0-461]%@[0-461]%@[0-461] "
                                                  @"for a CUEEngine generation 2 or [0-461] "
                                                  @"for a CUEEngine generation 1",
                        decimalPoint, decimalPoint ];
     
                    [ self issueAlertWithTitle:@"Invalid Format"
                                    andMessage:alertMsg ];
                }
            }

            break;
        }
        case CUEEngineModeMultiTrigger: {
            if(self.triggerAsNumber) {
                NSString* num_s = [[self textEntryField] text];
                BOOL isNum = true;
                for( int i = 0; i < [num_s length]; i++) {
                    int c = [num_s characterAtIndex:i];
                    isNum = isdigit(c);
                    if(! isNum) {
                        [self issueAlertWithTitle:@"Invalid format"
                                       andMessage:@"Should be a number in a range: 0-9724154565432383"];
                        return;
                    }
                }
                long long number = (long long) [num_s longLongValue];
                validationResult = [CUEEngine.sharedInstance queueMultiTriggerAsNumber:number];
                if( validationResult == CUE_ENGINE_ERR_MULTI_TRIGGER_AS_NUMBER_MAX_NUMBER_EXCEEDED ) {
                    title = @"Invalid Format";
                    message = @"Multi-trigger as number can not exceed 972415456543238";
                } else if ( validationResult == CUE_ENGINE_ERR_G1_QUEUE_MULTI_TRIGGER_UNSUPPORTED) {
                    title = @"Unsupported";
                    message = @"Can not queue a multi-trigger for a CUEEngine generation 1";
                }
            } else {
                NSString* triggerStr = [self.textEntryField.text stringByReplacingOccurrencesOfString:decimalPoint withString:@"."];
                validationResult = [CUEEngine.sharedInstance queueMultiTrigger:triggerStr];
                if( validationResult == CUE_ENGINE_ERR_G1_QUEUE_MULTI_TRIGGER_UNSUPPORTED ) {
                    title = @"Unsupported";
                    message = @"Can not queue a multi-trigger for a CUEEngine generation 1";
                } else if (validationResult < 0) {
                    title = @"Invalid Format";
                    message = [ NSString stringWithFormat:
                        @"MultiTriggers must be of the format "
                        @"[0-461]%@[0-461]%@[0-461]%@[0-461]%@[0-461]%@[0-461]",
                        decimalPoint, decimalPoint, decimalPoint, decimalPoint, decimalPoint ];
                }
            }

            if( ![title  isEqual: @""] && ![message  isEqual: @""] ) {
                [ self issueAlertWithTitle:title andMessage:message ];
            }
            break;
        }
        case CUEEngineModeLL: {
            validationResult = [CUEEngine.sharedInstance queueLL:self.textEntryField.text];
            if( validationResult == CUE_ENGINE_ERR_G1_QUEUE_LL_UNSUPPORTED ) {
                title = @"Unsupported";
                message = @"Can not queue ll for a CUEEngine generation 1";
            } else if( validationResult == CUE_ENGINE_ERR_G2_QUEUE_LL_MODE_LL_ONLY_OR_MODE_BASIC_SHOULD_BE_SET ) {
                title = @"Unsupported";
                message = @"Can not queue ll: please set a config mode to 'basic' or to 'll_only'";
            } else if( validationResult == CUE_ENGINE_ERR_G2_LL_IS_ON_IN_BASIC_CAN_NOT_QUEUE ) {
                title = @"Already active";
                message = @"LL is already on in a config 'basic' mode, can not queue, please wait while it is off";
            } else if ( validationResult < 0 ){
                title = @"Invalid format";
                message = [ NSString stringWithFormat:
                            @"LL message must be of the format [0-125]%@[0-125]...",
                            decimalPoint ];
            } else {
                title = @"";
                message = @"";
            }
            
            if( ![title  isEqual: @""] && ![message  isEqual: @""] ) {
                [ self issueAlertWithTitle:title andMessage:message ];
            }
            break;
        }
        case CUEEngineModeData: {
            validationResult = [CUEEngine.sharedInstance queueMessage:self.textEntryField.text];
            if(validationResult == CUE_ENGINE_ERR_G2_MESSAGE_STRING_SIZE_IN_BYTES_EXCEEDED ) {
                [ self issueAlertWithTitle:@"Invalid Format"
                                andMessage:@"Data stream can not containt more then 256 symbols" ];
            } else if( validationResult == CUE_ENGINE_ERR_G1_QUEUE_MESSAGE_UNSUPPORTED ) {
                [ self issueAlertWithTitle:@"Unsupported"
                                andMessage:@"queue message: unsupported for a CUEEngine generation 1" ];
            }
            break;
        }
        default:
            break;
    }
}

# pragma mark UIPickerView

- (void) setupPickerView {
    self.modePicker.delegate = self;
    self.modePicker.dataSource = self;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return [self.modes count] + 2;
}

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 1;
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    switch (row) {
        case 0:
            return @"Trigger";
        case 1:
            return @"Number";
        case 2:
            return @"MultiTrigger";
        case 3:
            return @"NumMultTrg";
        case 4:
            return @"LL";
        default:
            return @"Data";
    }
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    //self.selectedMode = [[self.modes objectAtIndex:row] integerValue];
    self.triggerAsNumber = NO;

    switch(row) {
        case 0:
            self.selectedMode = CUEEngineModeTrigger;
            break;
        case 1:
            self.selectedMode = CUEEngineModeTrigger;
            self.triggerAsNumber = YES;
            break;
        case 2:
            self.selectedMode = CUEEngineModeMultiTrigger;
            break;
        case 3:
            self.selectedMode = CUEEngineModeMultiTrigger;
            self.triggerAsNumber = YES;
            break;
        case 4:
            self.selectedMode = CUEEngineModeLL;
            break;
        default:
            self.selectedMode = CUEEngineModeData;
            break;
    }

    switch (self.selectedMode) {
        case CUEEngineModeTrigger:{
            if(self.triggerAsNumber) {
                self.textEntryField.placeholder = @"123123";
                [self setKeyboardType:UIKeyboardTypeNumberPad];
            } else {
                self.textEntryField.placeholder = [
                    NSString stringWithFormat:@"1%@2%@34",
                    decimalPoint, decimalPoint ];
                [self setKeyboardType:UIKeyboardTypeDecimalPad];
            }
            break;
        }
        case CUEEngineModeMultiTrigger: {
            if(self.triggerAsNumber) {
                self.textEntryField.placeholder = @"123123";
                [self setKeyboardType:UIKeyboardTypeNumberPad];
            } else {
                self.textEntryField.placeholder = [
                    NSString stringWithFormat:@"1%@2%@3%@4%@5%@6",
                    decimalPoint, decimalPoint, decimalPoint, decimalPoint, decimalPoint ];
                [self setKeyboardType:UIKeyboardTypeDecimalPad];
            }
            break;
        }
        case CUEEngineModeLL: {
            self.textEntryField.placeholder = [
                NSString stringWithFormat:@"10%@20%@30%@40 ...",
                decimalPoint, decimalPoint, decimalPoint ];
            [self setKeyboardType:UIKeyboardTypeDecimalPad];
            break;
        }
        case CUEEngineModeData:
            self.textEntryField.placeholder = @"Hello World";
            [self setKeyboardType:UIKeyboardTypeDefault];
            break;
        default:
            break;
    }
}

- (void)setKeyboardType:(UIKeyboardType)kbType
{
    self.textEntryField.keyboardType = kbType;
    [self.textEntryField reloadInputViews];
}

# pragma mark UITextField

- (void)textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason {
    if (textField.text.length) {
        self.sendButton.enabled = true;
    } else self.sendButton.enabled = false;
}

- (void) setupTextEntryField {
    self.textEntryField.delegate = self;
    self.textEntryField.placeholder = [
        NSString stringWithFormat:@"1%@2%@34", decimalPoint, decimalPoint ];
    self.textEntryField.keyboardType = UIKeyboardTypeDecimalPad;
}

@end


================================================
FILE: iOS/consumer/consumer/main.m
================================================
//
//  main.m
//  objC_consumer
//
//  Created by π on 01/03/2018.
//  Copyright © 2018 π. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}


================================================
FILE: iOS/consumer/consumer.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 52;
	objects = {

/* Begin PBXBuildFile section */
		90403B82212B25B500B49DE2 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90403B81212B25B500B49DE2 /* Accelerate.framework */; };
		90403B86212B25E300B49DE2 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 90403B85212B25E300B49DE2 /* libc++.tbd */; };
		905A3D6825FB2BCD00951DA9 /* engine.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 905A3D6625FB2AC200951DA9 /* engine.xcframework */; };
		905A3D6925FB2BCD00951DA9 /* engine.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 905A3D6625FB2AC200951DA9 /* engine.xcframework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
		90646593212B1A6E00C0F4C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 90646592212B1A6E00C0F4C7 /* AppDelegate.m */; };
		90646596212B1A6E00C0F4C7 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90646595212B1A6E00C0F4C7 /* ViewController.m */; };
		90646599212B1A6E00C0F4C7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 90646597212B1A6E00C0F4C7 /* Main.storyboard */; };
		9064659B212B1A7000C0F4C7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9064659A212B1A7000C0F4C7 /* Assets.xcassets */; };
		9064659E212B1A7000C0F4C7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9064659C212B1A7000C0F4C7 /* LaunchScreen.storyboard */; };
		906465A1212B1A7000C0F4C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 906465A0212B1A7000C0F4C7 /* main.m */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
		9070C0DD226F1C7400F547E6 /* Embed Frameworks */ = {
			isa = PBXCopyFilesBuildPhase;
			buildActionMask = 2147483647;
			dstPath = "";
			dstSubfolderSpec = 10;
			files = (
				905A3D6925FB2BCD00951DA9 /* engine.xcframework in Embed Frameworks */,
			);
			name = "Embed Frameworks";
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
		90403B81212B25B500B49DE2 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
		90403B85212B25E300B49DE2 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
		905A3D6625FB2AC200951DA9 /* engine.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = engine.xcframework; sourceTree = "<group>"; };
		9064658E212B1A6E00C0F4C7 /* consumer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = consumer.app; sourceTree = BUILT_PRODUCTS_DIR; };
		90646591212B1A6E00C0F4C7 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
		90646592212B1A6E00C0F4C7 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
		90646594212B1A6E00C0F4C7 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
		90646595212B1A6E00C0F4C7 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
		90646598212B1A6E00C0F4C7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
		9064659A212B1A7000C0F4C7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
		9064659D212B1A7000C0F4C7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
		9064659F212B1A7000C0F4C7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		906465A0212B1A7000C0F4C7 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		9064658B212B1A6E00C0F4C7 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				905A3D6825FB2BCD00951DA9 /* engine.xcframework in Frameworks */,
				90403B86212B25E300B49DE2 /* libc++.tbd in Frameworks */,
				90403B82212B25B500B49DE2 /* Accelerate.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		90403B7E212B25AA00B49DE2 /* Frameworks */ = {
			isa = PBXGroup;
			children = (
				905A3D6625FB2AC200951DA9 /* engine.xcframework */,
				90403B85212B25E300B49DE2 /* libc++.tbd */,
				90403B81212B25B500B49DE2 /* Accelerate.framework */,
			);
			name = Frameworks;
			sourceTree = "<group>";
		};
		90646585212B1A6E00C0F4C7 = {
			isa = PBXGroup;
			children = (
				90646590212B1A6E00C0F4C7 /* consumer */,
				9064658F212B1A6E00C0F4C7 /* Products */,
				90403B7E212B25AA00B49DE2 /* Frameworks */,
			);
			sourceTree = "<group>";
		};
		9064658F212B1A6E00C0F4C7 /* Products */ = {
			isa = PBXGroup;
			children = (
				9064658E212B1A6E00C0F4C7 /* consumer.app */,
			);
			name = Products;
			sourceTree = "<group>";
		};
		90646590212B1A6E00C0F4C7 /* consumer */ = {
			isa = PBXGroup;
			children = (
				90646591212B1A6E00C0F4C7 /* AppDelegate.h */,
				90646592212B1A6E00C0F4C7 /* AppDelegate.m */,
				90646594212B1A6E00C0F4C7 /* ViewController.h */,
				90646595212B1A6E00C0F4C7 /* ViewController.m */,
				90646597212B1A6E00C0F4C7 /* Main.storyboard */,
				9064659A212B1A7000C0F4C7 /* Assets.xcassets */,
				9064659C212B1A7000C0F4C7 /* LaunchScreen.storyboard */,
				9064659F212B1A7000C0F4C7 /* Info.plist */,
				906465A0212B1A7000C0F4C7 /* main.m */,
			);
			path = consumer;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		9064658D212B1A6E00C0F4C7 /* consumer */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 906465A4212B1A7000C0F4C7 /* Build configuration list for PBXNativeTarget "consumer" */;
			buildPhases = (
				9064658A212B1A6E00C0F4C7 /* Sources */,
				9064658B212B1A6E00C0F4C7 /* Frameworks */,
				9064658C212B1A6E00C0F4C7 /* Resources */,
				9070C0DD226F1C7400F547E6 /* Embed Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = consumer;
			productName = consumer;
			productReference = 9064658E212B1A6E00C0F4C7 /* consumer.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		90646586212B1A6E00C0F4C7 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				LastUpgradeCheck = 0940;
				ORGANIZATIONNAME = "CUE Audio";
				TargetAttributes = {
					9064658D212B1A6E00C0F4C7 = {
						CreatedOnToolsVersion = 9.4.1;
					};
				};
			};
			buildConfigurationList = 90646589212B1A6E00C0F4C7 /* Build configuration list for PBXProject "consumer-customer-xcf" */;
			compatibilityVersion = "Xcode 9.3";
			developmentRegion = en;
			hasScannedForEncodings = 0;
			knownRegions = (
				en,
				Base,
			);
			mainGroup = 90646585212B1A6E00C0F4C7;
			productRefGroup = 9064658F212B1A6E00C0F4C7 /* Products */;
			projectDirPath = "";
			projectRoot = "";
			targets = (
				9064658D212B1A6E00C0F4C7 /* consumer */,
			);
		};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
		9064658C212B1A6E00C0F4C7 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				9064659E212B1A7000C0F4C7 /* LaunchScreen.storyboard in Resources */,
				9064659B212B1A7000C0F4C7 /* Assets.xcassets in Resources */,
				90646599212B1A6E00C0F4C7 /* Main.storyboard in Resources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		9064658A212B1A6E00C0F4C7 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				90646596212B1A6E00C0F4C7 /* ViewController.m in Sources */,
				906465A1212B1A7000C0F4C7 /* main.m in Sources */,
				90646593212B1A6E00C0F4C7 /* AppDelegate.m in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin PBXVariantGroup section */
		90646597212B1A6E00C0F4C7 /* Main.storyboard */ = {
			isa = PBXVariantGroup;
			children = (
				90646598212B1A6E00C0F4C7 /* Base */,
			);
			name = Main.storyboard;
			sourceTree = "<group>";
		};
		9064659C212B1A7000C0F4C7 /* LaunchScreen.storyboard */ = {
			isa = PBXVariantGroup;
			children = (
				9064659D212B1A7000C0F4C7 /* Base */,
			);
			name = LaunchScreen.storyboard;
			sourceTree = "<group>";
		};
/* End PBXVariantGroup section */

/* Begin XCBuildConfiguration section */
		906465A2212B1A7000C0F4C7 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_ENABLE_OBJC_WEAK = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				CODE_SIGN_IDENTITY = "iPhone Developer";
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = dwarf;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_TESTABILITY = YES;
				GCC_C_LANGUAGE_STANDARD = gnu11;
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 0;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				IPHONEOS_DEPLOYMENT_TARGET = 11.4;
				MTL_ENABLE_DEBUG_INFO = YES;
				ONLY_ACTIVE_ARCH = YES;
				SDKROOT = iphoneos;
			};
			name = Debug;
		};
		906465A3212B1A7000C0F4C7 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_ENABLE_OBJC_WEAK = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				CODE_SIGN_IDENTITY = "iPhone Developer";
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
				ENABLE_NS_ASSERTIONS = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = gnu11;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				IPHONEOS_DEPLOYMENT_TARGET = 11.4;
				MTL_ENABLE_DEBUG_INFO = NO;
				SDKROOT = iphoneos;
				VALIDATE_PRODUCT = YES;
			};
			name = Release;
		};
		906465A5212B1A7000C0F4C7 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				CODE_SIGN_STYLE = Automatic;
				DEVELOPMENT_TEAM = EL8TZV5FP2;
				FRAMEWORK_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)",
				);
				INFOPLIST_FILE = consumer/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = (
					"$(inherited)",
					"@executable_path/Frameworks",
				);
				PRODUCT_BUNDLE_IDENTIFIER = com.cueaudio.engine.consumer;
				PRODUCT_NAME = "$(TARGET_NAME)";
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Debug;
		};
		906465A6212B1A7000C0F4C7 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				CODE_SIGN_STYLE = Automatic;
				DEVELOPMENT_TEAM = EL8TZV5FP2;
				FRAMEWORK_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)",
				);
				INFOPLIST_FILE = consumer/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = (
					"$(inherited)",
					"@executable_path/Frameworks",
				);
				PRODUCT_BUNDLE_IDENTIFIER = com.cueaudio.engine.consumer;
				PRODUCT_NAME = "$(TARGET_NAME)";
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		90646589212B1A6E00C0F4C7 /* Build configuration list for PBXProject "consumer-customer-xcf" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				906465A2212B1A7000C0F4C7 /* Debug */,
				906465A3212B1A7000C0F4C7 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		906465A4212B1A7000C0F4C7 /* Build configuration list for PBXNativeTarget "consumer" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				906465A5212B1A7000C0F4C7 /* Debug */,
				906465A6212B1A7000C0F4C7 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
/* End XCConfigurationList section */
	};
	rootObject = 90646586212B1A6E00C0F4C7 /* Project object */;
}


================================================
FILE: iOS/consumer/engine.xcframework/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>AvailableLibraries</key>
	<array>
		<dict>
			<key>LibraryIdentifier</key>
			<string>ios-arm64</string>
			<key>LibraryPath</key>
			<string>engine.framework</string>
			<key>SupportedArchitectures</key>
			<array>
				<string>arm64</string>
			</array>
			<key>SupportedPlatform</key>
			<string>ios</string>
		</dict>
		<dict>
			<key>LibraryIdentifier</key>
			<string>ios-x86_64-simulator</string>
			<key>LibraryPath</key>
			<string>engine.framework</string>
			<key>SupportedArchitectures</key>
			<array>
				<string>x86_64</string>
			</array>
			<key>SupportedPlatform</key>
			<string>ios</string>
			<key>SupportedPlatformVariant</key>
			<string>simulator</string>
		</dict>
	</array>
	<key>CFBundlePackageType</key>
	<string>XFWK</string>
	<key>XCFrameworkFormatVersion</key>
	<string>1.0</string>
</dict>
</plist>


================================================
FILE: iOS/consumer/engine.xcframework/LICENSE/3rd_party/CREDITS-LIBC++.TXT
================================================
This file is a partial list of people who have contributed to the LLVM/libc++
project.  If you have contributed a patch or made some other contribution to
LLVM/libc++, please submit a patch to this file to add yourself, and it will be
done!

The list is sorted by surname and formatted to allow easy grepping and
beautification by scripts.  The fields are: name (N), email (E), web-address
(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
(S).

N: Saleem Abdulrasool
E: compnerd@compnerd.org
D: Minor patches and Linux fixes.

N: Dan Albert
E: danalbert@google.com
D: Android support and test runner improvements.

N: Dimitry Andric
E: dimitry@andric.com
D: Visibility fixes, minor FreeBSD portability patches.

N: Holger Arnold
E: holgerar@gmail.com
D: Minor fix.

N: Ruben Van Boxem
E: vanboxem dot ruben at gmail dot com
D: Initial Windows patches.

N: David Chisnall
E: theraven at theravensnest dot org
D: FreeBSD and Solaris ports, libcxxrt support, some atomics work.

N: Marshall Clow
E: mclow.lists@gmail.com
E: marshall@idio.com
D: C++14 support, patches and bug fixes.

N: Jonathan B Coe
E: jbcoe@me.com
D: Implementation of propagate_const.

N: Eric Fiselier
E: eric@efcs.ca
D: LFTS support, patches and bug fixes.

N: Bill Fisher
E: william.w.fisher@gmail.com
D: Regex bug fixes.

N: Matthew Dempsky
E: matthew@dempsky.org
D: Minor patches and bug fixes.

N: Google Inc.
D: Copyright owner and contributor of the CityHash algorithm

N: Howard Hinnant
E: hhinnant@apple.com
D: Architect and primary author of libc++

N: Hyeon-bin Jeong
E: tuhertz@gmail.com
D: Minor patches and bug fixes.

N: Argyrios Kyrtzidis
E: kyrtzidis@apple.com
D: Bug fixes.

N: Bruce Mitchener, Jr.
E: bruce.mitchener@gmail.com
D: Emscripten-related changes.

N: Michel Morin
E: mimomorin@gmail.com
D: Minor patches to is_convertible.

N: Andrew Morrow
E: andrew.c.morrow@gmail.com
D: Minor patches and Linux fixes.

N: Michael Park
E: mcypark@gmail.com
D: Implementation of <variant>.

N: Arvid Picciani
E: aep at exys dot org
D: Minor patches and musl port.

N: Bjorn Reese
E: breese@users.sourceforge.net
D: Initial regex prototype

N: Nico Rieck
E: nico.rieck@gmail.com
D: Windows fixes

N: Jon Roelofs
E: jonathan@codesourcery.com
D: Remote testing, Newlib port, baremetal/single-threaded support.

N: Jonathan Sauer
D: Minor patches, mostly related to constexpr

N: Craig Silverstein
E: csilvers@google.com
D: Implemented Cityhash as the string hash function on 64-bit machines

N: Richard Smith
D: Minor patches.

N: Joerg Sonnenberger
E: joerg@NetBSD.org
D: NetBSD port.

N: Stephan Tolksdorf
E: st@quanttec.com
D: Minor <atomic> fix

N: Michael van der Westhuizen
E: r1mikey at gmail dot com

N: Larisse Voufo
D: Minor patches.

N: Klaas de Vries
E: klaas at klaasgaaf dot nl
D: Minor bug fix.

N: Zhang Xiongpang
E: zhangxiongpang@gmail.com
D: Minor patches and bug fixes.

N: Xing Xue
E: xingxue@ca.ibm.com
D: AIX port

N: Zhihao Yuan
E: lichray@gmail.com
D: Standard compatibility fixes.

N: Jeffrey Yasskin
E: jyasskin@gmail.com
E: jyasskin@google.com
D: Linux fixes.


================================================
FILE: iOS/consumer/engine.xcframework/LICENSE/3rd_party/NOTICE
================================================
mbedtls -> https://github.com/ARMmbed/mbedtls
----------------
Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-------------------------------------------------------------------------------


http-parser -> https://github.com/nodejs/http-parser
----------------
Copyright Joyent, Inc. and other Node contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE. 

-------------------------------------------------------------------------------


json -> https://github.com/nlohmann/json
----------------
Copyright (c) 2013-2018 Niels Lohmann

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

-------------------------------------------------------------------------------


kissfft -> https://github.com/mborgerding/kissfft
----------------
Copyright (c) 2003-2010 Mark Borgerding . All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-------------------------------------------------------------------------------


libsamplerate -> https://github.com/erikd/libsamplerate
----------------
Copyright (c) 2012-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-------------------------------------------------------------------------------


zlib -> https://www.zlib.net 
----------------
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
 claim that you wrote the original software. If you use this software
 in a product, an acknowledgment in the product documentation would be
 appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
 misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

Jean-loup Gailly        Mark Adler
jloup@gzip.org          madler@alumni.caltech.edu

-------------------------------------------------------------------------------


yahdlc -> https://github.com/bang-olufsen/yahdlc
----------------
Copyright (c) 2015 Bang & Olufsen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

-------------------------------------------------------------------------------


==============================================================================
libc++ License
==============================================================================

The libc++ library is dual licensed under both the University of Illinois
"BSD-Like" license and the MIT license.  As a user of this code you may choose
to use it under either license.  As a contributor, you agree to allow your code
to be used under both.

Full text of the relevant licenses is included below.

==============================================================================

University of Illinois/NCSA
Open Source License

Copyright (c) 2009-2017 by the contributors listed in CREDITS-LIBC++.TXT

All rights reserved.

Developed by:

    LLVM Team

    University of Illinois at Urbana-Champaign

    http://llvm.org

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimers.

    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimers in the
      documentation and/or other materials provided with the distribution.

    * Neither the names of the LLVM Team, University of Illinois at
      Urbana-Champaign, nor the names of its contributors may be used to
      endorse or promote products derived from this Software without specific
      prior written permission.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.

==============================================================================

Copyright (c) 2009-2014 by the contributors listed in CREDITS-LIBC++.TXT

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Headers/AudioSession.h
================================================
//
//  AudioSession.h
//  PiDetector
//
//  Created by Pi on 09/11/2010.
//

#pragma once

#import <Foundation/Foundation.h>

#include <CoreAudio/CoreAudioTypes.h>
// ^ for AudioStreamBasicDescription (digging thru AudioToolbox/AudioToolbox.h)

// Must be power-of-2
#define POT_AUDIOBUFLEN 256

@interface AudioSession : NSObject

+ (bool) setup;

@end


================================================
FILE: iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Headers/CUEEngine.h
================================================
//
//  CUEEngine.h
//  objC_consumer
//
//  Created by π on 12/03/2018.
//  Copyright © 2018 π. All rights reserved.
//

#pragma once

#import <Foundation/Foundation.h>
#import "CUEErrno.h"

@interface CUEEngine : NSObject

typedef void(^ReceiverCallback)( NSString* _Nonnull json );
typedef void(^RefreshPayloadsCallback)( void );

+ (nonnull CUEEngine*) sharedInstance;

- (void) didEnterForeground;

// you can set the tone callback at any moment in the life-cycle of the object
- (void) setReceiverCallback: (nonnull ReceiverCallback) blk;

// NOTE: If you don't have microphone permission before you setup,
//         iOS will automatically request it.

- (void) setupWithAPIKey: (nonnull NSString*) apiKey; 

- (void) setupWithAPIKey: (nonnull NSString*) apiKey 
           andWithConfig: (nonnull NSString*) config;

// this will trigger an assertion failure if setup didn't complete
- (void) startListening;

- (void) feed:(null_unspecified float*) bufOfFloats
   withNSamps:(int) nSamps
 andWithSRate:(double) sRate;

- (void) stopListening;

- (BOOL) isListening;

- (BOOL) didSetup;

- (CUE_ENGINE_ERROR) queueLive:                 (nonnull NSString*) live;
- (CUE_ENGINE_ERROR) queueLL:                   (nonnull NSString*) message;
- (CUE_ENGINE_ERROR) queueTrigger:              (nonnull NSString*) trigger;
- (CUE_ENGINE_ERROR) queueTriggerAsNumber:      (unsigned long) n;
- (CUE_ENGINE_ERROR) queueMultiTrigger:         (nonnull NSString*) multiTrigger;
- (CUE_ENGINE_ERROR) queueMultiTriggerAsNumber: (const long long) n;
- (CUE_ENGINE_ERROR) queueData:                 (nonnull NSString*) data;
- (CUE_ENGINE_ERROR) queueMessage:              (nonnull NSString*) message;

- (nonnull NSString*) getEngineDeviceId;

- (void) setDefaultGeneration: (int) g;

- (void) refreshPayloads: (nonnull RefreshPayloadsCallback) blk;
- (nonnull NSDictionary*) getPayload: (nonnull NSString*) trigger;

@end


================================================
FILE: iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Headers/CUEErrno.h
================================================
#import <Foundation/Foundation.h>

typedef NS_ENUM(NSInteger, CUE_ENGINE_ERROR) {
    CUE_ENGINE_SUCCESS = 0,
    CUE_ENGINE_ERR_UNKNOWN = -100,
    CUE_ENGINE_ERR_QUEUE_TRIGGER_NO_ACTIVE_TRANSMITTER = -1,
    CUE_ENGINE_ERR_QUEUE_MESSAGE_NO_ACTIVE_TRANSMITTER = -2,
    CUE_ENGINE_ERR_NUMBER_OF_SYMBOLS_MISMATCH = -3,
    CUE_ENGINE_ERR_SYMBOL_NOT_A_NUMBER = -5,
    CUE_ENGINE_ERR_NO_ACTIVE_TRANSMITTER = -6,
    CUE_ENGINE_ERR_TRIGGER_AS_NUMBER_MAX_NUMBER_EXCEEDED = -7,
    CUE_ENGINE_ERR_INDEX_VALUE_EXCEEDED = -8,
    CUE_ENGINE_ERR_UNSUPPORTED_ENGINE_GENERATION = -9,
    CUE_ENGINE_ERR_MULTI_TRIGGER_AS_NUMBER_MAX_NUMBER_EXCEEDED = -10,
    CUE_ENGINE_ERR_GEN_LIVE_UNSUPPORTED = -11,
    CUE_ENGINE_ERR_QUEUE_LIVE_UNSUPPORTED = -12,
    CUE_ENGINE_ERR_G1_NUMBER_OF_SYMBOLS_EXCEEDED = -102,
    CUE_ENGINE_ERR_G1_GEN_MESSAGE_UNSUPPORTED = -103,
    CUE_ENGINE_ERR_G1_QUEUE_LL_UNSUPPORTED = -104,
    CUE_ENGINE_ERR_G1_GEN_LL_UNSUPPORTED = -105,
    CUE_ENGINE_ERR_G1_QUEUE_MULTI_TRIGGER_UNSUPPORTED = -106,
    CUE_ENGINE_ERR_G1_QUEUE_DATA_UNSUPPORTED = -107,
    CUE_ENGINE_ERR_G1_QUEUE_MESSAGE_UNSUPPORTED = -108,
    CUE_ENGINE_ERR_G2_MESSAGE_STRING_SIZE_IN_BYTES_EXCEEDED = -201,
    CUE_ENGINE_ERR_G2_QUEUE_DATA_UNSUPPORTED = -203,
    CUE_ENGINE_ERR_G2_QUEUE_TRIGGER_NON_BASIC_MODE_IS_USED = -204,
    CUE_ENGINE_ERR_G2_QUEUE_LL_MODE_LL_ONLY_OR_MODE_BASIC_SHOULD_BE_SET = -205,
    CUE_ENGINE_ERR_G2_GEN_LL_MODE_LL_ONLY_OR_MODE_BASIC_SHOULD_BE_SET = -206,
    CUE_ENGINE_ERR_G2_LL_IS_ON_IN_BASIC_CAN_NOT_QUEUE = -207
};


================================================
FILE: iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Headers/CUETrigger.h
================================================
//
//  CUETrigger.h
//  engine
//
//  Created by Jameson Rader on 6/25/19.
//

#import <Foundation/Foundation.h>

typedef NS_ENUM(NSInteger, CUEEngineMode) {
    CUEEngineModeUnknown = -1,
    CUEEngineModeTrigger = 0,
    CUEEngineModeMultiTrigger = 1,
    CUEEngineModeLive = 2,
    CUEEngineModeLL = 3,
    CUEEngineModeData = 4
};

NS_ASSUME_NONNULL_BEGIN

@interface CUETrigger : NSObject

@property int generation;
@property CUEEngineMode mode;

@property double latencyMs;
@property double noise;
@property double power;

@property NSString *rawIndices;
@property (nullable) NSArray<NSNumber *> *rawCalibrations;
@property (nullable) NSArray<NSArray<NSNumber *>*> *rawTrigger;

@property NSString *winnerIndices;
@property long long triggerAsNumber;

@property NSString *rawJsonString;

@property (nullable) NSString *message;

@property NSDictionary *payload;

- (instancetype)initWithJsonString: (NSString *) jsonString;

+ (NSString *) modeAsString: (CUEEngineMode) mode;
+ (NSString *) formatFullData: (CUETrigger *) trigger;
+ (NSString *) formatPartialData: (CUETrigger *) trigger;

@end

NS_ASSUME_NONNULL_END


================================================
FILE: iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>English</string>
	<key>CFBundleExecutable</key>
	<string>engine</string>
	<key>CFBundleIconFile</key>
	<string></string>
	<key>CFBundleIdentifier</key>
	<string>com.cueaudio</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>MinimumOSVersion</key>
	<string>10.3</string>
	<key>CFBundleVersion</key>
	<string>1.33.1</string>
	<key>CFBundleShortVersionString</key>
	<string>1.33.1</string>
	<key>CSResourcesFileMapped</key>
	<true/>
</dict>
</plist>


================================================
FILE: iOS/consumer/engine.xcframework/ios-arm64/engine.framework/LICENSE/3rd_party/CREDITS-LIBC++.TXT
================================================
This file is a partial list of people who have contributed to the LLVM/libc++
project.  If you have contributed a patch or made some other contribution to
LLVM/libc++, please submit a patch to this file to add yourself, and it will be
done!

The list is sorted by surname and formatted to allow easy grepping and
beautification by scripts.  The fields are: name (N), email (E), web-address
(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
(S).

N: Saleem Abdulrasool
E: compnerd@compnerd.org
D: Minor patches and Linux fixes.

N: Dan Albert
E: danalbert@google.com
D: Android support and test runner improvements.

N: Dimitry Andric
E: dimitry@andric.com
D: Visibility fixes, minor FreeBSD portability patches.

N: Holger Arnold
E: holgerar@gmail.com
D: Minor fix.

N: Ruben Van Boxem
E: vanboxem dot ruben at gmail dot com
D: Initial Windows patches.

N: David Chisnall
E: theraven at theravensnest dot org
D: FreeBSD and Solaris ports, libcxxrt support, some atomics work.

N: Marshall Clow
E: mclow.lists@gmail.com
E: marshall@idio.com
D: C++14 support, patches and bug fixes.

N: Jonathan B Coe
E: jbcoe@me.com
D: Implementation of propagate_const.

N: Eric Fiselier
E: eric@efcs.ca
D: LFTS support, patches and bug fixes.

N: Bill Fisher
E: william.w.fisher@gmail.com
D: Regex bug fixes.

N: Matthew Dempsky
E: matthew@dempsky.org
D: Minor patches and bug fixes.

N: Google Inc.
D: Copyright owner and contributor of the CityHash algorithm

N: Howard Hinnant
E: hhinnant@apple.com
D: Architect and primary author of libc++

N: Hyeon-bin Jeong
E: tuhertz@gmail.com
D: Minor patches and bug fixes.

N: Argyrios Kyrtzidis
E: kyrtzidis@apple.com
D: Bug fixes.

N: Bruce Mitchener, Jr.
E: bruce.mitchener@gmail.com
D: Emscripten-related changes.

N: Michel Morin
E: mimomorin@gmail.com
D: Minor patches to is_convertible.

N: Andrew Morrow
E: andrew.c.morrow@gmail.com
D: Minor patches and Linux fixes.

N: Michael Park
E: mcypark@gmail.com
D: Implementation of <variant>.

N: Arvid Picciani
E: aep at exys dot org
D: Minor patches and musl port.

N: Bjorn Reese
E: breese@users.sourceforge.net
D: Initial regex prototype

N: Nico Rieck
E: nico.rieck@gmail.com
D: Windows fixes

N: Jon Roelofs
E: jonathan@codesourcery.com
D: Remote testing, Newlib port, baremetal/single-threaded support.

N: Jonathan Sauer
D: Minor patches, mostly related to constexpr

N: Craig Silverstein
E: csilvers@google.com
D: Implemented Cityhash as the string hash function on 64-bit machines

N: Richard Smith
D: Minor patches.

N: Joerg Sonnenberger
E: joerg@NetBSD.org
D: NetBSD port.

N: Stephan Tolksdorf
E: st@quanttec.com
D: Minor <atomic> fix

N: Michael van der Westhuizen
E: r1mikey at gmail dot com

N: Larisse Voufo
D: Minor patches.

N: Klaas de Vries
E: klaas at klaasgaaf dot nl
D: Minor bug fix.

N: Zhang Xiongpang
E: zhangxiongpang@gmail.com
D: Minor patches and bug fixes.

N: Xing Xue
E: xingxue@ca.ibm.com
D: AIX port

N: Zhihao Yuan
E: lichray@gmail.com
D: Standard compatibility fixes.

N: Jeffrey Yasskin
E: jyasskin@gmail.com
E: jyasskin@google.com
D: Linux fixes.


================================================
FILE: iOS/consumer/engine.xcframework/ios-arm64/engine.framework/LICENSE/3rd_party/NOTICE
================================================
mbedtls -> https://github.com/ARMmbed/mbedtls
----------------
Copyright (C) 2006-2018, ARM Limited, All Rights Reserved
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-------------------------------------------------------------------------------


http-parser -> https://github.com/nodejs/http-parser
----------------
Copyright Joyent, Inc. and other Node contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE. 

-------------------------------------------------------------------------------


json -> https://github.com/nlohmann/json
----------------
Copyright (c) 2013-2018 Niels Lohmann

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

-------------------------------------------------------------------------------


kissfft -> https://github.com/mborgerding/kissfft
----------------
Copyright (c) 2003-2010 Mark Borgerding . All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-------------------------------------------------------------------------------


libsamplerate -> https://github.com/erikd/libsamplerate
----------------
Copyright (c) 2012-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-------------------------------------------------------------------------------


zlib -> https://www.zlib.net 
----------------
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
 claim that you wrote the original software. If you use this software
 in a product, an acknowledgment in the product documentation would be
 appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
 misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

Jean-loup Gailly        Mark Adler
jloup@gzip.org          madler@alumni.caltech.edu

-------------------------------------------------------------------------------


yahdlc -> https://github.com/bang-olufsen/yahdlc
----------------
Copyright (c) 2015 Bang & Olufsen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

-------------------------------------------------------------------------------


==============================================================================
libc++ License
==============================================================================

The libc++ library is dual licensed under both the University of Illinois
"BSD-Like" license and the MIT license.  As a user of this code you may choose
to use it under either license.  As a contributor, you agree to allow your code
to be used under both.

Full text of the relevant licenses is included below.

==============================================================================

University of Illinois/NCSA
Open Source License

Copyright (c) 2009-2017 by the contributors listed in CREDITS-LIBC++.TXT

All rights reserved.

Developed by:

    LLVM Team

    University of Illinois at Urbana-Champaign

    http://llvm.org

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimers.

    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimers in the
      documentation and/or other materials provided with the distribution.

    * Neither the names of the LLVM Team, University of Illinois at
      Urbana-Champaign, nor the names of its contributors may be used to
      endorse or promote products derived from this Software without specific
      prior written permission.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.

==============================================================================

Copyright (c) 2009-2014 by the contributors listed in CREDITS-LIBC++.TXT

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Modules/module.modulemap
================================================
framework module engine {
  module CUEEngine {
    header "CUEEngine.h"
  }

  module AudioSession {
    header "AudioSession.h"
  }

  module CUETrigger {
    header "CUETrigger.h"
  }

  module CUEErrno {
    header "CUEErrno.h"
  }
}


================================================
FILE: iOS/consumer/engine.xcframework/ios-x86_64-simulator/engine.framework/Headers/AudioSession.h
================================================
//
//  AudioSession.h
//  PiDetector
//
//  Created by Pi on 09/11/2010.
//

#pragma once

#import <Foundation/Foundation.h>

#include <CoreAudio/CoreAudioTypes.h>
// ^ for AudioStreamBasicDescription (digging thru AudioToolbox/AudioToolbox.h)

// Must be power-of-2
#define POT_AUDIOBUFLEN 256

@interface AudioSession : NSObject

+ (bool) setup;

@end


================================================
FILE: iOS/consumer/engine.xcframework/ios-x86_64-simulator/engine.framework/Headers/CUEEngine.h
================================================
//
//  CUEEngine.h
//  objC_consumer
//
//  Created by π on 12/03/2018.
//  Copyright © 2018 π. All rights reserved.
//

#pragma once

#import <Foundation/Foundation.h>
#import "CUEErrno.h"

@interface CUEEngine : NSObject

typedef void(^ReceiverCallback)( NSString* _Nonnull json );
typedef void(^RefreshPayloadsCallback)( void );

+ (nonnull CUEEngine*) sharedInstance;

- (void) didEnterForeground;

// you can set the tone callback at any moment in the life-cycle of the object
- (void) setReceiverCallback: (nonnull ReceiverCallback) blk;

// NOTE: If you don't have microphone permission before you setup,
//         iOS will automatically request it.

- (void) setupWithAPIKey: (nonnull NSString*) apiKey; 

- (void) setupWithAPIKey: (nonnull NSString*) apiKey 
       
Download .txt
gitextract_94ypakwa/

├── .gitignore
├── Android/
│   ├── consumer/
│   │   ├── .gitignore
│   │   ├── app/
│   │   │   ├── .gitignore
│   │   │   ├── build.gradle
│   │   │   ├── proguard-rules.pro
│   │   │   └── src/
│   │   │       └── main/
│   │   │           ├── AndroidManifest.xml
│   │   │           ├── java/
│   │   │           │   └── com/
│   │   │           │       └── cueaudio/
│   │   │           │           └── engine_consumer/
│   │   │           │               └── MainActivity.java
│   │   │           └── res/
│   │   │               ├── drawable/
│   │   │               │   ├── ic_clear.xml
│   │   │               │   ├── ic_launcher_background.xml
│   │   │               │   ├── ic_notification.xml
│   │   │               │   ├── ic_send.xml
│   │   │               │   ├── ic_start.xml
│   │   │               │   └── ic_stop.xml
│   │   │               ├── drawable-v24/
│   │   │               │   └── ic_launcher_foreground.xml
│   │   │               ├── layout/
│   │   │               │   └── activity_main.xml
│   │   │               ├── menu/
│   │   │               │   └── main.xml
│   │   │               ├── mipmap-anydpi-v26/
│   │   │               │   ├── ic_launcher.xml
│   │   │               │   └── ic_launcher_round.xml
│   │   │               └── values/
│   │   │                   ├── colors.xml
│   │   │                   ├── strings.xml
│   │   │                   └── styles.xml
│   │   ├── build.gradle
│   │   ├── config/
│   │   │   └── debug.keystore
│   │   ├── gradle/
│   │   │   └── wrapper/
│   │   │       ├── gradle-wrapper.jar
│   │   │       └── gradle-wrapper.properties
│   │   ├── gradle.properties
│   │   ├── gradlew
│   │   ├── gradlew.bat
│   │   └── settings.gradle
│   └── engine.aar
├── License.md
├── README.md
├── doc/
│   ├── Android_README.md
│   ├── CUEEngine_JSON_Structure.md
│   ├── iOS_README.md
│   └── licenses/
│       └── 3rd_party/
│           ├── CREDITS-LIBC++.TXT
│           └── NOTICE
└── iOS/
    ├── consumer/
    │   ├── consumer/
    │   │   ├── AppDelegate.h
    │   │   ├── AppDelegate.m
    │   │   ├── Assets.xcassets/
    │   │   │   ├── AppIcon.appiconset/
    │   │   │   │   └── Contents.json
    │   │   │   └── Contents.json
    │   │   ├── Base.lproj/
    │   │   │   ├── LaunchScreen.storyboard
    │   │   │   └── Main.storyboard
    │   │   ├── Info.plist
    │   │   ├── ViewController.h
    │   │   ├── ViewController.m
    │   │   └── main.m
    │   ├── consumer.xcodeproj/
    │   │   └── project.pbxproj
    │   └── engine.xcframework/
    │       ├── Info.plist
    │       ├── LICENSE/
    │       │   └── 3rd_party/
    │       │       ├── CREDITS-LIBC++.TXT
    │       │       └── NOTICE
    │       ├── ios-arm64/
    │       │   └── engine.framework/
    │       │       ├── Headers/
    │       │       │   ├── AudioSession.h
    │       │       │   ├── CUEEngine.h
    │       │       │   ├── CUEErrno.h
    │       │       │   └── CUETrigger.h
    │       │       ├── Info.plist
    │       │       ├── LICENSE/
    │       │       │   └── 3rd_party/
    │       │       │       ├── CREDITS-LIBC++.TXT
    │       │       │       └── NOTICE
    │       │       ├── Modules/
    │       │       │   └── module.modulemap
    │       │       └── engine
    │       └── ios-x86_64-simulator/
    │           └── engine.framework/
    │               ├── Headers/
    │               │   ├── AudioSession.h
    │               │   ├── CUEEngine.h
    │               │   ├── CUEErrno.h
    │               │   └── CUETrigger.h
    │               ├── Info.plist
    │               ├── LICENSE/
    │               │   └── 3rd_party/
    │               │       ├── CREDITS-LIBC++.TXT
    │               │       └── NOTICE
    │               ├── Modules/
    │               │   └── module.modulemap
    │               └── engine
    ├── engine.framework/
    │   ├── Headers/
    │   │   ├── AudioSession.h
    │   │   ├── CUEEngine.h
    │   │   ├── CUEErrno.h
    │   │   └── CUETrigger.h
    │   ├── Info.plist
    │   ├── LICENSE/
    │   │   └── 3rd_party/
    │   │       ├── CREDITS-LIBC++.TXT
    │   │       └── NOTICE
    │   ├── Modules/
    │   │   └── module.modulemap
    │   └── engine
    └── engine.xcframework/
        ├── Info.plist
        ├── LICENSE/
        │   └── 3rd_party/
        │       ├── CREDITS-LIBC++.TXT
        │       └── NOTICE
        ├── ios-arm64/
        │   └── engine.framework/
        │       ├── Headers/
        │       │   ├── AudioSession.h
        │       │   ├── CUEEngine.h
        │       │   ├── CUEErrno.h
        │       │   └── CUETrigger.h
        │       ├── Info.plist
        │       ├── LICENSE/
        │       │   └── 3rd_party/
        │       │       ├── CREDITS-LIBC++.TXT
        │       │       └── NOTICE
        │       ├── Modules/
        │       │   └── module.modulemap
        │       └── engine
        └── ios-x86_64-simulator/
            └── engine.framework/
                ├── Headers/
                │   ├── AudioSession.h
                │   ├── CUEEngine.h
                │   ├── CUEErrno.h
                │   └── CUETrigger.h
                ├── Info.plist
                ├── LICENSE/
                │   └── 3rd_party/
                │       ├── CREDITS-LIBC++.TXT
                │       └── NOTICE
                ├── Modules/
                │   └── module.modulemap
                └── engine
Download .txt
SYMBOL INDEX (20 symbols across 1 files)

FILE: Android/consumer/app/src/main/java/com/cueaudio/engine_consumer/MainActivity.java
  class MainActivity (line 48) | public class MainActivity extends AppCompatActivity {
    method getModeByPosition (line 75) | private int getModeByPosition(int position) {
    method getTriggerAsNumberByPosition (line 97) | private boolean getTriggerAsNumberByPosition(int position) {
    method onCreate (line 104) | @Override
    method onStart (line 183) | @Override
    method onStop (line 192) | @Override
    method selectMode (line 200) | private void selectMode(int position) {
    method validateInput (line 225) | private void validateInput(@NonNull String input) {
    method queueInput (line 238) | private void queueInput(@NonNull String input, int mode, boolean trigg...
    method onCreateOptionsMenu (line 321) | @Override
    method onPrepareOptionsMenu (line 327) | @Override
    method onOptionsItemSelected (line 343) | @Override
    method checkPermission (line 357) | private void checkPermission() {
    method onRequestPermissionsResult (line 365) | @Override
    method onTriggerHeard (line 391) | private void onTriggerHeard(CUETrigger model) {
    method showNotification (line 415) | private void showNotification(@NonNull String message) {
    method enableListening (line 448) | private void enableListening(boolean enable) {
    method refreshKeyboard (line 457) | private static void refreshKeyboard(@NonNull View view) {
    class OutputListener (line 465) | private class OutputListener implements CUEReceiverCallbackInterface {
      method run (line 466) | @Override
Condensed preview — 99 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (310K chars).
[
  {
    "path": ".gitignore",
    "chars": 200,
    "preview": "# macOS\n.DS_Store\n\n#iOS\nxcshareddata/\niOS/consumer/build.vars\n\n# xcode\nxcuserdata\n*.xcuserstate\nproject.xcworkspace\n\n# A"
  },
  {
    "path": "Android/consumer/.gitignore",
    "chars": 125,
    "preview": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n.i"
  },
  {
    "path": "Android/consumer/app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "Android/consumer/app/build.gradle",
    "chars": 1636,
    "preview": "apply plugin: 'com.android.application'\n//apply plugin: 'com.google.gms.google-services'\n\nandroid {\n    compileSdkVersio"
  },
  {
    "path": "Android/consumer/app/proguard-rules.pro",
    "chars": 751,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "Android/consumer/app/src/main/AndroidManifest.xml",
    "chars": 1361,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:to"
  },
  {
    "path": "Android/consumer/app/src/main/java/com/cueaudio/engine_consumer/MainActivity.java",
    "chars": 18717,
    "preview": "package com.cueaudio.engine_consumer;\n\nimport android.app.Activity;\nimport android.app.NotificationChannel;\nimport andro"
  },
  {
    "path": "Android/consumer/app/src/main/res/drawable/ic_clear.xml",
    "chars": 391,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\""
  },
  {
    "path": "Android/consumer/app/src/main/res/drawable/ic_launcher_background.xml",
    "chars": 5606,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:wi"
  },
  {
    "path": "Android/consumer/app/src/main/res/drawable/ic_notification.xml",
    "chars": 810,
    "preview": "<vector android:height=\"24dp\" android:viewportHeight=\"22\"\n    android:viewportWidth=\"22\" android:width=\"24dp\" xmlns:andr"
  },
  {
    "path": "Android/consumer/app/src/main/res/drawable/ic_send.xml",
    "chars": 328,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\""
  },
  {
    "path": "Android/consumer/app/src/main/res/drawable/ic_start.xml",
    "chars": 304,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\""
  },
  {
    "path": "Android/consumer/app/src/main/res/drawable/ic_stop.xml",
    "chars": 303,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\""
  },
  {
    "path": "Android/consumer/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "chars": 1880,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    "
  },
  {
    "path": "Android/consumer/app/src/main/res/layout/activity_main.xml",
    "chars": 3514,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "Android/consumer/app/src/main/res/menu/main.xml",
    "chars": 524,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"h"
  },
  {
    "path": "Android/consumer/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "chars": 272,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "Android/consumer/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "chars": 272,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "Android/consumer/app/src/main/res/values/colors.xml",
    "chars": 314,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "Android/consumer/app/src/main/res/values/strings.xml",
    "chars": 3927,
    "preview": "<resources>\n    <string name=\"app_name\">CUE Consumer</string>\n\n    <string name=\"menu_start_listening\">Start listening</"
  },
  {
    "path": "Android/consumer/app/src/main/res/values/styles.xml",
    "chars": 197,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"android:Theme.Holo.Light.DarkAction"
  },
  {
    "path": "Android/consumer/build.gradle",
    "chars": 645,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    \n"
  },
  {
    "path": "Android/consumer/gradle/wrapper/gradle-wrapper.properties",
    "chars": 232,
    "preview": "#Wed Aug 21 13:46:46 BST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "Android/consumer/gradle.properties",
    "chars": 783,
    "preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
  },
  {
    "path": "Android/consumer/gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "Android/consumer/gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "Android/consumer/settings.gradle",
    "chars": 15,
    "preview": "include ':app'\n"
  },
  {
    "path": "License.md",
    "chars": 19635,
    "preview": "For a better formatted version, see [HERE](./doc/licenses/License.pdf)\n\n# End User License Agreement\n\nThis End User Lice"
  },
  {
    "path": "README.md",
    "chars": 4627,
    "preview": "\n# High Reliability Acoustic Modem  \n\n## CUE Audio\n\nCUE Audio provides an extremely reliable acoustic modem, permitting "
  },
  {
    "path": "doc/Android_README.md",
    "chars": 3574,
    "preview": "# CUE Engine -- Android\n\n## Using the Demo Project\n\nTo run CUE Audio's ultrasonic engine on Android, simply follow these"
  },
  {
    "path": "doc/CUEEngine_JSON_Structure.md",
    "chars": 2970,
    "preview": "# Structure of CUETrigger\n\n## Basic terms\nEach time a CUE audio signal is detected by the device's audio input or microp"
  },
  {
    "path": "doc/iOS_README.md",
    "chars": 4013,
    "preview": "# CUE Engine - iOS\n\n## Using the Demo Project\n\nTo run CUE Audio's ultrasonic engine on iOS, simply follow these steps:\n\n"
  },
  {
    "path": "doc/licenses/3rd_party/CREDITS-LIBC++.TXT",
    "chars": 3096,
    "preview": "This file is a partial list of people who have contributed to the LLVM/libc++\nproject.  If you have contributed a patch "
  },
  {
    "path": "doc/licenses/3rd_party/NOTICE",
    "chars": 12124,
    "preview": "mbedtls -> https://github.com/ARMmbed/mbedtls\n----------------\nCopyright (C) 2006-2018, ARM Limited, All Rights Reserved"
  },
  {
    "path": "iOS/consumer/consumer/AppDelegate.h",
    "chars": 361,
    "preview": "//\n//  AppDelegate.h\n//  objC_consumer\n//\n//  Created by CUEAudio on 01/03/2018.\n//  © CUEAudio, 2018 to the last syllab"
  },
  {
    "path": "iOS/consumer/consumer/AppDelegate.m",
    "chars": 1447,
    "preview": "//\n//  AppDelegate.m\n//  objC_consumer\n//\n//  Created by CUEAudio on 01/03/2018.\n//  © CUEAudio, 2018 to the last syllab"
  },
  {
    "path": "iOS/consumer/consumer/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "chars": 1590,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\""
  },
  {
    "path": "iOS/consumer/consumer/Assets.xcassets/Contents.json",
    "chars": 62,
    "preview": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/consumer/consumer/Base.lproj/LaunchScreen.storyboard",
    "chars": 1681,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
  },
  {
    "path": "iOS/consumer/consumer/Base.lproj/Main.storyboard",
    "chars": 11356,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
  },
  {
    "path": "iOS/consumer/consumer/Info.plist",
    "chars": 1779,
    "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": "iOS/consumer/consumer/ViewController.h",
    "chars": 246,
    "preview": "//\n//  ViewController.h\n//  objC_consumer\n//\n//  Created by CUEAudio on 01/03/2018.\n//  © CUEAudio, 2018 to the last syl"
  },
  {
    "path": "iOS/consumer/consumer/ViewController.m",
    "chars": 17411,
    "preview": "//\n//  ViewController.m\n//  objC_consumer\n//\n//  Created by CUEAudio on 01/03/2018.\n//  © CUEAudio, 2018 to the last syl"
  },
  {
    "path": "iOS/consumer/consumer/main.m",
    "chars": 323,
    "preview": "//\n//  main.m\n//  objC_consumer\n//\n//  Created by π on 01/03/2018.\n//  Copyright © 2018 π. All rights reserved.\n//\n\n#imp"
  },
  {
    "path": "iOS/consumer/consumer.xcodeproj/project.pbxproj",
    "chars": 15378,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 52;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "iOS/consumer/engine.xcframework/Info.plist",
    "chars": 1007,
    "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": "iOS/consumer/engine.xcframework/LICENSE/3rd_party/CREDITS-LIBC++.TXT",
    "chars": 3096,
    "preview": "This file is a partial list of people who have contributed to the LLVM/libc++\nproject.  If you have contributed a patch "
  },
  {
    "path": "iOS/consumer/engine.xcframework/LICENSE/3rd_party/NOTICE",
    "chars": 12124,
    "preview": "mbedtls -> https://github.com/ARMmbed/mbedtls\n----------------\nCopyright (C) 2006-2018, ARM Limited, All Rights Reserved"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Headers/AudioSession.h",
    "chars": 354,
    "preview": "//\n//  AudioSession.h\n//  PiDetector\n//\n//  Created by Pi on 09/11/2010.\n//\n\n#pragma once\n\n#import <Foundation/Foundatio"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Headers/CUEEngine.h",
    "chars": 1914,
    "preview": "//\n//  CUEEngine.h\n//  objC_consumer\n//\n//  Created by π on 12/03/2018.\n//  Copyright © 2018 π. All rights reserved.\n//\n"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Headers/CUEErrno.h",
    "chars": 1533,
    "preview": "#import <Foundation/Foundation.h>\n\ntypedef NS_ENUM(NSInteger, CUE_ENGINE_ERROR) {\n    CUE_ENGINE_SUCCESS = 0,\n    CUE_EN"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Headers/CUETrigger.h",
    "chars": 1124,
    "preview": "//\n//  CUETrigger.h\n//  engine\n//\n//  Created by Jameson Rader on 6/25/19.\n//\n\n#import <Foundation/Foundation.h>\n\ntypede"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Info.plist",
    "chars": 811,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.c"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-arm64/engine.framework/LICENSE/3rd_party/CREDITS-LIBC++.TXT",
    "chars": 3096,
    "preview": "This file is a partial list of people who have contributed to the LLVM/libc++\nproject.  If you have contributed a patch "
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-arm64/engine.framework/LICENSE/3rd_party/NOTICE",
    "chars": 12124,
    "preview": "mbedtls -> https://github.com/ARMmbed/mbedtls\n----------------\nCopyright (C) 2006-2018, ARM Limited, All Rights Reserved"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-arm64/engine.framework/Modules/module.modulemap",
    "chars": 237,
    "preview": "framework module engine {\n  module CUEEngine {\n    header \"CUEEngine.h\"\n  }\n\n  module AudioSession {\n    header \"AudioSe"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-x86_64-simulator/engine.framework/Headers/AudioSession.h",
    "chars": 354,
    "preview": "//\n//  AudioSession.h\n//  PiDetector\n//\n//  Created by Pi on 09/11/2010.\n//\n\n#pragma once\n\n#import <Foundation/Foundatio"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-x86_64-simulator/engine.framework/Headers/CUEEngine.h",
    "chars": 1914,
    "preview": "//\n//  CUEEngine.h\n//  objC_consumer\n//\n//  Created by π on 12/03/2018.\n//  Copyright © 2018 π. All rights reserved.\n//\n"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-x86_64-simulator/engine.framework/Headers/CUEErrno.h",
    "chars": 1533,
    "preview": "#import <Foundation/Foundation.h>\n\ntypedef NS_ENUM(NSInteger, CUE_ENGINE_ERROR) {\n    CUE_ENGINE_SUCCESS = 0,\n    CUE_EN"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-x86_64-simulator/engine.framework/Headers/CUETrigger.h",
    "chars": 1124,
    "preview": "//\n//  CUETrigger.h\n//  engine\n//\n//  Created by Jameson Rader on 6/25/19.\n//\n\n#import <Foundation/Foundation.h>\n\ntypede"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-x86_64-simulator/engine.framework/Info.plist",
    "chars": 811,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.c"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-x86_64-simulator/engine.framework/LICENSE/3rd_party/CREDITS-LIBC++.TXT",
    "chars": 3096,
    "preview": "This file is a partial list of people who have contributed to the LLVM/libc++\nproject.  If you have contributed a patch "
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-x86_64-simulator/engine.framework/LICENSE/3rd_party/NOTICE",
    "chars": 12124,
    "preview": "mbedtls -> https://github.com/ARMmbed/mbedtls\n----------------\nCopyright (C) 2006-2018, ARM Limited, All Rights Reserved"
  },
  {
    "path": "iOS/consumer/engine.xcframework/ios-x86_64-simulator/engine.framework/Modules/module.modulemap",
    "chars": 237,
    "preview": "framework module engine {\n  module CUEEngine {\n    header \"CUEEngine.h\"\n  }\n\n  module AudioSession {\n    header \"AudioSe"
  },
  {
    "path": "iOS/engine.framework/Headers/AudioSession.h",
    "chars": 354,
    "preview": "//\n//  AudioSession.h\n//  PiDetector\n//\n//  Created by Pi on 09/11/2010.\n//\n\n#pragma once\n\n#import <Foundation/Foundatio"
  },
  {
    "path": "iOS/engine.framework/Headers/CUEEngine.h",
    "chars": 1914,
    "preview": "//\n//  CUEEngine.h\n//  objC_consumer\n//\n//  Created by π on 12/03/2018.\n//  Copyright © 2018 π. All rights reserved.\n//\n"
  },
  {
    "path": "iOS/engine.framework/Headers/CUEErrno.h",
    "chars": 1533,
    "preview": "#import <Foundation/Foundation.h>\n\ntypedef NS_ENUM(NSInteger, CUE_ENGINE_ERROR) {\n    CUE_ENGINE_SUCCESS = 0,\n    CUE_EN"
  },
  {
    "path": "iOS/engine.framework/Headers/CUETrigger.h",
    "chars": 1124,
    "preview": "//\n//  CUETrigger.h\n//  engine\n//\n//  Created by Jameson Rader on 6/25/19.\n//\n\n#import <Foundation/Foundation.h>\n\ntypede"
  },
  {
    "path": "iOS/engine.framework/Info.plist",
    "chars": 811,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.c"
  },
  {
    "path": "iOS/engine.framework/LICENSE/3rd_party/CREDITS-LIBC++.TXT",
    "chars": 3096,
    "preview": "This file is a partial list of people who have contributed to the LLVM/libc++\nproject.  If you have contributed a patch "
  },
  {
    "path": "iOS/engine.framework/LICENSE/3rd_party/NOTICE",
    "chars": 12124,
    "preview": "mbedtls -> https://github.com/ARMmbed/mbedtls\n----------------\nCopyright (C) 2006-2018, ARM Limited, All Rights Reserved"
  },
  {
    "path": "iOS/engine.framework/Modules/module.modulemap",
    "chars": 237,
    "preview": "framework module engine {\n  module CUEEngine {\n    header \"CUEEngine.h\"\n  }\n\n  module AudioSession {\n    header \"AudioSe"
  },
  {
    "path": "iOS/engine.xcframework/Info.plist",
    "chars": 1007,
    "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": "iOS/engine.xcframework/LICENSE/3rd_party/CREDITS-LIBC++.TXT",
    "chars": 3096,
    "preview": "This file is a partial list of people who have contributed to the LLVM/libc++\nproject.  If you have contributed a patch "
  },
  {
    "path": "iOS/engine.xcframework/LICENSE/3rd_party/NOTICE",
    "chars": 12124,
    "preview": "mbedtls -> https://github.com/ARMmbed/mbedtls\n----------------\nCopyright (C) 2006-2018, ARM Limited, All Rights Reserved"
  },
  {
    "path": "iOS/engine.xcframework/ios-arm64/engine.framework/Headers/AudioSession.h",
    "chars": 354,
    "preview": "//\n//  AudioSession.h\n//  PiDetector\n//\n//  Created by Pi on 09/11/2010.\n//\n\n#pragma once\n\n#import <Foundation/Foundatio"
  },
  {
    "path": "iOS/engine.xcframework/ios-arm64/engine.framework/Headers/CUEEngine.h",
    "chars": 1914,
    "preview": "//\n//  CUEEngine.h\n//  objC_consumer\n//\n//  Created by π on 12/03/2018.\n//  Copyright © 2018 π. All rights reserved.\n//\n"
  },
  {
    "path": "iOS/engine.xcframework/ios-arm64/engine.framework/Headers/CUEErrno.h",
    "chars": 1533,
    "preview": "#import <Foundation/Foundation.h>\n\ntypedef NS_ENUM(NSInteger, CUE_ENGINE_ERROR) {\n    CUE_ENGINE_SUCCESS = 0,\n    CUE_EN"
  },
  {
    "path": "iOS/engine.xcframework/ios-arm64/engine.framework/Headers/CUETrigger.h",
    "chars": 1124,
    "preview": "//\n//  CUETrigger.h\n//  engine\n//\n//  Created by Jameson Rader on 6/25/19.\n//\n\n#import <Foundation/Foundation.h>\n\ntypede"
  },
  {
    "path": "iOS/engine.xcframework/ios-arm64/engine.framework/Info.plist",
    "chars": 811,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.c"
  },
  {
    "path": "iOS/engine.xcframework/ios-arm64/engine.framework/LICENSE/3rd_party/CREDITS-LIBC++.TXT",
    "chars": 3096,
    "preview": "This file is a partial list of people who have contributed to the LLVM/libc++\nproject.  If you have contributed a patch "
  },
  {
    "path": "iOS/engine.xcframework/ios-arm64/engine.framework/LICENSE/3rd_party/NOTICE",
    "chars": 12124,
    "preview": "mbedtls -> https://github.com/ARMmbed/mbedtls\n----------------\nCopyright (C) 2006-2018, ARM Limited, All Rights Reserved"
  },
  {
    "path": "iOS/engine.xcframework/ios-arm64/engine.framework/Modules/module.modulemap",
    "chars": 237,
    "preview": "framework module engine {\n  module CUEEngine {\n    header \"CUEEngine.h\"\n  }\n\n  module AudioSession {\n    header \"AudioSe"
  },
  {
    "path": "iOS/engine.xcframework/ios-x86_64-simulator/engine.framework/Headers/AudioSession.h",
    "chars": 354,
    "preview": "//\n//  AudioSession.h\n//  PiDetector\n//\n//  Created by Pi on 09/11/2010.\n//\n\n#pragma once\n\n#import <Foundation/Foundatio"
  },
  {
    "path": "iOS/engine.xcframework/ios-x86_64-simulator/engine.framework/Headers/CUEEngine.h",
    "chars": 1914,
    "preview": "//\n//  CUEEngine.h\n//  objC_consumer\n//\n//  Created by π on 12/03/2018.\n//  Copyright © 2018 π. All rights reserved.\n//\n"
  },
  {
    "path": "iOS/engine.xcframework/ios-x86_64-simulator/engine.framework/Headers/CUEErrno.h",
    "chars": 1533,
    "preview": "#import <Foundation/Foundation.h>\n\ntypedef NS_ENUM(NSInteger, CUE_ENGINE_ERROR) {\n    CUE_ENGINE_SUCCESS = 0,\n    CUE_EN"
  },
  {
    "path": "iOS/engine.xcframework/ios-x86_64-simulator/engine.framework/Headers/CUETrigger.h",
    "chars": 1124,
    "preview": "//\n//  CUETrigger.h\n//  engine\n//\n//  Created by Jameson Rader on 6/25/19.\n//\n\n#import <Foundation/Foundation.h>\n\ntypede"
  },
  {
    "path": "iOS/engine.xcframework/ios-x86_64-simulator/engine.framework/Info.plist",
    "chars": 811,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.c"
  },
  {
    "path": "iOS/engine.xcframework/ios-x86_64-simulator/engine.framework/LICENSE/3rd_party/CREDITS-LIBC++.TXT",
    "chars": 3096,
    "preview": "This file is a partial list of people who have contributed to the LLVM/libc++\nproject.  If you have contributed a patch "
  },
  {
    "path": "iOS/engine.xcframework/ios-x86_64-simulator/engine.framework/LICENSE/3rd_party/NOTICE",
    "chars": 12124,
    "preview": "mbedtls -> https://github.com/ARMmbed/mbedtls\n----------------\nCopyright (C) 2006-2018, ARM Limited, All Rights Reserved"
  },
  {
    "path": "iOS/engine.xcframework/ios-x86_64-simulator/engine.framework/Modules/module.modulemap",
    "chars": 237,
    "preview": "framework module engine {\n  module CUEEngine {\n    header \"CUEEngine.h\"\n  }\n\n  module AudioSession {\n    header \"AudioSe"
  }
]

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

About this extraction

This page contains the full source code of the jamesonrader/CUE-Ultrasonic-Transmissions-Protocol GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 99 files (47.5 MB), approximately 73.7k tokens, and a symbol index with 20 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!