[
  {
    "path": ".gitattributes",
    "content": "*.zip filter=lfs diff=lfs merge=lfs -text\n"
  },
  {
    "path": ".gitignore",
    "content": "#### CocoaPods\nPods/\n*.generated.swift\n\n#### Fastlane\nfastlane/report.xml\nfastlane/README.md\n\n#### macOS\n.DS_Store\n\n#### Xcode\nxcuserdata/\n*.xcworkspace\niOS/*.zip\n*.ipa\n\n# For rswift build workaround\nrswift.workaround.file\n\n*.Framework/\n[Ll]ibrary/\n[Tt]emp/\n[Oo]bj/\n[Bb]uild/\n[Bb]uilds/\nAssets/AssetStoreTools*\n\n# Visual Studio cache directory\n.vs/\n\n# Autogenerated VS/MD/Consulo solution and project files\nExportedObj/\n.consulo/\n*.csproj\n*.unityproj\n*.sln\n*.suo\n*.tmp\n*.user\n*.userprefs\n*.pidb\n*.booproj\n*.svd\n*.pdb\n*.opendb\n\n# Unity3D generated meta files\n*.pidb.meta\n*.pdb.meta\n\n# Unity3D Generated File On Crash Reports\nsysinfo.txt\n\n# Builds\n*.apk\n*.unitypackage\n*.Framework/\n*.framework.meta\n\n.DS_Store\n\nFritzConfig.asset\nFritzConfig.asset.meta\n\n# excluding local python version\n.python-version\n"
  },
  {
    "path": ".swiftlint.yml",
    "content": "included:\n  - Heartbeat/Source\nexcluded:\n  - Pods\n  - Supporting Files\nopt_in_rules:\n  - attributes\n  - closure_end_indentation\n  - empty_count\n  - explicit_top_level_acl\n  - force_unwrapping\ndisabled_rules:\n  - explicit_top_level_acl\n  - line_length\n"
  },
  {
    "path": "Android/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\ngradle/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# Intellij\n*.iml\n.idea\n\n# Keystore files\n*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n.DS_Store\n"
  },
  {
    "path": "Android/AnimatedSkyApp/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea\n\n# Keystore files\n# Uncomment the following line if you do not want to check your keystore files in.\n#*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n# fastlane\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\nfastlane/readme.md\n"
  },
  {
    "path": "Android/AnimatedSkyApp/README.md",
    "content": "# Animations with Sky Segmentation\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we create a simple photo app to replace the sky with an animation.\n\n![](images/skyani.gif)\n\nThis example app uses the on-device Image Segmentation API with the Sky Segmentation Model for Android.\n\n- [Overview](https://www.fritz.ai/features/image-segmentation.html?utm_source=github&utm_campaign=fritz-examples)\n- [Documentation](https://docs.fritz.ai/develop/vision/image-segmentation/android.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Android Studio 3.2 or above\n- Android device in developer model (USB debugging enabled)\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nRegister the Android app in your Fritz account with the package id \"ai.fritz.animatedSky\". During registration, you'll receive an API key for the app. Save this for later. To find it in the webapp, you can go to Project Settings > Apps > Your App > Show API Key.\n\n**Step 2: Clone / Fork the fritz-examples repository and open the AnimatedSkyApp app in Android Studio**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\nIn Android Studio, choose \"Open an existing Android Studio project\" and select `AnimatedSkyApp`.\n\n**Step 3: Edit the fritz.xml file with your API Key**\n\nIn app/src/main/res/values/fritz.xml, change the fritz_api_key attribute with the one you received in step 1.\n\n**Step 4: Build the Android Studio Project**\n\nSelect \"Build > Make Project\" from the top nav. Download any missing libraries if applicable. This should sync the gradle dependencies so give the build a second to complete.\n\n**Step 5: Install the app onto your device**\n\nWith your Android device connected, select `Run > Run App` from the top nav. When running the app for the first time, you'll have to give permissions to access the camera. After the app is installed and running, take a picture outside and watch as we replace the sky with an animated image.\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 28\n    defaultConfig {\n        // MUST MATCH THE APPLICATION YOU CREATE IN FRITZ\n        applicationId \"ai.fritz.animatedSky\"\n        minSdkVersion 24\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n}\n\ndependencies {\n    implementation 'com.android.support:appcompat-v7:28.0.0'\n    implementation 'com.android.support.constraint:constraint-layout:1.1.3'\n\n    implementation \"ai.fritz:vision:6.0.3\"\n    implementation \"ai.fritz:vision-sky-segmentation-model-fast:3.0.0\"\n\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'com.android.support.test:runner:1.0.2'\n    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'\n}\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.animatedSky\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\"ai.fritz.animatedSky.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <service\n            android:name=\"ai.fritz.core.FritzCustomModelService\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/java/ai/fritz/animatedSky/AutoFitTextureView.java",
    "content": "package ai.fritz.animatedSky;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.TextureView;\n\n/**\n * A {@link TextureView} that can be adjusted to a specified aspect ratio.\n */\npublic class AutoFitTextureView extends TextureView {\n\n    private int mRatioWidth = 0;\n    private int mRatioHeight = 0;\n\n    public AutoFitTextureView(Context context) {\n        this(context, null);\n    }\n\n    public AutoFitTextureView(Context context, AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    /**\n     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio\n     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that\n     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.\n     *\n     * @param width  Relative horizontal size\n     * @param height Relative vertical size\n     */\n    public void setAspectRatio(int width, int height) {\n        if (width < 0 || height < 0) {\n            throw new IllegalArgumentException(\"Size cannot be negative.\");\n        }\n        mRatioWidth = width;\n        mRatioHeight = height;\n        requestLayout();\n    }\n\n    @Override\n    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\n        super.onMeasure(widthMeasureSpec, heightMeasureSpec);\n        int width = MeasureSpec.getSize(widthMeasureSpec);\n        int height = MeasureSpec.getSize(heightMeasureSpec);\n        if (0 == mRatioWidth || 0 == mRatioHeight) {\n            setMeasuredDimension(width, height);\n            return;\n        }\n        if (width < height * mRatioWidth / mRatioHeight) {\n            setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);\n            return;\n        }\n        setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);\n    }\n}"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/java/ai/fritz/animatedSky/BaseCameraActivity.java",
    "content": "package ai.fritz.animatedSky;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.support.v7.app.AppCompatActivity;\nimport android.util.DisplayMetrics;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.KeyEvent;\nimport android.view.WindowManager;\nimport android.widget.Toast;\n\n\npublic abstract class BaseCameraActivity extends AppCompatActivity implements OnImageAvailableListener {\n    private static final String TAG = BaseCameraActivity.class.getSimpleName();\n    private static int MAX_WIDTH = 500;\n    private static final int PERMISSIONS_REQUEST = 1;\n\n    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;\n    private static final String PERMISSION_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;\n    private boolean useCamera2API;\n\n    private boolean debug = false;\n\n    private Handler handler;\n    private HandlerThread handlerThread;\n\n    protected String cameraId;\n    protected int cameraFacingDirection = CameraCharacteristics.LENS_FACING_BACK;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        Log.d(TAG, \"onCreate \" + this);\n        super.onCreate(null);\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        setContentView(R.layout.activity_main);\n\n        if (hasPermission()) {\n            setFragment();\n        } else {\n            requestPermission();\n        }\n    }\n\n    @Override\n    public synchronized void onStart() {\n        Log.d(TAG, \"onStart \" + this);\n        super.onStart();\n    }\n\n    @Override\n    public synchronized void onResume() {\n        Log.d(TAG, \"onResume \" + this);\n        super.onResume();\n\n        handlerThread = new HandlerThread(\"inference\");\n        handlerThread.start();\n        handler = new Handler(handlerThread.getLooper());\n    }\n\n    @Override\n    public synchronized void onPause() {\n        Log.d(TAG, \"onPause \" + this);\n\n        handlerThread.quitSafely();\n        try {\n            handlerThread.join();\n            handlerThread = null;\n            handler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n\n        super.onPause();\n    }\n\n    @Override\n    public synchronized void onStop() {\n        Log.d(TAG, \"onStop \" + this);\n        super.onStop();\n    }\n\n    @Override\n    public synchronized void onDestroy() {\n        Log.d(TAG, \"onDestroy \" + this);\n        super.onDestroy();\n    }\n\n    protected int getCameraFacingDirection() {\n        return cameraFacingDirection;\n    }\n\n    protected synchronized void runInBackground(final Runnable r) {\n        if (handler != null) {\n            handler.post(r);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(\n            final int requestCode, final String[] permissions, final int[] grantResults) {\n        switch (requestCode) {\n            case PERMISSIONS_REQUEST: {\n                if (grantResults.length > 0\n                        && grantResults[0] == PackageManager.PERMISSION_GRANTED\n                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {\n                    setFragment();\n                } else {\n                    requestPermission();\n                }\n            }\n        }\n    }\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            boolean cameraPermission = checkSelfPermission(PERMISSION_CAMERA) == PackageManager.PERMISSION_GRANTED;\n            return  cameraPermission;\n        } else {\n            return true;\n        }\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA) || shouldShowRequestPermissionRationale(PERMISSION_STORAGE)) {\n                Toast.makeText(BaseCameraActivity.this, \"Camera AND storage permission are required for this demo\", Toast.LENGTH_LONG).show();\n            }\n            requestPermissions(new String[]{PERMISSION_CAMERA, PERMISSION_STORAGE}, PERMISSIONS_REQUEST);\n        }\n    }\n\n    protected void setFragment() {\n        cameraId = chooseCamera();\n        final CameraConnectionFragment fragment =\n                CameraConnectionFragment.newInstance(\n                        new CameraConnectionFragment.ConnectionCallback() {\n                            @Override\n                            public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n                                BaseCameraActivity.this.onPreviewSizeChosen(previewSize, cameraViewSize, rotation);\n                            }\n                        },\n                        this,\n                        getLayoutId(),\n                        getDesiredPreviewFrameSize());\n\n        fragment.setCamera(cameraId);\n\n        getFragmentManager()\n                .beginTransaction()\n                .replace(R.id.camera_container, fragment)\n                .commit();\n    }\n\n    protected void toggleCameraFacingDirection() {\n        if (cameraFacingDirection == CameraCharacteristics.LENS_FACING_FRONT) {\n            cameraFacingDirection = CameraCharacteristics.LENS_FACING_BACK;\n        } else {\n            cameraFacingDirection = CameraCharacteristics.LENS_FACING_FRONT;\n        }\n\n        setFragment();\n    }\n\n    private String chooseCamera() {\n        final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);\n        try {\n            for (final String cameraId : manager.getCameraIdList()) {\n                final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n                // We don't use a front facing camera in this sample.\n                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);\n                if (facing != null && facing != cameraFacingDirection) {\n                    continue;\n                }\n\n                final StreamConfigurationMap map =\n                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n                if (map == null) {\n                    continue;\n                }\n\n                // Fallback to camera1 API for internal cameras that don't have full support.\n                // This should help with legacy situations where using the camera2 API causes\n                // distorted or otherwise broken previews.\n                useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)\n                        || isHardwareLevelSupported(characteristics,\n                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);\n                Log.i(TAG, \"Camera API lv2?: \" + useCamera2API);\n                return cameraId;\n            }\n        } catch (CameraAccessException e) {\n            Log.e(TAG, \"Not allowed to access camera: \" + e);\n        }\n\n        return null;\n    }\n\n    // Returns true if the device supports the required hardware level, or better.\n    private boolean isHardwareLevelSupported(\n            CameraCharacteristics characteristics, int requiredLevel) {\n        int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);\n        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {\n            return requiredLevel == deviceLevel;\n        }\n        // deviceLevel is not LEGACY, can use numerical sort\n        return requiredLevel <= deviceLevel;\n    }\n\n\n    public boolean isDebug() {\n        return debug;\n    }\n\n    public void requestRender() {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.postInvalidate();\n        }\n    }\n\n    public void setCallback(final OverlayView.DrawCallback callback) {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.setCallback(callback);\n        }\n    }\n\n    public void onSetDebug(final boolean debug) {\n    }\n\n    @Override\n    public boolean onKeyDown(final int keyCode, final KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {\n            debug = !debug;\n            requestRender();\n            onSetDebug(debug);\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    protected abstract void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation);\n\n    protected abstract int getLayoutId();\n\n    protected Size getDesiredPreviewFrameSize() {\n        DisplayMetrics metrics = getResources().getDisplayMetrics();\n        float ratio = (float) metrics.heightPixels / metrics.widthPixels;\n        return new Size(MAX_WIDTH, (int) ratio * MAX_WIDTH);\n    }\n}\n\n\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/java/ai/fritz/animatedSky/CameraConnectionFragment.java",
    "content": "package ai.fritz.animatedSky;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.app.DialogFragment;\nimport android.app.Fragment;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.graphics.ImageFormat;\nimport android.graphics.Matrix;\nimport android.graphics.RectF;\nimport android.graphics.SurfaceTexture;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCaptureSession;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraDevice;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.CaptureRequest;\nimport android.hardware.camera2.CaptureResult;\nimport android.hardware.camera2.TotalCaptureResult;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.LayoutInflater;\nimport android.view.Surface;\nimport android.view.TextureView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\n\n\npublic class CameraConnectionFragment extends Fragment {\n    private static final String TAG = CameraConnectionFragment.class.getSimpleName();\n\n    public CameraConnectionFragment() {\n\n    }\n\n    /**\n     * The camera preview size will be chosen to be the smallest frame by pixel size capable of\n     * containing a DESIRED_SIZE x DESIRED_SIZE square.\n     */\n    private static final int MINIMUM_PREVIEW_SIZE = 320;\n\n    /**\n     * Conversion from screen rotation to JPEG orientation.\n     */\n    private static final String FRAGMENT_DIALOG = \"dialog\";\n\n    /**\n     * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a\n     * {@link TextureView}.\n     */\n    private final TextureView.SurfaceTextureListener surfaceTextureListener =\n            new TextureView.SurfaceTextureListener() {\n                @Override\n                public void onSurfaceTextureAvailable(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    openCamera(width, height);\n                }\n\n                @Override\n                public void onSurfaceTextureSizeChanged(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    configureTransform(width, height);\n                }\n\n                @Override\n                public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {\n                    return true;\n                }\n\n                @Override\n                public void onSurfaceTextureUpdated(final SurfaceTexture texture) {\n                }\n            };\n\n    /**\n     * Callback for Activities to use to initialize their data once the\n     * selected preview size is known.\n     */\n    public interface ConnectionCallback {\n        void onPreviewSizeChosen(Size size, Size cameraViewSize, int cameraRotation);\n    }\n\n    /**\n     * ID of the current {@link CameraDevice}.\n     */\n    private String cameraId;\n\n    /**\n     * An {@link AutoFitTextureView} for camera preview.\n     */\n    private AutoFitTextureView textureView;\n\n    /**\n     * A {@link CameraCaptureSession } for camera preview.\n     */\n    private CameraCaptureSession captureSession;\n\n    /**\n     * A reference to the opened {@link CameraDevice}.\n     */\n    private CameraDevice cameraDevice;\n\n    /**\n     * The rotation in degrees of the camera sensor from the display.\n     */\n    private Integer sensorOrientation;\n\n    /**\n     * The {@link android.util.Size} of camera preview.\n     */\n    private Size previewSize;\n\n    /**\n     * {@link android.hardware.camera2.CameraDevice.StateCallback}\n     * is called when {@link CameraDevice} changes its state.\n     */\n    private final CameraDevice.StateCallback stateCallback =\n            new CameraDevice.StateCallback() {\n                @Override\n                public void onOpened(final CameraDevice cd) {\n                    // This method is called when the camera is opened.  We start camera preview here.\n                    cameraOpenCloseLock.release();\n                    cameraDevice = cd;\n                    createCameraPreviewSession();\n                }\n\n                @Override\n                public void onDisconnected(final CameraDevice cd) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                }\n\n                @Override\n                public void onError(final CameraDevice cd, final int error) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                    final Activity activity = getActivity();\n                    if (null != activity) {\n                        activity.finish();\n                    }\n                }\n            };\n\n    /**\n     * An additional thread for running tasks that shouldn't block the UI.\n     */\n    private HandlerThread backgroundThread;\n\n    /**\n     * A {@link Handler} for running tasks in the background.\n     */\n    private Handler backgroundHandler;\n\n    /**\n     * An {@link ImageReader} that handles preview frame capture.\n     */\n    private ImageReader previewReader;\n\n    /**\n     * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview\n     */\n    private CaptureRequest.Builder previewRequestBuilder;\n\n    /**\n     * {@link CaptureRequest} generated by {@link #previewRequestBuilder}\n     */\n    private CaptureRequest previewRequest;\n\n    /**\n     * A {@link Semaphore} to prevent the app from exiting before closing the camera.\n     */\n    private final Semaphore cameraOpenCloseLock = new Semaphore(1);\n\n    /**\n     * A {@link OnImageAvailableListener} to receive frames as they are available.\n     */\n    private OnImageAvailableListener imageListener = null;\n\n    /**\n     * The input size in pixels desired by TensorFlow (width and height of a square bitmap).\n     */\n    private Size inputSize = null;\n\n    /**\n     * The layout identifier to inflate for this Fragment.\n     */\n    private int layout = -1;\n\n\n    private ConnectionCallback cameraConnectionCallback = null;\n\n    private CameraConnectionFragment(\n            final ConnectionCallback connectionCallback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        this.cameraConnectionCallback = connectionCallback;\n        this.imageListener = imageListener;\n        this.layout = layout;\n        this.inputSize = inputSize;\n    }\n\n    /**\n     * Shows a {@link Toast} on the UI thread.\n     *\n     * @param text The message to show\n     */\n    private void showToast(final String text) {\n        final Activity activity = getActivity();\n        if (activity != null) {\n            activity.runOnUiThread(\n                    new Runnable() {\n                        @Override\n                        public void run() {\n                            Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();\n                        }\n                    });\n        }\n    }\n\n    /**\n     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose\n     * width and height are at least as large as the minimum of both, or an exact match if possible.\n     *\n     * @param choices The list of sizes that the camera supports for the intended output class\n     * @param width   The minimum desired width\n     * @param height  The minimum desired height\n     * @return The optimal {@code Size}, or an arbitrary one if none were big enough\n     */\n    protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {\n        final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);\n        final Size desiredSize = new Size(width, height);\n\n        // Collect the supported resolutions that are at least as big as the preview Surface\n        boolean exactSizeFound = false;\n        final List<Size> bigEnough = new ArrayList<Size>();\n        final List<Size> tooSmall = new ArrayList<Size>();\n        for (final Size option : choices) {\n            if (option.equals(desiredSize)) {\n                // Set the size but don't return yet so that remaining sizes will still be logged.\n                exactSizeFound = true;\n            }\n\n            if (option.getHeight() >= minSize && option.getWidth() >= minSize) {\n                bigEnough.add(option);\n            } else {\n                tooSmall.add(option);\n            }\n        }\n\n        Log.d(TAG, \"Desired size: \" + desiredSize + \", min size: \" + minSize + \"x\" + minSize);\n        Log.d(TAG, \"Valid preview sizes: [\" + TextUtils.join(\", \", bigEnough) + \"]\");\n        Log.d(TAG, \"Rejected preview sizes: [\" + TextUtils.join(\", \", tooSmall) + \"]\");\n\n        if (exactSizeFound) {\n            Log.d(TAG, \"Exact size match found.\");\n            return desiredSize;\n        }\n\n        // Pick the smallest of those, assuming we found any\n        if (bigEnough.size() > 0) {\n            final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());\n            Log.d(TAG, \"Chosen size: \" + chosenSize.getWidth() + \"x\" + chosenSize.getHeight());\n            return chosenSize;\n        } else {\n            Log.e(TAG, \"Couldn't find any suitable preview size\");\n            return choices[0];\n        }\n    }\n\n    public static CameraConnectionFragment newInstance(\n            final ConnectionCallback callback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        return new CameraConnectionFragment(callback, imageListener, layout, inputSize);\n    }\n\n    @Override\n    public View onCreateView(\n            final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {\n        return inflater.inflate(layout, container, false);\n    }\n\n    @Override\n    public void onViewCreated(final View view, final Bundle savedInstanceState) {\n        textureView = (AutoFitTextureView) view.findViewById(R.id.texture);\n    }\n\n    @Override\n    public void onActivityCreated(final Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        startBackgroundThread();\n\n        // When the screen is turned off and turned back on, the SurfaceTexture is ai.fritz.heartbeat.ui.AutoFitTextureViewalready\n        // available, and \"onSurfaceTextureAvailable\" will not be called. In that case, we can open\n        // a camera and start preview from here (otherwise, we wait until the surface is ready in\n        // the SurfaceTextureListener).\n        if (textureView.isAvailable()) {\n            openCamera(textureView.getWidth(), textureView.getHeight());\n        } else {\n            textureView.setSurfaceTextureListener(surfaceTextureListener);\n        }\n    }\n\n    @Override\n    public void onPause() {\n        closeCamera();\n        stopBackgroundThread();\n        super.onPause();\n    }\n\n    public void setCamera(String cameraId) {\n        this.cameraId = cameraId;\n    }\n\n    /**\n     * Sets up member variables related to camera.\n     */\n    private void setUpCameraOutputs() {\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n            final StreamConfigurationMap map =\n                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n            // For still image captures, we use the largest available size.\n            final Size largest =\n                    Collections.max(\n                            Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),\n                            new CompareSizesByArea());\n\n            sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);\n\n            // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera\n            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of\n            // garbage capture data.\n            previewSize =\n                    chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),\n                            inputSize.getWidth(),\n                            inputSize.getHeight());\n        } catch (final CameraAccessException e) {\n            Log.e(TAG,  \"Exception!\" + e);\n        } catch (final NullPointerException e) {\n            // Currently an NPE is thrown when the Camera2API is used but not supported on the\n            // device this code runs.\n            // TODO(andrewharp): abstract ErrorDialog/RuntimeException handling out into new method and\n            // reuse throughout app.\n            ErrorDialog.newInstance(getString(R.string.camera_error))\n                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);\n            throw new RuntimeException(getString(R.string.camera_error));\n        }\n\n        Size textureViewSize = new Size(textureView.getWidth(), textureView.getHeight());\n        cameraConnectionCallback.onPreviewSizeChosen(previewSize, textureViewSize, sensorOrientation);\n    }\n\n    /**\n     * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.\n     */\n    private void openCamera(final int width, final int height) {\n        setUpCameraOutputs();\n        configureTransform(width, height);\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\n                throw new RuntimeException(\"Time out waiting to lock camera opening.\");\n            }\n            manager.openCamera(cameraId, stateCallback, backgroundHandler);\n        } catch (final CameraAccessException | SecurityException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\n        }\n    }\n\n    /**\n     * Closes the current {@link CameraDevice}.\n     */\n    private void closeCamera() {\n        try {\n            cameraOpenCloseLock.acquire();\n            if (null != captureSession) {\n                captureSession.close();\n                captureSession = null;\n            }\n            if (null != cameraDevice) {\n                cameraDevice.close();\n                cameraDevice = null;\n            }\n            if (null != previewReader) {\n                previewReader.close();\n                previewReader = null;\n            }\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera closing.\", e);\n        } finally {\n            cameraOpenCloseLock.release();\n        }\n    }\n\n    /**\n     * Starts a background thread and its {@link Handler}.\n     */\n    private void startBackgroundThread() {\n        backgroundThread = new HandlerThread(\"ImageListener\");\n        backgroundThread.start();\n        backgroundHandler = new Handler(backgroundThread.getLooper());\n    }\n\n    /**\n     * Stops the background thread and its {@link Handler}.\n     */\n    private void stopBackgroundThread() {\n        backgroundThread.quitSafely();\n        try {\n            backgroundThread.join();\n            backgroundThread = null;\n            backgroundHandler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    private final CameraCaptureSession.CaptureCallback captureCallback =\n            new CameraCaptureSession.CaptureCallback() {\n                @Override\n                public void onCaptureProgressed(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final CaptureResult partialResult) {\n                }\n\n                @Override\n                public void onCaptureCompleted(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final TotalCaptureResult result) {\n                }\n            };\n\n    /**\n     * Creates a new {@link CameraCaptureSession} for camera preview.\n     */\n    private void createCameraPreviewSession() {\n        try {\n            final SurfaceTexture texture = textureView.getSurfaceTexture();\n            assert texture != null;\n\n            // We configure the size of default buffer to be the size of camera preview we want.\n            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());\n\n            // This is the output Surface we need to start preview.\n            final Surface surface = new Surface(texture);\n\n            // We set up a CaptureRequest.Builder with the output Surface.\n            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\n            previewRequestBuilder.addTarget(surface);\n\n            Log.i(TAG, \"Opening camera preview: \" + previewSize.getWidth() + \"x\" + previewSize.getHeight());\n\n            // Create the reader for the preview frames.\n            previewReader =\n                    ImageReader.newInstance(\n                            previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);\n            previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);\n            previewRequestBuilder.addTarget(previewReader.getSurface());\n\n            // Here, we create a CameraCaptureSession for camera preview.\n            cameraDevice.createCaptureSession(\n                    Arrays.asList(surface, previewReader.getSurface()),\n                    new CameraCaptureSession.StateCallback() {\n\n                        @Override\n                        public void onConfigured(final CameraCaptureSession cameraCaptureSession) {\n                            // The camera is already closed\n                            if (null == cameraDevice) {\n                                return;\n                            }\n\n                            // When the session is ready, we start displaying the preview.\n                            captureSession = cameraCaptureSession;\n                            try {\n                                // Auto focus should be continuous for camera preview.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AF_MODE,\n                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\n                                // Flash is automatically enabled when necessary.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);\n\n                                // Finally, we start displaying the camera preview.\n                                previewRequest = previewRequestBuilder.build();\n                                captureSession.setRepeatingRequest(\n                                        previewRequest, captureCallback, backgroundHandler);\n                            } catch (final CameraAccessException e) {\n                                Log.e(TAG, \"Exception!\" + e);\n                            }\n                        }\n\n                        @Override\n                        public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {\n                            showToast(\"Failed\");\n                        }\n                    },\n                    null);\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    /**\n     * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.\n     * This method should be called after the camera preview size is determined in\n     * setUpCameraOutputs and also the size of `mTextureView` is fixed.\n     *\n     * @param viewWidth  The width of `mTextureView`\n     * @param viewHeight The height of `mTextureView`\n     */\n    private void configureTransform(final int viewWidth, final int viewHeight) {\n        final Activity activity = getActivity();\n        if (null == textureView || null == previewSize || null == activity) {\n            return;\n        }\n        final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();\n        final Matrix matrix = new Matrix();\n        final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);\n        final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());\n        final float centerX = viewRect.centerX();\n        final float centerY = viewRect.centerY();\n        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {\n            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());\n            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);\n            final float scale =\n                    Math.max(\n                            (float) viewHeight / previewSize.getHeight(),\n                            (float) viewWidth / previewSize.getWidth());\n            matrix.postScale(scale, scale, centerX, centerY);\n            matrix.postRotate(90 * (rotation - 2), centerX, centerY);\n        } else if (Surface.ROTATION_180 == rotation) {\n            matrix.postRotate(180, centerX, centerY);\n        }\n        textureView.setTransform(matrix);\n    }\n\n    /**\n     * Compares two {@code Size}s based on their areas.\n     */\n    static class CompareSizesByArea implements Comparator<Size> {\n        @Override\n        public int compare(final Size lhs, final Size rhs) {\n            // We cast here to ensure the multiplications won't overflow\n            return Long.signum(\n                    (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());\n        }\n    }\n\n    /**\n     * Shows an error message dialog.\n     */\n    public static class ErrorDialog extends DialogFragment {\n        private static final String ARG_MESSAGE = \"message\";\n\n        public static ErrorDialog newInstance(final String message) {\n            final ErrorDialog dialog = new ErrorDialog();\n            final Bundle args = new Bundle();\n            args.putString(ARG_MESSAGE, message);\n            dialog.setArguments(args);\n            return dialog;\n        }\n\n        @Override\n        public Dialog onCreateDialog(final Bundle savedInstanceState) {\n            final Activity activity = getActivity();\n            return new AlertDialog.Builder(activity)\n                    .setMessage(getArguments().getString(ARG_MESSAGE))\n                    .setPositiveButton(\n                            android.R.string.ok,\n                            new DialogInterface.OnClickListener() {\n                                @Override\n                                public void onClick(final DialogInterface dialogInterface, final int i) {\n                                    activity.finish();\n                                }\n                            })\n                    .create();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/java/ai/fritz/animatedSky/MainActivity.java",
    "content": "package ai.fritz.animatedSky;\n\nimport android.animation.ValueAnimator;\nimport android.content.Context;\nimport android.content.res.AssetManager;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.graphics.RectF;\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.os.Bundle;\nimport android.util.Size;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.ImageView;\nimport android.widget.ProgressBar;\nimport android.widget.RelativeLayout;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.core.Fritz;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\nimport ai.fritz.vision.ImageRotation;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictorOptions;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationResult;\nimport ai.fritz.vision.imagesegmentation.MaskClass;\nimport ai.fritz.vision.imagesegmentation.SegmentationOnDeviceModel;\n\n\npublic class MainActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n    private static final String TAG = MainActivity.class.getSimpleName();\n\n    private AtomicBoolean shouldSample = new AtomicBoolean(true);\n    private FritzVisionSegmentationPredictor predictor;\n    private ImageOrientation orientation;\n\n    private static final int DURATION = 5000;\n\n    private ValueAnimator mCurrentAnimator;\n    private Matrix mMatrix = new Matrix();\n    private ImageView mImageView;\n    private float mScaleFactor;\n    private RectF mDisplayRect = new RectF();\n\n    private FritzVisionSegmentationResult segmentResult;\n    private FritzVisionImage visionImage;\n\n    Button snapshotButton;\n    RelativeLayout previewLayout;\n    RelativeLayout snapshotLayout;\n    OverlayView snapshotOverlay;\n    ProgressBar snapshotProcessingSpinner;\n    Button closeButton;\n    FritzVisionSegmentationPredictorOptions options;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Fritz.configure(getApplicationContext());\n\n        SegmentationOnDeviceModel onDeviceModel = FritzVisionModels.getSkySegmentationOnDeviceModel(ModelVariant.FAST);\n        options = new FritzVisionSegmentationPredictorOptions();\n        options.confidenceThreshold = .6f;\n        predictor = FritzVision.ImageSegmentation.getPredictor(onDeviceModel, options);\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.sky_fragment;\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size size, final Size cameraSize, final int rotation) {\n        orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n\n        snapshotButton = findViewById(R.id.take_picture_btn);\n        previewLayout = findViewById(R.id.preview_frame);\n        snapshotLayout = findViewById(R.id.snapshot_frame);\n        snapshotOverlay = findViewById(R.id.snapshot_view);\n        closeButton = findViewById(R.id.close_btn);\n        snapshotProcessingSpinner = findViewById(R.id.snapshotProcessingSpinner);\n        mImageView = findViewById(R.id.backgroundImgView);\n\n        snapshotOverlay.setCallback(new OverlayView.DrawCallback() {\n            @Override\n            public void drawCallback(final Canvas canvas) {\n\n                // If there's no result, just return\n                if (segmentResult == null) {\n                    return;\n                }\n\n                // Create a bitmap for undetected items. Scale it up for the camera.\n                Bitmap notSkyMask = segmentResult.buildSingleClassMask(MaskClass.NONE);\n                Bitmap notSkyBitmap = visionImage.mask(notSkyMask);\n\n                // Scale the non-sky bitmap (scale up from preview size (size of the original image)\n                // to fill the view (cameraSize)).\n                float scaleWidth = ((float) cameraSize.getWidth()) / notSkyBitmap.getWidth();\n                float scaleHeight = ((float) cameraSize.getHeight()) / notSkyBitmap.getHeight();\n                final Matrix matrix = new Matrix();\n                float scale = Math.min(scaleWidth, scaleHeight);\n                matrix.postScale(scale, scale);\n                Bitmap scaledNonSkyBitmap = Bitmap.createBitmap(notSkyBitmap, 0, 0, notSkyBitmap.getWidth(), notSkyBitmap.getHeight(), matrix, false);\n\n                // Start the animation\n                mImageView.post(new Runnable() {\n                    @Override\n                    public void run() {\n                        mScaleFactor = (float) mImageView.getHeight() / (float) mImageView.getDrawable().getIntrinsicHeight();\n                        mMatrix.postScale(mScaleFactor, mScaleFactor);\n                        mImageView.setImageMatrix(mMatrix);\n                        startAnimation();\n                    }\n                });\n\n                // Draw the non-sky bitmap on the bottom center.\n                canvas.drawBitmap(scaledNonSkyBitmap, (cameraSize.getWidth() - scaledNonSkyBitmap.getWidth()) / 2, cameraSize.getHeight() - scaledNonSkyBitmap.getHeight(), new Paint());\n            }\n        });\n\n        snapshotButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                if (!shouldSample.compareAndSet(true, false)) {\n                    return;\n                }\n\n                snapshotOverlay.postInvalidate();\n\n                runInBackground(\n                        new Runnable() {\n                            @Override\n                            public void run() {\n                                showSpinner();\n                                segmentResult = predictor.predict(visionImage);\n                                showSnapshotLayout();\n                                hideSpinner();\n                                snapshotOverlay.postInvalidate();\n                            }\n                        });\n            }\n        });\n\n        closeButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                showPreviewLayout();\n                shouldSample.set(true);\n                mCurrentAnimator.end();\n                mMatrix = new Matrix();\n                mImageView.setImageMatrix(mMatrix);\n                mDisplayRect = new RectF();\n            }\n        });\n    }\n\n    // For more information on how this animation works:\n    // http://old.flavienlaurent.com/blog/2013/08/05/make-your-background-moving-like-on-play-music-app/\n    // In short, use displayRect to maintain the real size and position of the bg.\n    // Animate the background by applying a translation.\n    private void startAnimation() {\n        int width = mImageView.getDrawable().getIntrinsicWidth();\n        int height = mImageView.getDrawable().getIntrinsicHeight();\n        mDisplayRect.set(0, 0, width, height);\n        mMatrix.mapRect(mDisplayRect);\n        animate(mDisplayRect.left, mDisplayRect.left - (mDisplayRect.right - mImageView.getWidth()));\n    }\n\n    private void animate(float from, float to) {\n        mCurrentAnimator = ValueAnimator.ofFloat(from, to);\n        mCurrentAnimator.setRepeatCount(ValueAnimator.INFINITE);\n        mCurrentAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n            @Override\n            public void onAnimationUpdate(ValueAnimator animation) {\n                float value = (Float) animation.getAnimatedValue();\n\n                mMatrix.reset();\n                mMatrix.postScale(mScaleFactor, mScaleFactor);\n                mMatrix.postTranslate(value, 0);\n\n                mImageView.setImageMatrix(mMatrix);\n            }\n        });\n        mCurrentAnimator.setDuration(DURATION);\n        mCurrentAnimator.start();\n    }\n\n    private void showSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void hideSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.GONE);\n            }\n        });\n    }\n\n    private void showSnapshotLayout() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                previewLayout.setVisibility(View.GONE);\n                snapshotLayout.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void showPreviewLayout() {\n        previewLayout.setVisibility(View.VISIBLE);\n        snapshotLayout.setVisibility(View.GONE);\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!shouldSample.get()) {\n            image.close();\n            return;\n        }\n\n        // Feel free to uncomment if you'd like to try it out with a static image\n//         Bitmap testImage = getBitmapForAsset(this, \"climbing.png\");\n//         visionImage = FritzVisionImage.fromBitmap(testImage, ImageRotation.ROTATE_0);\n\n        // Using the image from the camera\n        visionImage = FritzVisionImage.fromMediaImage(image, orientation);\n        image.close();\n    }\n\n    public static Bitmap getBitmapForAsset(Context context, String path) {\n        AssetManager assetManager = context.getAssets();\n        InputStream inputStream;\n        Bitmap bitmap = null;\n        try {\n            inputStream = assetManager.open(path);\n            bitmap = BitmapFactory.decodeStream(inputStream);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n        return bitmap;\n    }\n}"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/java/ai/fritz/animatedSky/OverlayView.java",
    "content": "package ai.fritz.animatedSky;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.util.AttributeSet;\nimport android.view.View;\n\n/**\n * A simple View providing a render callback to other classes.\n */\npublic class OverlayView extends View {\n    private DrawCallback callback;\n\n    public OverlayView(final Context context, final AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    /**\n     * Interface defining the callback for client classes.\n     */\n    public interface DrawCallback {\n        public void drawCallback(final Canvas canvas);\n    }\n\n    public void setCallback(final DrawCallback callback) {\n        this.callback = callback;\n    }\n\n    @Override\n    public synchronized void draw(final Canvas canvas) {\n        super.draw(canvas);\n        if(callback != null) {\n            callback.drawCallback(canvas);\n        }\n    }\n}"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/drawable/ic_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24.0\"\n    android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        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\"/>\n</vector>"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/drawable/round_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\">\n    <stroke\n        android:color=\"#FFFF\"\n        android:width=\"5dip\"/>\n    <size android:width=\"100dp\" android:height=\"100dp\"/>\n</shape>"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/layout/activity_main.xml",
    "content": "<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <FrameLayout\n        android:id=\"@+id/camera_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</android.support.constraint.ConstraintLayout>"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/layout/sky_fragment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n Copyright 2016 The TensorFlow Authors. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:id=\"@+id/preview_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <ai.fritz.animatedSky.AutoFitTextureView\n            android:id=\"@+id/texture\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\" />\n\n        <ai.fritz.animatedSky.OverlayView\n            android:id=\"@+id/debug_overlay\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\" />\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginTop=\"@dimen/margin_sm\"\n            android:layout_marginBottom=\"@dimen/margin_lg\">\n\n            <Button\n                android:id=\"@+id/take_picture_btn\"\n                android:layout_width=\"80dp\"\n                android:layout_height=\"80dp\"\n                android:layout_centerInParent=\"true\"\n                android:background=\"@drawable/round_button\"\n                android:textColor=\"#fff\" />\n\n            <ProgressBar\n                android:id=\"@+id/snapshotProcessingSpinner\"\n                style=\"?android:attr/progressBarStyleLarge\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerInParent=\"true\"\n                android:indeterminateTint=\"#fff\"\n                android:visibility=\"gone\" />\n        </RelativeLayout>\n    </RelativeLayout>\n\n    <RelativeLayout\n        android:id=\"@+id/snapshot_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:id=\"@+id/backgroundImgView\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:adjustViewBounds=\"true\"\n            android:scaleType=\"matrix\"\n            android:src=\"@drawable/skybgreplacement\"/>\n\n        <ai.fritz.animatedSky.OverlayView\n            android:id=\"@+id/snapshot_view\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\" />\n\n        <Button\n            android:id=\"@+id/close_btn\"\n            android:layout_width=\"50dp\"\n            android:layout_height=\"50dp\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_alignParentRight=\"true\"\n            android:layout_marginTop=\"@dimen/margin_sm\"\n            android:layout_marginRight=\"@dimen/margin_sm\"\n            android:background=\"@drawable/ic_close\" />\n\n    </RelativeLayout>\n\n\n</RelativeLayout>\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/values/dimen.xml",
    "content": "<!--\n  Copyright 2013 The Android Open Source Project\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n\n<resources>\n\n    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->\n\n    <dimen name=\"margin_xs\">4dp</dimen>\n    <dimen name=\"margin_sm\">8dp</dimen>\n    <dimen name=\"margin_md\">16dp</dimen>\n    <dimen name=\"margin_lg\">32dp</dimen>\n    <dimen name=\"margin_xl\">64dp</dimen>\n\n    <!-- Semantic definitions -->\n\n    <dimen name=\"horizontal_page_margin\">@dimen/margin_md</dimen>\n    <dimen name=\"vertical_page_margin\">@dimen/margin_md</dimen>\n\n</resources>"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Sky Animation</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n</resources>\n"
  },
  {
    "path": "Android/AnimatedSkyApp/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "Android/AnimatedSkyApp/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.4.1'\n\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n\n        // ADD FOR FRITZ DEPENDENCIES\n        maven { url \"https://fritz.mycloudrepo.io/public/repositories/android\" }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "Android/AnimatedSkyApp/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n"
  },
  {
    "path": "Android/AnimatedSkyApp/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/AnimatedSkyApp/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/AnimatedSkyApp/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea\n\n# Keystore files\n# Uncomment the following line if you do not want to check your keystore files in.\n#*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n# fastlane\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\nfastlane/readme.md\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/README.md",
    "content": "# Automatic Background Replacement with People Segmentation\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we create a mask of a person and then replace the background with any picture in the camera gallery.\n\n![](images/background_changer.png)\n\nFor the full tutorial, visit [our post on Heartbeat](https://heartbeat.fritz.ai/image-segmentation-for-android-smart-background-replacement-with-fritz-a09d8b0592a4).\n\nThis example app uses the on-device People Segmentation API for Android.\n\n- [Overview](https://www.fritz.ai/features/image-segmentation.html)\n- [Documentation](https://docs.fritz.ai/develop/vision/image-segmentation/android.html)\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Android Studio 3.2 or above\n- Android device in developer model (USB debugging enabled)\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nRegister the Android app in your Fritz account with the package id \"ai.fritz.backgroundChanger\". During registration, you'll receive an API key for the app. Save this for later. To find it in the webapp, you can go to Project Settings > Apps > Your App > Show API Key.\n\n**Step 2: Clone / Fork the fritz-examples repository and open the BackgroundReplacementApp app in Android Studio**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\nIn Android Studio, choose \"Open an existing Android Studio project\" and select `BackgroundReplacementApp`.\n\n**Step 3: Edit the fritz.xml file with your API Key**\n\nIn app/src/main/res/values/fritz.xml, change the fritz_api_key attribute with the one you received in step 1.\n\n**Step 4: Build the Android Studio Project**\n\nSelect \"Build > Make Project\" from the top nav. Download any missing libraries if applicable. This should sync the gradle dependencies so give the build a second to complete.\n\n**Step 5: Install the app onto your device**\n\nWith your Android device connected, select `Run > Run App` from the top nav. When running the app for the first time, you'll have to give permissions to access the camera. After the app is installed and running, take a picture of a person and then after that mask is created, select a photo from your camera gallery to replace the background.\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack)\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 28\n    defaultConfig {\n        // MUST MATCH THE APPLICATION YOU CREATE IN FRITZ\n        applicationId \"ai.fritz.backgroundChanger\"\n        minSdkVersion 24\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n}\n\ndependencies {\n    implementation 'com.android.support:appcompat-v7:28.0.0-rc02'\n    implementation 'com.android.support.constraint:constraint-layout:1.1.2'\n\n    implementation \"ai.fritz:core:6.0.3\"\n    implementation \"ai.fritz:vision:6.0.3\"\n    implementation \"ai.fritz:vision-people-segmentation-model-accurate:3.1.0\"\n\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'com.android.support.test:runner:1.0.2'\n    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'\n}\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.replaceBackground\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\"ai.fritz.replaceBackground.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <service\n            android:name=\"ai.fritz.core.FritzCustomModelService\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/java/ai/fritz/replaceBackground/AutoFitTextureView.java",
    "content": "package ai.fritz.replaceBackground;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.TextureView;\n\n/**\n * A {@link TextureView} that can be adjusted to a specified aspect ratio.\n */\npublic class AutoFitTextureView extends TextureView {\n    private int ratioWidth = 0;\n    private int ratioHeight = 0;\n\n    public AutoFitTextureView(final Context context) {\n        this(context, null);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    /**\n     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio\n     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that\n     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.\n     *\n     * @param width  Relative horizontal size\n     * @param height Relative vertical size\n     */\n    public void setAspectRatio(final int width, final int height) {\n        if (width < 0 || height < 0) {\n            throw new IllegalArgumentException(\"Size cannot be negative.\");\n        }\n        ratioWidth = width;\n        ratioHeight = height;\n        requestLayout();\n    }\n}"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/java/ai/fritz/replaceBackground/BaseCameraActivity.java",
    "content": "package ai.fritz.replaceBackground;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.support.v7.app.AppCompatActivity;\nimport android.util.DisplayMetrics;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.KeyEvent;\nimport android.view.WindowManager;\nimport android.widget.Toast;\n\n\npublic abstract class BaseCameraActivity extends AppCompatActivity implements OnImageAvailableListener {\n    private static final String TAG = BaseCameraActivity.class.getSimpleName();\n    private static int MAX_WIDTH = 500;\n    private static final int PERMISSIONS_REQUEST = 1;\n\n    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;\n    private static final String PERMISSION_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;\n    private boolean useCamera2API;\n\n    private boolean debug = false;\n\n    private Handler handler;\n    private HandlerThread handlerThread;\n\n    protected String cameraId;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        Log.d(TAG, \"onCreate \" + this);\n        super.onCreate(null);\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        setContentView(R.layout.activity_main);\n\n        if (hasPermission()) {\n            setFragment();\n        } else {\n            requestPermission();\n        }\n    }\n\n    @Override\n    public synchronized void onStart() {\n        Log.d(TAG, \"onStart \" + this);\n        super.onStart();\n    }\n\n    @Override\n    public synchronized void onResume() {\n        Log.d(TAG, \"onResume \" + this);\n        super.onResume();\n\n        handlerThread = new HandlerThread(\"inference\");\n        handlerThread.start();\n        handler = new Handler(handlerThread.getLooper());\n    }\n\n    @Override\n    public synchronized void onPause() {\n        Log.d(TAG, \"onPause \" + this);\n\n        handlerThread.quitSafely();\n        try {\n            handlerThread.join();\n            handlerThread = null;\n            handler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n\n        super.onPause();\n    }\n\n    @Override\n    public synchronized void onStop() {\n        Log.d(TAG, \"onStop \" + this);\n        super.onStop();\n    }\n\n    @Override\n    public synchronized void onDestroy() {\n        Log.d(TAG, \"onDestroy \" + this);\n        super.onDestroy();\n    }\n\n    protected synchronized void runInBackground(final Runnable r) {\n        if (handler != null) {\n            handler.post(r);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(\n            final int requestCode, final String[] permissions, final int[] grantResults) {\n        switch (requestCode) {\n            case PERMISSIONS_REQUEST: {\n                if (grantResults.length > 0\n                        && grantResults[0] == PackageManager.PERMISSION_GRANTED\n                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {\n                    setFragment();\n                } else {\n                    requestPermission();\n                }\n            }\n        }\n    }\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            return checkSelfPermission(PERMISSION_CAMERA) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(PERMISSION_STORAGE) == PackageManager.PERMISSION_GRANTED;\n        } else {\n            return true;\n        }\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA) || shouldShowRequestPermissionRationale(PERMISSION_STORAGE)) {\n                Toast.makeText(BaseCameraActivity.this, \"Camera AND storage permission are required for this demo\", Toast.LENGTH_LONG).show();\n            }\n            requestPermissions(new String[]{PERMISSION_CAMERA, PERMISSION_STORAGE}, PERMISSIONS_REQUEST);\n        }\n    }\n\n    protected void setFragment() {\n        cameraId = chooseCamera();\n        final CameraConnectionFragment fragment =\n                CameraConnectionFragment.newInstance(\n                        new CameraConnectionFragment.ConnectionCallback() {\n                            @Override\n                            public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n                                BaseCameraActivity.this.onPreviewSizeChosen(previewSize, cameraViewSize, rotation);\n                            }\n                        },\n                        this,\n                        getLayoutId(),\n                        getDesiredPreviewFrameSize());\n\n        fragment.setCamera(cameraId);\n\n        getFragmentManager()\n                .beginTransaction()\n                .replace(R.id.camera_container, fragment)\n                .commit();\n    }\n\n    private String chooseCamera() {\n        final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);\n        try {\n            for (final String cameraId : manager.getCameraIdList()) {\n                final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n                // We don't use a front facing camera in this sample.\n                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);\n                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {\n                    continue;\n                }\n\n                final StreamConfigurationMap map =\n                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n                if (map == null) {\n                    continue;\n                }\n\n                // Fallback to camera1 API for internal cameras that don't have full support.\n                // This should help with legacy situations where using the camera2 API causes\n                // distorted or otherwise broken previews.\n                useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)\n                        || isHardwareLevelSupported(characteristics,\n                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);\n                Log.i(TAG, \"Camera API lv2?: \" + useCamera2API);\n                return cameraId;\n            }\n        } catch (CameraAccessException e) {\n            Log.e(TAG, \"Not allowed to access camera: \" + e);\n        }\n\n        return null;\n    }\n\n    // Returns true if the device supports the required hardware level, or better.\n    private boolean isHardwareLevelSupported(\n            CameraCharacteristics characteristics, int requiredLevel) {\n        int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);\n        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {\n            return requiredLevel == deviceLevel;\n        }\n        // deviceLevel is not LEGACY, can use numerical sort\n        return requiredLevel <= deviceLevel;\n    }\n\n\n    public boolean isDebug() {\n        return debug;\n    }\n\n    public void requestRender() {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.postInvalidate();\n        }\n    }\n\n    public void setCallback(final OverlayView.DrawCallback callback) {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.setCallback(callback);\n        }\n    }\n\n    public void onSetDebug(final boolean debug) {\n    }\n\n    @Override\n    public boolean onKeyDown(final int keyCode, final KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {\n            debug = !debug;\n            requestRender();\n            onSetDebug(debug);\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    protected abstract void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation);\n\n    protected abstract int getLayoutId();\n\n    protected Size getDesiredPreviewFrameSize() {\n        DisplayMetrics metrics = getResources().getDisplayMetrics();\n        float ratio = (float) metrics.heightPixels / metrics.widthPixels;\n        return new Size(MAX_WIDTH, (int) ratio * MAX_WIDTH);\n    }\n}\n\n\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/java/ai/fritz/replaceBackground/CameraConnectionFragment.java",
    "content": "package ai.fritz.replaceBackground;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.app.DialogFragment;\nimport android.app.Fragment;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.graphics.ImageFormat;\nimport android.graphics.Matrix;\nimport android.graphics.RectF;\nimport android.graphics.SurfaceTexture;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCaptureSession;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraDevice;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.CaptureRequest;\nimport android.hardware.camera2.CaptureResult;\nimport android.hardware.camera2.TotalCaptureResult;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.LayoutInflater;\nimport android.view.Surface;\nimport android.view.TextureView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\n\n\npublic class CameraConnectionFragment extends Fragment {\n    private static final String TAG = CameraConnectionFragment.class.getSimpleName();\n\n    public CameraConnectionFragment() {\n\n    }\n\n    /**\n     * The camera preview size will be chosen to be the smallest frame by pixel size capable of\n     * containing a DESIRED_SIZE x DESIRED_SIZE square.\n     */\n    private static final int MINIMUM_PREVIEW_SIZE = 320;\n\n    /**\n     * Conversion from screen rotation to JPEG orientation.\n     */\n    private static final String FRAGMENT_DIALOG = \"dialog\";\n\n    /**\n     * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a\n     * {@link TextureView}.\n     */\n    private final TextureView.SurfaceTextureListener surfaceTextureListener =\n            new TextureView.SurfaceTextureListener() {\n                @Override\n                public void onSurfaceTextureAvailable(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    openCamera(width, height);\n                }\n\n                @Override\n                public void onSurfaceTextureSizeChanged(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    configureTransform(width, height);\n                }\n\n                @Override\n                public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {\n                    return true;\n                }\n\n                @Override\n                public void onSurfaceTextureUpdated(final SurfaceTexture texture) {\n                }\n            };\n\n    /**\n     * Callback for Activities to use to initialize their data once the\n     * selected preview size is known.\n     */\n    public interface ConnectionCallback {\n        void onPreviewSizeChosen(Size size, Size cameraViewSize, int cameraRotation);\n    }\n\n    /**\n     * ID of the current {@link CameraDevice}.\n     */\n    private String cameraId;\n\n    /**\n     * An {@link AutoFitTextureView} for camera preview.\n     */\n    private AutoFitTextureView textureView;\n\n    /**\n     * A {@link CameraCaptureSession } for camera preview.\n     */\n    private CameraCaptureSession captureSession;\n\n    /**\n     * A reference to the opened {@link CameraDevice}.\n     */\n    private CameraDevice cameraDevice;\n\n    /**\n     * The rotation in degrees of the camera sensor from the display.\n     */\n    private Integer sensorOrientation;\n\n    /**\n     * The {@link android.util.Size} of camera preview.\n     */\n    private Size previewSize;\n\n    /**\n     * {@link android.hardware.camera2.CameraDevice.StateCallback}\n     * is called when {@link CameraDevice} changes its state.\n     */\n    private final CameraDevice.StateCallback stateCallback =\n            new CameraDevice.StateCallback() {\n                @Override\n                public void onOpened(final CameraDevice cd) {\n                    // This method is called when the camera is opened.  We start camera preview here.\n                    cameraOpenCloseLock.release();\n                    cameraDevice = cd;\n                    createCameraPreviewSession();\n                }\n\n                @Override\n                public void onDisconnected(final CameraDevice cd) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                }\n\n                @Override\n                public void onError(final CameraDevice cd, final int error) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                    final Activity activity = getActivity();\n                    if (null != activity) {\n                        activity.finish();\n                    }\n                }\n            };\n\n    /**\n     * An additional thread for running tasks that shouldn't block the UI.\n     */\n    private HandlerThread backgroundThread;\n\n    /**\n     * A {@link Handler} for running tasks in the background.\n     */\n    private Handler backgroundHandler;\n\n    /**\n     * An {@link ImageReader} that handles preview frame capture.\n     */\n    private ImageReader previewReader;\n\n    /**\n     * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview\n     */\n    private CaptureRequest.Builder previewRequestBuilder;\n\n    /**\n     * {@link CaptureRequest} generated by {@link #previewRequestBuilder}\n     */\n    private CaptureRequest previewRequest;\n\n    /**\n     * A {@link Semaphore} to prevent the app from exiting before closing the camera.\n     */\n    private final Semaphore cameraOpenCloseLock = new Semaphore(1);\n\n    /**\n     * A {@link OnImageAvailableListener} to receive frames as they are available.\n     */\n    private OnImageAvailableListener imageListener = null;\n\n    /**\n     * The input size in pixels desired by TensorFlow (width and height of a square bitmap).\n     */\n    private Size inputSize = null;\n\n    /**\n     * The layout identifier to inflate for this Fragment.\n     */\n    private int layout = -1;\n\n\n    private ConnectionCallback cameraConnectionCallback = null;\n\n    private CameraConnectionFragment(\n            final ConnectionCallback connectionCallback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        this.cameraConnectionCallback = connectionCallback;\n        this.imageListener = imageListener;\n        this.layout = layout;\n        this.inputSize = inputSize;\n    }\n\n    /**\n     * Shows a {@link Toast} on the UI thread.\n     *\n     * @param text The message to show\n     */\n    private void showToast(final String text) {\n        final Activity activity = getActivity();\n        if (activity != null) {\n            activity.runOnUiThread(\n                    new Runnable() {\n                        @Override\n                        public void run() {\n                            Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();\n                        }\n                    });\n        }\n    }\n\n    /**\n     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose\n     * width and height are at least as large as the minimum of both, or an exact match if possible.\n     *\n     * @param choices The list of sizes that the camera supports for the intended output class\n     * @param width   The minimum desired width\n     * @param height  The minimum desired height\n     * @return The optimal {@code Size}, or an arbitrary one if none were big enough\n     */\n    protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {\n        final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);\n        final Size desiredSize = new Size(width, height);\n\n        // Collect the supported resolutions that are at least as big as the preview Surface\n        boolean exactSizeFound = false;\n        final List<Size> bigEnough = new ArrayList<Size>();\n        final List<Size> tooSmall = new ArrayList<Size>();\n        for (final Size option : choices) {\n            if (option.equals(desiredSize)) {\n                // Set the size but don't return yet so that remaining sizes will still be logged.\n                exactSizeFound = true;\n            }\n\n            if (option.getHeight() >= minSize && option.getWidth() >= minSize) {\n                bigEnough.add(option);\n            } else {\n                tooSmall.add(option);\n            }\n        }\n\n        Log.d(TAG, \"Desired size: \" + desiredSize + \", min size: \" + minSize + \"x\" + minSize);\n        Log.d(TAG, \"Valid preview sizes: [\" + TextUtils.join(\", \", bigEnough) + \"]\");\n        Log.d(TAG, \"Rejected preview sizes: [\" + TextUtils.join(\", \", tooSmall) + \"]\");\n\n        if (exactSizeFound) {\n            Log.d(TAG, \"Exact size match found.\");\n            return desiredSize;\n        }\n\n        // Pick the smallest of those, assuming we found any\n        if (bigEnough.size() > 0) {\n            final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());\n            Log.d(TAG, \"Chosen size: \" + chosenSize.getWidth() + \"x\" + chosenSize.getHeight());\n            return chosenSize;\n        } else {\n            Log.e(TAG, \"Couldn't find any suitable preview size\");\n            return choices[0];\n        }\n    }\n\n    public static CameraConnectionFragment newInstance(\n            final ConnectionCallback callback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        return new CameraConnectionFragment(callback, imageListener, layout, inputSize);\n    }\n\n    @Override\n    public View onCreateView(\n            final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {\n        return inflater.inflate(layout, container, false);\n    }\n\n    @Override\n    public void onViewCreated(final View view, final Bundle savedInstanceState) {\n        textureView = (AutoFitTextureView) view.findViewById(R.id.texture);\n    }\n\n    @Override\n    public void onActivityCreated(final Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        startBackgroundThread();\n\n        // When the screen is turned off and turned back on, the SurfaceTexture is already\n        // available, and \"onSurfaceTextureAvailable\" will not be called. In that case, we can open\n        // a camera and start preview from here (otherwise, we wait until the surface is ready in\n        // the SurfaceTextureListener).\n        if (textureView.isAvailable()) {\n            openCamera(textureView.getWidth(), textureView.getHeight());\n        } else {\n            textureView.setSurfaceTextureListener(surfaceTextureListener);\n        }\n    }\n\n    @Override\n    public void onPause() {\n        closeCamera();\n        stopBackgroundThread();\n        super.onPause();\n    }\n\n    public void setCamera(String cameraId) {\n        this.cameraId = cameraId;\n    }\n\n    /**\n     * Sets up member variables related to camera.\n     */\n    private void setUpCameraOutputs() {\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n            final StreamConfigurationMap map =\n                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n            // For still image captures, we use the largest available size.\n            final Size largest =\n                    Collections.max(\n                            Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),\n                            new CompareSizesByArea());\n\n            sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);\n\n            // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera\n            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of\n            // garbage capture data.\n            previewSize =\n                    chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),\n                            inputSize.getWidth(),\n                            inputSize.getHeight());\n        } catch (final CameraAccessException e) {\n            Log.e(TAG,  \"Exception!\" + e);\n        } catch (final NullPointerException e) {\n            // Currently an NPE is thrown when the Camera2API is used but not supported on the\n            // device this code runs.\n            // TODO(andrewharp): abstract ErrorDialog/RuntimeException handling out into new method and\n            // reuse throughout app.\n            ErrorDialog.newInstance(getString(R.string.camera_error))\n                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);\n            throw new RuntimeException(getString(R.string.camera_error));\n        }\n\n        Size textureViewSize = new Size(textureView.getWidth(), textureView.getHeight());\n        cameraConnectionCallback.onPreviewSizeChosen(previewSize, textureViewSize, sensorOrientation);\n    }\n\n    /**\n     * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.\n     */\n    private void openCamera(final int width, final int height) {\n        setUpCameraOutputs();\n        configureTransform(width, height);\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\n                throw new RuntimeException(\"Time out waiting to lock camera opening.\");\n            }\n            manager.openCamera(cameraId, stateCallback, backgroundHandler);\n        } catch (final CameraAccessException | SecurityException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\n        }\n    }\n\n    /**\n     * Closes the current {@link CameraDevice}.\n     */\n    private void closeCamera() {\n        try {\n            cameraOpenCloseLock.acquire();\n            if (null != captureSession) {\n                captureSession.close();\n                captureSession = null;\n            }\n            if (null != cameraDevice) {\n                cameraDevice.close();\n                cameraDevice = null;\n            }\n            if (null != previewReader) {\n                previewReader.close();\n                previewReader = null;\n            }\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera closing.\", e);\n        } finally {\n            cameraOpenCloseLock.release();\n        }\n    }\n\n    /**\n     * Starts a background thread and its {@link Handler}.\n     */\n    private void startBackgroundThread() {\n        backgroundThread = new HandlerThread(\"ImageListener\");\n        backgroundThread.start();\n        backgroundHandler = new Handler(backgroundThread.getLooper());\n    }\n\n    /**\n     * Stops the background thread and its {@link Handler}.\n     */\n    private void stopBackgroundThread() {\n        backgroundThread.quitSafely();\n        try {\n            backgroundThread.join();\n            backgroundThread = null;\n            backgroundHandler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    private final CameraCaptureSession.CaptureCallback captureCallback =\n            new CameraCaptureSession.CaptureCallback() {\n                @Override\n                public void onCaptureProgressed(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final CaptureResult partialResult) {\n                }\n\n                @Override\n                public void onCaptureCompleted(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final TotalCaptureResult result) {\n                }\n            };\n\n    /**\n     * Creates a new {@link CameraCaptureSession} for camera preview.\n     */\n    private void createCameraPreviewSession() {\n        try {\n            final SurfaceTexture texture = textureView.getSurfaceTexture();\n            assert texture != null;\n\n            // We configure the size of default buffer to be the size of camera preview we want.\n            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());\n\n            // This is the output Surface we need to start preview.\n            final Surface surface = new Surface(texture);\n\n            // We set up a CaptureRequest.Builder with the output Surface.\n            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\n            previewRequestBuilder.addTarget(surface);\n\n            Log.i(TAG, \"Opening camera preview: \" + previewSize.getWidth() + \"x\" + previewSize.getHeight());\n\n            // Create the reader for the preview frames.\n            previewReader =\n                    ImageReader.newInstance(\n                            previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);\n\n            previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);\n            previewRequestBuilder.addTarget(previewReader.getSurface());\n\n            // Here, we create a CameraCaptureSession for camera preview.\n            cameraDevice.createCaptureSession(\n                    Arrays.asList(surface, previewReader.getSurface()),\n                    new CameraCaptureSession.StateCallback() {\n\n                        @Override\n                        public void onConfigured(final CameraCaptureSession cameraCaptureSession) {\n                            // The camera is already closed\n                            if (null == cameraDevice) {\n                                return;\n                            }\n\n                            // When the session is ready, we start displaying the preview.\n                            captureSession = cameraCaptureSession;\n                            try {\n                                // Auto focus should be continuous for camera preview.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AF_MODE,\n                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\n                                // Flash is automatically enabled when necessary.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);\n\n                                // Finally, we start displaying the camera preview.\n                                previewRequest = previewRequestBuilder.build();\n                                captureSession.setRepeatingRequest(\n                                        previewRequest, captureCallback, backgroundHandler);\n                            } catch (final CameraAccessException e) {\n                                Log.e(TAG, \"Exception!\" + e);\n                            }\n                        }\n\n                        @Override\n                        public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {\n                            showToast(\"Failed\");\n                        }\n                    },\n                    null);\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    /**\n     * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.\n     * This method should be called after the camera preview size is determined in\n     * setUpCameraOutputs and also the size of `mTextureView` is fixed.\n     *\n     * @param viewWidth  The width of `mTextureView`\n     * @param viewHeight The height of `mTextureView`\n     */\n    private void configureTransform(final int viewWidth, final int viewHeight) {\n        final Activity activity = getActivity();\n        if (null == textureView || null == previewSize || null == activity) {\n            return;\n        }\n        final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();\n        final Matrix matrix = new Matrix();\n        final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);\n        final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());\n        final float centerX = viewRect.centerX();\n        final float centerY = viewRect.centerY();\n        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {\n            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());\n            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);\n            final float scale =\n                    Math.max(\n                            (float) viewHeight / previewSize.getHeight(),\n                            (float) viewWidth / previewSize.getWidth());\n            matrix.postScale(scale, scale, centerX, centerY);\n            matrix.postRotate(90 * (rotation - 2), centerX, centerY);\n        } else if (Surface.ROTATION_180 == rotation) {\n            matrix.postRotate(180, centerX, centerY);\n        }\n        textureView.setTransform(matrix);\n    }\n\n    /**\n     * Compares two {@code Size}s based on their areas.\n     */\n    static class CompareSizesByArea implements Comparator<Size> {\n        @Override\n        public int compare(final Size lhs, final Size rhs) {\n            // We cast here to ensure the multiplications won't overflow\n            return Long.signum(\n                    (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());\n        }\n    }\n\n    /**\n     * Shows an error message dialog.\n     */\n    public static class ErrorDialog extends DialogFragment {\n        private static final String ARG_MESSAGE = \"message\";\n\n        public static ErrorDialog newInstance(final String message) {\n            final ErrorDialog dialog = new ErrorDialog();\n            final Bundle args = new Bundle();\n            args.putString(ARG_MESSAGE, message);\n            dialog.setArguments(args);\n            return dialog;\n        }\n\n        @Override\n        public Dialog onCreateDialog(final Bundle savedInstanceState) {\n            final Activity activity = getActivity();\n            return new AlertDialog.Builder(activity)\n                    .setMessage(getArguments().getString(ARG_MESSAGE))\n                    .setPositiveButton(\n                            android.R.string.ok,\n                            new DialogInterface.OnClickListener() {\n                                @Override\n                                public void onClick(final DialogInterface dialogInterface, final int i) {\n                                    activity.finish();\n                                }\n                            })\n                    .create();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/java/ai/fritz/replaceBackground/MainActivity.java",
    "content": "package ai.fritz.replaceBackground;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.media.ExifInterface;\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.provider.MediaStore;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.ProgressBar;\nimport android.widget.RelativeLayout;\nimport android.widget.Toast;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.core.Fritz;\nimport ai.fritz.core.utils.BitmapUtils;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\nimport ai.fritz.vision.ImageRotation;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictorOptions;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationResult;\nimport ai.fritz.vision.imagesegmentation.MaskClass;\nimport ai.fritz.vision.imagesegmentation.SegmentationOnDeviceModel;\n\n\npublic class MainActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n    private static final String TAG = MainActivity.class.getSimpleName();\n    private static final int SELECT_IMAGE = 1;\n\n    private AtomicBoolean shouldSample = new AtomicBoolean(true);\n    private FritzVisionSegmentationPredictor predictor;\n    private ImageOrientation orientation;\n\n    private FritzVisionSegmentationResult segmentResult;\n    private FritzVisionImage visionImage;\n\n    Button snapshotButton;\n    Button selectBackgroundBtn;\n    RelativeLayout previewLayout;\n    RelativeLayout snapshotLayout;\n    OverlayView snapshotOverlay;\n    ProgressBar snapshotProcessingSpinner;\n    Button closeButton;\n\n    private Bitmap backgroundBitmap;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Fritz.configure(getApplicationContext(), \"bbe75c73f8b24e63bc05bf81ed9d2829\");\n\n        SegmentationOnDeviceModel onDeviceModel = FritzVisionModels.getPeopleSegmentationOnDeviceModel(ModelVariant.ACCURATE);\n        FritzVisionSegmentationPredictorOptions options = new FritzVisionSegmentationPredictorOptions();\n        options.confidenceThreshold = .4f;\n        predictor = FritzVision.ImageSegmentation.getPredictor(onDeviceModel, options);\n    }\n\n    @Override\n    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\n        super.onActivityResult(requestCode, resultCode, data);\n\n\n        if (requestCode != SELECT_IMAGE) {\n            return;\n        }\n        if (resultCode == Activity.RESULT_CANCELED) {\n            Toast.makeText(this, \"Canceled\", Toast.LENGTH_SHORT).show();\n            return;\n        }\n\n        if (resultCode == Activity.RESULT_OK) {\n            if (data == null) {\n                return;\n            }\n            try {\n                Uri selectedPicture = data.getData();\n                Log.d(TAG, \"IMAGE CHOSEN: \" + selectedPicture);\n\n                InputStream inputStream = getContentResolver().openInputStream(selectedPicture);\n                ExifInterface exif = new ExifInterface(inputStream);\n                int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);\n\n                backgroundBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedPicture);\n\n                switch (orientation) {\n                    case ExifInterface.ORIENTATION_ROTATE_90:\n                        backgroundBitmap = BitmapUtils.rotate(backgroundBitmap, 0);\n                    case ExifInterface.ORIENTATION_ROTATE_180:\n                        backgroundBitmap = BitmapUtils.rotate(backgroundBitmap, 270);\n                    case ExifInterface.ORIENTATION_ROTATE_270:\n                        backgroundBitmap = BitmapUtils.rotate(backgroundBitmap, 180);\n                }\n\n            } catch (IOException e) {\n                throw new RuntimeException(e);\n            }\n        }\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.camera_connection_fragment_background_replace;\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size size, final Size cameraSize, final int rotation) {\n        orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n\n        snapshotButton = findViewById(R.id.take_picture_btn);\n        previewLayout = findViewById(R.id.preview_frame);\n        snapshotLayout = findViewById(R.id.snapshot_frame);\n        snapshotOverlay = findViewById(R.id.snapshot_view);\n        closeButton = findViewById(R.id.close_btn);\n        snapshotProcessingSpinner = findViewById(R.id.snapshotProcessingSpinner);\n        selectBackgroundBtn = findViewById(R.id.selectBackgroundBtn);\n\n        snapshotOverlay.setCallback(new OverlayView.DrawCallback() {\n            @Override\n            public void drawCallback(final Canvas canvas) {\n\n                // If the prediction has not run\n                if (segmentResult == null) {\n                    return;\n                }\n\n                // Show the people segmentation result when the background hasn't been chosen.\n                if (backgroundBitmap == null) {\n                    Bitmap personMask = segmentResult.buildSingleClassMask(MaskClass.PERSON, 180, .5f, .5f);\n                    Bitmap result = visionImage.overlay(personMask);\n                    Bitmap scaledBitmap = BitmapUtils.resize(result, cameraSize.getWidth(), cameraSize.getHeight());\n                    canvas.drawBitmap(scaledBitmap, new Matrix(), new Paint());\n                    return;\n                }\n\n                // Show the background replacement\n                Bitmap scaledBackgroundBitmap = BitmapUtils.resize(backgroundBitmap, cameraSize.getWidth(), cameraSize.getHeight());\n                canvas.drawBitmap(scaledBackgroundBitmap, new Matrix(), new Paint());\n\n                // Draw the masked bitmap\n                long startTime = System.currentTimeMillis();\n                // Use a max alpha of 255 so that there isn't any transparency in the mask.\n                Bitmap maskedBitmap = segmentResult.buildSingleClassMask(MaskClass.PERSON, 255, .5f, .5f);\n                Bitmap croppedMask = visionImage.mask(maskedBitmap, true);\n                Log.d(TAG, \"Masked bitmap took \" + (System.currentTimeMillis() - startTime) + \"ms to create.\");\n\n                if (croppedMask != null) {\n                    // Scale the result\n                    float scaleWidth = ((float) cameraSize.getWidth()) / croppedMask.getWidth();\n                    float scaleHeight = ((float) cameraSize.getWidth()) / croppedMask.getHeight();\n\n                    final Matrix matrix = new Matrix();\n                    float scale = Math.min(scaleWidth, scaleHeight);\n                    matrix.postScale(scale, scale);\n\n                    Bitmap scaledMaskBitmap = Bitmap.createBitmap(croppedMask, 0, 0, croppedMask.getWidth(), croppedMask.getHeight(), matrix, false);\n                    // Print the background bitmap with the masked bitmap\n                    // Center the masked bitmap at the bottom of the image.\n                    canvas.drawBitmap(scaledMaskBitmap, (cameraSize.getWidth() - scaledMaskBitmap.getWidth()) / 2, cameraSize.getHeight() - scaledMaskBitmap.getHeight(), new Paint());\n                }\n            }\n        });\n\n        snapshotButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                if (!shouldSample.compareAndSet(true, false)) {\n                    return;\n                }\n\n                snapshotOverlay.postInvalidate();\n\n                runInBackground(\n                        new Runnable() {\n                            @Override\n                            public void run() {\n                                showSpinner();\n                                segmentResult = predictor.predict(visionImage);\n                                showSnapshotLayout();\n                                hideSpinner();\n                                snapshotOverlay.postInvalidate();\n                            }\n                        });\n            }\n        });\n\n\n        selectBackgroundBtn.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                Intent intent = new Intent();\n                intent.setType(\"image/*\");\n                intent.setAction(Intent.ACTION_GET_CONTENT);\n                startActivityForResult(Intent.createChooser(intent, \"Select Picture\"), SELECT_IMAGE);\n            }\n        });\n\n        closeButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                showPreviewLayout();\n                shouldSample.set(true);\n                backgroundBitmap = null;\n            }\n        });\n    }\n\n    private void showSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void hideSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.GONE);\n            }\n        });\n    }\n\n    private void showSnapshotLayout() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                previewLayout.setVisibility(View.GONE);\n                snapshotLayout.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void showPreviewLayout() {\n        previewLayout.setVisibility(View.VISIBLE);\n        snapshotLayout.setVisibility(View.GONE);\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!shouldSample.get()) {\n            image.close();\n            return;\n        }\n\n        visionImage = FritzVisionImage.fromMediaImage(image, orientation);\n        image.close();\n    }\n}"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/java/ai/fritz/replaceBackground/OverlayView.java",
    "content": "package ai.fritz.replaceBackground;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.util.AttributeSet;\nimport android.view.View;\n\n/**\n * A simple View providing a render callback to other classes.\n */\npublic class OverlayView extends View {\n    private DrawCallback callback;\n\n    public OverlayView(final Context context, final AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    /**\n     * Interface defining the callback for client classes.\n     */\n    public interface DrawCallback {\n        public void drawCallback(final Canvas canvas);\n    }\n\n    public void setCallback(final DrawCallback callback) {\n        this.callback = callback;\n    }\n\n    @Override\n    public synchronized void draw(final Canvas canvas) {\n        super.draw(canvas);\n        if(callback != null) {\n            callback.drawCallback(canvas);\n        }\n    }\n}"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/drawable/ic_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24.0\"\n    android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        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\"/>\n</vector>"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/drawable/round_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\">\n    <stroke\n        android:color=\"#FFFF\"\n        android:width=\"5dip\"/>\n    <size android:width=\"100dp\" android:height=\"100dp\"/>\n</shape>"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/layout/activity_main.xml",
    "content": "<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <FrameLayout\n        android:id=\"@+id/camera_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</android.support.constraint.ConstraintLayout>"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/layout/camera_connection_fragment_background_replace.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n Copyright 2016 The TensorFlow Authors. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:id=\"@+id/preview_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <ai.fritz.replaceBackground.AutoFitTextureView\n            android:id=\"@+id/texture\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\" />\n\n        <ai.fritz.replaceBackground.OverlayView\n            android:id=\"@+id/debug_overlay\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\" />\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginTop=\"@dimen/margin_sm\"\n            android:layout_marginBottom=\"@dimen/margin_lg\">\n\n            <Button\n                android:id=\"@+id/take_picture_btn\"\n                android:layout_width=\"80dp\"\n                android:layout_height=\"80dp\"\n                android:layout_centerInParent=\"true\"\n                android:background=\"@drawable/round_button\"\n                android:textColor=\"#fff\" />\n\n            <ProgressBar\n                android:id=\"@+id/snapshotProcessingSpinner\"\n                style=\"?android:attr/progressBarStyleLarge\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerInParent=\"true\"\n                android:indeterminateTint=\"#fff\"\n                android:visibility=\"gone\" />\n        </RelativeLayout>\n    </RelativeLayout>\n\n    <RelativeLayout\n        android:id=\"@+id/snapshot_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\">\n\n        <ai.fritz.replaceBackground.OverlayView\n            android:id=\"@+id/snapshot_view\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\" />\n\n        <Button\n            android:id=\"@+id/selectBackgroundBtn\"\n            android:text=\"Replace Background\"\n            android:textAlignment=\"gravity\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:background=\"@color/colorPrimary\"\n            android:paddingTop=\"15dp\"\n            android:paddingBottom=\"15dp\"\n            android:textStyle=\"bold\"\n            android:textColor=\"#fff\" />\n\n        <Button\n            android:id=\"@+id/close_btn\"\n            android:layout_width=\"50dp\"\n            android:layout_height=\"50dp\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_alignParentRight=\"true\"\n            android:layout_marginTop=\"@dimen/margin_sm\"\n            android:layout_marginRight=\"@dimen/margin_sm\"\n            android:background=\"@drawable/ic_close\" />\n\n    </RelativeLayout>\n\n\n</RelativeLayout>\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/values/dimen.xml",
    "content": "<!--\n  Copyright 2013 The Android Open Source Project\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n\n<resources>\n\n    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->\n\n    <dimen name=\"margin_xs\">4dp</dimen>\n    <dimen name=\"margin_sm\">8dp</dimen>\n    <dimen name=\"margin_md\">16dp</dimen>\n    <dimen name=\"margin_lg\">32dp</dimen>\n    <dimen name=\"margin_xl\">64dp</dimen>\n\n    <!-- Semantic definitions -->\n\n    <dimen name=\"horizontal_page_margin\">@dimen/margin_md</dimen>\n    <dimen name=\"vertical_page_margin\">@dimen/margin_md</dimen>\n\n</resources>"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Background Changer</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n</resources>\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.1.4'\n\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n\n        // ADD FOR FRITZ DEPENDENCIES\n        maven { url \"https://fritz.mycloudrepo.io/public/repositories/android\" }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/BackgroundReplacementApp/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea\n\n# Keystore files\n# Uncomment the following line if you do not want to check your keystore files in.\n#*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n# fastlane\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\nfastlane/readme.md\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/README.md",
    "content": "# Camera Boilerplate\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nWe've created this simple camera app to make it easier for developers to try out ML models using the Camera 2 API.\n\nFor a full list of tutorials, please visit our [examples and tutorials page](https://www.fritz.ai/resources/tutorials.html).\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Android Studio 3.2 or above\n- Android device in developer model (USB debugging enabled)\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nRegister the Android app in your Fritz account with the package id \"ai.fritz.camera\". During registration, you'll receive an API key for the app. Save this for later. To find it in the webapp, you can go to Project Settings > Apps > Your App > Show API Key.\n\n**Step 2: Clone / Fork the fritz-examples repository and open the camera app in Android Studio**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\nIn Android Studio, choose \"Open an existing Android Studio project\" and select `skeleton-live-video-app`.\n\n**Step 3: Edit the fritz.xml file with your API Key**\n\nIn app/src/main/res/values/fritz.xml, change the fritz_api_key attribute with the one you received in step 1.\n\n**Step 4: Build the Android Studio Project**\n\nSelect \"Build > Make Project\" from the top nav. Download any missing libraries if applicable. This should sync the gradle dependencies so give the build a second to complete.\n\n**Step 5: Install the app onto your device**\n\nWith your Android device connected, select `Run > Run App` from the top nav. You should see a simple camera app for you to play around with.\n\nIn future tutorials, we'll use this as a starting point in order to run the model on each camera frame and show the result.\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 28\n    defaultConfig {\n        // MUST MATCH THE APPLICATION YOU CREATE IN FRITZ\n        applicationId \"ai.fritz.camera\"\n        minSdkVersion 21\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n}\n\ndependencies {\n    implementation 'com.android.support:appcompat-v7:28.0.0'\n    implementation 'com.android.support.constraint:constraint-layout:1.1.3'\n\n    implementation \"ai.fritz:core:6.0.3\"\n    implementation \"ai.fritz:vision:6.0.3\"\n\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'com.android.support.test:runner:1.0.2'\n    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'\n}\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/androidTest/java/ai/fritz/camera/ExampleInstrumentedTest.java",
    "content": "package ai.fritz.camera;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"ai.fritz.camera\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.camera\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/java/ai/fritz/camera/AutoFitTextureView.java",
    "content": "package ai.fritz.camera;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.TextureView;\n\n/**\n * A {@link TextureView} that can be adjusted to a specified aspect ratio.\n */\npublic class AutoFitTextureView extends TextureView {\n    private int ratioWidth = 0;\n    private int ratioHeight = 0;\n\n    public AutoFitTextureView(final Context context) {\n        this(context, null);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    /**\n     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio\n     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that\n     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.\n     *\n     * @param width  Relative horizontal size\n     * @param height Relative vertical size\n     */\n    public void setAspectRatio(final int width, final int height) {\n        if (width < 0 || height < 0) {\n            throw new IllegalArgumentException(\"Size cannot be negative.\");\n        }\n        ratioWidth = width;\n        ratioHeight = height;\n        requestLayout();\n    }\n}"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/java/ai/fritz/camera/BaseCameraActivity.java",
    "content": "package ai.fritz.camera;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.support.v7.app.AppCompatActivity;\nimport android.util.DisplayMetrics;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.KeyEvent;\nimport android.view.WindowManager;\nimport android.widget.Toast;\n\n\npublic abstract class BaseCameraActivity extends AppCompatActivity implements OnImageAvailableListener {\n    private static final String TAG = BaseCameraActivity.class.getSimpleName();\n    private static int MAX_WIDTH = 500;\n    private static final int PERMISSIONS_REQUEST = 1;\n\n    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;\n    private boolean useCamera2API;\n\n    private boolean debug = false;\n\n    private Handler handler;\n    private HandlerThread handlerThread;\n\n    protected String cameraId;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        Log.d(TAG, \"onCreate \" + this);\n        super.onCreate(null);\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        setContentView(R.layout.activity_main);\n\n        if (hasPermission()) {\n            setFragment();\n        } else {\n            requestPermission();\n        }\n    }\n\n    @Override\n    public synchronized void onStart() {\n        Log.d(TAG, \"onStart \" + this);\n        super.onStart();\n    }\n\n    @Override\n    public synchronized void onResume() {\n        Log.d(TAG, \"onResume \" + this);\n        super.onResume();\n\n        handlerThread = new HandlerThread(\"inference\");\n        handlerThread.start();\n        handler = new Handler(handlerThread.getLooper());\n    }\n\n    @Override\n    public synchronized void onPause() {\n        Log.d(TAG, \"onPause \" + this);\n\n        if (!isFinishing()) {\n            Log.d(TAG, \"Requesting finish\");\n            finish();\n        }\n\n        handlerThread.quitSafely();\n        try {\n            handlerThread.join();\n            handlerThread = null;\n            handler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n\n        super.onPause();\n    }\n\n    @Override\n    public synchronized void onStop() {\n        Log.d(TAG, \"onStop \" + this);\n        super.onStop();\n    }\n\n    @Override\n    public synchronized void onDestroy() {\n        Log.d(TAG, \"onDestroy \" + this);\n        super.onDestroy();\n    }\n\n    protected synchronized void runInBackground(final Runnable r) {\n        if (handler != null) {\n            handler.post(r);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(\n            final int requestCode, final String[] permissions, final int[] grantResults) {\n        switch (requestCode) {\n            case PERMISSIONS_REQUEST: {\n                if (grantResults.length > 0\n                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {\n                    setFragment();\n                } else {\n                    requestPermission();\n                }\n            }\n        }\n    }\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            int permission = checkSelfPermission(PERMISSION_CAMERA);\n            return permission == PackageManager.PERMISSION_GRANTED;\n        } else {\n            return true;\n        }\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA)) {\n                Toast.makeText(BaseCameraActivity.this, \"Camera permission are required for this demo\", Toast.LENGTH_LONG).show();\n            }\n            requestPermissions(new String[]{PERMISSION_CAMERA}, PERMISSIONS_REQUEST);\n        }\n    }\n\n    protected void setFragment() {\n        cameraId = chooseCamera();\n        final CameraConnectionFragment fragment =\n                CameraConnectionFragment.newInstance(\n                        new CameraConnectionFragment.ConnectionCallback() {\n                            @Override\n                            public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n                                BaseCameraActivity.this.onPreviewSizeChosen(previewSize, cameraViewSize, rotation);\n                            }\n                        },\n                        this,\n                        getLayoutId(),\n                        getDesiredPreviewFrameSize());\n\n        fragment.setCamera(cameraId);\n\n        getFragmentManager()\n                .beginTransaction()\n                .replace(R.id.camera_container, fragment)\n                .commit();\n    }\n\n    private String chooseCamera() {\n        final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);\n        try {\n            for (final String cameraId : manager.getCameraIdList()) {\n                final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n                // We don't use a front facing camera in this sample.\n                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);\n                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {\n                    continue;\n                }\n\n                final StreamConfigurationMap map =\n                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n                if (map == null) {\n                    continue;\n                }\n\n                // Fallback to camera1 API for internal cameras that don't have full support.\n                // This should help with legacy situations where using the camera2 API causes\n                // distorted or otherwise broken previews.\n                useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)\n                        || isHardwareLevelSupported(characteristics,\n                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);\n                Log.i(TAG, \"Camera API lv2?: \" + useCamera2API);\n                return cameraId;\n            }\n        } catch (CameraAccessException e) {\n            Log.e(TAG, \"Not allowed to access camera: \" + e);\n        }\n\n        return null;\n    }\n\n    // Returns true if the device supports the required hardware level, or better.\n    private boolean isHardwareLevelSupported(\n            CameraCharacteristics characteristics, int requiredLevel) {\n        int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);\n        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {\n            return requiredLevel == deviceLevel;\n        }\n        // deviceLevel is not LEGACY, can use numerical sort\n        return requiredLevel <= deviceLevel;\n    }\n\n\n    public boolean isDebug() {\n        return debug;\n    }\n\n    public void requestRender() {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.postInvalidate();\n        }\n    }\n\n    public void setCallback(final OverlayView.DrawCallback callback) {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.setCallback(callback);\n        }\n    }\n\n    public void onSetDebug(final boolean debug) {\n    }\n\n    @Override\n    public boolean onKeyDown(final int keyCode, final KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {\n            debug = !debug;\n            requestRender();\n            onSetDebug(debug);\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    protected abstract void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation);\n\n    protected abstract int getLayoutId();\n\n    protected Size getDesiredPreviewFrameSize() {\n        DisplayMetrics metrics = getResources().getDisplayMetrics();\n        float ratio = (float) metrics.heightPixels / metrics.widthPixels;\n        return new Size(MAX_WIDTH, (int) ratio * MAX_WIDTH);\n    }\n}\n\n\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/java/ai/fritz/camera/CameraConnectionFragment.java",
    "content": "package ai.fritz.camera;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.app.DialogFragment;\nimport android.app.Fragment;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.graphics.ImageFormat;\nimport android.graphics.Matrix;\nimport android.graphics.RectF;\nimport android.graphics.SurfaceTexture;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCaptureSession;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraDevice;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.CaptureRequest;\nimport android.hardware.camera2.CaptureResult;\nimport android.hardware.camera2.TotalCaptureResult;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.LayoutInflater;\nimport android.view.Surface;\nimport android.view.TextureView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\n\n\n\npublic class CameraConnectionFragment extends Fragment {\n    private static final String TAG = CameraConnectionFragment.class.getSimpleName();\n\n    public CameraConnectionFragment() {\n\n    }\n\n    /**\n     * The camera preview size will be chosen to be the smallest frame by pixel size capable of\n     * containing a DESIRED_SIZE x DESIRED_SIZE square.\n     */\n    private static final int MINIMUM_PREVIEW_SIZE = 320;\n\n    /**\n     * Conversion from screen rotation to JPEG orientation.\n     */\n    private static final String FRAGMENT_DIALOG = \"dialog\";\n\n    /**\n     * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a\n     * {@link TextureView}.\n     */\n    private final TextureView.SurfaceTextureListener surfaceTextureListener =\n            new TextureView.SurfaceTextureListener() {\n                @Override\n                public void onSurfaceTextureAvailable(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    openCamera(width, height);\n                }\n\n                @Override\n                public void onSurfaceTextureSizeChanged(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    configureTransform(width, height);\n                }\n\n                @Override\n                public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {\n                    return true;\n                }\n\n                @Override\n                public void onSurfaceTextureUpdated(final SurfaceTexture texture) {\n                }\n            };\n\n    /**\n     * Callback for Activities to use to initialize their data once the\n     * selected preview size is known.\n     */\n    public interface ConnectionCallback {\n        void onPreviewSizeChosen(Size size, Size cameraViewSize, int cameraRotation);\n    }\n\n    /**\n     * ID of the current {@link CameraDevice}.\n     */\n    private String cameraId;\n\n    /**\n     * An {@link AutoFitTextureView} for camera preview.\n     */\n    private AutoFitTextureView textureView;\n\n    /**\n     * A {@link CameraCaptureSession } for camera preview.\n     */\n    private CameraCaptureSession captureSession;\n\n    /**\n     * A reference to the opened {@link CameraDevice}.\n     */\n    private CameraDevice cameraDevice;\n\n    /**\n     * The rotation in degrees of the camera sensor from the display.\n     */\n    private Integer sensorOrientation;\n\n    /**\n     * The {@link android.util.Size} of camera preview.\n     */\n    private Size previewSize;\n\n    /**\n     * {@link android.hardware.camera2.CameraDevice.StateCallback}\n     * is called when {@link CameraDevice} changes its state.\n     */\n    private final CameraDevice.StateCallback stateCallback =\n            new CameraDevice.StateCallback() {\n                @Override\n                public void onOpened(final CameraDevice cd) {\n                    // This method is called when the camera is opened.  We start camera preview here.\n                    cameraOpenCloseLock.release();\n                    cameraDevice = cd;\n                    createCameraPreviewSession();\n                }\n\n                @Override\n                public void onDisconnected(final CameraDevice cd) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                }\n\n                @Override\n                public void onError(final CameraDevice cd, final int error) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                    final Activity activity = getActivity();\n                    if (null != activity) {\n                        activity.finish();\n                    }\n                }\n            };\n\n    /**\n     * An additional thread for running tasks that shouldn't block the UI.\n     */\n    private HandlerThread backgroundThread;\n\n    /**\n     * A {@link Handler} for running tasks in the background.\n     */\n    private Handler backgroundHandler;\n\n    /**\n     * An {@link ImageReader} that handles preview frame capture.\n     */\n    private ImageReader previewReader;\n\n    /**\n     * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview\n     */\n    private CaptureRequest.Builder previewRequestBuilder;\n\n    /**\n     * {@link CaptureRequest} generated by {@link #previewRequestBuilder}\n     */\n    private CaptureRequest previewRequest;\n\n    /**\n     * A {@link Semaphore} to prevent the app from exiting before closing the camera.\n     */\n    private final Semaphore cameraOpenCloseLock = new Semaphore(1);\n\n    /**\n     * A {@link OnImageAvailableListener} to receive frames as they are available.\n     */\n    private OnImageAvailableListener imageListener = null;\n\n    /**\n     * The input size in pixels desired by TensorFlow (width and height of a square bitmap).\n     */\n    private Size inputSize = null;\n\n    /**\n     * The layout identifier to inflate for this Fragment.\n     */\n    private int layout = -1;\n\n\n    private ConnectionCallback cameraConnectionCallback = null;\n\n    private CameraConnectionFragment(\n            final ConnectionCallback connectionCallback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        this.cameraConnectionCallback = connectionCallback;\n        this.imageListener = imageListener;\n        this.layout = layout;\n        this.inputSize = inputSize;\n    }\n\n    /**\n     * Shows a {@link Toast} on the UI thread.\n     *\n     * @param text The message to show\n     */\n    private void showToast(final String text) {\n        final Activity activity = getActivity();\n        if (activity != null) {\n            activity.runOnUiThread(\n                    new Runnable() {\n                        @Override\n                        public void run() {\n                            Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();\n                        }\n                    });\n        }\n    }\n\n    /**\n     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose\n     * width and height are at least as large as the minimum of both, or an exact match if possible.\n     *\n     * @param choices The list of sizes that the camera supports for the intended output class\n     * @param width   The minimum desired width\n     * @param height  The minimum desired height\n     * @return The optimal {@code Size}, or an arbitrary one if none were big enough\n     */\n    protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {\n        final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);\n        final Size desiredSize = new Size(width, height);\n\n        // Collect the supported resolutions that are at least as big as the preview Surface\n        boolean exactSizeFound = false;\n        final List<Size> bigEnough = new ArrayList<Size>();\n        final List<Size> tooSmall = new ArrayList<Size>();\n        for (final Size option : choices) {\n            if (option.equals(desiredSize)) {\n                // Set the size but don't return yet so that remaining sizes will still be logged.\n                exactSizeFound = true;\n            }\n\n            if (option.getHeight() >= minSize && option.getWidth() >= minSize) {\n                bigEnough.add(option);\n            } else {\n                tooSmall.add(option);\n            }\n        }\n\n        Log.d(TAG, \"Desired size: \" + desiredSize + \", min size: \" + minSize + \"x\" + minSize);\n        Log.d(TAG, \"Valid preview sizes: [\" + TextUtils.join(\", \", bigEnough) + \"]\");\n        Log.d(TAG, \"Rejected preview sizes: [\" + TextUtils.join(\", \", tooSmall) + \"]\");\n\n        if (exactSizeFound) {\n            Log.d(TAG, \"Exact size match found.\");\n            return desiredSize;\n        }\n\n        // Pick the smallest of those, assuming we found any\n        if (bigEnough.size() > 0) {\n            final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());\n            Log.d(TAG, \"Chosen size: \" + chosenSize.getWidth() + \"x\" + chosenSize.getHeight());\n            return chosenSize;\n        } else {\n            Log.e(TAG, \"Couldn't find any suitable preview size\");\n            return choices[0];\n        }\n    }\n\n    public static CameraConnectionFragment newInstance(\n            final ConnectionCallback callback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        return new CameraConnectionFragment(callback, imageListener, layout, inputSize);\n    }\n\n    @Override\n    public View onCreateView(\n            final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {\n        return inflater.inflate(layout, container, false);\n    }\n\n    @Override\n    public void onViewCreated(final View view, final Bundle savedInstanceState) {\n        textureView = (AutoFitTextureView) view.findViewById(R.id.texture);\n    }\n\n    @Override\n    public void onActivityCreated(final Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        startBackgroundThread();\n\n        // When the screen is turned off and turned back on, the SurfaceTexture is already\n        // available, and \"onSurfaceTextureAvailable\" will not be called. In that case, we can open\n        // a camera and start preview from here (otherwise, we wait until the surface is ready in\n        // the SurfaceTextureListener).\n        if (textureView.isAvailable()) {\n            openCamera(textureView.getWidth(), textureView.getHeight());\n        } else {\n            textureView.setSurfaceTextureListener(surfaceTextureListener);\n        }\n    }\n\n    @Override\n    public void onPause() {\n        closeCamera();\n        stopBackgroundThread();\n        super.onPause();\n    }\n\n    public void setCamera(String cameraId) {\n        this.cameraId = cameraId;\n    }\n\n    /**\n     * Sets up member variables related to camera.\n     */\n    private void setUpCameraOutputs() {\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n            final StreamConfigurationMap map =\n                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n            // For still image captures, we use the largest available size.\n            final Size largest =\n                    Collections.max(\n                            Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),\n                            new CompareSizesByArea());\n\n            sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);\n\n            // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera\n            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of\n            // garbage capture data.\n            previewSize =\n                    chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),\n                            inputSize.getWidth(),\n                            inputSize.getHeight());\n        } catch (final CameraAccessException e) {\n            Log.e(TAG,  \"Exception!\" + e);\n        } catch (final NullPointerException e) {\n            // Currently an NPE is thrown when the Camera2API is used but not supported on the\n            // device this code runs.\n            // TODO(andrewharp): abstract ErrorDialog/RuntimeException handling out into new method and\n            // reuse throughout app.\n            ErrorDialog.newInstance(getString(R.string.camera_error))\n                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);\n            throw new RuntimeException(getString(R.string.camera_error));\n        }\n\n        Size textureViewSize = new Size(textureView.getWidth(), textureView.getHeight());\n        cameraConnectionCallback.onPreviewSizeChosen(previewSize, textureViewSize, sensorOrientation);\n    }\n\n    /**\n     * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.\n     */\n    private void openCamera(final int width, final int height) {\n        setUpCameraOutputs();\n        configureTransform(width, height);\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\n                throw new RuntimeException(\"Time out waiting to lock camera opening.\");\n            }\n            manager.openCamera(cameraId, stateCallback, backgroundHandler);\n        } catch (final CameraAccessException | SecurityException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\n        }\n    }\n\n    /**\n     * Closes the current {@link CameraDevice}.\n     */\n    private void closeCamera() {\n        try {\n            cameraOpenCloseLock.acquire();\n            if (null != captureSession) {\n                captureSession.close();\n                captureSession = null;\n            }\n            if (null != cameraDevice) {\n                cameraDevice.close();\n                cameraDevice = null;\n            }\n            if (null != previewReader) {\n                previewReader.close();\n                previewReader = null;\n            }\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera closing.\", e);\n        } finally {\n            cameraOpenCloseLock.release();\n        }\n    }\n\n    /**\n     * Starts a background thread and its {@link Handler}.\n     */\n    private void startBackgroundThread() {\n        backgroundThread = new HandlerThread(\"ImageListener\");\n        backgroundThread.start();\n        backgroundHandler = new Handler(backgroundThread.getLooper());\n    }\n\n    /**\n     * Stops the background thread and its {@link Handler}.\n     */\n    private void stopBackgroundThread() {\n        backgroundThread.quitSafely();\n        try {\n            backgroundThread.join();\n            backgroundThread = null;\n            backgroundHandler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    private final CameraCaptureSession.CaptureCallback captureCallback =\n            new CameraCaptureSession.CaptureCallback() {\n                @Override\n                public void onCaptureProgressed(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final CaptureResult partialResult) {\n                }\n\n                @Override\n                public void onCaptureCompleted(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final TotalCaptureResult result) {\n                }\n            };\n\n    /**\n     * Creates a new {@link CameraCaptureSession} for camera preview.\n     */\n    private void createCameraPreviewSession() {\n        try {\n            final SurfaceTexture texture = textureView.getSurfaceTexture();\n            assert texture != null;\n\n            // We configure the size of default buffer to be the size of camera preview we want.\n            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());\n\n            // This is the output Surface we need to start preview.\n            final Surface surface = new Surface(texture);\n\n            // We set up a CaptureRequest.Builder with the output Surface.\n            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\n            previewRequestBuilder.addTarget(surface);\n\n            Log.i(TAG, \"Opening camera preview: \" + previewSize.getWidth() + \"x\" + previewSize.getHeight());\n\n            // Create the reader for the preview frames.\n            previewReader =\n                    ImageReader.newInstance(\n                            previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);\n\n            previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);\n            previewRequestBuilder.addTarget(previewReader.getSurface());\n\n            // Here, we create a CameraCaptureSession for camera preview.\n            cameraDevice.createCaptureSession(\n                    Arrays.asList(surface, previewReader.getSurface()),\n                    new CameraCaptureSession.StateCallback() {\n\n                        @Override\n                        public void onConfigured(final CameraCaptureSession cameraCaptureSession) {\n                            // The camera is already closed\n                            if (null == cameraDevice) {\n                                return;\n                            }\n\n                            // When the session is ready, we start displaying the preview.\n                            captureSession = cameraCaptureSession;\n                            try {\n                                // Auto focus should be continuous for camera preview.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AF_MODE,\n                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\n                                // Flash is automatically enabled when necessary.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);\n\n                                // Finally, we start displaying the camera preview.\n                                previewRequest = previewRequestBuilder.build();\n                                captureSession.setRepeatingRequest(\n                                        previewRequest, captureCallback, backgroundHandler);\n                            } catch (final CameraAccessException e) {\n                                Log.e(TAG, \"Exception!\" + e);\n                            }\n                        }\n\n                        @Override\n                        public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {\n                            showToast(\"Failed\");\n                        }\n                    },\n                    null);\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    /**\n     * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.\n     * This method should be called after the camera preview size is determined in\n     * setUpCameraOutputs and also the size of `mTextureView` is fixed.\n     *\n     * @param viewWidth  The width of `mTextureView`\n     * @param viewHeight The height of `mTextureView`\n     */\n    private void configureTransform(final int viewWidth, final int viewHeight) {\n        final Activity activity = getActivity();\n        if (null == textureView || null == previewSize || null == activity) {\n            return;\n        }\n        final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();\n        final Matrix matrix = new Matrix();\n        final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);\n        final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());\n        final float centerX = viewRect.centerX();\n        final float centerY = viewRect.centerY();\n        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {\n            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());\n            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);\n            final float scale =\n                    Math.max(\n                            (float) viewHeight / previewSize.getHeight(),\n                            (float) viewWidth / previewSize.getWidth());\n            matrix.postScale(scale, scale, centerX, centerY);\n            matrix.postRotate(90 * (rotation - 2), centerX, centerY);\n        } else if (Surface.ROTATION_180 == rotation) {\n            matrix.postRotate(180, centerX, centerY);\n        }\n        textureView.setTransform(matrix);\n    }\n\n    /**\n     * Compares two {@code Size}s based on their areas.\n     */\n    static class CompareSizesByArea implements Comparator<Size> {\n        @Override\n        public int compare(final Size lhs, final Size rhs) {\n            // We cast here to ensure the multiplications won't overflow\n            return Long.signum(\n                    (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());\n        }\n    }\n\n    /**\n     * Shows an error message dialog.\n     */\n    public static class ErrorDialog extends DialogFragment {\n        private static final String ARG_MESSAGE = \"message\";\n\n        public static ErrorDialog newInstance(final String message) {\n            final ErrorDialog dialog = new ErrorDialog();\n            final Bundle args = new Bundle();\n            args.putString(ARG_MESSAGE, message);\n            dialog.setArguments(args);\n            return dialog;\n        }\n\n        @Override\n        public Dialog onCreateDialog(final Bundle savedInstanceState) {\n            final Activity activity = getActivity();\n            return new AlertDialog.Builder(activity)\n                    .setMessage(getArguments().getString(ARG_MESSAGE))\n                    .setPositiveButton(\n                            android.R.string.ok,\n                            new DialogInterface.OnClickListener() {\n                                @Override\n                                public void onClick(final DialogInterface dialogInterface, final int i) {\n                                    activity.finish();\n                                }\n                            })\n                    .create();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/java/ai/fritz/camera/LiveCameraActivity.java",
    "content": "package ai.fritz.camera;\n\nimport android.graphics.Canvas;\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.os.Bundle;\nimport android.util.Size;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\n\npublic abstract class LiveCameraActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n\n    private static final String TAG = MainActivity.class.getSimpleName();\n\n    private static final Size DESIRED_PREVIEW_SIZE = new Size(1280, 960);\n\n    private AtomicBoolean computing = new AtomicBoolean(false);\n\n    @Override\n    public void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        initializeFritz();\n        setupPredictor();\n    }\n\n    protected abstract void initializeFritz();\n\n    protected abstract void setupPredictor();\n\n    protected abstract void setupImageForPrediction(Image image);\n\n    protected abstract void runInference();\n\n    protected abstract void showResult(Canvas canvas, Size cameraViewSize);\n\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.camera_connection_fragment;\n    }\n\n    @Override\n    protected Size getDesiredPreviewFrameSize() {\n        return DESIRED_PREVIEW_SIZE;\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n\n        // Callback draws a canvas on the OverlayView\n        setCallback(\n                new OverlayView.DrawCallback() {\n                    @Override\n                    public void drawCallback(final Canvas canvas) {\n                        showResult(canvas, cameraViewSize);\n                    }\n                });\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!computing.compareAndSet(false, true)) {\n            image.close();\n            return;\n        }\n\n        setupImageForPrediction(image);\n\n        image.close();\n\n        runInBackground(\n                new Runnable() {\n                    @Override\n                    public void run() {\n\n                        runInference();\n                        // Fire callback to change the OverlayView\n                        requestRender();\n                        computing.set(false);\n                    }\n                });\n    }\n}\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/java/ai/fritz/camera/MainActivity.java",
    "content": "package ai.fritz.camera;\n\nimport android.graphics.Canvas;\nimport android.media.Image;\nimport android.util.Size;\n\n\npublic class MainActivity extends LiveCameraActivity {\n\n    @Override\n    protected void initializeFritz() {\n        // TODO: Uncomment this and modify your api key in fritz.xml.\n        // Fritz.configure(this);\n    }\n\n    @Override\n    protected void setupPredictor() {\n        // STEP 1: Get the predictor and set the options.\n        // ----------------------------------------------\n        // A FritzOnDeviceModel object is available when a model has been\n        // successfully downloaded and included with the app.\n        // TODO: Create a predictor\n        // ----------------------------------------------\n        // END STEP 1\n    }\n\n    @Override\n    protected void setupImageForPrediction(Image image) {\n        // STEP 2: Create the FritzVisionImage object from media.Image\n        // ------------------------------------------------------------------------\n        // TODO: Add code for creating FritzVisionImage from a media.Image object\n        // ------------------------------------------------------------------------\n        // END STEP 2\n    }\n\n    @Override\n    protected void runInference() {\n        // STEP 3: Run predict on the image\n        // ---------------------------------------------------\n        // TODO: Add code for running prediction on the image\n        // ----------------------------------------------------\n        // END STEP 3\n    }\n\n    @Override\n    protected void showResult(Canvas canvas, Size cameraSize) {\n        // STEP 4: Draw the prediction result\n        // ----------------------------------\n        // TODO: Draw the result.\n        // ----------------------------------\n        // END STEP 4\n    }\n}\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/java/ai/fritz/camera/OverlayView.java",
    "content": "package ai.fritz.camera;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.util.AttributeSet;\nimport android.view.View;\n\n/**\n * A simple View providing a render callback to other classes.\n */\npublic class OverlayView extends View {\n    private DrawCallback callback;\n\n    public OverlayView(final Context context, final AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    /**\n     * Interface defining the callback for client classes.\n     */\n    public interface DrawCallback {\n        void drawCallback(final Canvas canvas);\n    }\n\n    public void setCallback(final DrawCallback callback) {\n        this.callback = callback;\n    }\n\n    @Override\n    public synchronized void draw(final Canvas canvas) {\n        super.draw(canvas);\n        if(callback != null) {\n            callback.drawCallback(canvas);\n        }\n    }\n}"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/drawable/ic_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24.0\"\n    android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        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\"/>\n</vector>"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/drawable/round_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\">\n    <stroke\n        android:color=\"#FFFF\"\n        android:width=\"5dip\"/>\n    <size android:width=\"100dp\" android:height=\"100dp\"/>\n</shape>"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/layout/activity_main.xml",
    "content": "<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <FrameLayout\n        android:id=\"@+id/camera_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</android.support.constraint.ConstraintLayout>"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/layout/camera_connection_fragment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <ai.fritz.camera.AutoFitTextureView\n        android:id=\"@+id/texture\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"/>\n\n    <ai.fritz.camera.OverlayView\n        android:id=\"@+id/debug_overlay\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"/>\n</RelativeLayout>\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/layout/camera_connection_fragment_stylize.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <ai.fritz.camera.AutoFitTextureView\n        android:id=\"@+id/texture\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\" />\n\n    <ai.fritz.camera.OverlayView\n        android:id=\"@+id/debug_overlay\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\" />\n</RelativeLayout>\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/values/dimens.xml",
    "content": "<!--\n  Copyright 2013 The Android Open Source Project\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n\n<resources>\n\n    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->\n\n    <dimen name=\"margin_xs\">4dp</dimen>\n    <dimen name=\"margin_sm\">8dp</dimen>\n    <dimen name=\"margin_md\">16dp</dimen>\n    <dimen name=\"margin_lg\">32dp</dimen>\n    <dimen name=\"margin_xl\">64dp</dimen>\n\n    <!-- Semantic definitions -->\n\n    <dimen name=\"horizontal_page_margin\">@dimen/margin_md</dimen>\n    <dimen name=\"vertical_page_margin\">@dimen/margin_md</dimen>\n\n</resources>"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Fritz Camera Template</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n</resources>\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/app/src/test/java/ai/fritz/camera/ExampleUnitTest.java",
    "content": "package ai.fritz.camera;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/CameraBoilerplateApp/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.1.4'\n\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n\n        // ADD FOR FRITZ DEPENDENCIES\n        maven { url \"https://fritz.mycloudrepo.io/public/repositories/android\" }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/CameraBoilerplateApp/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "Android/FritzAIStudio/LICENSE.md",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Android/FritzAIStudio/README.md",
    "content": "# Fritz AI Studio App\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n**Vision API: Prebuilt models that you can simply drop into your apps:**\n\n- [Image Segmentation](https://www.fritz.ai/features/image-segmentation.html): Create pixel level masks of different objects in a scene ([code](app/src/main/java/ai/fritz/aistudio/activities/vision/ImageSegmentationActivity.java))\n- [Image Labeling](https://www.fritz.ai/features/image-labeling.html): Classify different objects in an video or image ([code](app/src/main/java/ai/fritz/aistudio/activities/vision/ImageLabelingActivity.java))\n- [Pose Estimation](https://www.fritz.ai/features/pose-estimation.html): Identify and track a person's body position ([code](app/src/main/java/ai/fritz/aistudio/activities/vision/PoseEstimationActivity.java))\n- [Object Detection](https://www.fritz.ai/features/object-detection.html): Detect multiple objects and track their location ([code](app/src/main/java/ai/fritz/aistudio/activities/vision/ObjectDetectionActivity.java))\n- [Style Transfer](https://www.fritz.ai/features/style-transfer.html): Transform photos and videos into artistic masterpieces ([code](app/src/main/java/ai/fritz/aistudio/activities/vision/StyleTransferActivity.java))\n\n**Custom Models: Deploy, Monitor, and Update your own models:**\n\nWe currently support both TensorFlow Lite and TensorFlow Mobile for Android.\n\n- [Analytics and Monitoring](https://www.fritz.ai/features/analytics-monitoring.html): Monitor machine learning models running on-device with Fritz AI\n- [Model Management](https://www.fritz.ai/features/model-management.html): Iterate on your ML models over-the-air, without having to release your app\n- [Model Protection](https://www.fritz.ai/features/model-protection.html): Use model protection to keep models from being tampered-with or stolen\n\n## Requirements\n\n- Android Studio 3.2 or above\n- Android device in developer model (USB debugging enabled)\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nRegister the Android app in your Fritz account with the package id \"ai.fritz.aistudiobuild\". During registration, you'll receive an API key for the app. Save this for later. To find it in the webapp, you can go to Project Settings > Apps > Your App > Show API Key.\n\n**Step 2: Clone / Fork the fritz-examples repository and open the demo app in Android Studio**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\nIn Android Studio, choose \"Open an existing Android Studio project\" and select `FritzAIStudio`.\n\n**Step 3: Edit the fritz.xml file with your API Key**\n\nIn app/src/main/res/values/fritz.xml, change the fritz_api_key attribute with the one you received in step 1.\n\n**Step 4: Build the Android Studio Project**\n\nSelect \"Build > Make Project\" from the top nav. Download any missing libraries if applicable. This should sync the gradle dependencies so give the build a second to complete.\n\n**Step 5: Install the app onto your device**\n\nWith your Android device connected, select `Run > Run App` from the top nav. After it's installed, select any of the options to try out the different ML features. When running the app for the first time, you'll have to give permissions to access the camera.\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "Android/FritzAIStudio/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\n\nandroid {\n    configurations.all {\n        resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'\n    }\n    compileSdkVersion 28\n    defaultConfig {\n        applicationId \"ai.fritz.aistudiobuild\"\n        minSdkVersion 21\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n    lintOptions {\n        abortOnError false\n    }\n    productFlavors {\n    }\n}\n\ndependencies {\n    implementation 'com.jakewharton:butterknife:8.8.1'\n\n    implementation \"ai.fritz:core:6.0.3\"\n    implementation \"ai.fritz:vision:6.0.3\"\n\n    implementation \"ai.fritz:vision-labeling-model-fast:3.0.0\"\n    implementation \"ai.fritz:vision-object-detection-model-fast:3.0.0\"\n    implementation \"ai.fritz:vision-style-painting-models:3.0.0\"\n    implementation \"ai.fritz:vision-pose-estimation-model-fast:3.0.0\"\n    implementation \"ai.fritz:vision-hair-segmentation-model-fast:3.0.0\"\n\n    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'\n    implementation fileTree(include: ['*.jar'], dir: 'libs')\n    implementation 'com.android.support.constraint:constraint-layout:1.1.2'\n    implementation 'com.android.support:appcompat-v7:28.0.0-rc02'\n    implementation 'com.android.support:recyclerview-v7:28.0.0-rc02'\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'com.android.support.test:runner:1.0.2'\n    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.aistudio\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:largeHeap=\"true\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n\n        <activity\n            android:name=\"ai.fritz.aistudio.activities.SplashActivity\"\n            android:screenOrientation=\"portrait\"\n            android:theme=\"@style/SplashTheme\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n\n            </intent-filter>\n\n        </activity>\n        <activity\n            android:name=\"ai.fritz.aistudio.activities.MainActivity\"\n            android:screenOrientation=\"portrait\"\n            android:theme=\"@style/MainTheme\" />\n        <activity\n            android:name=\"ai.fritz.aistudio.activities.vision.StyleTransferActivity\"\n            android:parentActivityName=\"ai.fritz.aistudio.activities.MainActivity\"\n            android:screenOrientation=\"portrait\"\n            android:theme=\"@style/MainTheme\" />\n        <activity\n            android:name=\"ai.fritz.aistudio.activities.vision.ImageLabelingActivity\"\n            android:parentActivityName=\"ai.fritz.aistudio.activities.MainActivity\"\n            android:screenOrientation=\"portrait\" />\n        <activity\n            android:name=\"ai.fritz.aistudio.activities.vision.ObjectDetectionActivity\"\n            android:parentActivityName=\"ai.fritz.aistudio.activities.MainActivity\"\n            android:screenOrientation=\"portrait\" />\n        <activity\n            android:name=\"ai.fritz.aistudio.activities.vision.ImageSegmentationActivity\"\n            android:parentActivityName=\"ai.fritz.aistudio.activities.MainActivity\"\n            android:screenOrientation=\"portrait\"\n            android:theme=\"@style/MainTheme\" />\n        <activity\n            android:name=\"ai.fritz.aistudio.activities.vision.PoseEstimationActivity\"\n            android:parentActivityName=\"ai.fritz.aistudio.activities.MainActivity\"\n            android:screenOrientation=\"portrait\" />\n        <activity\n            android:name=\"ai.fritz.aistudio.activities.custommodel.CustomTFLiteActivity\"\n            android:parentActivityName=\"ai.fritz.aistudio.activities.MainActivity\" />\n\n        <meta-data\n            android:name=\"fritz_api_key\"\n            android:value=\"@string/fritz_api_key\" />\n\n\n        <service\n            android:name=\"ai.fritz.core.FritzCustomModelService\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/assets/coco_labels_list.txt",
    "content": "???\nperson\nbicycle\ncar\nmotorcycle\nairplane\nbus\ntrain\ntruck\nboat\ntraffic light\nfire hydrant\n???\nstop sign\nparking meter\nbench\nbird\ncat\ndog\nhorse\nsheep\ncow\nelephant\nbear\nzebra\ngiraffe\n???\nbackpack\numbrella\n???\n???\nhandbag\ntie\nsuitcase\nfrisbee\nskis\nsnowboard\nsports ball\nkite\nbaseball bat\nbaseball glove\nskateboard\nsurfboard\ntennis racket\nbottle\n???\nwine glass\ncup\nfork\nknife\nspoon\nbowl\nbanana\napple\nsandwich\norange\nbroccoli\ncarrot\nhot dog\npizza\ndonut\ncake\nchair\ncouch\npotted plant\nbed\n???\ndining table\n???\n???\ntoilet\n???\ntv\nlaptop\nmouse\nremote\nkeyboard\ncell phone\nmicrowave\noven\ntoaster\nsink\nrefrigerator\n???\nbook\nclock\nvase\nscissors\nteddy bear\nhair drier\ntoothbrush\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/assets/imagenet_comp_graph_label_strings.txt",
    "content": "dummy\nkit fox\nEnglish setter\nSiberian husky\nAustralian terrier\nEnglish springer\ngrey whale\nlesser panda\nEgyptian cat\nibex\nPersian cat\ncougar\ngazelle\nporcupine\nsea lion\nmalamute\nbadger\nGreat Dane\nWalker hound\nWelsh springer spaniel\nwhippet\nScottish deerhound\nkiller whale\nmink\nAfrican elephant\nWeimaraner\nsoft-coated wheaten terrier\nDandie Dinmont\nred wolf\nOld English sheepdog\njaguar\notterhound\nbloodhound\nAiredale\nhyena\nmeerkat\ngiant schnauzer\ntiti\nthree-toed sloth\nsorrel\nblack-footed ferret\ndalmatian\nblack-and-tan coonhound\npapillon\nskunk\nStaffordshire bullterrier\nMexican hairless\nBouvier des Flandres\nweasel\nminiature poodle\nCardigan\nmalinois\nbighorn\nfox squirrel\ncolobus\ntiger cat\nLhasa\nimpala\ncoyote\nYorkshire terrier\nNewfoundland\nbrown bear\nred fox\nNorwegian elkhound\nRottweiler\nhartebeest\nSaluki\ngrey fox\nschipperke\nPekinese\nBrabancon griffon\nWest Highland white terrier\nSealyham terrier\nguenon\nmongoose\nindri\ntiger\nIrish wolfhound\nwild boar\nEntleBucher\nzebra\nram\nFrench bulldog\norangutan\nbasenji\nleopard\nBernese mountain dog\nMaltese dog\nNorfolk terrier\ntoy terrier\nvizsla\ncairn\nsquirrel monkey\ngroenendael\nclumber\nSiamese cat\nchimpanzee\nkomondor\nAfghan hound\nJapanese spaniel\nproboscis monkey\nguinea pig\nwhite wolf\nice bear\ngorilla\nborzoi\ntoy poodle\nKerry blue terrier\nox\nScotch terrier\nTibetan mastiff\nspider monkey\nDoberman\nBoston bull\nGreater Swiss Mountain dog\nAppenzeller\nShih-Tzu\nIrish water spaniel\nPomeranian\nBedlington terrier\nwarthog\nArabian camel\nsiamang\nminiature schnauzer\ncollie\ngolden retriever\nIrish terrier\naffenpinscher\nBorder collie\nhare\nboxer\nsilky terrier\nbeagle\nLeonberg\nGerman short-haired pointer\npatas\ndhole\nbaboon\nmacaque\nChesapeake Bay retriever\nbull mastiff\nkuvasz\ncapuchin\npug\ncurly-coated retriever\nNorwich terrier\nflat-coated retriever\nhog\nkeeshond\nEskimo dog\nBrittany spaniel\nstandard poodle\nLakeland terrier\nsnow leopard\nGordon setter\ndingo\nstandard schnauzer\nhamster\nTibetan terrier\nArctic fox\nwire-haired fox terrier\nbasset\nwater buffalo\nAmerican black bear\nAngora\nbison\nhowler monkey\nhippopotamus\nchow\ngiant panda\nAmerican Staffordshire terrier\nShetland sheepdog\nGreat Pyrenees\nChihuahua\ntabby\nmarmoset\nLabrador retriever\nSaint Bernard\narmadillo\nSamoyed\nbluetick\nredbone\npolecat\nmarmot\nkelpie\ngibbon\nllama\nminiature pinscher\nwood rabbit\nItalian greyhound\nlion\ncocker spaniel\nIrish setter\ndugong\nIndian elephant\nbeaver\nSussex spaniel\nPembroke\nBlenheim spaniel\nMadagascar cat\nRhodesian ridgeback\nlynx\nAfrican hunting dog\nlangur\nIbizan hound\ntimber wolf\ncheetah\nEnglish foxhound\nbriard\nsloth bear\nBorder terrier\nGerman shepherd\notter\nkoala\ntusker\nechidna\nwallaby\nplatypus\nwombat\nrevolver\numbrella\nschooner\nsoccer ball\naccordion\nant\nstarfish\nchambered nautilus\ngrand piano\nlaptop\nstrawberry\nairliner\nwarplane\nairship\nballoon\nspace shuttle\nfireboat\ngondola\nspeedboat\nlifeboat\ncanoe\nyawl\ncatamaran\ntrimaran\ncontainer ship\nliner\npirate\naircraft carrier\nsubmarine\nwreck\nhalf track\ntank\nmissile\nbobsled\ndogsled\nbicycle-built-for-two\nmountain bike\nfreight car\npassenger car\nbarrow\nshopping cart\nmotor scooter\nforklift\nelectric locomotive\nsteam locomotive\namphibian\nambulance\nbeach wagon\ncab\nconvertible\njeep\nlimousine\nminivan\nModel T\nracer\nsports car\ngo-kart\ngolfcart\nmoped\nsnowplow\nfire engine\ngarbage truck\npickup\ntow truck\ntrailer truck\nmoving van\npolice van\nrecreational vehicle\nstreetcar\nsnowmobile\ntractor\nmobile home\ntricycle\nunicycle\nhorse cart\njinrikisha\noxcart\nbassinet\ncradle\ncrib\nfour-poster\nbookcase\nchina cabinet\nmedicine chest\nchiffonier\ntable lamp\nfile\npark bench\nbarber chair\nthrone\nfolding chair\nrocking chair\nstudio couch\ntoilet seat\ndesk\npool table\ndining table\nentertainment center\nwardrobe\nGranny Smith\norange\nlemon\nfig\npineapple\nbanana\njackfruit\ncustard apple\npomegranate\nacorn\nhip\near\nrapeseed\ncorn\nbuckeye\norgan\nupright\nchime\ndrum\ngong\nmaraca\nmarimba\nsteel drum\nbanjo\ncello\nviolin\nharp\nacoustic guitar\nelectric guitar\ncornet\nFrench horn\ntrombone\nharmonica\nocarina\npanpipe\nbassoon\noboe\nsax\nflute\ndaisy\nyellow lady's slipper\ncliff\nvalley\nalp\nvolcano\npromontory\nsandbar\ncoral reef\nlakeside\nseashore\ngeyser\nhatchet\ncleaver\nletter opener\nplane\npower drill\nlawn mower\nhammer\ncorkscrew\ncan opener\nplunger\nscrewdriver\nshovel\nplow\nchain saw\ncock\nhen\nostrich\nbrambling\ngoldfinch\nhouse finch\njunco\nindigo bunting\nrobin\nbulbul\njay\nmagpie\nchickadee\nwater ouzel\nkite\nbald eagle\nvulture\ngreat grey owl\nblack grouse\nptarmigan\nruffed grouse\nprairie chicken\npeacock\nquail\npartridge\nAfrican grey\nmacaw\nsulphur-crested cockatoo\nlorikeet\ncoucal\nbee eater\nhornbill\nhummingbird\njacamar\ntoucan\ndrake\nred-breasted merganser\ngoose\nblack swan\nwhite stork\nblack stork\nspoonbill\nflamingo\nAmerican egret\nlittle blue heron\nbittern\ncrane\nlimpkin\nAmerican coot\nbustard\nruddy turnstone\nred-backed sandpiper\nredshank\ndowitcher\noystercatcher\nEuropean gallinule\npelican\nking penguin\nalbatross\ngreat white shark\ntiger shark\nhammerhead\nelectric ray\nstingray\nbarracouta\ncoho\ntench\ngoldfish\neel\nrock beauty\nanemone fish\nlionfish\npuffer\nsturgeon\ngar\nloggerhead\nleatherback turtle\nmud turtle\nterrapin\nbox turtle\nbanded gecko\ncommon iguana\nAmerican chameleon\nwhiptail\nagama\nfrilled lizard\nalligator lizard\nGila monster\ngreen lizard\nAfrican chameleon\nKomodo dragon\ntriceratops\nAfrican crocodile\nAmerican alligator\nthunder snake\nringneck snake\nhognose snake\ngreen snake\nking snake\ngarter snake\nwater snake\nvine snake\nnight snake\nboa constrictor\nrock python\nIndian cobra\ngreen mamba\nsea snake\nhorned viper\ndiamondback\nsidewinder\nEuropean fire salamander\ncommon newt\neft\nspotted salamander\naxolotl\nbullfrog\ntree frog\ntailed frog\nwhistle\nwing\npaintbrush\nhand blower\noxygen mask\nsnorkel\nloudspeaker\nmicrophone\nscreen\nmouse\nelectric fan\noil filter\nstrainer\nspace heater\nstove\nguillotine\nbarometer\nrule\nodometer\nscale\nanalog clock\ndigital clock\nwall clock\nhourglass\nsundial\nparking meter\nstopwatch\ndigital watch\nstethoscope\nsyringe\nmagnetic compass\nbinoculars\nprojector\nsunglasses\nloupe\nradio telescope\nbow\ncannon [ground]\nassault rifle\nrifle\nprojectile\ncomputer keyboard\ntypewriter keyboard\ncrane\nlighter\nabacus\ncash machine\nslide rule\ndesktop computer\nhand-held computer\nnotebook\nweb site\nharvester\nthresher\nprinter\nslot\nvending machine\nsewing machine\njoystick\nswitch\nhook\ncar wheel\npaddlewheel\npinwheel\npotter's wheel\ngas pump\ncarousel\nswing\nreel\nradiator\npuck\nhard disc\nsunglass\npick\ncar mirror\nsolar dish\nremote control\ndisk brake\nbuckle\nhair slide\nknot\ncombination lock\npadlock\nnail\nsafety pin\nscrew\nmuzzle\nseat belt\nski\ncandle\njack-o'-lantern\nspotlight\ntorch\nneck brace\npier\ntripod\nmaypole\nmousetrap\nspider web\ntrilobite\nharvestman\nscorpion\nblack and gold garden spider\nbarn spider\ngarden spider\nblack widow\ntarantula\nwolf spider\ntick\ncentipede\nisopod\nDungeness crab\nrock crab\nfiddler crab\nking crab\nAmerican lobster\nspiny lobster\ncrayfish\nhermit crab\ntiger beetle\nladybug\nground beetle\nlong-horned beetle\nleaf beetle\ndung beetle\nrhinoceros beetle\nweevil\nfly\nbee\ngrasshopper\ncricket\nwalking stick\ncockroach\nmantis\ncicada\nleafhopper\nlacewing\ndragonfly\ndamselfly\nadmiral\nringlet\nmonarch\ncabbage butterfly\nsulphur butterfly\nlycaenid\njellyfish\nsea anemone\nbrain coral\nflatworm\nnematode\nconch\nsnail\nslug\nsea slug\nchiton\nsea urchin\nsea cucumber\niron\nespresso maker\nmicrowave\nDutch oven\nrotisserie\ntoaster\nwaffle iron\nvacuum\ndishwasher\nrefrigerator\nwasher\nCrock Pot\nfrying pan\nwok\ncaldron\ncoffeepot\nteapot\nspatula\naltar\ntriumphal arch\npatio\nsteel arch bridge\nsuspension bridge\nviaduct\nbarn\ngreenhouse\npalace\nmonastery\nlibrary\napiary\nboathouse\nchurch\nmosque\nstupa\nplanetarium\nrestaurant\ncinema\nhome theater\nlumbermill\ncoil\nobelisk\ntotem pole\ncastle\nprison\ngrocery store\nbakery\nbarbershop\nbookshop\nbutcher shop\nconfectionery\nshoe shop\ntobacco shop\ntoyshop\nfountain\ncliff dwelling\nyurt\ndock\nbrass\nmegalith\nbannister\nbreakwater\ndam\nchainlink fence\npicket fence\nworm fence\nstone wall\ngrille\nsliding door\nturnstile\nmountain tent\nscoreboard\nhoneycomb\nplate rack\npedestal\nbeacon\nmashed potato\nbell pepper\nhead cabbage\nbroccoli\ncauliflower\nzucchini\nspaghetti squash\nacorn squash\nbutternut squash\ncucumber\nartichoke\ncardoon\nmushroom\nshower curtain\njean\ncarton\nhandkerchief\nsandal\nashcan\nsafe\nplate\nnecklace\ncroquet ball\nfur coat\nthimble\npajama\nrunning shoe\ncocktail shaker\nchest\nmanhole cover\nmodem\ntub\ntray\nbalance beam\nbagel\nprayer rug\nkimono\nhot pot\nwhiskey jug\nknee pad\nbook jacket\nspindle\nski mask\nbeer bottle\ncrash helmet\nbottlecap\ntile roof\nmask\nmaillot\nPetri dish\nfootball helmet\nbathing cap\nteddy bear\nholster\npop bottle\nphotocopier\nvestment\ncrossword puzzle\ngolf ball\ntrifle\nsuit\nwater tower\nfeather boa\ncloak\nred wine\ndrumstick\nshield\nChristmas stocking\nhoopskirt\nmenu\nstage\nbonnet\nmeat loaf\nbaseball\nface powder\nscabbard\nsunscreen\nbeer glass\nhen-of-the-woods\nguacamole\nlampshade\nwool\nhay\nbow tie\nmailbag\nwater jug\nbucket\ndishrag\nsoup bowl\neggnog\nmortar\ntrench coat\npaddle\nchain\nswab\nmixing bowl\npotpie\nwine bottle\nshoji\nbulletproof vest\ndrilling platform\nbinder\ncardigan\nsweatshirt\npot\nbirdhouse\nhamper\nping-pong ball\npencil box\npay-phone\nconsomme\napron\npunching bag\nbackpack\ngroom\nbearskin\npencil sharpener\nbroom\nmosquito net\nabaya\nmortarboard\nponcho\ncrutch\nPolaroid camera\nspace bar\ncup\nracket\ntraffic light\nquill\nradio\ndough\ncuirass\nmilitary uniform\nlipstick\nshower cap\nmonitor\noscilloscope\nmitten\nbrassiere\nFrench loaf\nvase\nmilk can\nrugby ball\npaper towel\nearthstar\nenvelope\nminiskirt\ncowboy hat\ntrolleybus\nperfume\nbathtub\nhotdog\ncoral fungus\nbullet train\npillow\ntoilet tissue\ncassette\ncarpenter's kit\nladle\nstinkhorn\nlotion\nhair spray\nacademic gown\ndome\ncrate\nwig\nburrito\npill bottle\nchain mail\ntheater curtain\nwindow shade\nbarrel\nwashbasin\nballpoint\nbasketball\nbath towel\ncowboy boot\ngown\nwindow screen\nagaric\ncellular telephone\nnipple\nbarbell\nmailbox\nlab coat\nfire screen\nminibus\npacket\nmaze\npole\nhorizontal bar\nsombrero\npickelhaube\nrain barrel\nwallet\ncassette player\ncomic book\npiggy bank\nstreet sign\nbell cote\nfountain pen\nWindsor tie\nvolleyball\noverskirt\nsarong\npurse\nbolo tie\nbib\nparachute\nsleeping bag\ntelevision\nswimming trunks\nmeasuring cup\nespresso\npizza\nbreastplate\nshopping basket\nwooden spoon\nsaltshaker\nchocolate sauce\nballplayer\ngoblet\ngyromitra\nstretcher\nwater bottle\ndial telephone\nsoap dispenser\njersey\nschool bus\njigsaw puzzle\nplastic bag\nreflex camera\ndiaper\nBand Aid\nice lolly\nvelvet\ntennis ball\ngasmask\ndoormat\nLoafer\nice cream\npretzel\nquilt\nmaillot\ntape player\nclog\niPod\nbolete\nscuba diver\npitcher\nmatchstick\nbikini\nsock\nCD player\nlens cap\nthatch\nvault\nbeaker\nbubble\ncheeseburger\nparallel bars\nflagpole\ncoffee mug\nrubber eraser\nstole\ncarbonara\ndumbbell\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/Navigation.java",
    "content": "package ai.fritz.aistudio;\n\nimport android.content.Context;\nimport android.content.Intent;\n\nimport ai.fritz.aistudio.activities.custommodel.CustomTFLiteActivity;\nimport ai.fritz.aistudio.activities.vision.ImageLabelingActivity;\nimport ai.fritz.aistudio.activities.vision.ImageSegmentationActivity;\nimport ai.fritz.aistudio.activities.vision.ObjectDetectionActivity;\nimport ai.fritz.aistudio.activities.vision.PoseEstimationActivity;\nimport ai.fritz.aistudio.activities.vision.StyleTransferActivity;\n\n/**\n * Navigation is a helper class for common links throughout the app.\n */\npublic class Navigation {\n\n    public static void goToTFLite(Context context) {\n        Intent tflite = new Intent(context, CustomTFLiteActivity.class);\n        context.startActivity(tflite);\n    }\n\n    public static void goToLabelingActivity(Context context) {\n        Intent labelActivity = new Intent(context, ImageLabelingActivity.class);\n        context.startActivity(labelActivity);\n    }\n\n    public static void goToStyleTransfer(Context context) {\n        Intent styleActivity = new Intent(context, StyleTransferActivity.class);\n        context.startActivity(styleActivity);\n    }\n\n    public static void goToImageSegmentation(Context context) {\n        Intent imgSegActivity = new Intent(context, ImageSegmentationActivity.class);\n        context.startActivity(imgSegActivity);\n    }\n\n    public static void goToObjectDetection(Context context) {\n        Intent objectDetection = new Intent(context, ObjectDetectionActivity.class);\n        context.startActivity(objectDetection);\n    }\n\n    public static void goToPoseEstimation(Context context) {\n        Intent poseEstimation = new Intent(context, PoseEstimationActivity.class);\n        context.startActivity(poseEstimation);\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/PredictorType.java",
    "content": "package ai.fritz.aistudio;\n\npublic enum PredictorType {\n    POSE_ESTIMATION,\n    STYLE_TRANSFER,\n    IMAGE_LABELING,\n    OBJECT_DETECTION,\n    PEOPLE_SEGMENTATION,\n    LIVING_ROOM_SEGMENTATION,\n    OUTDOOR_SEGMENTATION,\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/BaseCameraActivity.java",
    "content": "package ai.fritz.aistudio.activities;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.support.v7.app.AppCompatActivity;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.KeyEvent;\nimport android.view.WindowManager;\nimport android.widget.Toast;\n\nimport ai.fritz.aistudio.R;\nimport ai.fritz.aistudio.fragments.CameraConnectionFragment;\nimport ai.fritz.aistudio.ui.OverlayView;\n\n\npublic abstract class BaseCameraActivity extends AppCompatActivity implements OnImageAvailableListener {\n    private static final String TAG = BaseCameraActivity.class.getSimpleName();\n    private static final int PERMISSIONS_REQUEST = 1;\n\n    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;\n    private static final String PERMISSION_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;\n    private boolean useCamera2API;\n\n    private boolean debug = false;\n\n    private Handler handler;\n    private HandlerThread handlerThread;\n\n    protected String cameraId;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        Log.d(TAG, \"onCreate \" + this);\n        super.onCreate(null);\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        setContentView(R.layout.activity_camera);\n\n        if (hasPermission()) {\n            setFragment();\n        } else {\n            requestPermission();\n        }\n    }\n\n    @Override\n    public synchronized void onStart() {\n        Log.d(TAG, \"onStart \" + this);\n        super.onStart();\n    }\n\n    @Override\n    public synchronized void onResume() {\n        Log.d(TAG, \"onResume \" + this);\n        super.onResume();\n\n        handlerThread = new HandlerThread(\"inference\");\n        handlerThread.start();\n        handler = new Handler(handlerThread.getLooper());\n    }\n\n    @Override\n    public synchronized void onPause() {\n        Log.d(TAG, \"onPause \" + this);\n\n        handlerThread.quitSafely();\n        try {\n            handlerThread.join();\n            handlerThread = null;\n            handler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n\n        super.onPause();\n    }\n\n    @Override\n    public synchronized void onStop() {\n        Log.d(TAG, \"onStop \" + this);\n        super.onStop();\n    }\n\n    @Override\n    public synchronized void onDestroy() {\n        Log.d(TAG, \"onDestroy \" + this);\n        super.onDestroy();\n    }\n\n    protected synchronized void runInBackground(final Runnable r) {\n        if (handler != null) {\n            handler.post(r);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(\n            final int requestCode, final String[] permissions, final int[] grantResults) {\n        switch (requestCode) {\n            case PERMISSIONS_REQUEST: {\n                if (grantResults.length > 0\n                        && grantResults[0] == PackageManager.PERMISSION_GRANTED\n                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {\n                    setFragment();\n                } else {\n                    requestPermission();\n                }\n            }\n        }\n    }\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            return checkSelfPermission(PERMISSION_CAMERA) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(PERMISSION_STORAGE) == PackageManager.PERMISSION_GRANTED;\n        } else {\n            return true;\n        }\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA) || shouldShowRequestPermissionRationale(PERMISSION_STORAGE)) {\n                Toast.makeText(BaseCameraActivity.this, \"Camera AND storage permission are required for this demo\", Toast.LENGTH_LONG).show();\n            }\n            requestPermissions(new String[]{PERMISSION_CAMERA, PERMISSION_STORAGE}, PERMISSIONS_REQUEST);\n        }\n    }\n\n    protected void setFragment() {\n        cameraId = chooseCamera();\n        final CameraConnectionFragment fragment =\n                CameraConnectionFragment.newInstance(\n                        new CameraConnectionFragment.ConnectionCallback() {\n                            @Override\n                            public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n                                BaseCameraActivity.this.onPreviewSizeChosen(previewSize, cameraViewSize, rotation);\n                            }\n                        },\n                        this,\n                        getLayoutId(),\n                        getDesiredPreviewFrameSize());\n\n        fragment.setCamera(cameraId);\n\n        getFragmentManager()\n                .beginTransaction()\n                .replace(R.id.camera_container, fragment)\n                .commit();\n    }\n\n    private String chooseCamera() {\n        final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);\n        try {\n            for (final String cameraId : manager.getCameraIdList()) {\n                final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n                // We don't use a front facing camera in this sample.\n                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);\n                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {\n                    continue;\n                }\n\n                final StreamConfigurationMap map =\n                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n                if (map == null) {\n                    continue;\n                }\n\n                // Fallback to camera1 API for internal cameras that don't have full support.\n                // This should help with legacy situations where using the camera2 API causes\n                // distorted or otherwise broken previews.\n                useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)\n                        || isHardwareLevelSupported(characteristics,\n                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);\n                Log.i(TAG, \"Camera API lv2?: \" + useCamera2API);\n                return cameraId;\n            }\n        } catch (CameraAccessException e) {\n            Log.e(TAG, \"Not allowed to access camera: \" + e);\n        }\n\n        return null;\n    }\n\n    // Returns true if the device supports the required hardware level, or better.\n    private boolean isHardwareLevelSupported(\n            CameraCharacteristics characteristics, int requiredLevel) {\n        int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);\n        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {\n            return requiredLevel == deviceLevel;\n        }\n        // deviceLevel is not LEGACY, can use numerical sort\n        return requiredLevel <= deviceLevel;\n    }\n\n\n    public boolean isDebug() {\n        return debug;\n    }\n\n    public void requestRender() {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.postInvalidate();\n        }\n    }\n\n    public void setCallback(final OverlayView.DrawCallback callback) {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.setCallback(callback);\n        }\n    }\n\n    public void onSetDebug(final boolean debug) {\n    }\n\n    @Override\n    public boolean onKeyDown(final int keyCode, final KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {\n            debug = !debug;\n            requestRender();\n            onSetDebug(debug);\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    protected abstract void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation);\n\n    protected abstract int getLayoutId();\n\n    protected Size getDesiredPreviewFrameSize() {\n        return new Size(640, 480);\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/BaseLiveVideoActivity.java",
    "content": "package ai.fritz.aistudio.activities;\n\nimport android.graphics.Canvas;\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.os.Bundle;\nimport android.util.Size;\nimport android.widget.Button;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.aistudio.R;\nimport ai.fritz.aistudio.ui.OverlayView;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\n\npublic abstract class BaseLiveVideoActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n\n    private static final String TAG = BaseLiveVideoActivity.class.getSimpleName();\n    private AtomicBoolean computing = new AtomicBoolean(false);\n    protected FritzVisionImage fritzVisionImage;\n\n    private ImageOrientation orientation;\n    protected Button chooseModelBtn;\n\n    @Override\n    public void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size size, final Size cameraSize, final int rotation) {\n        orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n        chooseModelBtn = findViewById(R.id.chose_model_btn);\n\n        setCallback(\n                new OverlayView.DrawCallback() {\n                    @Override\n                    public void drawCallback(final Canvas canvas) {\n                        handleDrawingResult(canvas, cameraSize);\n                    }\n                });\n\n        onCameraSetup(cameraSize);\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!computing.compareAndSet(false, true)) {\n            image.close();\n            return;\n        }\n        fritzVisionImage = FritzVisionImage.fromMediaImage(image, orientation);\n        image.close();\n\n        runInBackground(\n                new Runnable() {\n                    @Override\n                    public void run() {\n                        runInference(fritzVisionImage);\n                        requestRender();\n                        computing.set(false);\n                    }\n                });\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.camera_connection_fragment_tracking;\n    }\n\n    @Override\n    public void onSetDebug(final boolean debug) {\n\n    }\n\n    protected abstract void onCameraSetup(Size cameraSize);\n\n    protected abstract void handleDrawingResult(Canvas canvas, Size cameraSize);\n\n    protected abstract void runInference(FritzVisionImage fritzVisionImage);\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/BaseRecordingActivity.java",
    "content": "package ai.fritz.aistudio.activities;\n\nimport android.content.DialogInterface;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.RectF;\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.CountDownTimer;\nimport android.os.Handler;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.ProgressBar;\n\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicLong;\n\nimport ai.fritz.aistudio.R;\nimport ai.fritz.aistudio.ui.ChooseModelDialog;\nimport ai.fritz.aistudio.ui.OverlayView;\nimport ai.fritz.aistudio.utils.VideoProcessingQueue;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\nimport ai.fritz.vision.ImageRotation;\n\n\npublic abstract class BaseRecordingActivity extends BaseCameraActivity implements OnImageAvailableListener {\n    private static final String TAG = BaseRecordingActivity.class.getSimpleName();\n    private static final long TIME_BETWEEN_FRAMES_MS = 100;\n    private static final long TIME_BUFFER_FRAMES_MS = 50;\n    private static final long MAX_RECORDING_TIME_MS = TimeUnit.SECONDS.toMillis(5);\n    private static final long TIME_BETWEEN_RECORDING_INTERVAL_MS = 50;\n    private static final int NUM_PROGRESS_INTERVALS = (int) (MAX_RECORDING_TIME_MS / TIME_BETWEEN_RECORDING_INTERVAL_MS);\n\n    private AtomicBoolean isRecording = new AtomicBoolean(false);\n\n    private OverlayView overlayView;\n    private ImageOrientation orientation;\n\n    private ChooseModelDialog imageSegDialog;\n    private Button takeVideoBtn;\n    private Button closeBtn;\n    private Button chooseModelBtn;\n    private ProgressBar processingVideoProgress;\n    private ProgressBar videoRecordingProgress;\n    private ProgressBar loadingModelSpinner;\n\n    private VideoProcessingQueue videoProcessingQueue;\n    private LinkedBlockingQueue<Bitmap> processedBitmaps = new LinkedBlockingQueue<>();\n\n    private AtomicLong lastRecordedFrameAt = new AtomicLong(0);\n    private CountDownTimer mCountDownTimer;\n    private Handler playBackHandler = new Handler();\n\n    private int processingProgress = 0;\n\n    protected abstract int getModelOptionsTextId();\n\n    protected abstract Bitmap runPrediction(FritzVisionImage visionImage, Size cameraViewSize);\n\n    protected abstract void loadPredictor(int choice);\n\n\n    @Override\n    public void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.camera_connection_fragment_recording;\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n        overlayView = findViewById(R.id.debug_overlay);\n        takeVideoBtn = findViewById(R.id.take_video_btn);\n        processingVideoProgress = findViewById(R.id.processingVideoProgress);\n        videoRecordingProgress = findViewById(R.id.videoRecordingProgress);\n        closeBtn = findViewById(R.id.close_btn);\n        chooseModelBtn = findViewById(R.id.choose_model_btn);\n        loadingModelSpinner = findViewById(R.id.loadingModelSpinner);\n\n        showCameraViews();\n\n        // Create a predictor\n\n        loadPredictor(0);\n        chooseModelBtn.setText(getModelText(0));\n\n        videoProcessingQueue = new VideoProcessingQueue(new VideoProcessingQueue.Listener() {\n            @Override\n            public void processVisionImage(FritzVisionImage visionImage) {\n                Bitmap result = runPrediction(visionImage, cameraViewSize);\n                processedBitmaps.add(result);\n                Log.d(TAG, \"Processed Frame #: \" + processedBitmaps.size());\n\n                if (!isRecording.get()) {\n                    processingVideoProgress.setProgress(++processingProgress);\n                }\n            }\n\n            @Override\n            public void finishedProcessing() {\n                Log.d(TAG, \"Finished processing video clips\");\n                finishProcessing();\n            }\n        });\n\n        orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n\n        // Dialog for image seg choice;\n        imageSegDialog = new ChooseModelDialog(getModelOptionsTextId(), new DialogInterface.OnClickListener() {\n            public void onClick(DialogInterface dialog, int which) {\n                // The 'which' argument contains the index position\n                // of the selected item.\n                loadPredictor(which);\n\n                chooseModelBtn.setText(getModelText(which));\n            }\n        });\n\n\n        closeBtn.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                showCameraViews();\n            }\n        });\n        final Paint paint = new Paint();\n        setCallback(\n                new OverlayView.DrawCallback() {\n                    @Override\n                    public void drawCallback(final Canvas canvas) {\n                        if (!processedBitmaps.isEmpty()) {\n                            Bitmap bitmap = processedBitmaps.poll();\n                            canvas.drawBitmap(bitmap, null, new RectF(0, 0, cameraViewSize.getWidth(), cameraViewSize.getHeight()), null);\n\n                        }\n                    }\n                });\n        takeVideoBtn.setOnTouchListener(new View.OnTouchListener() {\n            @Override\n            public boolean onTouch(View v, MotionEvent event) {\n                if (event.getAction() == MotionEvent.ACTION_DOWN) {\n                    isRecording.compareAndSet(false, true);\n                    lastRecordedFrameAt.set(0);\n                    showStartRecordingViews();\n                    return true;\n                } else if (event.getAction() == MotionEvent.ACTION_UP) {\n                    isRecording.compareAndSet(true, false);\n                    showFinishRecordingViews();\n                    return true;\n                }\n\n                return false;\n            }\n        });\n\n        chooseModelBtn.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                imageSegDialog.show(getSupportFragmentManager(), ChooseModelDialog.TAG);\n            }\n        });\n    }\n\n    protected void showPredictorReadyViews() {\n        takeVideoBtn.setVisibility(View.VISIBLE);\n        chooseModelBtn.setVisibility(View.VISIBLE);\n        loadingModelSpinner.setVisibility(View.GONE);\n    }\n\n    protected void showPredictorNotReadyViews() {\n        takeVideoBtn.setVisibility(View.GONE);\n        chooseModelBtn.setVisibility(View.GONE);\n        loadingModelSpinner.setVisibility(View.VISIBLE);\n    }\n\n    private void showStartRecordingViews() {\n        videoRecordingProgress.setVisibility(View.VISIBLE);\n        videoRecordingProgress.setMax(NUM_PROGRESS_INTERVALS);\n        videoRecordingProgress.setProgress(0);\n\n        chooseModelBtn.setVisibility(View.GONE);\n        mCountDownTimer = new CountDownTimer(MAX_RECORDING_TIME_MS, TIME_BETWEEN_RECORDING_INTERVAL_MS) {\n\n            @Override\n            public void onTick(long millisUntilFinished) {\n                int progress = (int) (NUM_PROGRESS_INTERVALS - millisUntilFinished / TIME_BETWEEN_RECORDING_INTERVAL_MS);\n                videoRecordingProgress.setProgress(progress);\n            }\n\n            @Override\n            public void onFinish() {\n                // finish recording when MAX_RECORDING_TIME_MS is met\n                if (isRecording.compareAndSet(true, false)) {\n                    videoRecordingProgress.setProgress(NUM_PROGRESS_INTERVALS);\n                    showFinishRecordingViews();\n                }\n            }\n        };\n        mCountDownTimer.start();\n    }\n\n    private void showCameraViews() {\n        overlayView.setVisibility(View.GONE);\n        closeBtn.setVisibility(View.GONE);\n        takeVideoBtn.setVisibility(View.VISIBLE);\n        chooseModelBtn.setVisibility(View.VISIBLE);\n        videoRecordingProgress.setProgress(0);\n        videoRecordingProgress.setVisibility(View.GONE);\n    }\n\n    private void showFinishRecordingViews() {\n        videoRecordingProgress.setProgress(0);\n        takeVideoBtn.setVisibility(View.GONE);\n        overlayView.setVisibility(View.VISIBLE);\n        videoRecordingProgress.setVisibility(View.INVISIBLE);\n        processingVideoProgress.setVisibility(View.VISIBLE);\n        processingVideoProgress.setMax(videoProcessingQueue.getNumFramesToProcess());\n        processingVideoProgress.setProgress(0);\n    }\n\n    private void showStyleResults() {\n        processingVideoProgress.setVisibility(View.GONE);\n        closeBtn.setVisibility(View.VISIBLE);\n        overlayView.setVisibility(View.VISIBLE);\n    }\n\n    private void finishProcessing() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                showStyleResults();\n            }\n        });\n        processingProgress = 0;\n        // Redraw the overlay view\n        overlayView.postInvalidate();\n\n        // This is a bit hacky but re-render the\n        // overlay view with a new bitmap result after\n        // a certain amount of time until all the bitmaps are shown.\n        Runnable runnable = new Runnable() {\n            @Override\n            public void run() {\n                if (processedBitmaps.isEmpty()) {\n                    return;\n                }\n                overlayView.postInvalidate();\n                playBackHandler.postDelayed(this, TIME_BETWEEN_FRAMES_MS + TIME_BUFFER_FRAMES_MS);\n            }\n        };\n        runnable.run();\n    }\n\n    public String getModelText(int choice) {\n        String[] options = getResources().getStringArray(getModelOptionsTextId());\n        return options[choice];\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        // Save Images when we're recording\n        if (!isRecording.get()) {\n            image.close();\n            return;\n        }\n\n        // Only grab a frame every 100ms\n        if (System.currentTimeMillis() - lastRecordedFrameAt.get() < TIME_BETWEEN_FRAMES_MS) {\n            image.close();\n            return;\n        }\n\n        // Add the frame to a queue to process\n        lastRecordedFrameAt.set(System.currentTimeMillis());\n        final FritzVisionImage fritzImage = FritzVisionImage.fromMediaImage(image, orientation);\n        videoProcessingQueue.addVisionImage(fritzImage);\n        image.close();\n    }\n}\n\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/MainActivity.java",
    "content": "package ai.fritz.aistudio.activities;\n\nimport android.content.Intent;\nimport android.graphics.Color;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.support.v7.widget.Toolbar;\nimport android.view.View;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Logger;\n\nimport ai.fritz.core.Fritz;\nimport ai.fritz.aistudio.PredictorType;\nimport ai.fritz.aistudio.R;\nimport ai.fritz.aistudio.adapters.DemoAdapter;\nimport ai.fritz.aistudio.adapters.DemoItem;\nimport ai.fritz.aistudio.ui.SeparatorDecoration;\nimport ai.fritz.aistudio.Navigation;\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\n\n/**\n * The primary activity that shows the different model demos.\n */\npublic class MainActivity extends AppCompatActivity {\n\n    private static final String FRITZ_URL = \"https://fritz.ai\";\n\n    private Logger logger = Logger.getLogger(this.getClass().getName());\n\n    @BindView(R.id.demo_list_view)\n    RecyclerView recyclerView;\n\n    @BindView(R.id.app_toolbar)\n    Toolbar appBar;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n        setTitle(R.string.demo_title);\n        ButterKnife.bind(this);\n\n        // customize the action bar\n        setSupportActionBar(appBar);\n\n        // Initialize Fritz\n        Fritz.configure(this);\n\n        // Setup the recycler view\n        recyclerView.setHasFixedSize(true);\n        LinearLayoutManager rvLinearLayoutMgr = new LinearLayoutManager(this);\n        recyclerView.setLayoutManager(rvLinearLayoutMgr);\n\n        // Add a divider\n        SeparatorDecoration decoration = new SeparatorDecoration(this, Color.GRAY, 1);\n        recyclerView.addItemDecoration(decoration);\n\n        // Add the adapter\n        DemoAdapter adapter = new DemoAdapter(getDemoItems());\n        recyclerView.setAdapter(adapter);\n        recyclerView.setClickable(true);\n    }\n\n    private List<DemoItem> getDemoItems() {\n        // Add different demo items here\n        List<DemoItem> demoItems = new ArrayList<>();\n        demoItems.add(new DemoItem(\n                getString(R.string.fritz_vision_title),\n                getString(R.string.fritz_vision_description_live_video),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        logger.info(\"FRITZ VISION LIVE VIDEO\");\n                        Navigation.goToLabelingActivity(v.getContext());\n                    }\n                }));\n        demoItems.add(new DemoItem(\n                getString(R.string.fritz_object_detection_title),\n                getString(R.string.fritz_object_detection_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Navigation.goToObjectDetection(v.getContext());\n                    }\n                }));\n        demoItems.add(new DemoItem(\n                getString(R.string.fritz_vision_style_transfer),\n                getString(R.string.fritz_vision_style_transfer_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Navigation.goToStyleTransfer(v.getContext());\n                    }\n                }));\n        demoItems.add(new DemoItem(\n                getString(R.string.fritz_vision_img_seg_title),\n                getString(R.string.fritz_vision_img_seg_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Navigation.goToImageSegmentation(v.getContext());\n                    }\n                }));\n        demoItems.add(new DemoItem(\n                getString(R.string.fritz_pose_estimation_title),\n                getString(R.string.fritz_pose_estimation_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Navigation.goToPoseEstimation(v.getContext());\n                    }\n                }));\n        demoItems.add(new DemoItem(\n                getString(R.string.fritz_customtflite_title),\n                getString(R.string.fritz_customtflite_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Navigation.goToTFLite(v.getContext());\n                    }\n                }));\n        demoItems.add(new DemoItem(\n                getString(R.string.fritz_info_title),\n                getString(R.string.fritz_info_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Intent i = new Intent(Intent.ACTION_VIEW);\n                        i.setData(Uri.parse(FRITZ_URL));\n                        startActivity(i);\n                    }\n                }));\n        return demoItems;\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/SplashActivity.java",
    "content": "package ai.fritz.aistudio.activities;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.support.v7.app.AppCompatActivity;\n\nimport ai.fritz.aistudio.activities.MainActivity;\n\n/**\n * The splash activity is the entry point for the rest of the app.\n */\npublic class SplashActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Intent intent = new Intent(this, MainActivity.class);\n        startActivity(intent);\n        finish();\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/custommodel/CustomTFLiteActivity.java",
    "content": "package ai.fritz.aistudio.activities.custommodel;\n\nimport android.graphics.PointF;\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.support.v7.widget.Toolbar;\nimport android.util.Log;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport ai.fritz.aistudio.R;\nimport ai.fritz.aistudio.activities.custommodel.ml.MnistClassifier;\nimport ai.fritz.aistudio.ui.DrawModel;\nimport ai.fritz.aistudio.ui.DrawView;\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\n\n\npublic class CustomTFLiteActivity extends AppCompatActivity {\n    private final String TAG = this.getClass().getSimpleName();\n\n    private static final int PIXEL_WIDTH = 28;\n\n    private float lastX;\n    private float lastY;\n\n    private DrawModel drawModel;\n\n    private PointF fPoint = new PointF();\n\n    private MnistClassifier mnistClassifier;\n\n    @BindView(R.id.view_draw)\n    DrawView mDrawView;\n\n    @BindView(R.id.button_detect)\n    View detectButton;\n\n    @BindView(R.id.button_clear)\n    View clearButton;\n\n    @BindView(R.id.text_result)\n    TextView mResultText;\n\n    @BindView(R.id.app_toolbar)\n    Toolbar appBar;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_mnist);\n        setTitle(R.string.app_name);\n        ButterKnife.bind(this);\n\n        setSupportActionBar(appBar);\n        getSupportActionBar().setDisplayHomeAsUpEnabled(true);\n\n        mnistClassifier = new MnistClassifier(this);\n\n        drawModel = new DrawModel(PIXEL_WIDTH, PIXEL_WIDTH);\n\n        mDrawView.setModel(drawModel);\n        mDrawView.setOnTouchListener(new DrawOnTouchListener());\n\n        detectButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                onDetectClicked();\n            }\n        });\n\n        clearButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                onClearClicked();\n            }\n        });\n    }\n\n    @Override\n    protected void onResume() {\n        mDrawView.onResume();\n        super.onResume();\n    }\n\n    @Override\n    protected void onPause() {\n        mDrawView.onPause();\n        super.onPause();\n    }\n\n    private void onDetectClicked() {\n        int digit = mnistClassifier.classify(mDrawView.getDrawnBitmap());\n        if (digit >= 0) {\n            Log.d(TAG, \"Found Digit = \" + digit);\n            mResultText.setText(getString(R.string.found_digits, String.valueOf(digit)));\n        } else {\n            mResultText.setText(getString(R.string.not_detected));\n        }\n    }\n\n    private void onClearClicked() {\n        drawModel.clear();\n        mDrawView.reset();\n        mDrawView.invalidate();\n        mResultText.setText(\"\");\n    }\n\n    /**\n     * DrawOnTouchListener to handle drawing actions.\n     */\n    public class DrawOnTouchListener implements View.OnTouchListener {\n        @Override\n        public boolean onTouch(View v, MotionEvent event) {\n            int action = event.getAction() & MotionEvent.ACTION_MASK;\n\n            if (action == MotionEvent.ACTION_DOWN) {\n                processTouchDown(event);\n                return true;\n\n            } else if (action == MotionEvent.ACTION_MOVE) {\n                processTouchMove(event);\n                return true;\n\n            } else if (action == MotionEvent.ACTION_UP) {\n                processTouchUp();\n                return true;\n            }\n            return false;\n        }\n\n        private void processTouchDown(MotionEvent event) {\n            lastX = event.getX();\n            lastY = event.getY();\n            mDrawView.calcPos(lastX, lastY, fPoint);\n            float lastConvX = fPoint.x;\n            float lastConvY = fPoint.y;\n            drawModel.startLine(lastConvX, lastConvY);\n        }\n\n        private void processTouchMove(MotionEvent event) {\n            float x = event.getX();\n            float y = event.getY();\n\n            mDrawView.calcPos(x, y, fPoint);\n            float newConvX = fPoint.x;\n            float newConvY = fPoint.y;\n            drawModel.addLineElem(newConvX, newConvY);\n\n            lastX = x;\n            lastY = y;\n            mDrawView.invalidate();\n        }\n\n        private void processTouchUp() {\n            drawModel.endLine();\n        }\n\n    }\n}\n\n\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/custommodel/ml/Classifier.java",
    "content": "package ai.fritz.aistudio.activities.custommodel.ml;\n\n/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n==============================================================================*/\n\n\nimport android.graphics.Bitmap;\nimport android.graphics.RectF;\n\nimport java.util.List;\n\n/**\n * Generic interface for interacting with different recognition engines.\n */\npublic interface Classifier {\n    /**\n     * An immutable result returned by a Classifier describing what was recognized.\n     */\n    public class Recognition {\n        /**\n         * A unique identifier for what has been recognized. Specific to the class, not the instance of\n         * the object.\n         */\n        private final String id;\n\n        /**\n         * Display name for the recognition.\n         */\n        private final String title;\n\n        /**\n         * A sortable score for how good the recognition is relative to others. Higher should be better.\n         */\n        private final Float confidence;\n\n        /**\n         * Optional location within the source image for the location of the recognized object.\n         */\n        private RectF location;\n\n        public Recognition(\n                final String id, final String title, final Float confidence, final RectF location) {\n            this.id = id;\n            this.title = title;\n            this.confidence = confidence;\n            this.location = location;\n        }\n\n        public String getId() {\n            return id;\n        }\n\n        public String getTitle() {\n            return title;\n        }\n\n        public Float getConfidence() {\n            return confidence;\n        }\n\n        public RectF getLocation() {\n            return new RectF(location);\n        }\n\n        public void setLocation(RectF location) {\n            this.location = location;\n        }\n\n        @Override\n        public String toString() {\n            String resultString = \"\";\n            if (id != null) {\n                resultString += \"[\" + id + \"] \";\n            }\n\n            if (title != null) {\n                resultString += title + \" \";\n            }\n\n            if (confidence != null) {\n                resultString += String.format(\"(%.1f%%) \", confidence * 100.0f);\n            }\n\n            if (location != null) {\n                resultString += location + \" \";\n            }\n\n            return resultString.trim();\n        }\n    }\n\n    List<Recognition> recognizeImage(Bitmap bitmap);\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/custommodel/ml/MnistClassifier.java",
    "content": "package ai.fritz.aistudio.activities.custommodel.ml;\n\nimport android.app.Activity;\nimport android.graphics.Bitmap;\nimport android.os.SystemClock;\nimport android.util.Log;\n\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\n\nimport ai.fritz.aistudio.R;\nimport ai.fritz.core.FritzManagedModel;\nimport ai.fritz.core.FritzOnDeviceModel;\nimport ai.fritz.core.FritzTFLiteInterpreter;\nimport ai.fritz.core.ModelReadyListener;\nimport ai.fritz.core.utils.FritzModelManager;\n\n\npublic class MnistClassifier {\n    private final String TAG = this.getClass().getSimpleName();\n\n    // The tensorflow lite file\n    private FritzTFLiteInterpreter tflite;\n\n    // Input byte buffer\n    private ByteBuffer imgData = null;\n\n    // Output array [batch_size, 10]\n    private float[][] mnistOutput = null;\n\n    // Name of the file in the assets folder\n\n    // Specify the output size\n    private static final int NUMBER_LENGTH = 10;\n\n    // Specify the input size\n    private static final int DIM_BATCH_SIZE = 1;\n    private static final int DIM_IMG_SIZE_X = 28;\n    private static final int DIM_IMG_SIZE_Y = 28;\n    private static final int DIM_PIXEL_SIZE = 1;\n\n    // Number of bytes to hold a float (32 bits / float) / (8 bits / byte) = 4 bytes / float\n    private static final int BYTE_SIZE_OF_FLOAT = 4;\n\n    public MnistClassifier(Activity activity) {\n\n        /**\n         * This MNIST model provided is used to demonstrate custom models with TensorFlow Lite\n         * and should not be used in production.\n         */\n        FritzManagedModel managedModel = new FritzManagedModel(activity.getString(R.string.tflite_model_id));\n        FritzModelManager modelManager = new FritzModelManager(managedModel);\n        modelManager.loadModel(new ModelReadyListener() {\n            @Override\n            public void onModelReady(FritzOnDeviceModel onDeviceModel) {\n                tflite = new FritzTFLiteInterpreter(onDeviceModel);\n                Log.d(TAG, \"Interpreter is now ready to use\");\n            }\n        });\n        imgData =\n                ByteBuffer.allocateDirect(\n                        BYTE_SIZE_OF_FLOAT * DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);\n        imgData.order(ByteOrder.nativeOrder());\n        mnistOutput = new float[DIM_BATCH_SIZE][NUMBER_LENGTH];\n        Log.d(TAG, \"Created a Tensorflow Lite MNIST Classifier.\");\n    }\n\n    /**\n     * Run the TFLite model\n     */\n    protected void runInference() {\n        long startTime = SystemClock.uptimeMillis();\n        tflite.run(imgData, mnistOutput);\n        long endTime = SystemClock.uptimeMillis();\n        Log.d(TAG, \"Timecost to run model inference: \" + Long.toString(endTime - startTime));\n    }\n\n    /**\n     * Classifies the number with the mnist model.\n     *\n     * @param bitmap\n     * @return the identified number\n     */\n    public int classify(Bitmap bitmap) {\n        if (tflite == null) {\n            Log.e(TAG, \"Image classifier has not been initialized; Skipped.\");\n            return -1;\n        }\n        convertBitmapToByteBuffer(bitmap);\n        runInference();\n\n        return getResult();\n    }\n\n    /**\n     * Go through the output and find the number that was identified.\n     *\n     * @return the number that was identified (returns -1 if one wasn't found)\n     */\n    private int getResult() {\n        for (int i = 0; i < mnistOutput[0].length; i++) {\n            float value = mnistOutput[0][i];\n            Log.d(TAG, \"Output for \" + Integer.toString(i) + \": \" + Float.toString(value));\n            if (value == 1f) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n    /**\n     * Converts it into the Byte Buffer to feed into the model\n     *\n     * @param bitmap\n     */\n    private void convertBitmapToByteBuffer(Bitmap bitmap) {\n        if (bitmap == null || imgData == null) {\n            return;\n        }\n\n        // Reset the image data\n        imgData.rewind();\n\n        int width = bitmap.getWidth();\n        int height = bitmap.getHeight();\n\n        long startTime = SystemClock.uptimeMillis();\n\n        // The bitmap shape should be 28 x 28\n        int[] pixels = new int[width * height];\n        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);\n\n        for (int i = 0; i < pixels.length; ++i) {\n            // Set 0 for white and 255 for black pixels\n            int pixel = pixels[i];\n            int b = pixel & 0xff;\n            imgData.putFloat(0xff - b);\n        }\n        long endTime = SystemClock.uptimeMillis();\n        Log.d(TAG, \"Time cost to put values into ByteBuffer: \" + Long.toString(endTime - startTime));\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/vision/ImageLabelingActivity.java",
    "content": "package ai.fritz.aistudio.activities.vision;\n\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.os.Bundle;\nimport android.os.SystemClock;\nimport android.support.v7.widget.Toolbar;\nimport android.util.Log;\nimport android.util.Size;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.aistudio.R;\nimport ai.fritz.aistudio.activities.BaseCameraActivity;\nimport ai.fritz.aistudio.ui.ResultsView;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\nimport ai.fritz.vision.imagelabeling.FritzVisionLabelPredictor;\nimport ai.fritz.vision.imagelabeling.FritzVisionLabelResult;\nimport ai.fritz.vision.imagelabeling.LabelingOnDeviceModel;\nimport butterknife.BindView;\nimport butterknife.ButterKnife;\n\npublic class ImageLabelingActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n    private static final String TAG = ImageLabelingActivity.class.getSimpleName();\n\n    /**\n     * Requests for the size of the preview depending on the camera results. We will try to match the closest\n     * in terms of size and aspect ratio.\n     */\n    private static final Size DESIRED_PREVIEW_SIZE = new Size(640, 480);\n\n    private AtomicBoolean computing = new AtomicBoolean(false);\n\n    private FritzVisionLabelPredictor predictor;\n    private FritzVisionLabelResult labelResult;\n\n    private ImageOrientation orientation;\n\n    @BindView(R.id.app_toolbar)\n    Toolbar appBar;\n\n    ResultsView resultsView;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        ButterKnife.bind(this);\n        setTitle(R.string.fritz_vision_title);\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.camera_connection_fragment;\n    }\n\n    @Override\n    protected Size getDesiredPreviewFrameSize() {\n        return DESIRED_PREVIEW_SIZE;\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size size, final Size cameraSize, final int rotation) {\n        orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n        LabelingOnDeviceModel onDeviceModel = FritzVisionModels.getImageLabelingOnDeviceModel();\n        predictor = FritzVision.ImageLabeling.getPredictor(onDeviceModel);\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!computing.compareAndSet(false, true)) {\n            image.close();\n            return;\n        }\n\n        final FritzVisionImage fritzImage = FritzVisionImage.fromMediaImage(image, orientation);\n        image.close();\n\n\n        runInBackground(\n                new Runnable() {\n                    @Override\n                    public void run() {\n                        final long startTime = SystemClock.uptimeMillis();\n                        labelResult = predictor.predict(fritzImage);\n                        labelResult.logResult();\n\n                        if (resultsView == null) {\n                            resultsView = findViewById(R.id.results);\n                        }\n                        resultsView.setResult(labelResult.getVisionLabels());\n                        Log.d(TAG, \"INFERENCE TIME:\" + (SystemClock.uptimeMillis() - startTime));\n                        requestRender();\n                        computing.set(false);\n                    }\n                });\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/vision/ImageSegmentationActivity.java",
    "content": "package ai.fritz.aistudio.activities.vision;\n\nimport android.graphics.Bitmap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.util.Size;\n\nimport ai.fritz.aistudio.R;\nimport ai.fritz.aistudio.activities.BaseRecordingActivity;\nimport ai.fritz.core.FritzOnDeviceModel;\nimport ai.fritz.core.utils.FritzModelManager;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.PredictorStatusListener;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictorOptions;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationResult;\nimport ai.fritz.vision.imagesegmentation.SegmentationManagedModel;\nimport ai.fritz.vision.imagesegmentation.SegmentationOnDeviceModel;\n\n\npublic class ImageSegmentationActivity extends BaseRecordingActivity implements OnImageAvailableListener {\n\n    private static final String TAG = ImageSegmentationActivity.class.getSimpleName();\n    private FritzVisionSegmentationPredictor predictor;\n    private FritzVisionSegmentationPredictorOptions options;\n\n    @Override\n    public void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n\n        options = new FritzVisionSegmentationPredictorOptions();\n    }\n\n    @Override\n    protected int getModelOptionsTextId() {\n        return R.array.img_seg_model_options;\n    }\n\n    @Override\n    protected Bitmap runPrediction(FritzVisionImage visionImage, Size cameraViewSize) {\n        FritzVisionSegmentationResult segmentResult = predictor.predict(visionImage);\n        Bitmap bitmap = segmentResult.buildMultiClassMask();\n        return visionImage.overlay(bitmap);\n    }\n\n    @Override\n    protected void loadPredictor(int choice) {\n        SegmentationManagedModel managedModel = getManagedModel(choice);\n        FritzOnDeviceModel activeOnDeviceModel = FritzModelManager.getActiveOnDeviceModel(managedModel.getModelId());\n        if (activeOnDeviceModel != null) {\n            showPredictorReadyViews();\n            SegmentationOnDeviceModel onDeviceModel = new SegmentationOnDeviceModel(activeOnDeviceModel, managedModel);\n            predictor = FritzVision.ImageSegmentation.getPredictor(onDeviceModel, options);\n        } else {\n            showPredictorNotReadyViews();\n            FritzVision.ImageSegmentation.loadPredictor(managedModel, new PredictorStatusListener<FritzVisionSegmentationPredictor>() {\n                @Override\n                public void onPredictorReady(FritzVisionSegmentationPredictor segmentPredictor) {\n                    Log.d(TAG, \"Segmentation predictor is ready\");\n                    predictor = segmentPredictor;\n                    showPredictorReadyViews();\n                }\n            });\n        }\n    }\n\n    private SegmentationManagedModel getManagedModel(int choice) {\n        switch (choice) {\n            case (1):\n                return FritzVisionModels.getLivingRoomSegmentationManagedModel(ModelVariant.FAST);\n            case (2):\n                return FritzVisionModels.getOutdoorSegmentationManagedModel(ModelVariant.FAST);\n            default:\n                return FritzVisionModels.getPeopleSegmentationManagedModel(ModelVariant.FAST);\n        }\n\n    }\n}\n\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/vision/ObjectDetectionActivity.java",
    "content": "package ai.fritz.aistudio.activities.vision;\n\nimport android.graphics.Canvas;\nimport android.util.Size;\n\nimport java.util.List;\n\nimport ai.fritz.aistudio.activities.BaseLiveVideoActivity;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.FritzVisionObject;\nimport ai.fritz.vision.objectdetection.FritzVisionObjectPredictor;\nimport ai.fritz.vision.objectdetection.FritzVisionObjectResult;\nimport ai.fritz.vision.objectdetection.ObjectDetectionOnDeviceModel;\n\npublic class ObjectDetectionActivity extends BaseLiveVideoActivity {\n\n    private FritzVisionObjectPredictor objectPredictor;\n    private FritzVisionObjectResult objectResult;\n\n    @Override\n    protected void onCameraSetup(final Size cameraSize) {\n        ObjectDetectionOnDeviceModel onDeviceModel = FritzVisionModels.getObjectDetectionOnDeviceModel();\n        objectPredictor = FritzVision.ObjectDetection.getPredictor(onDeviceModel);\n    }\n\n    @Override\n    protected void handleDrawingResult(Canvas canvas, Size cameraSize) {\n        if (objectResult != null) {\n            List<FritzVisionObject> visionObjects = objectResult.getObjects();\n            for (FritzVisionObject object : visionObjects) {\n                object.draw(canvas);\n            }\n        }\n    }\n\n    @Override\n    protected void runInference(FritzVisionImage fritzVisionImage) {\n        objectResult = objectPredictor.predict(fritzVisionImage);\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/vision/PoseEstimationActivity.java",
    "content": "package ai.fritz.aistudio.activities.vision;\n\nimport android.graphics.Canvas;\nimport android.util.Size;\n\nimport java.util.List;\n\nimport ai.fritz.aistudio.activities.BaseLiveVideoActivity;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.filter.OneEuroFilterMethod;\nimport ai.fritz.vision.poseestimation.FritzVisionPosePredictor;\nimport ai.fritz.vision.poseestimation.FritzVisionPosePredictorOptions;\nimport ai.fritz.vision.poseestimation.FritzVisionPoseResult;\nimport ai.fritz.vision.poseestimation.Pose;\nimport ai.fritz.vision.poseestimation.PoseOnDeviceModel;\n\npublic class PoseEstimationActivity extends BaseLiveVideoActivity {\n\n    private FritzVisionPosePredictor posePredictor;\n    private FritzVisionPoseResult poseResult;\n    private FritzVisionPosePredictorOptions options;\n\n    @Override\n    protected void onCameraSetup(final Size cameraSize) {\n        PoseOnDeviceModel onDeviceModel = FritzVisionModels.getHumanPoseEstimationOnDeviceModel(ModelVariant.FAST);\n        options = new FritzVisionPosePredictorOptions();\n        options.smoothingOptions = new OneEuroFilterMethod();\n        posePredictor = FritzVision.PoseEstimation.getPredictor(onDeviceModel);\n    }\n\n    @Override\n    protected void handleDrawingResult(Canvas canvas, Size cameraSize) {\n        if (poseResult != null) {\n            List<Pose> poseList = poseResult.getPoses();\n            for (Pose pose : poseList) {\n                pose.draw(canvas);\n            }\n        }\n    }\n\n    @Override\n    protected void runInference(FritzVisionImage fritzVisionImage) {\n        poseResult = posePredictor.predict(fritzVisionImage);\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/vision/StyleTransferActivity.java",
    "content": "package ai.fritz.aistudio.activities.vision;\n\nimport android.graphics.Bitmap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.util.Size;\n\nimport ai.fritz.core.FritzOnDeviceModel;\nimport ai.fritz.aistudio.R;\nimport ai.fritz.aistudio.activities.BaseRecordingActivity;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.styletransfer.FritzVisionStylePredictor;\nimport ai.fritz.vision.styletransfer.FritzVisionStylePredictorOptions;\nimport ai.fritz.vision.styletransfer.FritzVisionStyleResult;\n\n\npublic class StyleTransferActivity extends BaseRecordingActivity implements OnImageAvailableListener {\n    private FritzVisionStylePredictor predictor;\n\n    @Override\n    public void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n    }\n\n    @Override\n    protected int getModelOptionsTextId() {\n        return R.array.style_transfer_options;\n    }\n\n    @Override\n    protected Bitmap runPrediction(FritzVisionImage visionImage, Size cameraViewSize) {\n        FritzVisionStyleResult styleResult = predictor.predict(visionImage);\n        return styleResult.toBitmap();\n    }\n\n    @Override\n    protected void loadPredictor(int choice) {\n        FritzOnDeviceModel onDeviceModel = getModel(choice);\n        FritzVisionStylePredictorOptions options = new FritzVisionStylePredictorOptions();\n        predictor = FritzVision.StyleTransfer.getPredictor(onDeviceModel, options);\n    }\n\n    private FritzOnDeviceModel getModel(int choice) {\n        FritzOnDeviceModel[] styles = FritzVisionModels.getPaintingStyleModels().getAll();\n        return styles[choice];\n    }\n}\n\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/adapters/DemoAdapter.java",
    "content": "package ai.fritz.aistudio.adapters;\n\nimport android.support.v7.widget.RecyclerView;\nimport android.view.LayoutInflater;\nimport android.view.ViewGroup;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\n\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport ai.fritz.aistudio.R;\n\n/**\n * Demo items adapter to manage the list of models.\n */\npublic class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.ViewHolder> {\n    private List<DemoItem> demoItems = new ArrayList<>();\n\n    /**\n     * View holder for each demo item to display in the list.\n     */\n    public static class ViewHolder extends RecyclerView.ViewHolder {\n        public LinearLayout linearLayout;\n        public TextView titleView;\n        public TextView descriptionView;\n\n        public ViewHolder(LinearLayout v) {\n            super(v);\n            linearLayout = v;\n            titleView = linearLayout.findViewById(R.id.title);\n            descriptionView = linearLayout.findViewById(R.id.description);\n        }\n    }\n\n    /**\n     * Initialize the adapter with a list of demo items.\n     *\n     * @param demoItems\n     */\n    public DemoAdapter(List<DemoItem> demoItems) {\n        this.demoItems = demoItems;\n    }\n\n    /**\n     * Get the DemoItem and binds it to the recycled view.\n     * <p>\n     * Also sets the click actions here.\n     *\n     * @param holder\n     * @param position\n     */\n    @Override\n    public void onBindViewHolder(DemoAdapter.ViewHolder holder, int position) {\n        DemoItem demoItem = demoItems.get(position);\n        holder.titleView.setText(demoItem.getTitle());\n        holder.descriptionView.setText(demoItem.getDescription());\n        holder.linearLayout.setOnClickListener(demoItem.getOnClickListener());\n    }\n\n    /**\n     * Get number of demo items.\n     *\n     * @return number of items in the list\n     */\n    @Override\n    public int getItemCount() {\n        return demoItems.size();\n    }\n\n    /**\n     * Create a view holder for the DemoItems\n     *\n     * @param parent\n     * @param viewType\n     * @return\n     */\n    @Override\n    public DemoAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,\n                                                     int viewType) {\n        LinearLayout v = (LinearLayout) LayoutInflater.from(parent.getContext())\n                .inflate(R.layout.list_item_demo, parent, false);\n        ViewHolder holder = new ViewHolder(v);\n        return holder;\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/adapters/DemoItem.java",
    "content": "package ai.fritz.aistudio.adapters;\n\nimport android.view.View;\n\n/**\n * Helper class to show demo items for the DemoAdapter\n */\npublic class DemoItem {\n\n    private String title;\n    private String description;\n    private View.OnClickListener onClickListener;\n\n    public DemoItem(String title, String description, View.OnClickListener clickListener) {\n        this.title = title;\n        this.description = description;\n        this.onClickListener = clickListener;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public String getDescription() {\n        return description;\n    }\n\n    public void setDescription(String description) {\n        this.description = description;\n    }\n\n    public View.OnClickListener getOnClickListener() {\n        return onClickListener;\n    }\n\n    public void setOnClickListener(View.OnClickListener onClickListener) {\n        this.onClickListener = onClickListener;\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/fragments/CameraConnectionFragment.java",
    "content": "package ai.fritz.aistudio.fragments;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.app.DialogFragment;\nimport android.app.Fragment;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.graphics.ImageFormat;\nimport android.graphics.Matrix;\nimport android.graphics.RectF;\nimport android.graphics.SurfaceTexture;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCaptureSession;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraDevice;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.CaptureRequest;\nimport android.hardware.camera2.CaptureResult;\nimport android.hardware.camera2.TotalCaptureResult;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.LayoutInflater;\nimport android.view.Surface;\nimport android.view.TextureView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\n\nimport ai.fritz.aistudio.R;\nimport ai.fritz.aistudio.ui.AutoFitTextureView;\n\npublic class CameraConnectionFragment extends Fragment {\n    private static final String TAG = CameraConnectionFragment.class.getSimpleName();\n\n    public CameraConnectionFragment() {\n\n    }\n\n    /**\n     * The camera preview size will be chosen to be the smallest frame by pixel size capable of\n     * containing a DESIRED_SIZE x DESIRED_SIZE square.\n     */\n    private static final int MINIMUM_PREVIEW_SIZE = 320;\n\n    /**\n     * Conversion from screen rotation to JPEG orientation.\n     */\n    private static final String FRAGMENT_DIALOG = \"dialog\";\n\n    /**\n     * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a\n     * {@link TextureView}.\n     */\n    private final TextureView.SurfaceTextureListener surfaceTextureListener =\n            new TextureView.SurfaceTextureListener() {\n                @Override\n                public void onSurfaceTextureAvailable(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    openCamera(width, height);\n                }\n\n                @Override\n                public void onSurfaceTextureSizeChanged(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    configureTransform(width, height);\n                }\n\n                @Override\n                public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {\n                    return true;\n                }\n\n                @Override\n                public void onSurfaceTextureUpdated(final SurfaceTexture texture) {\n                }\n            };\n\n    /**\n     * Callback for Activities to use to initialize their data once the\n     * selected preview size is known.\n     */\n    public interface ConnectionCallback {\n        void onPreviewSizeChosen(Size size, Size cameraViewSize, int cameraRotation);\n    }\n\n    /**\n     * ID of the current {@link CameraDevice}.\n     */\n    private String cameraId;\n\n    /**\n     * An {@link AutoFitTextureView} for camera preview.\n     */\n    private AutoFitTextureView textureView;\n\n    /**\n     * A {@link CameraCaptureSession } for camera preview.\n     */\n    private CameraCaptureSession captureSession;\n\n    /**\n     * A reference to the opened {@link CameraDevice}.\n     */\n    private CameraDevice cameraDevice;\n\n    /**\n     * The rotation in degrees of the camera sensor from the display.\n     */\n    private Integer sensorOrientation;\n\n    /**\n     * The {@link android.util.Size} of camera preview.\n     */\n    private Size previewSize;\n\n    /**\n     * {@link android.hardware.camera2.CameraDevice.StateCallback}\n     * is called when {@link CameraDevice} changes its state.\n     */\n    private final CameraDevice.StateCallback stateCallback =\n            new CameraDevice.StateCallback() {\n                @Override\n                public void onOpened(final CameraDevice cd) {\n                    // This method is called when the camera is opened.  We start camera preview here.\n                    cameraOpenCloseLock.release();\n                    cameraDevice = cd;\n                    createCameraPreviewSession();\n                }\n\n                @Override\n                public void onDisconnected(final CameraDevice cd) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                }\n\n                @Override\n                public void onError(final CameraDevice cd, final int error) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                    final Activity activity = getActivity();\n                    if (null != activity) {\n                        activity.finish();\n                    }\n                }\n            };\n\n    /**\n     * An additional thread for running tasks that shouldn't block the UI.\n     */\n    private HandlerThread backgroundThread;\n\n    /**\n     * A {@link Handler} for running tasks in the background.\n     */\n    private Handler backgroundHandler;\n\n    /**\n     * An {@link ImageReader} that handles preview frame capture.\n     */\n    private ImageReader previewReader;\n\n    /**\n     * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview\n     */\n    private CaptureRequest.Builder previewRequestBuilder;\n\n    /**\n     * {@link CaptureRequest} generated by {@link #previewRequestBuilder}\n     */\n    private CaptureRequest previewRequest;\n\n    /**\n     * A {@link Semaphore} to prevent the app from exiting before closing the camera.\n     */\n    private final Semaphore cameraOpenCloseLock = new Semaphore(1);\n\n    /**\n     * A {@link OnImageAvailableListener} to receive frames as they are available.\n     */\n    private OnImageAvailableListener imageListener = null;\n\n    /**\n     * The input size in pixels desired by TensorFlow (width and height of a square bitmap).\n     */\n    private Size inputSize = null;\n\n    /**\n     * The layout identifier to inflate for this Fragment.\n     */\n    private int layout = -1;\n\n\n    private ConnectionCallback cameraConnectionCallback = null;\n\n    private CameraConnectionFragment(\n            final ConnectionCallback connectionCallback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        this.cameraConnectionCallback = connectionCallback;\n        this.imageListener = imageListener;\n        this.layout = layout;\n        this.inputSize = inputSize;\n    }\n\n    /**\n     * Shows a {@link Toast} on the UI thread.\n     *\n     * @param text The message to show\n     */\n    private void showToast(final String text) {\n        final Activity activity = getActivity();\n        if (activity != null) {\n            activity.runOnUiThread(\n                    new Runnable() {\n                        @Override\n                        public void run() {\n                            Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();\n                        }\n                    });\n        }\n    }\n\n    /**\n     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose\n     * width and height are at least as large as the minimum of both, or an exact match if possible.\n     *\n     * @param choices The list of sizes that the camera supports for the intended output class\n     * @param width   The minimum desired width\n     * @param height  The minimum desired height\n     * @return The optimal {@code Size}, or an arbitrary one if none were big enough\n     */\n    protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {\n        final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);\n        final Size desiredSize = new Size(width, height);\n\n        // Collect the supported resolutions that are at least as big as the preview Surface\n        boolean exactSizeFound = false;\n        final List<Size> bigEnough = new ArrayList<Size>();\n        final List<Size> tooSmall = new ArrayList<Size>();\n        for (final Size option : choices) {\n            if (option.equals(desiredSize)) {\n                // Set the size but don't return yet so that remaining sizes will still be logged.\n                exactSizeFound = true;\n            }\n\n            if (option.getHeight() >= minSize && option.getWidth() >= minSize) {\n                bigEnough.add(option);\n            } else {\n                tooSmall.add(option);\n            }\n        }\n\n        Log.d(TAG, \"Desired size: \" + desiredSize + \", min size: \" + minSize + \"x\" + minSize);\n        Log.d(TAG, \"Valid preview sizes: [\" + TextUtils.join(\", \", bigEnough) + \"]\");\n        Log.d(TAG, \"Rejected preview sizes: [\" + TextUtils.join(\", \", tooSmall) + \"]\");\n\n        if (exactSizeFound) {\n            Log.d(TAG, \"Exact size match found.\");\n            return desiredSize;\n        }\n\n        // Pick the smallest of those, assuming we found any\n        if (bigEnough.size() > 0) {\n            final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());\n            Log.d(TAG, \"Chosen size: \" + chosenSize.getWidth() + \"x\" + chosenSize.getHeight());\n            return chosenSize;\n        } else {\n            Log.e(TAG, \"Couldn't find any suitable preview size\");\n            return choices[0];\n        }\n    }\n\n    public static CameraConnectionFragment newInstance(\n            final ConnectionCallback callback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        return new CameraConnectionFragment(callback, imageListener, layout, inputSize);\n    }\n\n    @Override\n    public View onCreateView(\n            final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {\n        return inflater.inflate(layout, container, false);\n    }\n\n    @Override\n    public void onViewCreated(final View view, final Bundle savedInstanceState) {\n        textureView = (AutoFitTextureView) view.findViewById(R.id.texture);\n    }\n\n    @Override\n    public void onActivityCreated(final Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        startBackgroundThread();\n\n        // When the screen is turned off and turned back on, the SurfaceTexture is already\n        // available, and \"onSurfaceTextureAvailable\" will not be called. In that case, we can open\n        // a camera and start preview from here (otherwise, we wait until the surface is ready in\n        // the SurfaceTextureListener).\n        if (textureView.isAvailable()) {\n            openCamera(textureView.getWidth(), textureView.getHeight());\n        } else {\n            textureView.setSurfaceTextureListener(surfaceTextureListener);\n        }\n    }\n\n    @Override\n    public void onPause() {\n        closeCamera();\n        stopBackgroundThread();\n        super.onPause();\n    }\n\n    public void setCamera(String cameraId) {\n        this.cameraId = cameraId;\n    }\n\n    /**\n     * Sets up member variables related to camera.\n     */\n    private void setUpCameraOutputs() {\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n            final StreamConfigurationMap map =\n                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n            // For still image captures, we use the largest available size.\n            final Size largest =\n                    Collections.max(\n                            Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),\n                            new CompareSizesByArea());\n\n            sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);\n\n            // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera\n            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of\n            // garbage capture data.\n            previewSize =\n                    chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),\n                            inputSize.getWidth(),\n                            inputSize.getHeight());\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, e.toString());\n        } catch (final NullPointerException e) {\n            // Currently an NPE is thrown when the Camera2API is used but not supported on the\n            // device this code runs.\n            // TODO(andrewharp): abstract ErrorDialog/RuntimeException handling out into new method and\n            // reuse throughout app.\n            ErrorDialog.newInstance(getString(R.string.camera_error))\n                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);\n            throw new RuntimeException(getString(R.string.camera_error));\n        }\n\n        Size textureViewSize = new Size(textureView.getWidth(), textureView.getHeight());\n        cameraConnectionCallback.onPreviewSizeChosen(previewSize, textureViewSize, sensorOrientation);\n    }\n\n    /**\n     * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.\n     */\n    private void openCamera(final int width, final int height) {\n        setUpCameraOutputs();\n        configureTransform(width, height);\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\n                throw new RuntimeException(\"Time out waiting to lock camera opening.\");\n            }\n            manager.openCamera(cameraId, stateCallback, backgroundHandler);\n        } catch (final CameraAccessException | SecurityException e) {\n            Log.e(TAG, e.toString());\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\n        }\n    }\n\n    /**\n     * Closes the current {@link CameraDevice}.\n     */\n    private void closeCamera() {\n        try {\n            cameraOpenCloseLock.acquire();\n            if (null != captureSession) {\n                captureSession.close();\n                captureSession = null;\n            }\n            if (null != cameraDevice) {\n                cameraDevice.close();\n                cameraDevice = null;\n            }\n            if (null != previewReader) {\n                previewReader.close();\n                previewReader = null;\n            }\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera closing.\", e);\n        } finally {\n            cameraOpenCloseLock.release();\n        }\n    }\n\n    /**\n     * Starts a background thread and its {@link Handler}.\n     */\n    private void startBackgroundThread() {\n        backgroundThread = new HandlerThread(\"ImageListener\");\n        backgroundThread.start();\n        backgroundHandler = new Handler(backgroundThread.getLooper());\n    }\n\n    /**\n     * Stops the background thread and its {@link Handler}.\n     */\n    private void stopBackgroundThread() {\n        backgroundThread.quitSafely();\n        try {\n            backgroundThread.join();\n            backgroundThread = null;\n            backgroundHandler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, e.toString());\n        }\n    }\n\n    private final CameraCaptureSession.CaptureCallback captureCallback =\n            new CameraCaptureSession.CaptureCallback() {\n                @Override\n                public void onCaptureProgressed(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final CaptureResult partialResult) {\n                }\n\n                @Override\n                public void onCaptureCompleted(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final TotalCaptureResult result) {\n                }\n            };\n\n    /**\n     * Creates a new {@link CameraCaptureSession} for camera preview.\n     */\n    private void createCameraPreviewSession() {\n        try {\n            final SurfaceTexture texture = textureView.getSurfaceTexture();\n            assert texture != null;\n\n            // We configure the size of default buffer to be the size of camera preview we want.\n            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());\n\n            // This is the output Surface we need to start preview.\n            final Surface surface = new Surface(texture);\n\n            // We set up a CaptureRequest.Builder with the output Surface.\n            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\n            previewRequestBuilder.addTarget(surface);\n\n            Log.d(TAG, \"Opening camera preview: \" + previewSize.getWidth() + \"x\" + previewSize.getHeight());\n\n            // Create the reader for the preview frames.\n            previewReader =\n                    ImageReader.newInstance(\n                            previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);\n\n            previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);\n            previewRequestBuilder.addTarget(previewReader.getSurface());\n\n            // Here, we create a CameraCaptureSession for camera preview.\n            cameraDevice.createCaptureSession(\n                    Arrays.asList(surface, previewReader.getSurface()),\n                    new CameraCaptureSession.StateCallback() {\n\n                        @Override\n                        public void onConfigured(final CameraCaptureSession cameraCaptureSession) {\n                            // The camera is already closed\n                            if (null == cameraDevice) {\n                                return;\n                            }\n\n                            // When the session is ready, we start displaying the preview.\n                            captureSession = cameraCaptureSession;\n                            try {\n                                // Auto focus should be continuous for camera preview.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AF_MODE,\n                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\n                                // Flash is automatically enabled when necessary.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);\n\n                                // Finally, we start displaying the camera preview.\n                                previewRequest = previewRequestBuilder.build();\n                                captureSession.setRepeatingRequest(\n                                        previewRequest, captureCallback, backgroundHandler);\n                            } catch (final CameraAccessException e) {\n                                Log.e(TAG, e.toString());\n                            }\n                        }\n\n                        @Override\n                        public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {\n                            showToast(\"Failed\");\n                        }\n                    },\n                    null);\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, e.toString());\n        }\n    }\n\n    /**\n     * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.\n     * This method should be called after the camera preview size is determined in\n     * setUpCameraOutputs and also the size of `mTextureView` is fixed.\n     *\n     * @param viewWidth  The width of `mTextureView`\n     * @param viewHeight The height of `mTextureView`\n     */\n    private void configureTransform(final int viewWidth, final int viewHeight) {\n        final Activity activity = getActivity();\n        if (null == textureView || null == previewSize || null == activity) {\n            return;\n        }\n        final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();\n        final Matrix matrix = new Matrix();\n        final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);\n        final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());\n        final float centerX = viewRect.centerX();\n        final float centerY = viewRect.centerY();\n        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {\n            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());\n            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);\n            final float scale =\n                    Math.max(\n                            (float) viewHeight / previewSize.getHeight(),\n                            (float) viewWidth / previewSize.getWidth());\n            matrix.postScale(scale, scale, centerX, centerY);\n            matrix.postRotate(90 * (rotation - 2), centerX, centerY);\n        } else if (Surface.ROTATION_180 == rotation) {\n            matrix.postRotate(180, centerX, centerY);\n        }\n        textureView.setTransform(matrix);\n    }\n\n    /**\n     * Compares two {@code Size}s based on their areas.\n     */\n    static class CompareSizesByArea implements Comparator<Size> {\n        @Override\n        public int compare(final Size lhs, final Size rhs) {\n            // We cast here to ensure the multiplications won't overflow\n            return Long.signum(\n                    (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());\n        }\n    }\n\n    /**\n     * Shows an error message dialog.\n     */\n    public static class ErrorDialog extends DialogFragment {\n        private static final String ARG_MESSAGE = \"message\";\n\n        public static ErrorDialog newInstance(final String message) {\n            final ErrorDialog dialog = new ErrorDialog();\n            final Bundle args = new Bundle();\n            args.putString(ARG_MESSAGE, message);\n            dialog.setArguments(args);\n            return dialog;\n        }\n\n        @Override\n        public Dialog onCreateDialog(final Bundle savedInstanceState) {\n            final Activity activity = getActivity();\n            return new AlertDialog.Builder(activity)\n                    .setMessage(getArguments().getString(ARG_MESSAGE))\n                    .setPositiveButton(\n                            android.R.string.ok,\n                            new DialogInterface.OnClickListener() {\n                                @Override\n                                public void onClick(final DialogInterface dialogInterface, final int i) {\n                                    activity.finish();\n                                }\n                            })\n                    .create();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/ui/AutoFitTextureView.java",
    "content": "/*\n * Copyright 2016 The TensorFlow Authors. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *       http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage ai.fritz.aistudio.ui;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.TextureView;\n\n/**\n * A {@link TextureView} that can be adjusted to a specified aspect ratio.\n */\npublic class AutoFitTextureView extends TextureView {\n    private int ratioWidth = 0;\n    private int ratioHeight = 0;\n\n    public AutoFitTextureView(final Context context) {\n        this(context, null);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    /**\n     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio\n     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that\n     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.\n     *\n     * @param width  Relative horizontal size\n     * @param height Relative vertical size\n     */\n    public void setAspectRatio(final int width, final int height) {\n        if (width < 0 || height < 0) {\n            throw new IllegalArgumentException(\"Size cannot be negative.\");\n        }\n        ratioWidth = width;\n        ratioHeight = height;\n        requestLayout();\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/ui/ChooseModelDialog.java",
    "content": "package ai.fritz.aistudio.ui;\n\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.content.DialogInterface;\nimport android.os.Bundle;\nimport android.support.v4.app.DialogFragment;\n\nimport ai.fritz.aistudio.R;\n\npublic class ChooseModelDialog extends DialogFragment {\n\n    public static final String TAG = ChooseModelDialog.class.getSimpleName();\n\n    private int choice = 0;\n    private int itemsResourceId;\n    private DialogInterface.OnClickListener listener;\n\n    public ChooseModelDialog(int itemsResourceId, DialogInterface.OnClickListener listener) {\n        this.itemsResourceId = itemsResourceId;\n        this.listener = listener;\n    }\n\n    @Override\n    public Dialog onCreateDialog(Bundle savedInstanceState) {\n        // Use the Builder class for convenient dialog construction\n        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.CustomDialog);\n        builder.setTitle(R.string.available_models)\n                .setItems(itemsResourceId, listener);\n        // Create the AlertDialog object and return it\n        return builder.create();\n    }\n\n    public int getChoice() {\n        return choice;\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/ui/DrawModel.java",
    "content": "package ai.fritz.aistudio.ui;\n\n/*\n   Copyright 2016 Narrative Nights Inc. All Rights Reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class DrawModel {\n\n    public static class LineElem {\n        public float x;\n        public float y;\n\n        private LineElem(float x, float y) {\n            this.x = x;\n            this.y = y;\n        }\n    }\n\n    public static class Line {\n        private List<LineElem> elems = new ArrayList<>();\n\n        private Line() {\n        }\n\n        private void addElem(LineElem elem) {\n            elems.add(elem);\n        }\n\n        public int getElemSize() {\n            return elems.size();\n        }\n\n        public LineElem getElem(int index) {\n            return elems.get(index);\n        }\n    }\n\n    private Line mCurrentLine;\n\n    private int mWidth;  // pixel width = 28\n    private int mHeight; // pixel height = 28\n\n    private List<Line> mLines = new ArrayList<>();\n\n    public DrawModel(int width, int height) {\n        this.mWidth = width;\n        this.mHeight = height;\n    }\n\n    public int getWidth() {\n        return mWidth;\n    }\n\n    public int getHeight() {\n        return mHeight;\n    }\n\n    public void startLine(float x, float y) {\n        mCurrentLine = new Line();\n        mCurrentLine.addElem(new LineElem(x, y));\n        mLines.add(mCurrentLine);\n    }\n\n    public void endLine() {\n        mCurrentLine = null;\n    }\n\n    public void addLineElem(float x, float y) {\n        if (mCurrentLine != null) {\n            mCurrentLine.addElem(new LineElem(x, y));\n        }\n    }\n\n    public int getLineSize() {\n        return mLines.size();\n    }\n\n    public Line getLine(int index) {\n        return mLines.get(index);\n    }\n\n    public void clear() {\n        mLines.clear();\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/ui/DrawRenderer.java",
    "content": "package ai.fritz.aistudio.ui;\n\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\n\n\npublic class DrawRenderer {\n    /**\n     * Draw lines to canvas\n     */\n    public static void renderModel(Canvas canvas, DrawModel model, Paint paint,\n                                   int startLineIndex) {\n        paint.setAntiAlias(true);\n\n        int lineSize = model.getLineSize();\n        for (int i = startLineIndex; i < lineSize; ++i) {\n            DrawModel.Line line = model.getLine(i);\n            paint.setColor(Color.BLACK);\n            int elemSize = line.getElemSize();\n            if (elemSize < 1) {\n                continue;\n            }\n            DrawModel.LineElem elem = line.getElem(0);\n            float lastX = elem.x;\n            float lastY = elem.y;\n\n            for (int j = 0; j < elemSize; ++j) {\n                elem = line.getElem(j);\n                float x = elem.x;\n                float y = elem.y;\n                canvas.drawLine(lastX, lastY, x, y, paint);\n                lastX = x;\n                lastY = y;\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/ui/DrawView.java",
    "content": "package ai.fritz.aistudio.ui;\n\n/*\n   Copyright 2016 Narrative Nights Inc. All Rights Reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.graphics.PointF;\nimport android.graphics.Rect;\nimport android.util.AttributeSet;\nimport android.view.View;\n\npublic class DrawView extends View {\n    private Paint mPaint = new Paint();\n    private DrawModel mModel;\n    // 28x28 pixel Bitmap\n    private Bitmap mOffscreenBitmap;\n    private Canvas mOffscreenCanvas;\n\n    private Matrix mMatrix = new Matrix();\n    private Matrix mInvMatrix = new Matrix();\n    private int mDrawnLineSize = 0;\n    private boolean mSetuped = false;\n\n    private float mTmpPoints[] = new float[2];\n\n    public DrawView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    public void setModel(DrawModel model) {\n        this.mModel = model;\n    }\n\n    public void reset() {\n        mDrawnLineSize = 0;\n        if (mOffscreenBitmap != null) {\n            mPaint.setColor(Color.WHITE);\n            int width = mOffscreenBitmap.getWidth();\n            int height = mOffscreenBitmap.getHeight();\n            mOffscreenCanvas.drawRect(new Rect(0, 0, width, height), mPaint);\n        }\n    }\n\n    private void setup() {\n        mSetuped = true;\n\n        // View size\n        float width = getWidth();\n        float height = getHeight();\n\n        // Model (bitmap) size\n        float modelWidth = mModel.getWidth();\n        float modelHeight = mModel.getHeight();\n\n        float scaleW = width / modelWidth;\n        float scaleH = height / modelHeight;\n\n        float scale = scaleW;\n        if (scale > scaleH) {\n            scale = scaleH;\n        }\n\n        float newCx = modelWidth * scale / 2;\n        float newCy = modelHeight * scale / 2;\n        float dx = width / 2 - newCx;\n        float dy = height / 2 - newCy;\n\n        mMatrix.setScale(scale, scale);\n        mMatrix.postTranslate(dx, dy);\n        mMatrix.invert(mInvMatrix);\n        mSetuped = true;\n    }\n\n    @Override\n    public void onDraw(Canvas canvas) {\n        if (mModel == null) {\n            return;\n        }\n        if (!mSetuped) {\n            setup();\n        }\n        if (mOffscreenBitmap == null) {\n            return;\n        }\n\n        int startIndex = mDrawnLineSize - 1;\n        if (startIndex < 0) {\n            startIndex = 0;\n        }\n\n        DrawRenderer.renderModel(mOffscreenCanvas, mModel, mPaint, startIndex);\n        canvas.drawBitmap(mOffscreenBitmap, mMatrix, mPaint);\n\n        mDrawnLineSize = mModel.getLineSize();\n    }\n\n    /**\n     * Convert screen position to local pos (pos in bitmap)\n     */\n    public void calcPos(float x, float y, PointF out) {\n        mTmpPoints[0] = x;\n        mTmpPoints[1] = y;\n        mInvMatrix.mapPoints(mTmpPoints);\n        out.x = mTmpPoints[0];\n        out.y = mTmpPoints[1];\n    }\n\n    public void onResume() {\n        createBitmap();\n    }\n\n    public void onPause() {\n        releaseBitmap();\n    }\n\n    private void createBitmap() {\n        if (mOffscreenBitmap != null) {\n            mOffscreenBitmap.recycle();\n        }\n        mOffscreenBitmap = Bitmap.createBitmap(mModel.getWidth(), mModel.getHeight(), Bitmap.Config.ARGB_8888);\n        mOffscreenCanvas = new Canvas(mOffscreenBitmap);\n        reset();\n    }\n\n    private void releaseBitmap() {\n        if (mOffscreenBitmap != null) {\n            mOffscreenBitmap.recycle();\n            mOffscreenBitmap = null;\n            mOffscreenCanvas = null;\n        }\n        reset();\n    }\n\n    public Bitmap getDrawnBitmap() {\n        return mOffscreenBitmap;\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/ui/OverlayView.java",
    "content": "package ai.fritz.aistudio.ui;\n/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n    http://www.apache.org/licenses/LICENSE-2.0\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n==============================================================================*/\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.util.AttributeSet;\nimport android.view.View;\n\n/**\n * A simple View providing a render callback to other classes.\n */\npublic class OverlayView extends View {\n    private DrawCallback callback;\n\n    public OverlayView(final Context context, final AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    /**\n     * Interface defining the callback for client classes.\n     */\n    public interface DrawCallback {\n        public void drawCallback(final Canvas canvas);\n    }\n\n    public void setCallback(final DrawCallback callback) {\n        this.callback = callback;\n    }\n\n    @Override\n    public synchronized void draw(final Canvas canvas) {\n        super.draw(canvas);\n        if(callback != null) {\n            callback.drawCallback(canvas);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/ui/RecognitionScoreView.java",
    "content": "package ai.fritz.aistudio.ui;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.util.AttributeSet;\nimport android.util.TypedValue;\nimport android.view.View;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport ai.fritz.aistudio.activities.custommodel.ml.Classifier.Recognition;\nimport ai.fritz.vision.FritzVisionLabel;\n\npublic class RecognitionScoreView extends View implements ResultsView {\n    private static final float TEXT_SIZE_DIP = 24;\n    private List<Recognition> results = new ArrayList<>();\n    private List<FritzVisionLabel> labels = new ArrayList<>();\n    private final float textSizePx;\n    private final Paint fgPaint;\n    private final Paint bgPaint;\n\n    public RecognitionScoreView(final Context context, final AttributeSet set) {\n        super(context, set);\n\n        textSizePx =\n                TypedValue.applyDimension(\n                        TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics());\n        fgPaint = new Paint();\n        fgPaint.setTextSize(textSizePx);\n\n        bgPaint = new Paint();\n        bgPaint.setColor(0xcc4285f4);\n    }\n\n    @Override\n    public void setResults(final List<Recognition> results) {\n        this.results = results;\n        postInvalidate();\n    }\n\n    @Override\n    public void setResult(final List<FritzVisionLabel> labels) {\n        this.labels = labels;\n        postInvalidate();\n    }\n\n    @Override\n    public void onDraw(final Canvas canvas) {\n        final int x = 10;\n        int y = (int) (fgPaint.getTextSize() * 1.5f);\n\n        canvas.drawPaint(bgPaint);\n\n        if (results.size() > 0) {\n            for (final Recognition recog : results) {\n                canvas.drawText(recog.getTitle() + \": \" + recog.getConfidence(), x, y, fgPaint);\n                y += fgPaint.getTextSize() * 1.5f;\n            }\n        }\n\n        if (labels.size() > 0) {\n            for (final FritzVisionLabel label : labels) {\n                canvas.drawText(label.getText() + \": \" + label.getConfidence(), x, y, fgPaint);\n                y += fgPaint.getTextSize() * 1.5f;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/ui/ResultsView.java",
    "content": "package ai.fritz.aistudio.ui;\n\nimport java.util.List;\n\nimport ai.fritz.aistudio.activities.custommodel.ml.Classifier.Recognition;\nimport ai.fritz.vision.FritzVisionLabel;\n\npublic interface ResultsView {\n    void setResults(final List<Recognition> results);\n\n    void setResult(final List<FritzVisionLabel> labels);\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/ui/SeparatorDecoration.java",
    "content": "package ai.fritz.aistudio.ui;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.support.annotation.ColorInt;\nimport android.support.annotation.FloatRange;\nimport android.support.annotation.NonNull;\nimport android.support.v7.widget.RecyclerView;\nimport android.util.TypedValue;\nimport android.view.View;\n\n/**\n * Taken from https://github.com/bleeding182/recyclerviewItemDecorations\n */\npublic class SeparatorDecoration extends RecyclerView.ItemDecoration {\n\n    private final Paint mPaint;\n\n    /**\n     * Create a decoration that draws a line in the given color and width between the items in the view.\n     *\n     * @param context  a context to access the resources.\n     * @param color    the color of the separator to draw.\n     * @param heightDp the height of the separator in dp.\n     */\n    public SeparatorDecoration(@NonNull Context context, @ColorInt int color,\n                               @FloatRange(from = 0, fromInclusive = false) float heightDp) {\n        mPaint = new Paint();\n        mPaint.setColor(color);\n        final float thickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,\n                heightDp, context.getResources().getDisplayMetrics());\n        mPaint.setStrokeWidth(thickness);\n    }\n\n    @Override\n    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {\n        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();\n\n        // we want to retrieve the position in the list\n        final int position = params.getViewAdapterPosition();\n\n        // and add a separator to any view but the last one\n        if (position < state.getItemCount()) {\n            outRect.set(0, 0, 0, (int) mPaint.getStrokeWidth()); // left, top, right, bottom\n        } else {\n            outRect.setEmpty(); // 0, 0, 0, 0\n        }\n    }\n\n    @Override\n    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {\n        // we set the stroke width before, so as to correctly draw the line we have to offset by width / 2\n        final int offset = (int) (mPaint.getStrokeWidth() / 2);\n\n        // this will iterate over every visible view\n        for (int i = 0; i < parent.getChildCount(); i++) {\n            // get the view\n            final View view = parent.getChildAt(i);\n            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();\n\n            // get the position\n            final int position = params.getViewAdapterPosition();\n\n            // and finally draw the separator\n            if (position < state.getItemCount()) {\n                c.drawLine(view.getLeft(), view.getBottom() + offset, view.getRight(), view.getBottom() + offset, mPaint);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/utils/VideoProcessingQueue.java",
    "content": "package ai.fritz.aistudio.utils;\n\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.util.Log;\n\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.vision.FritzVisionImage;\n\npublic class VideoProcessingQueue {\n    private static final String TAG = VideoProcessingQueue.class.getSimpleName();\n\n    public interface Listener {\n        void processVisionImage(FritzVisionImage visionImage);\n\n        void finishedProcessing();\n    }\n\n    private AtomicBoolean isProcessingQueue = new AtomicBoolean(false);\n\n    private LinkedBlockingQueue<FritzVisionImage> recordedImages;\n    private Listener listener;\n    private Handler handler;\n\n\n    public VideoProcessingQueue(Listener listener) {\n        recordedImages = new LinkedBlockingQueue<>();\n        this.listener = listener;\n        HandlerThread handlerThread = new HandlerThread(\"Video Processing Thread\");\n        handlerThread.start();\n        this.handler = new Handler(handlerThread.getLooper());\n    }\n\n    public void addVisionImage(FritzVisionImage visionImage) {\n        recordedImages.add(visionImage);\n        if (isProcessingQueue.compareAndSet(false, true)) {\n            runQueueProcessor();\n        }\n    }\n\n    public int getNumFramesToProcess() {\n        return recordedImages.size();\n    }\n\n    private void runQueueProcessor() {\n        handler.post(new Runnable() {\n            @Override\n            public void run() {\n                while (!recordedImages.isEmpty()) {\n                    FritzVisionImage visionImage = recordedImages.poll();\n                    Log.d(TAG, \"Processing Image\");\n                    listener.processVisionImage(visionImage);\n                }\n                listener.finishedProcessing();\n                isProcessingQueue.set(false);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/drawable/circle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item>\n        <shape\n            android:shape=\"ring\"\n            android:thicknessRatio=\"16\"\n            android:useLevel=\"false\"></shape>\n    </item>\n    <item>\n        <rotate\n            android:fromDegrees=\"270\"\n            android:pivotX=\"50%\"\n            android:pivotY=\"50%\"\n            android:toDegrees=\"270\">\n            <shape\n                android:shape=\"ring\"\n                android:thicknessRatio=\"16\"\n                android:useLevel=\"true\">\n                <solid android:color=\"@color/brass\" />\n            </shape>\n        </rotate>\n    </item>\n</layer-list>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/drawable/circle_white.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item>\n        <shape\n            android:shape=\"ring\"\n            android:thicknessRatio=\"16\"\n            android:useLevel=\"false\"></shape>\n    </item>\n    <item>\n        <rotate\n            android:fromDegrees=\"270\"\n            android:pivotX=\"50%\"\n            android:pivotY=\"50%\"\n            android:toDegrees=\"270\">\n            <shape\n                android:shape=\"ring\"\n                android:thicknessRatio=\"16\"\n                android:useLevel=\"true\">\n                <solid android:color=\"#fff\" />\n            </shape>\n        </rotate>\n    </item>\n</layer-list>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/drawable/ic_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24.0\"\n    android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        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\"/>\n</vector>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/drawable/ic_heartbeat_logo.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"260dp\"\n        android:height=\"204dp\"\n        android:viewportWidth=\"260.61\"\n        android:viewportHeight=\"204.35\">\n    <path\n        android:pathData=\"M29.09,189.82H17.73V174.43h-3.5v15.65H0v3.36l14.23,0.05v10.86h3.5v-11h11.35v11h3.5v-29.92h-3.5V189.82zM44.34,204.35h15.6v-3.53H47.84v-7.45h10.38v-3.55H47.84v-11.86h12.1v-3.53H44.34V204.35zM79.14,174.43l-10.56,29.92h3.67l7.04,-20.96l7.33,20.96h3.67l-10.85,-29.92H79.14zM116,185.2c0,-6.03 -4.91,-10.77 -11.15,-10.77h-4.62v29.9h3.5v-8.15l1.33,-0.02c0.81,-0.02 1.64,-0.13 2.44,-0.31l4.95,8.5h4.04l-5.72,-9.83C113.99,192.53 116,189.11 116,185.2zM105.02,192.66h-1.28v-14.7h1.12c4.37,0 7.64,3.13 7.64,7.24C112.5,189.3 109.22,192.57 105.02,192.66zM124.54,177.86h6.13v26.49h3.52v-26.49h5.82v-3.53h-15.47V177.86zM162.32,186.33c0.99,-1.32 1.49,-2.8 1.49,-4.43c0,-4.09 -3.42,-7.45 -7.64,-7.47h-5.39v29.92h8.66c5.22,-0.06 9.45,-4.18 9.45,-9.25C168.89,191.09 166.2,187.56 162.32,186.33zM154.29,177.96h1.87c2.32,0 4.18,1.79 4.18,3.94c0,2.17 -1.86,3.95 -4.16,3.97h-1.89V177.96zM159.42,200.82h-5.14v-11.42h5.12c3.31,0.02 6.01,2.59 6.01,5.7C165.41,198.25 162.72,200.8 159.42,200.82zM179.25,204.35h15.6v-3.53h-12.1v-7.45h10.38v-3.55h-10.38v-11.86h12.1v-3.53h-15.6V204.35zM214.06,174.43l-10.56,29.92h3.67l7.04,-20.96l7.33,20.96h3.67l-10.85,-29.92H214.06zM230.74,174.33v3.53h6.13v26.49h3.52v-26.49h20.22v-3.53H230.74zM205.92,28.99L187.2,0h-38.85l-18.02,27.44L112.7,0H73.99L55.2,28.99l75.36,115.49L205.92,28.99zM62.62,28.99L77.55,5.61h31.59l21.18,32.9L151.97,5.61h31.59l14.86,23.38L174.75,65.68h-25.02l-10.2,14.81l-21.57,-33.46l-11.92,18.64l0,0.01H86.16L62.62,28.99zM89.74,71.27h20.26l7.96,-13.1l21.74,33.15l13.96,-20.04h17.49l-40.82,63.03L89.74,71.27z\"\n        android:fillType=\"evenOdd\"\n        android:fillColor=\"#9D8C3D\"/>\n</vector>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/drawable/round_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\">\n    <stroke\n        android:color=\"#FFFF\"\n        android:width=\"5dip\"/>\n    <size android:width=\"100dp\" android:height=\"100dp\"/>\n</shape>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/drawable/splash_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item android:drawable=\"@color/colorPrimary\" />\n\n    <item>\n        <bitmap android:src=\"@drawable/aistudio_logo\"\n            android:gravity=\"center\" />\n\n    </item>\n\n</layer-list>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/font/sf_display.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <font\n        android:font=\"@font/sf_ui_display_bold\"\n        android:fontStyle=\"normal\"\n        android:fontWeight=\"700\"\n        app:font=\"@font/sf_ui_display_bold\"\n        app:fontStyle=\"normal\"\n        app:fontWeight=\"700\" />\n    <font\n        android:font=\"@font/sf_ui_display_regular\"\n        android:fontStyle=\"normal\"\n        android:fontWeight=\"400\"\n        app:font=\"@font/sf_ui_display_regular\"\n        app:fontStyle=\"normal\"\n        app:fontWeight=\"400\" />\n    <font\n        android:font=\"@font/sf_ui_display_light\"\n        android:fontStyle=\"normal\"\n        android:fontWeight=\"200\"\n        app:font=\"@font/sf_ui_display_light\"\n        app:fontStyle=\"normal\"\n        app:fontWeight=\"200\" />\n</font-family>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/activity_camera.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n Copyright 2016 The TensorFlow Authors. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <include layout=\"@layout/app_bar\" />\n\n    <FrameLayout\n        android:id=\"@+id/camera_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        tools:context=\"ai.fritz.aistudio.activities.BaseCameraActivity\" />\n</android.support.constraint.ConstraintLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/activity_fritz_vision.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n    android:paddingBottom=\"@dimen/margin_md\"\n    android:paddingLeft=\"@dimen/margin_md\"\n    android:paddingRight=\"@dimen/margin_md\"\n    android:paddingTop=\"@dimen/margin_md\"\n    tools:context=\"ai.fritz.aistudio.VisionActivity\">\n\n    <include layout=\"@layout/app_bar\" />\n    \n    <ImageView\n        android:id=\"@+id/image_preview\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"200dp\"\n        android:maxWidth=\"200dp\"\n        />\n\n    <TextView\n        android:id=\"@+id/vision_result\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"1\"\n        android:paddingTop=\"@dimen/margin_sm\"\n        android:paddingBottom=\"@dimen/margin_sm\"\n        android:text=\"\"\n        android:textAppearance=\"?android:attr/textAppearanceMedium\" />\n\n    <Button\n        android:id=\"@+id/select_photo\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginRight=\"@dimen/margin_md\"\n        android:background=\"@color/lighter_black_bg\"\n        android:text=\"@string/select_photo\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"ai.fritz.aistudio.activities.MainActivity\">\n\n    <include layout=\"@layout/app_bar\" />\n\n    <android.support.v7.widget.RecyclerView\n        android:id=\"@+id/demo_list_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginTop=\"?attr/actionBarSize\"\n        android:scrollbars=\"vertical\" />\n\n</android.support.constraint.ConstraintLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/activity_mnist.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:paddingLeft=\"@dimen/margin_md\"\n    android:paddingRight=\"@dimen/margin_md\"\n    android:paddingTop=\"@dimen/margin_md\"\n    android:paddingBottom=\"@dimen/margin_md\"\n    android:orientation=\"vertical\">\n\n    <include layout=\"@layout/app_bar\" />\n\n    <ai.fritz.aistudio.ui.DrawView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:id=\"@+id/view_draw\"\n        android:layout_weight=\"1\"/>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:orientation=\"horizontal\"\n        android:layout_height=\"wrap_content\">\n\n        <Button\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"@string/clear\"\n            android:background=\"@color/lighter_black_bg\"\n            android:layout_marginRight=\"@dimen/margin_md\"\n            android:id=\"@+id/button_clear\"/>\n\n        <Button\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"@color/lighter_black_bg\"\n            android:text=\"@string/detect\"\n            android:id=\"@+id/button_detect\"/>\n\n        <TextView\n            android:paddingLeft=\"@dimen/margin_sm\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"\n            android:textAppearance=\"?android:attr/textAppearanceMedium\"\n            android:text=\"\"\n            android:id=\"@+id/text_result\"/>\n    </LinearLayout>\n\n</LinearLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/activity_tfmobile_camera.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n Copyright 2016 The TensorFlow Authors. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/container\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"#000\"\n    tools:context=\".activities.MainActivity\">\n    <include layout=\"@layout/app_bar\" />\n</FrameLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/app_bar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v7.widget.Toolbar xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/app_toolbar\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"?attr/actionBarSize\"\n    android:layout_alignParentTop=\"true\"\n    android:elevation=\"4dp\"\n    android:background=\"@color/appBarColor\"\n    android:theme=\"@style/ThemeOverlay.AppCompat.ActionBar\"\n    app:popupTheme=\"@style/ThemeOverlay.AppCompat.Light\" />\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/camera_connection_fragment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n Copyright 2016 The TensorFlow Authors. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <ai.fritz.aistudio.ui.AutoFitTextureView\n        android:id=\"@+id/texture\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentTop=\"true\" />\n\n    <ai.fritz.aistudio.ui.RecognitionScoreView\n        android:id=\"@+id/results\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"112dp\"\n        android:layout_alignParentBottom=\"true\" />\n\n    <ai.fritz.aistudio.ui.OverlayView\n        android:id=\"@+id/debug_overlay\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\" />\n\n</RelativeLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/camera_connection_fragment_recording.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <ai.fritz.aistudio.ui.AutoFitTextureView\n        android:id=\"@+id/texture\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\" />\n\n    <ai.fritz.aistudio.ui.OverlayView\n        android:id=\"@+id/debug_overlay\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"\n        android:visibility=\"gone\" />\n\n    <ProgressBar\n        android:id=\"@+id/loadingModelSpinner\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:indeterminateTint=\"#fff\"\n        android:visibility=\"gone\"\n        android:layout_centerInParent=\"true\" />\n\n    <ProgressBar\n        android:id=\"@+id/processingVideoProgress\"\n        style=\"?android:attr/progressBarStyleHorizontal\"\n        android:layout_width=\"80dp\"\n        android:layout_height=\"80dp\"\n        android:layout_centerInParent=\"true\"\n        android:indeterminate=\"false\"\n        android:indeterminateTint=\"#fff\"\n        android:progressDrawable=\"@drawable/circle_white\"\n        android:visibility=\"gone\" />\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"120dp\"\n        android:layout_alignParentBottom=\"true\"\n        android:layout_marginTop=\"@dimen/margin_sm\"\n        android:layout_marginBottom=\"@dimen/margin_xl\">\n\n        <Button\n            android:id=\"@+id/take_video_btn\"\n            android:layout_width=\"80dp\"\n            android:layout_height=\"80dp\"\n            android:layout_centerInParent=\"true\"\n            android:background=\"@drawable/round_button\"\n            android:textColor=\"#fff\" />\n\n        <ProgressBar\n            android:id=\"@+id/videoRecordingProgress\"\n            style=\"?android:attr/progressBarStyleHorizontal\"\n            android:layout_width=\"120dp\"\n            android:layout_height=\"120dp\"\n            android:layout_centerInParent=\"true\"\n            android:indeterminate=\"false\"\n            android:progressDrawable=\"@drawable/circle\" />\n    </RelativeLayout>\n\n    <Button\n        android:id=\"@+id/choose_model_btn\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentBottom=\"true\"\n        android:background=\"@color/colorPrimary\"\n        android:foreground=\"?attr/selectableItemBackground\"\n        android:gravity=\"center_horizontal\"\n        android:paddingTop=\"15dp\"\n        android:paddingBottom=\"15dp\"\n        android:textAlignment=\"gravity\"\n        android:textColor=\"#FFF\"\n        android:textSize=\"18sp\"\n        android:textStyle=\"bold\" />\n\n    <Button\n        android:id=\"@+id/close_btn\"\n        android:layout_width=\"50dp\"\n        android:layout_height=\"50dp\"\n        android:layout_alignParentTop=\"true\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_marginTop=\"@dimen/margin_md\"\n        android:layout_marginRight=\"@dimen/margin_md\"\n        android:background=\"@drawable/ic_close\"\n        android:visibility=\"gone\" />\n</RelativeLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/camera_connection_fragment_stylize.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n Copyright 2016 The TensorFlow Authors. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      android:orientation=\"vertical\"\n      android:layout_width=\"match_parent\"\n      android:layout_height=\"match_parent\">\n  <ai.fritz.aistudio.ui.AutoFitTextureView\n    android:id=\"@+id/texture\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:layout_alignParentTop=\"true\" />\n\n  <RelativeLayout\n    android:id=\"@+id/black\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"#FF000000\" />\n\n  <GridView\n    android:id=\"@+id/grid_layout\"\n    android:numColumns=\"7\"\n    android:stretchMode=\"columnWidth\"\n    android:layout_alignParentBottom=\"true\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\" />\n\n  <ai.fritz.aistudio.ui.OverlayView\n    android:id=\"@+id/debug_overlay\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layout_alignParentTop=\"true\" />\n</RelativeLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/camera_connection_fragment_tracking.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n      <ai.fritz.aistudio.ui.AutoFitTextureView\n          android:id=\"@+id/texture\"\n          android:layout_width=\"match_parent\"\n          android:layout_height=\"match_parent\"\n          android:layout_alignParentTop=\"true\"/>\n\n      <ai.fritz.aistudio.ui.OverlayView\n          android:id=\"@+id/debug_overlay\"\n          android:layout_width=\"match_parent\"\n          android:layout_height=\"match_parent\"\n          android:layout_alignParentTop=\"true\"/>\n\n      <Button\n          android:id=\"@+id/chose_model_btn\"\n          android:layout_width=\"match_parent\"\n          android:layout_height=\"wrap_content\"\n          android:paddingBottom=\"10dp\"\n          android:paddingTop=\"10dp\"\n          android:layout_alignParentBottom=\"true\"\n          android:gravity=\"center_horizontal\"\n          android:textSize=\"18sp\"\n          android:textColor=\"#FFF\"\n          android:background=\"@color/colorPrimary\"\n          android:textStyle=\"bold\"\n          android:visibility=\"gone\"\n          android:textAlignment=\"gravity\"\n          android:foreground=\"?attr/selectableItemBackground\"/>\n</RelativeLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/camera_connection_snapshot.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n Copyright 2016 The TensorFlow Authors. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:id=\"@+id/preview_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <ai.fritz.aistudio.ui.AutoFitTextureView\n            android:id=\"@+id/texture\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\" />\n\n        <RelativeLayout\n            android:id=\"@+id/black\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:background=\"#FF000000\" />\n\n        <ai.fritz.aistudio.ui.OverlayView\n            android:id=\"@+id/debug_overlay\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\" />\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginTop=\"@dimen/margin_sm\"\n            android:layout_marginBottom=\"@dimen/margin_md\"\n            android:layout_alignParentBottom=\"true\">\n            <Button\n                android:id=\"@+id/take_picture_btn\"\n                android:layout_width=\"80dp\"\n                android:layout_height=\"80dp\"\n                android:layout_centerInParent=\"true\"\n                android:background=\"@drawable/round_button\"\n                android:textColor=\"#fff\" />\n\n            <ProgressBar\n                android:id=\"@+id/spinner\"\n                style=\"?android:attr/progressBarStyleLarge\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:visibility=\"gone\"\n                android:indeterminateTint=\"#fff\"\n                android:layout_centerInParent=\"true\" />\n\n        </RelativeLayout>\n    </RelativeLayout>\n\n    <RelativeLayout\n        android:id=\"@+id/snapshot_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\">\n\n        <ai.fritz.aistudio.ui.OverlayView\n            android:id=\"@+id/snapshot_view\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\" />\n\n        <Button\n            android:id=\"@+id/close_btn\"\n            android:layout_width=\"50dp\"\n            android:layout_height=\"50dp\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_marginTop=\"@dimen/margin_xl\"\n            android:layout_marginRight=\"@dimen/margin_md\"\n            android:layout_alignParentRight=\"true\"\n            android:background=\"@drawable/ic_close\" />\n\n\n    </RelativeLayout>\n\n\n</RelativeLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/list_item_demo.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:theme=\"@android:style/ThemeOverlay.Material.Dark\"\n    android:background=\"?android:selectableItemBackground\"\n    android:layout_height=\"wrap_content\"\n    android:layout_width=\"match_parent\"\n    android:padding=\"@dimen/margin_md\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/title\"\n        style=\"@style/HeaderText\"\n        android:layout_height=\"wrap_content\"\n        android:layout_width=\"wrap_content\"\n        android:text=\"Header\"\n        android:layout_marginBottom=\"@dimen/margin_sm\" />\n\n    <TextView\n        android:id=\"@+id/description\"\n        style=\"@style/BodyText\"\n        android:layout_height=\"wrap_content\"\n        android:layout_width=\"wrap_content\"\n        android:text=\"Some Description\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/layout/list_text_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n Copyright 2017 The TensorFlow Authors. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n<TextView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/list_text_item\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:text=\"TextView\"\n    android:textSize=\"24dp\"\n    android:textAlignment=\"center\"\n    android:gravity=\"center_horizontal\"\n    />\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@color/ic_launcher_background\"/>\n    <foreground android:drawable=\"@mipmap/ic_launcher_foreground\"/>\n</adaptive-icon>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@color/ic_launcher_background\"/>\n    <foreground android:drawable=\"@mipmap/ic_launcher_foreground\"/>\n</adaptive-icon>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#000</color>\n    <color name=\"colorAccent\">#FF4081</color>\n    <color name=\"textColorPrimary\">#fff</color>\n    <color name=\"divider\">#aaa</color>\n    <color name=\"appBarColor\">#000</color>\n    <color name=\"lighter_black_bg\">#666</color>\n    <color name=\"brass\">#9F8D36</color>\n</resources>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/values/custom_models.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <!-- In the production demo account -->\n    <string name=\"inception_v3_model_id\">08c1cea18756489cb244952aa7b218a0</string>\n    <string name=\"tflite_model_id\">7bf64aad64b7420f94f9c106a5e96cbd</string>\n</resources>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/values/dimens.xml",
    "content": "<!--\n  Copyright 2013 The Android Open Source Project\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n\n<resources>\n\n    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->\n\n    <dimen name=\"margin_xs\">4dp</dimen>\n    <dimen name=\"margin_sm\">8dp</dimen>\n    <dimen name=\"margin_md\">16dp</dimen>\n    <dimen name=\"margin_lg\">32dp</dimen>\n    <dimen name=\"margin_xl\">64dp</dimen>\n\n    <!-- Semantic definitions -->\n\n    <dimen name=\"horizontal_page_margin\">@dimen/margin_md</dimen>\n    <dimen name=\"vertical_page_margin\">@dimen/margin_md</dimen>\n\n</resources>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/values/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"ic_launcher_background\">#000000</color>\n</resources>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Fritz AI Studio</string>\n    <!-- In the MainActivity -->\n    <string name=\"demo_title\">Fritz AI Studio</string>\n\n    <string name=\"fritz_vision_style_transfer\">Style Transfer</string>\n    <string name=\"fritz_vision_style_transfer_description\">Run style transfer on live video feed.</string>\n\n    <string name=\"fritz_vision_title\">Image Labeling</string>\n    <string name=\"fritz_vision_description\">Label a still image.</string>\n    <string name=\"fritz_vision_description_live_video\">Label video frames</string>\n\n    <string name=\"fritz_customtfmobile_title\">Custom TFMobile Model</string>\n    <string name=\"fritz_customtfmobile_description\">Demonstrates using a TFMobile model to label images. Note, this is not a prebuilt model provided by the Vision API.</string>\n\n    <string name=\"fritz_customtflite_title\">Custom TFLite Model</string>\n    <string name=\"fritz_customtflite_description\">Demonstrates using a custom TFLite model to identify handwritten numbers. Note, this is not a prebuilt model provided by the Vision API.</string>\n\n    <string name=\"fritz_handwriting_detection\">Handwriting Detection</string>\n    <string name=\"fritz_handwriting_detection_description\">Detects numbers from 0-9. Draw a number on the canvas and guess what it is.</string>\n\n    <string name=\"fritz_info_title\">Learn More About Fritz AI</string>\n    <string name=\"fritz_info_description\">Teach your mobile app to see, hear, sense, and think.</string>\n\n    <string name=\"fritz_object_detection_title\">Object Detection</string>\n    <string name=\"fritz_object_detection_description\">Detect objects in an image and label them</string>\n\n    <string name=\"fritz_vision_img_seg_title\">Image Segmentation</string>\n    <string name=\"fritz_vision_img_seg_description\">Take a picture and identify people in the photo (highlighted in blue).</string>\n\n    <string name=\"fritz_pose_estimation_title\">Pose Estimation</string>\n    <string name=\"fritz_pose_estimation_description\">Detect body position and keypoints.</string>\n\n    <string name=\"fritz_vision_people_segmentation_title\">People Segmentation</string>\n    <string name=\"fritz_vision_people_segmentation_description\">Create a mask on people in an image.</string>\n\n    <string name=\"fritz_vision_living_room_segmentation_title\">Living Room Segmentation</string>\n    <string name=\"fritz_vision_living_room_segmentation_description\">Create a mask on living room objects.</string>\n\n    <string name=\"fritz_vision_outdoor_segmentation_title\">Outdoor Segmentation</string>\n    <string name=\"fritz_vision_outdoor_segmentation_description\">Create a mask on outdoor objects in an image.</string>\n\n    <string name=\"mnist_title\">MNIST</string>\n    <string name=\"mnist_description\">Classic MNIST handwriting recognizer for digits 0&#8211;9</string>\n    <string name=\"picture\">Picture</string>\n    <string name=\"description_info\">Info</string>\n    <string name=\"request_permission\">This sample needs camera permission.</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n    <string name=\"toggle_turn_on\">NN:On</string>\n    <string name=\"toggle_turn_off\">NN:Off</string>\n    <string name=\"toggle\">Use NNAPI</string>\n    <string name=\"clear\">Clear</string>\n    <string name=\"select_photo\">Select Photo</string>\n    <string name=\"detect\">Detect</string>\n    <string name=\"not_detected\">Not detected</string>\n    <string name=\"found_digits\">Detected = %1$s</string>\n    <string name=\"available_models\">Available Models</string>\n    <string name=\"fritz_hair_color_title\">Hair Coloring</string>\n    <string name=\"fritz_hair_color_description\">Change your hair color with Image Segmentation.</string>\n\n    <string-array name=\"img_seg_model_options\">\n        <item>People</item>\n        <item>Living Room</item>\n        <item>Outdoor</item>\n    </string-array>\n    <string-array name=\"style_transfer_options\">\n        <item>Bicentennial Print</item>\n        <item>Femmes</item>\n        <item>Head of Clown</item>\n        <item>Horses on Seashore</item>\n        <item>Kaleidoscope</item>\n        <item>Pink Blue Rhombus</item>\n        <item>Poppy Field</item>\n        <item>Ritmo Plastico</item>\n        <item>Starry Night</item>\n        <item>The Scream</item>\n        <item>The Trail</item>\n    </string-array>\n</resources>\n"
  },
  {
    "path": "Android/FritzAIStudio/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.DayNight.NoActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimary</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n\n        <item name=\"android:windowBackground\">@color/colorPrimary</item>\n        <item name=\"android:textColor\">@color/textColorPrimary</item>\n        <item name=\"android:fontFamily\">@font/sf_display</item>\n        <item name=\"android:textColorPrimary\">@color/textColorPrimary</item>\n        <item name=\"android:dialogTheme\">@style/CustomDialog</item>s\n    </style>\n    <!-- Splash Theme -->\n     <style\n         name=\"SplashTheme\"\n         parent=\"Theme.AppCompat.NoActionBar\" >\n         <item name=\"android:windowBackground\">\n             @drawable/splash_bg\n         </item>\n     </style>\n\n    <style name=\"MainTheme\" parent=\"Theme.AppCompat.NoActionBar\">\n        <item name=\"android:windowBackground\">@color/colorPrimary</item>\n        <item name=\"android:dialogTheme\">@style/CustomDialog</item>\n    </style>\n\n    <style name=\"CustomDialog\" parent=\"@style/Theme.AppCompat.Light.Dialog\">\n        <item name=\"android:windowNoTitle\">false</item>\n    </style>\n\n    <!-- Text Themes -->\n    <style name=\"HeaderText\" parent=\"@android:style/TextAppearance.Medium\">\n        <item name=\"android:textColor\">@color/textColorPrimary</item>\n        <item name=\"android:textStyle\">normal</item>\n        <item name=\"android:fontFamily\">@font/sf_ui_display_regular</item>\n        <item name=\"android:textAllCaps\">true</item>\n        <item name=\"android:letterSpacing\">.12</item>\n    </style>\n\n    <style name=\"BodyText\" parent=\"@android:style/TextAppearance.Small\">\n        <item name=\"android:textColor\">@color/textColorPrimary</item>\n        <item name=\"android:textStyle\">normal</item>\n        <item name=\"android:fontFamily\">@font/sf_ui_display_light</item>\n        <item name=\"android:letterSpacing\">.05</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "Android/FritzAIStudio/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    repositories {\n        google()\n        jcenter()\n        mavenCentral()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.1.3'\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n        mavenCentral()\n\n        maven {\n            url 'https://maven.google.com/'\n        }\n        maven { url 'https://fritz.mycloudrepo.io/public/repositories/android' }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n\n"
  },
  {
    "path": "Android/FritzAIStudio/gradle.properties",
    "content": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n"
  },
  {
    "path": "Android/FritzAIStudio/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/FritzAIStudio/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/FritzAIStudio/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/.gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/caches\n/.idea/libraries\n/.idea/modules.xml\n/.idea/workspace.xml\n/.idea/navEditor.xml\n/.idea/assetWizardSettings.xml\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n.cxx\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 29\n    defaultConfig {\n        // MUST MATCH THE APPLICATION YOU CREATE IN FRITZ\n        applicationId \"ai.fritz.fritzvisionvideo\"\n        minSdkVersion 21\n        targetSdkVersion 29\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n}\n\ndependencies {\n    implementation 'androidx.appcompat:appcompat:1.1.0'\n    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'\n    implementation 'androidx.recyclerview:recyclerview:1.1.0'\n\n    implementation \"ai.fritz:vision:6.0.3\"\n    implementation \"ai.fritz:vision-hair-segmentation-model-fast:3.0.0\"\n    implementation \"ai.fritz:vision-people-segmentation-model-fast:3.1.0\"\n    implementation \"ai.fritz:vision-object-detection-model-fast:3.0.0\"\n    implementation \"ai.fritz:vision-pose-estimation-model-fast:3.0.0\"\n    implementation \"ai.fritz:vision-style-painting-models:3.0.0\"\n\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.2.0'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/androidTest/java/ai/fritz/fritzvisionvideo/ExampleInstrumentedTest.java",
    "content": "package ai.fritz.fritzvisionvideo;\n\nimport android.content.Context;\n\nimport androidx.test.platform.app.InstrumentationRegistry;\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n\n        assertEquals(\"ai.fritz.fritzvisionvideo\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.fritzvisionvideo\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".VideoActivity\"\n            android:parentActivityName=\".MainActivity\"/>\n        <service\n            android:name=\"ai.fritz.core.FritzCustomModelService\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/MainActivity.java",
    "content": "package ai.fritz.fritzvisionvideo;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport android.view.View;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport ai.fritz.core.Fritz;\nimport ai.fritz.fritzvisionvideo.strategies.MaskCutStrategy;\nimport ai.fritz.fritzvisionvideo.strategies.ObjectPoseStrategy;\nimport ai.fritz.fritzvisionvideo.strategies.PoseDoubleMaskStrategy;\nimport ai.fritz.fritzvisionvideo.strategies.StylizeBackgroundStrategy;\nimport ai.fritz.fritzvisionvideo.strategies.StylizeHairStrategy;\nimport ai.fritz.fritzvisionvideo.ui.DemoAdapter;\nimport ai.fritz.fritzvisionvideo.ui.DemoItem;\nimport ai.fritz.fritzvisionvideo.ui.SeparatorDecoration;\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\npublic class MainActivity extends AppCompatActivity {\n\n    private RecyclerView recyclerView;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Fritz.configure(this);\n        setContentView(R.layout.activity_main);\n\n        recyclerView = findViewById(R.id.demo_list_view);\n        recyclerView.setHasFixedSize(true);\n        LinearLayoutManager rvLinearLayoutMgr = new LinearLayoutManager(this);\n        recyclerView.setLayoutManager(rvLinearLayoutMgr);\n\n        // Add a divider\n        SeparatorDecoration decoration = new SeparatorDecoration(this, Color.GRAY, 1);\n        recyclerView.addItemDecoration(decoration);\n\n        // Add the adapter\n        DemoAdapter adapter = new DemoAdapter(getDemoItems());\n        recyclerView.setAdapter(adapter);\n        recyclerView.setClickable(true);\n    }\n\n    private List<DemoItem> getDemoItems() {\n        List<DemoItem> demoItems = new ArrayList<>();\n\n        demoItems.add(new DemoItem(\n                getString(R.string.starry_night_hair_title),\n                getString(R.string.starry_night_hair_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Context context = v.getContext();\n                        Intent intent = new Intent(context, VideoActivity.class);\n                        // Send a VideoFilterStrategy as a Parcelable\n                        intent.putExtra(getResources().getString(R.string.filter_strategy_key), new StylizeHairStrategy());\n                        context.startActivity(intent);\n                    }\n                }));\n\n        demoItems.add(new DemoItem(\n                getString(R.string.stylize_background_title),\n                getString(R.string.stylize_background_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Context context = v.getContext();\n                        Intent intent = new Intent(context, VideoActivity.class);\n                        // Send a VideoFilterStrategy as a Parcelable\n                        intent.putExtra(getResources().getString(R.string.filter_strategy_key), new StylizeBackgroundStrategy());\n                        context.startActivity(intent);\n                    }\n                }));\n\n        demoItems.add(new DemoItem(\n                getString(R.string.object_pose_title),\n                getString(R.string.object_pose_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Context context = v.getContext();\n                        Intent intent = new Intent(context, VideoActivity.class);\n                        // Send a VideoFilterStrategy as a Parcelable\n                        intent.putExtra(getResources().getString(R.string.filter_strategy_key), new ObjectPoseStrategy());\n                        context.startActivity(intent);\n                    }\n                }));\n\n        demoItems.add(new DemoItem(\n                getString(R.string.pose_double_mask_title),\n                getString(R.string.pose_double_mask_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Context context = v.getContext();\n                        Intent intent = new Intent(context, VideoActivity.class);\n                        // Send a VideoFilterStrategy as a Parcelable\n                        intent.putExtra(getResources().getString(R.string.filter_strategy_key), new PoseDoubleMaskStrategy());\n                        context.startActivity(intent);\n                    }\n                }));\n\n        demoItems.add(new DemoItem(\n                getString(R.string.mask_cut_title),\n                getString(R.string.mask_cut_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Context context = v.getContext();\n                        Intent intent = new Intent(context, VideoActivity.class);\n                        // Send a VideoFilterStrategy as a Parcelable\n                        intent.putExtra(getResources().getString(R.string.filter_strategy_key), new MaskCutStrategy());\n                        context.startActivity(intent);\n                    }\n                }));\n\n        return demoItems;\n    }\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/VideoActivity.java",
    "content": "package ai.fritz.fritzvisionvideo;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.media.MediaPlayer;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.os.Environment;\nimport android.provider.MediaStore;\nimport android.view.Menu;\nimport android.view.MenuItem;\nimport android.view.View;\nimport android.widget.ProgressBar;\nimport android.widget.TextView;\nimport android.widget.Toast;\nimport android.widget.VideoView;\n\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.nio.channels.FileChannel;\nimport java.util.Locale;\n\nimport ai.fritz.fritzvisionvideo.strategies.VideoFilterStrategy;\nimport ai.fritz.vision.video.ExportVideoOptions;\nimport ai.fritz.vision.video.FritzVisionImageFilter;\nimport ai.fritz.vision.video.FritzVisionVideo;\n\npublic class VideoActivity extends AppCompatActivity {\n\n    private static final int REQUEST_CODE = 1;\n\n    private VideoView videoView;\n    private ProgressBar progressBar;\n    private TextView progressText;\n    private MenuItem exportButton;\n\n    private VideoFilterStrategy strategy;\n\n    private File exportFile = null;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_video);\n        videoView = findViewById(R.id.video_view);\n        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {\n            @Override\n            public void onPrepared(MediaPlayer mediaPlayer) {\n                mediaPlayer.setLooping(true);\n                mediaPlayer.setVolume(1, 1);\n                mediaPlayer.start();\n            }\n        });\n        progressBar = findViewById(R.id.export_progress);\n        progressText = findViewById(R.id.progress_text);\n\n        // Retrieve the VideoFilterStrategy\n        strategy = getIntent().getParcelableExtra(getResources().getString(R.string.filter_strategy_key));\n\n        // Display the video picker\n        Intent filePicker = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI);\n        filePicker.putExtra(Intent.EXTRA_LOCAL_ONLY, true);\n        startActivityForResult(filePicker, 1);\n    }\n\n    @Override\n    public boolean onCreateOptionsMenu(Menu menu) {\n        // Show a top menu bar with an export button\n        getMenuInflater().inflate(R.menu.video_menu, menu);\n        exportButton = menu.findItem(R.id.export_button);\n        exportButton.setVisible(false);\n        exportButton.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {\n            @Override\n            public boolean onMenuItemClick(MenuItem menuItem) {\n                try {\n                    saveProcessedVideo();\n                } catch (IOException e) {\n                    throw new IllegalStateException(\"Unable to save video.\");\n                }\n                menuItem.setEnabled(false);\n                return true;\n            }\n        });\n        return super.onCreateOptionsMenu(menu);\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n\n        File cacheDir = getCacheDir();\n        File[] cachedFiles = cacheDir.listFiles();\n\n        // Delete any cached files\n        if (cachedFiles != null) {\n            for (File file : cachedFiles) {\n                file.delete();\n            }\n        }\n    }\n\n    @Override\n    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\n        if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {\n            // Process the video after a video is selected\n            startProcessing(data.getData());\n        } else {\n            finish();\n        }\n        super.onActivityResult(requestCode, resultCode, data);\n    }\n\n    /**\n     * Starts processing a video.\n     *\n     * @param videoUri The URI of the video to process.\n     */\n    private void startProcessing(Uri videoUri) {\n        try {\n            // Create a temporary file to write the processed video to\n            exportFile = File.createTempFile(\"tempExport\", \".mp4\", getCacheDir());\n        } catch (IOException e) {\n            throw new IllegalStateException(\"Unable to create a destination file.\");\n        }\n\n        // Get filters to apply on the video\n        FritzVisionImageFilter[] filters = strategy.getFilters();\n\n        // Create the FritzVisionVideo object with the filter and selected video URI\n        FritzVisionVideo fritzVideo = new FritzVisionVideo(videoUri, filters);\n\n        // Create and set the processing parameters\n        // Every third frame of the video will be processed\n        ExportVideoOptions options = new ExportVideoOptions();\n        options.frameInterval = 3;\n\n        // Uncomment following line to enable audio at the cost of increased processing time\n        // options.copyAudio = true;\n\n        final String exportPath = exportFile.getAbsolutePath();\n\n        // Start exporting and processing the video\n        fritzVideo.export(exportPath, options, new FritzVisionVideo.ExportProgressCallback() {\n            @Override\n            public void onProgress(Float response) {\n                // Update progress\n                int progress = (int) (response * 100);\n                updateProgress(progress);\n            }\n\n            @Override\n            public void onComplete() {\n                // Play the processed video\n                Uri uri = Uri.fromFile(exportFile);\n                displayVideo(uri);\n            }\n        });\n    }\n\n    /**\n     * Updates progress when processing.\n     */\n    private void updateProgress(final int progress) {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                progressBar.setProgress(progress);\n                progressText.setText(String.format(Locale.US, \"Processing %d%%\", progress));\n            }\n        });\n    }\n\n    /**\n     * Changes visibility of views when processing is complete.\n     */\n    private void displayVideo(final Uri videoUri) {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                progressBar.setVisibility(View.INVISIBLE);\n                progressText.setVisibility(View.INVISIBLE);\n                exportButton.setVisible(true);\n                videoView.setVideoURI(videoUri);\n            }\n        });\n    }\n\n    /**\n     * Write the contents of the processed video to Photos.\n     *\n     * @throws IOException If there is a file error.\n     */\n    private void saveProcessedVideo() throws IOException {\n        // Get the directory to save to\n        File file = getExternalFilesDir(Environment.DIRECTORY_MOVIES);\n\n        // Create the file to write to\n        String exportPath = (file.getAbsolutePath() + \"/\" + System.currentTimeMillis() + \".mp4\");\n        File destFile = new File(exportPath);\n\n        // Write contents of the processed video file to the destination file\n        try (FileChannel source = new FileInputStream(exportFile).getChannel();\n             FileChannel destination = new FileOutputStream(destFile).getChannel()) {\n            destination.transferFrom(source, 0, source.size());\n        }\n\n        // Notify the user that the video has been saved\n        Toast.makeText(\n                VideoActivity.this,\n                \"Saved video to \" + exportPath, Toast.LENGTH_LONG\n        ).show();\n    }\n}"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/strategies/MaskCutStrategy.java",
    "content": "package ai.fritz.fritzvisionvideo.strategies;\n\nimport android.os.Parcel;\n\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.MaskClass;\nimport ai.fritz.vision.imagesegmentation.SegmentationOnDeviceModel;\nimport ai.fritz.vision.video.FritzVisionImageFilter;\nimport ai.fritz.vision.video.filters.imagesegmentation.MaskCutOutOverlayFilter;\nimport ai.fritz.vision.video.filters.imagesegmentation.MaskOverlayFilter;\n\n\npublic class MaskCutStrategy extends VideoFilterStrategy {\n\n    private SegmentationOnDeviceModel peopleModel = FritzVisionModels.getPeopleSegmentationOnDeviceModel(ModelVariant.FAST);\n    private SegmentationOnDeviceModel hairModel = FritzVisionModels.getHairSegmentationOnDeviceModel(ModelVariant.FAST);\n\n    public MaskCutStrategy() {\n        super();\n    }\n\n    public MaskCutStrategy(Parcel in) {\n        super(in);\n    }\n\n    public static final Creator<VideoFilterStrategy> CREATOR = new Creator<VideoFilterStrategy>() {\n        @Override\n        public VideoFilterStrategy createFromParcel(Parcel in) {\n            return new MaskCutStrategy(in);\n        }\n\n        @Override\n        public VideoFilterStrategy[] newArray(int size) {\n            return new MaskCutStrategy[size];\n        }\n    };\n\n    @Override\n    public FritzVisionImageFilter[] getFilters() {\n        // Create predictors for the filter\n        FritzVisionSegmentationPredictor personPredictor = FritzVision.ImageSegmentation.getPredictor(peopleModel);\n        FritzVisionSegmentationPredictor hairPredictor = FritzVision.ImageSegmentation.getPredictor(hairModel);\n\n        return new FritzVisionImageFilter[]{\n                new MaskOverlayFilter(personPredictor, MaskClass.PERSON),\n                new MaskCutOutOverlayFilter(hairPredictor, MaskClass.HAIR)\n        };\n    }\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/strategies/ObjectPoseStrategy.java",
    "content": "package ai.fritz.fritzvisionvideo.strategies;\n\nimport android.os.Parcel;\n\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.objectdetection.FritzVisionObjectPredictor;\nimport ai.fritz.vision.objectdetection.ObjectDetectionOnDeviceModel;\nimport ai.fritz.vision.poseestimation.FritzVisionPosePredictor;\nimport ai.fritz.vision.poseestimation.PoseOnDeviceModel;\nimport ai.fritz.vision.video.FritzVisionImageFilter;\nimport ai.fritz.vision.video.filters.DrawBoxesCompoundFilter;\nimport ai.fritz.vision.video.filters.DrawSkeletonCompoundFilter;\n\npublic class ObjectPoseStrategy extends VideoFilterStrategy {\n\n    private ObjectDetectionOnDeviceModel objectModel = FritzVisionModels.getObjectDetectionOnDeviceModel();\n    private PoseOnDeviceModel poseModel = FritzVisionModels.getHumanPoseEstimationOnDeviceModel(ModelVariant.FAST);\n\n\n    public ObjectPoseStrategy() {\n        super();\n    }\n\n    public ObjectPoseStrategy(Parcel in) {\n        super(in);\n    }\n\n    public static final Creator<VideoFilterStrategy> CREATOR = new Creator<VideoFilterStrategy>() {\n        @Override\n        public VideoFilterStrategy createFromParcel(Parcel in) {\n            return new ObjectPoseStrategy(in);\n        }\n\n        @Override\n        public VideoFilterStrategy[] newArray(int size) {\n            return new ObjectPoseStrategy[size];\n        }\n    };\n\n    @Override\n    public FritzVisionImageFilter[] getFilters() {\n        // Create predictors for the filters\n        FritzVisionObjectPredictor objectPredictor = FritzVision.ObjectDetection.getPredictor(objectModel);\n        FritzVisionPosePredictor posePredictor = FritzVision.PoseEstimation.getPredictor(poseModel);\n\n        return new FritzVisionImageFilter[]{\n                new DrawBoxesCompoundFilter(objectPredictor), // Applied first\n                new DrawSkeletonCompoundFilter(posePredictor) // Applied second\n        };\n    }\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/strategies/PoseDoubleMaskStrategy.java",
    "content": "package ai.fritz.fritzvisionvideo.strategies;\n\nimport android.os.Parcel;\n\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationMaskOptions;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.MaskClass;\nimport ai.fritz.vision.imagesegmentation.SegmentationOnDeviceModel;\nimport ai.fritz.vision.poseestimation.FritzVisionPosePredictor;\nimport ai.fritz.vision.poseestimation.PoseOnDeviceModel;\nimport ai.fritz.vision.video.FritzVisionImageFilter;\nimport ai.fritz.vision.video.filters.DrawSkeletonCompoundFilter;\nimport ai.fritz.vision.video.filters.imagesegmentation.MaskOverlayFilter;\n\npublic class PoseDoubleMaskStrategy extends VideoFilterStrategy {\n\n    private PoseOnDeviceModel poseModel = FritzVisionModels.getHumanPoseEstimationOnDeviceModel(ModelVariant.FAST);\n    private SegmentationOnDeviceModel peopleModel = FritzVisionModels.getPeopleSegmentationOnDeviceModel(ModelVariant.FAST);\n    private SegmentationOnDeviceModel hairModel = FritzVisionModels.getHairSegmentationOnDeviceModel(ModelVariant.FAST);\n\n    private FritzVisionSegmentationMaskOptions peopleOptions = new FritzVisionSegmentationMaskOptions();\n\n    public PoseDoubleMaskStrategy() {\n        super();\n    }\n\n    public PoseDoubleMaskStrategy(Parcel in) {\n        super(in);\n    }\n\n    public static final Creator<VideoFilterStrategy> CREATOR = new Creator<VideoFilterStrategy>() {\n        @Override\n        public VideoFilterStrategy createFromParcel(Parcel in) {\n            return new PoseDoubleMaskStrategy(in);\n        }\n\n        @Override\n        public VideoFilterStrategy[] newArray(int size) {\n            return new PoseDoubleMaskStrategy[size];\n        }\n    };\n\n    @Override\n    public FritzVisionImageFilter[] getFilters() {\n        // Reduce the alpha of the people mask\n        peopleOptions.maxAlpha = 50;\n\n        // Create predictors for the filters\n        FritzVisionPosePredictor posePredictor = FritzVision.PoseEstimation.getPredictor(poseModel);\n        FritzVisionSegmentationPredictor peoplePredictor = FritzVision.ImageSegmentation.getPredictor(peopleModel);\n        FritzVisionSegmentationPredictor hairPredictor = FritzVision.ImageSegmentation.getPredictor(hairModel);\n\n        return new FritzVisionImageFilter[]{\n                new DrawSkeletonCompoundFilter(posePredictor), // Applied first\n                new MaskOverlayFilter(peoplePredictor, peopleOptions, MaskClass.PERSON), // Applied second\n                new MaskOverlayFilter(hairPredictor, MaskClass.HAIR) // Applied last\n        };\n    }\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/strategies/StylizeBackgroundStrategy.java",
    "content": "package ai.fritz.fritzvisionvideo.strategies;\n\nimport android.os.Parcel;\n\nimport ai.fritz.core.FritzOnDeviceModel;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.MaskClass;\nimport ai.fritz.vision.imagesegmentation.SegmentationOnDeviceModel;\nimport ai.fritz.vision.styletransfer.FritzVisionStylePredictor;\nimport ai.fritz.vision.video.FritzVisionImageFilter;\nimport ai.fritz.vision.video.filters.StylizeImageCompoundFilter;\nimport ai.fritz.vision.video.filters.imagesegmentation.MaskCutOutOverlayFilter;\n\npublic class StylizeBackgroundStrategy extends VideoFilterStrategy {\n\n    private FritzOnDeviceModel styleModel = FritzVisionModels.getPaintingStyleModels().getTheScream();\n    private SegmentationOnDeviceModel peopleModel = FritzVisionModels.getPeopleSegmentationOnDeviceModel(ModelVariant.FAST);\n\n    public StylizeBackgroundStrategy() {\n        super();\n    }\n\n    public StylizeBackgroundStrategy(Parcel in) {\n        super(in);\n    }\n\n    public static final Creator<VideoFilterStrategy> CREATOR = new Creator<VideoFilterStrategy>() {\n        @Override\n        public VideoFilterStrategy createFromParcel(Parcel in) {\n            return new StylizeBackgroundStrategy(in);\n        }\n\n        @Override\n        public VideoFilterStrategy[] newArray(int size) {\n            return new StylizeBackgroundStrategy[size];\n        }\n    };\n\n    @Override\n    public FritzVisionImageFilter[] getFilters() {\n        // Create predictors for the filters\n        FritzVisionStylePredictor stylePredictor = FritzVision.StyleTransfer.getPredictor(styleModel);\n        FritzVisionSegmentationPredictor segmentationPredictor = FritzVision.ImageSegmentation.getPredictor(peopleModel);\n\n        return new FritzVisionImageFilter[]{\n                new StylizeImageCompoundFilter(stylePredictor), // Applied first\n                new MaskCutOutOverlayFilter(segmentationPredictor, MaskClass.PERSON) // Applied second\n        };\n    }\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/strategies/StylizeHairStrategy.java",
    "content": "package ai.fritz.fritzvisionvideo.strategies;\n\nimport android.os.Parcel;\n\nimport ai.fritz.core.FritzOnDeviceModel;\nimport ai.fritz.fritzvisionvideo.strategies.customfilters.StylizeHairFilter;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.MaskClass;\nimport ai.fritz.vision.imagesegmentation.SegmentationOnDeviceModel;\nimport ai.fritz.vision.styletransfer.FritzVisionStylePredictor;\nimport ai.fritz.vision.video.FritzVisionImageFilter;\n\npublic class StylizeHairStrategy extends VideoFilterStrategy {\n\n    private FritzOnDeviceModel styleModel = FritzVisionModels.getPaintingStyleModels().getStarryNight();\n    private SegmentationOnDeviceModel hairModel = FritzVisionModels.getHairSegmentationOnDeviceModel(ModelVariant.FAST);\n\n    public StylizeHairStrategy() {\n        super();\n    }\n\n    public StylizeHairStrategy(Parcel in) {\n        super(in);\n    }\n\n    public static final Creator<VideoFilterStrategy> CREATOR = new Creator<VideoFilterStrategy>() {\n        @Override\n        public VideoFilterStrategy createFromParcel(Parcel in) {\n            return new StylizeHairStrategy(in);\n        }\n\n        @Override\n        public VideoFilterStrategy[] newArray(int size) {\n            return new StylizeHairStrategy[size];\n        }\n    };\n\n    @Override\n    public FritzVisionImageFilter[] getFilters() {\n        // Create predictors for the filter\n        FritzVisionSegmentationPredictor hairPredictor = FritzVision.ImageSegmentation.getPredictor(hairModel);\n        FritzVisionStylePredictor stylePredictor = FritzVision.StyleTransfer.getPredictor(styleModel);\n\n        return new FritzVisionImageFilter[]{\n                new StylizeHairFilter(stylePredictor, hairPredictor, MaskClass.HAIR)\n        };\n    }\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/strategies/VideoFilterStrategy.java",
    "content": "package ai.fritz.fritzvisionvideo.strategies;\n\nimport android.os.Parcel;\nimport android.os.Parcelable;\n\nimport ai.fritz.vision.video.FritzVisionImageFilter;\n\npublic abstract class VideoFilterStrategy implements Parcelable {\n\n    protected VideoFilterStrategy() {\n    }\n\n    protected VideoFilterStrategy(Parcel in) {\n    }\n\n    @Override\n    public void writeToParcel(Parcel dest, int flags) {\n    }\n\n    @Override\n    public int describeContents() {\n        return 0;\n    }\n\n    /**\n     * Retrieve created filters.\n     *\n     * @return A filter array.\n     */\n    public abstract FritzVisionImageFilter[] getFilters();\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/strategies/customfilters/StylizeHairFilter.java",
    "content": "package ai.fritz.fritzvisionvideo.strategies.customfilters;\n\nimport android.graphics.Bitmap;\n\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationMaskOptions;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationResult;\nimport ai.fritz.vision.imagesegmentation.MaskClass;\nimport ai.fritz.vision.styletransfer.FritzVisionStylePredictor;\nimport ai.fritz.vision.styletransfer.FritzVisionStyleResult;\nimport ai.fritz.vision.video.filters.imagesegmentation.FritzVisionSegmentationFilter;\n\npublic class StylizeHairFilter extends FritzVisionSegmentationFilter {\n\n    private FritzVisionStylePredictor stylePredictor;\n\n    public StylizeHairFilter(\n            FritzVisionStylePredictor stylePredictor,\n            FritzVisionSegmentationPredictor model,\n            MaskClass segmentationMask\n    ) {\n        super(model, segmentationMask);\n        this.stylePredictor = stylePredictor;\n    }\n\n    public StylizeHairFilter(\n            FritzVisionStylePredictor stylePredictor,\n            FritzVisionSegmentationPredictor predictor,\n            FritzVisionSegmentationMaskOptions options,\n            MaskClass segmentationMask\n    ) {\n        super(predictor, options, segmentationMask);\n        this.stylePredictor = stylePredictor;\n    }\n\n    @Override\n    public FilterCompositionMode getCompositionMode() {\n        return FilterCompositionMode.OVERLAY_ON_ORIGINAL_IMAGE;\n    }\n\n    @Override\n    public FritzVisionImage processImage(FritzVisionImage image) {\n        FritzVisionSegmentationResult hairResult = predictor.predict(image);\n        FritzVisionStyleResult styleResult = stylePredictor.predict(image);\n\n        FritzVisionImage stylizedImage = FritzVisionImage.fromBitmap(styleResult.toBitmap());\n        Bitmap mask = hairResult.buildSingleClassMask(segmentationMask, options);\n\n        return FritzVisionImage.fromBitmap(stylizedImage.mask(mask));\n    }\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/ui/DemoAdapter.java",
    "content": "package ai.fritz.fritzvisionvideo.ui;\n\nimport android.view.LayoutInflater;\nimport android.view.ViewGroup;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\n\nimport ai.fritz.fritzvisionvideo.R;\nimport androidx.recyclerview.widget.RecyclerView;\n\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Demo items adapter to manage the list of models.\n */\npublic class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.ViewHolder> {\n    private List<DemoItem> demoItems = new ArrayList<>();\n\n    /**\n     * View holder for each demo item to display in the list.\n     */\n    public static class ViewHolder extends RecyclerView.ViewHolder {\n        public LinearLayout linearLayout;\n        public TextView titleView;\n        public TextView descriptionView;\n\n        public ViewHolder(LinearLayout v) {\n            super(v);\n            linearLayout = v;\n            titleView = linearLayout.findViewById(R.id.title);\n            descriptionView = linearLayout.findViewById(R.id.description);\n        }\n    }\n\n    /**\n     * Initialize the adapter with a list of demo items.\n     *\n     * @param demoItems\n     */\n    public DemoAdapter(List<DemoItem> demoItems) {\n        this.demoItems = demoItems;\n    }\n\n    /**\n     * Get the DemoItem and binds it to the recycled view.\n     * <p>\n     * Also sets the click actions here.\n     *\n     * @param holder\n     * @param position\n     */\n    @Override\n    public void onBindViewHolder(DemoAdapter.ViewHolder holder, int position) {\n        DemoItem demoItem = demoItems.get(position);\n        holder.titleView.setText(demoItem.getTitle());\n        holder.descriptionView.setText(demoItem.getDescription());\n        holder.linearLayout.setOnClickListener(demoItem.getOnClickListener());\n    }\n\n    /**\n     * Get number of demo items.\n     *\n     * @return number of items in the list\n     */\n    @Override\n    public int getItemCount() {\n        return demoItems.size();\n    }\n\n    /**\n     * Create a view holder for the DemoItems\n     *\n     * @param parent\n     * @param viewType\n     * @return\n     */\n    @Override\n    public DemoAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,\n                                                     int viewType) {\n        LinearLayout v = (LinearLayout) LayoutInflater.from(parent.getContext())\n                .inflate(R.layout.list_item_demo, parent, false);\n        ViewHolder holder = new ViewHolder(v);\n        return holder;\n    }\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/ui/DemoItem.java",
    "content": "package ai.fritz.fritzvisionvideo.ui;\n\nimport android.view.View;\n\n/**\n * Helper class to show demo items for the DemoAdapter\n */\npublic class DemoItem {\n\n    private String title;\n    private String description;\n    private View.OnClickListener onClickListener;\n\n    public DemoItem(String title, String description, View.OnClickListener clickListener) {\n        this.title = title;\n        this.description = description;\n        this.onClickListener = clickListener;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public String getDescription() {\n        return description;\n    }\n\n    public void setDescription(String description) {\n        this.description = description;\n    }\n\n    public View.OnClickListener getOnClickListener() {\n        return onClickListener;\n    }\n\n    public void setOnClickListener(View.OnClickListener onClickListener) {\n        this.onClickListener = onClickListener;\n    }\n}\n\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/java/ai/fritz/fritzvisionvideo/ui/SeparatorDecoration.java",
    "content": "package ai.fritz.fritzvisionvideo.ui;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.FloatRange;\nimport androidx.annotation.NonNull;\n\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport android.util.TypedValue;\nimport android.view.View;\n\n/**\n * Taken from https://github.com/bleeding182/recyclerviewItemDecorations\n */\npublic class SeparatorDecoration extends RecyclerView.ItemDecoration {\n\n    private final Paint mPaint;\n\n    /**\n     * Create a decoration that draws a line in the given color and width between the items in the view.\n     *\n     * @param context  a context to access the resources.\n     * @param color    the color of the separator to draw.\n     * @param heightDp the height of the separator in dp.\n     */\n    public SeparatorDecoration(@NonNull Context context, @ColorInt int color,\n                               @FloatRange(from = 0, fromInclusive = false) float heightDp) {\n        mPaint = new Paint();\n        mPaint.setColor(color);\n        final float thickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,\n                heightDp, context.getResources().getDisplayMetrics());\n        mPaint.setStrokeWidth(thickness);\n    }\n\n    @Override\n    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {\n        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();\n\n        // we want to retrieve the position in the list\n        final int position = params.getViewAdapterPosition();\n\n        // and add a separator to any view but the last one\n        if (position < state.getItemCount()) {\n            outRect.set(0, 0, 0, (int) mPaint.getStrokeWidth()); // left, top, right, bottom\n        } else {\n            outRect.setEmpty(); // 0, 0, 0, 0\n        }\n    }\n\n    @Override\n    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {\n        // we set the stroke width before, so as to correctly draw the line we have to offset by width / 2\n        final int offset = (int) (mPaint.getStrokeWidth() / 2);\n\n        // this will iterate over every visible view\n        for (int i = 0; i < parent.getChildCount(); i++) {\n            // get the view\n            final View view = parent.getChildAt(i);\n            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();\n\n            // get the position\n            final int position = params.getViewAdapterPosition();\n\n            // and finally draw the separator\n            if (position < state.getItemCount()) {\n                c.drawLine(view.getLeft(), view.getBottom() + offset, view.getRight(), view.getBottom() + offset, mPaint);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#008577\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/font/sf_display.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <font\n        android:font=\"@font/sf_ui_display_bold\"\n        android:fontStyle=\"normal\"\n        android:fontWeight=\"700\"\n        app:font=\"@font/sf_ui_display_bold\"\n        app:fontStyle=\"normal\"\n        app:fontWeight=\"700\" />\n    <font\n        android:font=\"@font/sf_ui_display_regular\"\n        android:fontStyle=\"normal\"\n        android:fontWeight=\"400\"\n        app:font=\"@font/sf_ui_display_regular\"\n        app:fontStyle=\"normal\"\n        app:fontWeight=\"400\" />\n    <font\n        android:font=\"@font/sf_ui_display_light\"\n        android:fontStyle=\"normal\"\n        android:fontWeight=\"200\"\n        app:font=\"@font/sf_ui_display_light\"\n        app:fontStyle=\"normal\"\n        app:fontWeight=\"200\" />\n</font-family>"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@color/colorPrimary\">\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/demo_list_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:scrollbars=\"vertical\" />\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/layout/activity_video.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <VideoView\n        android:id=\"@+id/video_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n    <ProgressBar\n        android:id=\"@+id/export_progress\"\n        style=\"?android:attr/progressBarStyleHorizontal\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:progress=\"0\"\n        android:scaleY=\"3\"\n        android:layout_marginStart=\"@dimen/margin_xl\"\n        android:layout_marginEnd=\"@dimen/margin_xl\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n    <TextView\n        android:id=\"@+id/progress_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Processing...\"\n        android:textColor=\"@color/textColorPrimary\"\n        android:layout_marginTop=\"@dimen/margin_md\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/export_progress\" />\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/layout/app_bar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.appcompat.widget.Toolbar xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/app_toolbar\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"?attr/actionBarSize\"\n    android:layout_alignParentTop=\"true\"\n    android:elevation=\"4dp\"\n    android:background=\"@color/colorPrimary\"\n    android:theme=\"@style/ThemeOverlay.AppCompat.ActionBar\"\n    app:popupTheme=\"@style/ThemeOverlay.AppCompat.Light\" />\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/layout/list_item_demo.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:theme=\"@android:style/ThemeOverlay.Material.Dark\"\n    android:background=\"?android:selectableItemBackground\"\n    android:layout_height=\"wrap_content\"\n    android:layout_width=\"match_parent\"\n    android:padding=\"@dimen/margin_md\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/title\"\n        style=\"@style/HeaderText\"\n        android:layout_height=\"wrap_content\"\n        android:layout_width=\"wrap_content\"\n        android:text=\"Header\"\n        android:layout_marginBottom=\"@dimen/margin_sm\"/>\n\n    <TextView\n        android:id=\"@+id/description\"\n        style=\"@style/BodyText\"\n        android:layout_height=\"wrap_content\"\n        android:layout_width=\"wrap_content\"\n        android:text=\"Some Description\" />\n\n</LinearLayout>"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/menu/video_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n    <item\n        android:id=\"@+id/export_button\"\n        android:icon=\"@drawable/export_icon\"\n        android:orderInCategory=\"100\"\n        app:showAsAction=\"always\"\n        android:title=\"\" />\n</menu>"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#000</color>\n    <color name=\"colorPrimaryDark\">#000</color>\n    <color name=\"colorAccent\">#9E8D37</color>\n    <color name=\"textColorPrimary\">#fff</color>\n</resources>\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/values/dimens.xml",
    "content": "<!--\n  Copyright 2013 The Android Open Source Project\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n\n<resources>\n\n    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->\n\n    <dimen name=\"margin_xs\">4dp</dimen>\n    <dimen name=\"margin_sm\">8dp</dimen>\n    <dimen name=\"margin_md\">16dp</dimen>\n    <dimen name=\"margin_lg\">32dp</dimen>\n    <dimen name=\"margin_xl\">64dp</dimen>\n\n    <!-- Semantic definitions -->\n\n    <dimen name=\"horizontal_page_margin\">@dimen/margin_md</dimen>\n    <dimen name=\"vertical_page_margin\">@dimen/margin_md</dimen>\n\n</resources>"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Video Processing</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n\n    <string name=\"starry_night_hair_title\">Starry Night Hair</string>\n    <string name=\"starry_night_hair_description\">Stylize your hair with Starry Night by Vincent van Gogh.</string>\n\n    <string name=\"stylize_background_title\">Stylize Background</string>\n    <string name=\"stylize_background_description\">Cut out people and paste them on top of a background stylized with Ritmo Plastico by Gino Severini.</string>\n\n    <string name=\"object_pose_title\">Object Detection and Pose Estimation</string>\n    <string name=\"object_pose_description\">Detect and draw boxes around objects while identifying and tracking the body position of a person.</string>\n\n    <string name=\"pose_double_mask_title\">Pose Estimation with People and Hair Mask</string>\n    <string name=\"pose_double_mask_description\">Identify and track the body position of a person while putting a mask over people and hair.</string>\n\n    <string name=\"mask_cut_title\">People Mask with Original Hair</string>\n    <string name=\"mask_cut_description\">Put a mask over people while retaining their original hair.</string>\n\n    <string name=\"video_path_key\">video</string>\n    <string name=\"filter_strategy_key\">strategy</string>\n\n</resources>\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n    <!-- Text Themes -->\n    <style name=\"HeaderText\" parent=\"@android:style/TextAppearance.Medium\">\n        <item name=\"android:textColor\">@color/textColorPrimary</item>\n        <item name=\"android:textStyle\">normal</item>\n        <item name=\"android:fontFamily\">@font/sf_ui_display_regular</item>\n        <item name=\"android:textAllCaps\">true</item>\n        <item name=\"android:letterSpacing\">.12</item>\n    </style>\n\n    <style name=\"BodyText\" parent=\"@android:style/TextAppearance.Small\">\n        <item name=\"android:textColor\">@color/textColorPrimary</item>\n        <item name=\"android:textStyle\">normal</item>\n        <item name=\"android:fontFamily\">@font/sf_ui_display_light</item>\n        <item name=\"android:letterSpacing\">.05</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/app/src/test/java/ai/fritz/fritzvisionvideo/ExampleUnitTest.java",
    "content": "package ai.fritz.fritzvisionvideo;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/FritzVisionVideoApp/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        google()\n        jcenter()\n        \n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.5.0'\n        \n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n        maven { url 'https://jitpack.io' }\n\n        // ADD FOR FRITZ DEPENDENCIES\n        maven {\n            url \"https://fritz.mycloudrepo.io/public/repositories/android\"\n        }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n# AndroidX package structure to make it clearer which packages are bundled with the\n# Android operating system, and which are packaged with your app's APK\n# https://developer.android.com/topic/libraries/support-library/androidx-rn\nandroid.useAndroidX=true\n# Automatically convert third-party libraries to use AndroidX\nandroid.enableJetifier=true\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/FritzVisionVideoApp/settings.gradle",
    "content": "include ':app'\nrootProject.name='FritzVisionVideoDemo'\n"
  },
  {
    "path": "Android/HairColoringApp/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea\n\n# Keystore files\n# Uncomment the following line if you do not want to check your keystore files in.\n#*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n# fastlane\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\nfastlane/readme.md\n"
  },
  {
    "path": "Android/HairColoringApp/README.md",
    "content": "# Styling and Coloring with Hair Segmentation\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we automatically blend a color mask with the user's hair, transforming it to red.\n\n![](images/hair_segmentation.png)\n\nFor the full tutorial, visit [our post on Heartbeat](https://heartbeat.fritz.ai/embrace-your-new-look-with-hair-segmentation-by-fritz-now-available-for-android-developers-f20f5b4e9ae1).\n\nThis example app uses the on-device Hair Segmentation API for Android.\n\n- [Overview](https://www.fritz.ai/features/image-segmentation.html)\n- [Documentation](https://docs.fritz.ai/develop/vision/image-segmentation/android.html)\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Android Studio 3.2 or above\n- Android device in developer model (USB debugging enabled)\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nRegister the Android app in your Fritz account with the package id \"ai.fritz.haircoloring\". During registration, you'll receive an API key for the app. Save this for later. To find it in the webapp, you can go to Project Settings > Apps > Your App > Show API Key.\n\n**Step 2: Clone / Fork the fritz-examples repository and open the HairColoringApp in Android Studio**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\nIn Android Studio, choose \"Open an existing Android Studio project\" and select `HairColoringApp`.\n\n**Step 3: Edit the fritz.xml file with your API Key**\n\nIn app/src/main/res/values/fritz.xml, change the fritz_api_key attribute with the one you received in step 1.\n\n**Step 4: Build the Android Studio Project**\n\nSelect \"Build > Make Project\" from the top nav. Download any missing libraries if applicable. This should sync the gradle dependencies so give the build a second to complete.\n\n**Step 5: Install the app onto your device**\n\nWith your Android device connected, select `Run > Run App` from the top nav. When running the app for the first time, you'll have to give permissions to access the camera. After the app is installed and running, point your camera at someone's hair to automatically color it.\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "Android/HairColoringApp/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "Android/HairColoringApp/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 28\n    defaultConfig {\n        // MUST MATCH THE APPLICATION YOU CREATE IN FRITZ\n        applicationId \"ai.fritz.haircoloring\"\n        minSdkVersion 21\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n}\n\ndependencies {\n    implementation 'androidx.appcompat:appcompat:1.0.0'\n    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'\n    implementation 'androidx.recyclerview:recyclerview:1.0.0'\n\n    implementation 'com.github.veritas1:Android-VerticalSlideColorPicker:1.0.0'\n\n    implementation \"ai.fritz:vision:6.0.3\"\n    implementation \"ai.fritz:vision-hair-segmentation-model-fast:3.0.0\"\n\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'androidx.test:runner:1.1.0'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'\n}\n"
  },
  {
    "path": "Android/HairColoringApp/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/androidTest/java/ai/fritz/haircoloring/ExampleInstrumentedTest.java",
    "content": "package ai.fritz.haircoloring;\n\nimport android.content.Context;\nimport androidx.test.InstrumentationRegistry;\nimport androidx.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"ai.fritz.camera\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.haircoloring\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".activities.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".activities.LiveHairColorActivity\"\n            android:parentActivityName=\".activities.MainActivity\"/>\n        <activity\n            android:name=\".activities.VideoHairColorActivity\"\n            android:parentActivityName=\".activities.MainActivity\" />\n        <service\n            android:name=\"ai.fritz.core.FritzCustomModelService\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/activities/BaseCameraActivity.java",
    "content": "package ai.fritz.haircoloring.activities;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.KeyEvent;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.Toast;\n\nimport ai.fritz.haircoloring.R;\nimport ai.fritz.haircoloring.views.CameraConnectionFragment;\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport ai.fritz.haircoloring.views.OverlayView;\n\n\npublic abstract class BaseCameraActivity extends AppCompatActivity implements OnImageAvailableListener {\n    private static final String TAG = BaseCameraActivity.class.getSimpleName();\n    private static final int PERMISSIONS_REQUEST = 1;\n    private static final long DELAY_OVERLAY_VISIBLE = 500;\n\n    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;\n    private static final String PERMISSION_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;\n    private boolean useCamera2API;\n\n    private boolean debug = false;\n\n    private Handler handler;\n    private HandlerThread handlerThread;\n\n    protected String cameraId;\n    protected int cameraFacingDirection = CameraCharacteristics.LENS_FACING_BACK;\n    CameraConnectionFragment fragment;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        Log.d(TAG, \"onCreate \" + this);\n        super.onCreate(null);\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        setContentView(R.layout.activity_camera);\n\n        if (hasPermission()) {\n            setFragment();\n        } else {\n            requestPermission();\n        }\n    }\n\n    @Override\n    public synchronized void onStart() {\n        Log.d(TAG, \"onStart \" + this);\n        super.onStart();\n    }\n\n    @Override\n    public synchronized void onResume() {\n        Log.d(TAG, \"onResume \" + this);\n        super.onResume();\n\n        handlerThread = new HandlerThread(\"inference\");\n        handlerThread.start();\n        handler = new Handler(handlerThread.getLooper());\n    }\n\n    @Override\n    public synchronized void onPause() {\n        Log.d(TAG, \"onPause \" + this);\n\n        handlerThread.quitSafely();\n        try {\n            handlerThread.join();\n            handlerThread = null;\n            handler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n\n        super.onPause();\n    }\n\n    @Override\n    public synchronized void onStop() {\n        Log.d(TAG, \"onStop \" + this);\n        super.onStop();\n    }\n\n    @Override\n    public synchronized void onDestroy() {\n        Log.d(TAG, \"onDestroy \" + this);\n        super.onDestroy();\n    }\n\n    protected int getCameraFacingDirection() {\n        return cameraFacingDirection;\n    }\n\n    protected void setCameraFacingDirection(int cameraFacingDirection) {\n        this.cameraFacingDirection = cameraFacingDirection;\n    }\n\n    protected synchronized void runInBackground(final Runnable r) {\n        if (handler != null) {\n            handler.post(r);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(\n            final int requestCode, final String[] permissions, final int[] grantResults) {\n        switch (requestCode) {\n            case PERMISSIONS_REQUEST: {\n                if (grantResults.length > 0\n                        && grantResults[0] == PackageManager.PERMISSION_GRANTED\n                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {\n                    setFragment();\n                } else {\n                    requestPermission();\n                }\n            }\n        }\n    }\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            return checkSelfPermission(PERMISSION_CAMERA) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(PERMISSION_STORAGE) == PackageManager.PERMISSION_GRANTED;\n        } else {\n            return true;\n        }\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA) || shouldShowRequestPermissionRationale(PERMISSION_STORAGE)) {\n                Toast.makeText(BaseCameraActivity.this, \"Camera AND storage permission are required for this demo\", Toast.LENGTH_LONG).show();\n            }\n            requestPermissions(new String[]{PERMISSION_CAMERA, PERMISSION_STORAGE}, PERMISSIONS_REQUEST);\n        }\n    }\n\n    protected void setFragment() {\n        cameraId = chooseCamera();\n        fragment =\n                CameraConnectionFragment.newInstance(\n                        new CameraConnectionFragment.ConnectionCallback() {\n                            @Override\n                            public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n                                BaseCameraActivity.this.onPreviewSizeChosen(previewSize, cameraViewSize, rotation);\n                            }\n                        },\n                        this,\n                        getLayoutId(),\n                        getDesiredPreviewFrameSize(),\n                        new CameraConnectionFragment.CameraOpenListener() {\n                            @Override\n                            public void onCameraOpened() {\n                                final Handler handler = new Handler();\n                                handler.postDelayed(\n                                        new Runnable() {\n                                            @Override\n                                            public void run() {\n                                                runOnUiThread(new Runnable() {\n                                                    @Override\n                                                    public void run() {\n                                                        OverlayView overlay = findViewById(R.id.debug_overlay);\n                                                        if (overlay != null) {\n                                                            overlay.setVisibility(View.VISIBLE);\n                                                        }\n                                                    }\n                                                });\n                                            }\n                                        }, DELAY_OVERLAY_VISIBLE);\n                            }\n                        });\n\n        getFragmentManager()\n                .beginTransaction()\n                .replace(R.id.camera_container, fragment)\n                .commit();\n\n        fragment.setCamera(cameraId);\n\n    }\n\n    protected void toggleCameraFacingDirection() {\n        final OverlayView overlay = findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.setVisibility(View.INVISIBLE);\n        }\n\n        if (cameraFacingDirection == CameraCharacteristics.LENS_FACING_FRONT) {\n            cameraFacingDirection = CameraCharacteristics.LENS_FACING_BACK;\n        } else {\n            cameraFacingDirection = CameraCharacteristics.LENS_FACING_FRONT;\n        }\n\n        cameraId = chooseCamera();\n        fragment.switchCamera(cameraId);\n    }\n\n    private String chooseCamera() {\n        final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);\n        try {\n            for (final String cameraId : manager.getCameraIdList()) {\n                final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n                // We don't use a front facing camera in this sample.\n                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);\n                if (facing != null && facing != cameraFacingDirection) {\n                    continue;\n                }\n\n                final StreamConfigurationMap map =\n                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n                if (map == null) {\n                    continue;\n                }\n\n                // Fallback to camera1 API for internal cameras that don't have full support.\n                // This should help with legacy situations where using the camera2 API causes\n                // distorted or otherwise broken previews.\n                useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)\n                        || isHardwareLevelSupported(characteristics,\n                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);\n                Log.i(TAG, \"Camera API lv2?: \" + useCamera2API);\n                return cameraId;\n            }\n        } catch (CameraAccessException e) {\n            Log.e(TAG, \"Not allowed to access camera: \" + e);\n        }\n\n        return null;\n    }\n\n    // Returns true if the device supports the required hardware level, or better.\n    private boolean isHardwareLevelSupported(\n            CameraCharacteristics characteristics, int requiredLevel) {\n        int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);\n        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {\n            return requiredLevel == deviceLevel;\n        }\n        // deviceLevel is not LEGACY, can use numerical sort\n        return requiredLevel <= deviceLevel;\n    }\n\n\n    public boolean isDebug() {\n        return debug;\n    }\n\n    public void requestRender() {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.postInvalidate();\n        }\n    }\n\n    public void setCallback(final OverlayView.DrawCallback callback) {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.setCallback(callback);\n        }\n    }\n\n    public void onSetDebug(final boolean debug) {\n    }\n\n    @Override\n    public boolean onKeyDown(final int keyCode, final KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {\n            debug = !debug;\n            requestRender();\n            onSetDebug(debug);\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    protected abstract void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation);\n\n    protected abstract int getLayoutId();\n\n    protected Size getDesiredPreviewFrameSize() {\n        return new Size(640, 480);\n    }\n}\n\n\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/activities/BaseLiveGPUActivity.java",
    "content": "package ai.fritz.haircoloring.activities;\n\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.os.Bundle;\nimport android.util.Size;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.ImageButton;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.haircoloring.R;\nimport ai.fritz.vision.FritzSurfaceView;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\n\npublic abstract class BaseLiveGPUActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n\n    private static final String TAG = BaseLiveGPUActivity.class.getSimpleName();\n    private AtomicBoolean computing = new AtomicBoolean(false);\n\n    private ImageOrientation orientation;\n    protected Button chooseModelBtn;\n    protected ImageButton cameraSwitchBtn;\n    protected FritzVisionImage fritzVisionImage;\n    protected FritzSurfaceView fritzSurfaceView;\n\n    @Override\n    public void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size size, final Size cameraSize, final int rotation) {\n        orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n        chooseModelBtn = findViewById(R.id.chose_model_btn);\n        cameraSwitchBtn = findViewById(R.id.camera_switch_btn);\n        fritzSurfaceView = findViewById(R.id.gpuimageview);\n\n        cameraSwitchBtn.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                toggleCameraFacingDirection();\n            }\n        });\n\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        final Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!computing.compareAndSet(false, true)) {\n            image.close();\n            return;\n        }\n        fritzVisionImage = FritzVisionImage.fromMediaImage(image, orientation);\n        runInference(fritzVisionImage);\n        image.close();\n        computing.set(false);\n    }\n\n    protected abstract int getLayoutId();\n\n    @Override\n    public void onSetDebug(final boolean debug) {\n\n    }\n\n    protected abstract void runInference(FritzVisionImage fritzVisionImage);\n}\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/activities/LiveHairColorActivity.java",
    "content": "package ai.fritz.haircoloring.activities;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Color;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.os.Bundle;\nimport android.util.Size;\n\nimport com.github.veritas1.verticalslidecolorpicker.VerticalSlideColorPicker;\n\nimport ai.fritz.haircoloring.R;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.imagesegmentation.BlendMode;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictorOptions;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationResult;\nimport ai.fritz.vision.imagesegmentation.MaskClass;\nimport ai.fritz.vision.imagesegmentation.SegmentationOnDeviceModel;\n\n\npublic class LiveHairColorActivity extends BaseLiveGPUActivity {\n    private int maskColor = Color.RED;\n    private static final int HAIR_ALPHA = 180;\n    private static final BlendMode BLEND_MODE = BlendMode.SOFT_LIGHT;\n    private static final boolean RUN_ON_GPU = true;\n\n    private FritzVisionSegmentationPredictor hairPredictor;\n    private FritzVisionSegmentationResult hairResult;\n    private FritzVisionSegmentationPredictorOptions options;\n\n    private SegmentationOnDeviceModel onDeviceModel;\n\n    public void onCreate(final Bundle savedInstanceState) {\n        setCameraFacingDirection(CameraCharacteristics.LENS_FACING_FRONT);\n        super.onCreate(savedInstanceState);\n\n        // Create the segmentation options\n        options = new FritzVisionSegmentationPredictorOptions();\n        options.useGPU = RUN_ON_GPU;\n\n        // Set the on-device model\n        onDeviceModel = FritzVisionModels.getHairSegmentationOnDeviceModel(ModelVariant.FAST);\n\n        // Load the predictor when the activity is created (iff not running on the GPU)\n        if (!RUN_ON_GPU) {\n            hairPredictor = FritzVision.ImageSegmentation.getPredictor(onDeviceModel, options);\n        }\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size size, final Size cameraSize, final int rotation) {\n        super.onPreviewSizeChosen(size, cameraSize, rotation);\n\n        VerticalSlideColorPicker colorPicker = findViewById(R.id.color_picker);\n\n        // Change the mask color upon using the slider\n        colorPicker.setOnColorChangeListener(new VerticalSlideColorPicker.OnColorChangeListener() {\n            @Override\n            public void onColorChange(int selectedColor) {\n                if (selectedColor != Color.TRANSPARENT) {\n                    maskColor = selectedColor;\n                }\n            }\n        });\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.camera_color_slider;\n    }\n\n    @Override\n    protected void runInference(FritzVisionImage fritzVisionImage) {\n        // If you're using the GPU, it MUST run on the same thread\n        if (RUN_ON_GPU && hairPredictor == null) {\n            hairPredictor = FritzVision.ImageSegmentation.getPredictor(onDeviceModel, options);\n        }\n        hairResult = hairPredictor.predict(fritzVisionImage);\n        Bitmap alphaMask = hairResult.buildSingleClassMask(MaskClass.HAIR, HAIR_ALPHA, options.confidenceThreshold, options.confidenceThreshold, maskColor);\n        fritzSurfaceView.drawBlendedMask(fritzVisionImage, alphaMask, BLEND_MODE, getCameraFacingDirection() == CameraCharacteristics.LENS_FACING_FRONT);\n    }\n}\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/activities/MainActivity.java",
    "content": "package ai.fritz.haircoloring.activities;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport android.view.View;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport ai.fritz.core.Fritz;\nimport ai.fritz.haircoloring.R;\nimport ai.fritz.haircoloring.ui.DemoAdapter;\nimport ai.fritz.haircoloring.ui.DemoItem;\nimport ai.fritz.haircoloring.ui.SeparatorDecoration;\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\npublic class MainActivity extends AppCompatActivity {\n\n    private RecyclerView recyclerView;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Fritz.configure(this);\n        setContentView(R.layout.activity_main);\n\n        recyclerView = findViewById(R.id.demo_list_view);\n        recyclerView.setHasFixedSize(true);\n        LinearLayoutManager rvLinearLayoutMgr = new LinearLayoutManager(this);\n        recyclerView.setLayoutManager(rvLinearLayoutMgr);\n\n        // Add a divider\n        SeparatorDecoration decoration = new SeparatorDecoration(this, Color.GRAY, 1);\n        recyclerView.addItemDecoration(decoration);\n\n        // Add the adapter\n        DemoAdapter adapter = new DemoAdapter(getDemoItems());\n        recyclerView.setAdapter(adapter);\n        recyclerView.setClickable(true);\n    }\n\n    private List<DemoItem> getDemoItems() {\n        List<DemoItem> demoItems = new ArrayList<>();\n\n        demoItems.add(new DemoItem(\n                getString(R.string.fritz_hair_color_title),\n                getString(R.string.fritz_hair_color_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Context context = v.getContext();\n                        Intent liveHair = new Intent(context, LiveHairColorActivity.class);\n                        context.startActivity(liveHair);\n                    }\n                }));\n\n        demoItems.add(new DemoItem(\n                getString(R.string.fritz_video_hair_color_title),\n                getString(R.string.fritz_video_hair_color_description),\n                new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        Context context = v.getContext();\n                        Intent selectVideo = new Intent(context, VideoHairColorActivity.class);\n                        context.startActivity(selectVideo);\n                    }\n                }));\n\n        return demoItems;\n    }\n}\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/activities/VideoHairColorActivity.java",
    "content": "package ai.fritz.haircoloring.activities;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.media.MediaPlayer;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.os.Environment;\nimport android.provider.MediaStore;\nimport android.view.Menu;\nimport android.view.MenuItem;\nimport android.view.View;\nimport android.widget.ProgressBar;\nimport android.widget.TextView;\nimport android.widget.Toast;\nimport android.widget.VideoView;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.nio.channels.FileChannel;\nimport java.util.Locale;\n\nimport ai.fritz.haircoloring.R;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.imagesegmentation.BlendMode;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationMaskOptions;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictorOptions;\nimport ai.fritz.vision.imagesegmentation.MaskClass;\nimport ai.fritz.vision.imagesegmentation.SegmentationOnDeviceModel;\nimport ai.fritz.vision.video.ExportVideoOptions;\nimport ai.fritz.vision.video.FritzVisionImageFilter;\nimport ai.fritz.vision.video.FritzVisionVideo;\nimport ai.fritz.vision.video.filters.imagesegmentation.MaskBlendCompoundFilter;\n\nimport androidx.appcompat.app.AppCompatActivity;\n\npublic class VideoHairColorActivity extends AppCompatActivity {\n\n    private static final int REQUEST_CODE = 1;\n    private static final int HAIR_ALPHA = 180;\n    private static final float HAIR_CONFIDENCE_THRESHOLD = .5f;\n\n    private VideoView videoView;\n    private ProgressBar progressBar;\n    private TextView progressText;\n    private MenuItem exportButton;\n\n    private FritzVisionSegmentationPredictor hairPredictor;\n    private FritzVisionSegmentationMaskOptions maskOptions;\n\n    private File exportFile = null;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_video);\n        videoView = findViewById(R.id.video_view);\n        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {\n            @Override\n            public void onPrepared(MediaPlayer mediaPlayer) {\n                mediaPlayer.setLooping(true);\n                mediaPlayer.setVolume(1, 1);\n                mediaPlayer.start();\n            }\n        });\n        progressBar = findViewById(R.id.export_progress);\n        progressText = findViewById(R.id.progress_text);\n\n        // Create the segmentation options\n        FritzVisionSegmentationPredictorOptions options = new FritzVisionSegmentationPredictorOptions();\n        options.confidenceThreshold = HAIR_CONFIDENCE_THRESHOLD;\n\n        // Set the on-device model\n        SegmentationOnDeviceModel onDeviceModel = FritzVisionModels.getHairSegmentationOnDeviceModel(ModelVariant.FAST);\n        \n        // Create the predictor\n        hairPredictor = FritzVision.ImageSegmentation.getPredictor(onDeviceModel, options);\n\n        maskOptions = new FritzVisionSegmentationMaskOptions();\n        maskOptions.maxAlpha = HAIR_ALPHA;\n\n        // Display the video picker\n        Intent filePicker = new Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI);\n        filePicker.putExtra(Intent.EXTRA_LOCAL_ONLY, true);\n        startActivityForResult(filePicker, 1);\n    }\n\n    @Override\n    public boolean onCreateOptionsMenu(Menu menu) {\n        // Show a top menu bar with an export button\n        getMenuInflater().inflate(R.menu.video_menu, menu);\n        exportButton = menu.findItem(R.id.export_button);\n        exportButton.setVisible(false);\n        exportButton.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {\n            @Override\n            public boolean onMenuItemClick(MenuItem menuItem) {\n                try {\n                    saveProcessedVideo();\n                } catch (IOException e) {\n                    throw new IllegalStateException(\"Unable to save video.\");\n                }\n                menuItem.setEnabled(false);\n                return true;\n            }\n        });\n        return super.onCreateOptionsMenu(menu);\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n\n        File cacheDir = getCacheDir();\n        File[] cachedFiles = cacheDir.listFiles();\n\n        // Delete any cached files\n        if (cachedFiles != null) {\n            for (File file : cachedFiles) {\n                file.delete();\n            }\n        }\n    }\n\n    @Override\n    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\n        if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {\n            // Process the video after a video is selected\n            startProcessing(data.getData());\n        }\n        else {\n            finish();\n        }\n    }\n\n    /**\n     * Starts processing a video.\n     *\n     * @param videoUri The URI of the video to process.\n     */\n    private void startProcessing(Uri videoUri) {\n        try {\n            // Create a temporary file to write the processed video to\n            exportFile = File.createTempFile(\"tempExport\", \".mp4\", getCacheDir());\n        } catch (IOException e) {\n            throw new IllegalStateException(\"Unable to create a destination file.\");\n        }\n\n        // Create the filter to apply on the video\n        FritzVisionImageFilter[] filters = {\n                new MaskBlendCompoundFilter(hairPredictor, maskOptions, MaskClass.HAIR, BlendMode.SOFT_LIGHT)\n        };\n        \n        // Create the FritzVisionVideo object with the filter and selected video URI \n        FritzVisionVideo fritzVideo = new FritzVisionVideo(videoUri, filters);\n\n        // Create and set the processing parameters\n        // Every second frame of the video will be processed\n        // Enable audio to be copied\n        // Disable to decrease processing time\n        ExportVideoOptions options = new ExportVideoOptions();\n        options.copyAudio = true;\n        options.frameInterval = 2;\n\n        final String exportPath = exportFile.getAbsolutePath();\n\n        // Start exporting and processing the whole length of the video while skipping every other frame\n        fritzVideo.export(exportPath, options, new FritzVisionVideo.ExportProgressCallback() {\n            @Override\n            public void onProgress(Float response) {\n                // Update the export progress\n                int progress = (int) (response * 100);\n                updateProgress(progress);\n            }\n\n            @Override\n            public void onComplete() {\n                // Close the predictor\n                hairPredictor.close();\n\n                // Play the processed video\n                Uri uri = Uri.fromFile(exportFile);\n                displayVideo(uri);\n            }\n        });\n    }\n\n    /**\n     * Updates progress when processing.\n     */\n    private void updateProgress(final int progress) {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                progressBar.setProgress(progress);\n                progressText.setText(String.format(Locale.US, \"Processing %d%%\", progress));\n            }\n        });\n    }\n\n    /**\n     * Changes visibility of views when processing is complete.\n     */\n    private void displayVideo(final Uri videoUri) {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                progressBar.setVisibility(View.INVISIBLE);\n                progressText.setVisibility(View.INVISIBLE);\n                exportButton.setVisible(true);\n                videoView.setVideoURI(videoUri);\n            }\n        });\n    }\n\n    /**\n     * Write the contents of the processed video to Photos.\n     *\n     * @throws IOException If there is a file error.\n     */\n    private void saveProcessedVideo() throws IOException {\n        // Get the directory to save to\n        File file = getExternalFilesDir(Environment.DIRECTORY_MOVIES);\n\n        // Create the file to write to\n        String exportPath = (file.getAbsolutePath() + \"/\" + System.currentTimeMillis() + \".mp4\");\n        File destFile = new File(exportPath);\n\n        // Write contents of the processed video file to the destination file\n        try (FileChannel source = new FileInputStream(exportFile).getChannel();\n             FileChannel destination = new FileOutputStream(destFile).getChannel()) {\n            destination.transferFrom(source, 0, source.size());\n        }\n\n        // Notify the user that the video has been saved\n        Toast.makeText(\n                VideoHairColorActivity.this,\n                \"Saved video to \" + exportPath, Toast.LENGTH_LONG\n        ).show();\n    }\n}"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/ui/DemoAdapter.java",
    "content": "package ai.fritz.haircoloring.ui;\n\nimport android.view.LayoutInflater;\nimport android.view.ViewGroup;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\n\nimport ai.fritz.haircoloring.R;\nimport androidx.recyclerview.widget.RecyclerView;\n\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Demo items adapter to manage the list of models.\n */\npublic class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.ViewHolder> {\n    private List<DemoItem> demoItems = new ArrayList<>();\n\n    /**\n     * View holder for each demo item to display in the list.\n     */\n    public static class ViewHolder extends RecyclerView.ViewHolder {\n        public LinearLayout linearLayout;\n        public TextView titleView;\n        public TextView descriptionView;\n\n        public ViewHolder(LinearLayout v) {\n            super(v);\n            linearLayout = v;\n            titleView = linearLayout.findViewById(R.id.title);\n            descriptionView = linearLayout.findViewById(R.id.description);\n        }\n    }\n\n    /**\n     * Initialize the adapter with a list of demo items.\n     *\n     * @param demoItems\n     */\n    public DemoAdapter(List<DemoItem> demoItems) {\n        this.demoItems = demoItems;\n    }\n\n    /**\n     * Get the DemoItem and binds it to the recycled view.\n     * <p>\n     * Also sets the click actions here.\n     *\n     * @param holder\n     * @param position\n     */\n    @Override\n    public void onBindViewHolder(DemoAdapter.ViewHolder holder, int position) {\n        DemoItem demoItem = demoItems.get(position);\n        holder.titleView.setText(demoItem.getTitle());\n        holder.descriptionView.setText(demoItem.getDescription());\n        holder.linearLayout.setOnClickListener(demoItem.getOnClickListener());\n    }\n\n    /**\n     * Get number of demo items.\n     *\n     * @return number of items in the list\n     */\n    @Override\n    public int getItemCount() {\n        return demoItems.size();\n    }\n\n    /**\n     * Create a view holder for the DemoItems\n     *\n     * @param parent\n     * @param viewType\n     * @return\n     */\n    @Override\n    public DemoAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,\n                                                     int viewType) {\n        LinearLayout v = (LinearLayout) LayoutInflater.from(parent.getContext())\n                .inflate(R.layout.list_item_demo, parent, false);\n        ViewHolder holder = new ViewHolder(v);\n        return holder;\n    }\n}\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/ui/DemoItem.java",
    "content": "package ai.fritz.haircoloring.ui;\n\nimport android.view.View;\n\n/**\n * Helper class to show demo items for the DemoAdapter\n */\npublic class DemoItem {\n\n    private String title;\n    private String description;\n    private View.OnClickListener onClickListener;\n\n    public DemoItem(String title, String description, View.OnClickListener clickListener) {\n        this.title = title;\n        this.description = description;\n        this.onClickListener = clickListener;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public String getDescription() {\n        return description;\n    }\n\n    public void setDescription(String description) {\n        this.description = description;\n    }\n\n    public View.OnClickListener getOnClickListener() {\n        return onClickListener;\n    }\n\n    public void setOnClickListener(View.OnClickListener onClickListener) {\n        this.onClickListener = onClickListener;\n    }\n}\n\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/ui/SeparatorDecoration.java",
    "content": "package ai.fritz.haircoloring.ui;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.FloatRange;\nimport androidx.annotation.NonNull;\n\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport android.util.TypedValue;\nimport android.view.View;\n\n/**\n * Taken from https://github.com/bleeding182/recyclerviewItemDecorations\n */\npublic class SeparatorDecoration extends RecyclerView.ItemDecoration {\n\n    private final Paint mPaint;\n\n    /**\n     * Create a decoration that draws a line in the given color and width between the items in the view.\n     *\n     * @param context  a context to access the resources.\n     * @param color    the color of the separator to draw.\n     * @param heightDp the height of the separator in dp.\n     */\n    public SeparatorDecoration(@NonNull Context context, @ColorInt int color,\n                               @FloatRange(from = 0, fromInclusive = false) float heightDp) {\n        mPaint = new Paint();\n        mPaint.setColor(color);\n        final float thickness = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,\n                heightDp, context.getResources().getDisplayMetrics());\n        mPaint.setStrokeWidth(thickness);\n    }\n\n    @Override\n    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {\n        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();\n\n        // we want to retrieve the position in the list\n        final int position = params.getViewAdapterPosition();\n\n        // and add a separator to any view but the last one\n        if (position < state.getItemCount()) {\n            outRect.set(0, 0, 0, (int) mPaint.getStrokeWidth()); // left, top, right, bottom\n        } else {\n            outRect.setEmpty(); // 0, 0, 0, 0\n        }\n    }\n\n    @Override\n    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {\n        // we set the stroke width before, so as to correctly draw the line we have to offset by width / 2\n        final int offset = (int) (mPaint.getStrokeWidth() / 2);\n\n        // this will iterate over every visible view\n        for (int i = 0; i < parent.getChildCount(); i++) {\n            // get the view\n            final View view = parent.getChildAt(i);\n            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();\n\n            // get the position\n            final int position = params.getViewAdapterPosition();\n\n            // and finally draw the separator\n            if (position < state.getItemCount()) {\n                c.drawLine(view.getLeft(), view.getBottom() + offset, view.getRight(), view.getBottom() + offset, mPaint);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/views/AutoFitTextureView.java",
    "content": "package ai.fritz.haircoloring.views;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.TextureView;\n\n/**\n * A {@link TextureView} that can be adjusted to a specified aspect ratio.\n */\npublic class AutoFitTextureView extends TextureView {\n    private int ratioWidth = 0;\n    private int ratioHeight = 0;\n\n    public AutoFitTextureView(final Context context) {\n        this(context, null);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    /**\n     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio\n     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that\n     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.\n     *\n     * @param width  Relative horizontal size\n     * @param height Relative vertical size\n     */\n    public void setAspectRatio(final int width, final int height) {\n        if (width < 0 || height < 0) {\n            throw new IllegalArgumentException(\"Size cannot be negative.\");\n        }\n        ratioWidth = width;\n        ratioHeight = height;\n        requestLayout();\n    }\n}"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/views/CameraConnectionFragment.java",
    "content": "package ai.fritz.haircoloring.views;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.app.DialogFragment;\nimport android.app.Fragment;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.graphics.ImageFormat;\nimport android.graphics.Matrix;\nimport android.graphics.RectF;\nimport android.graphics.SurfaceTexture;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCaptureSession;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraDevice;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.CaptureRequest;\nimport android.hardware.camera2.CaptureResult;\nimport android.hardware.camera2.TotalCaptureResult;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.LayoutInflater;\nimport android.view.Surface;\nimport android.view.TextureView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\n\nimport ai.fritz.haircoloring.R;\n\n\npublic class CameraConnectionFragment extends Fragment {\n    private static final String TAG = CameraConnectionFragment.class.getSimpleName();\n\n    public interface CameraOpenListener {\n        void onCameraOpened();\n    }\n\n    public CameraConnectionFragment() {\n\n    }\n\n    /**\n     * The camera preview size will be chosen to be the smallest frame by pixel size capable of\n     * containing a DESIRED_SIZE x DESIRED_SIZE square.\n     */\n    private static final int MINIMUM_PREVIEW_SIZE = 320;\n\n    /**\n     * Conversion from screen rotation to JPEG orientation.\n     */\n    private static final String FRAGMENT_DIALOG = \"dialog\";\n\n    /**\n     * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a\n     * {@link TextureView}.\n     */\n    private final TextureView.SurfaceTextureListener surfaceTextureListener =\n            new TextureView.SurfaceTextureListener() {\n                @Override\n                public void onSurfaceTextureAvailable(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    openCamera(width, height);\n                }\n\n                @Override\n                public void onSurfaceTextureSizeChanged(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    configureTransform(width, height);\n                }\n\n                @Override\n                public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {\n                    return true;\n                }\n\n                @Override\n                public void onSurfaceTextureUpdated(final SurfaceTexture texture) {\n                }\n            };\n\n    /**\n     * Callback for Activities to use to initialize their data once the\n     * selected preview size is known.\n     */\n    public interface ConnectionCallback {\n        void onPreviewSizeChosen(Size size, Size cameraViewSize, int cameraRotation);\n    }\n\n    /**\n     * ID of the current {@link CameraDevice}.\n     */\n    private String cameraId;\n\n    /**\n     * An {@link AutoFitTextureView} for camera preview.\n     */\n    private AutoFitTextureView textureView;\n\n    /**\n     * A {@link CameraCaptureSession } for camera preview.\n     */\n    private CameraCaptureSession captureSession;\n\n    /**\n     * A reference to the opened {@link CameraDevice}.\n     */\n    private CameraDevice cameraDevice;\n\n    /**\n     * The rotation in degrees of the camera sensor from the display.\n     */\n    private Integer sensorOrientation;\n\n    /**\n     * The {@link android.util.Size} of camera preview.\n     */\n    private Size previewSize;\n\n    /**\n     * {@link android.hardware.camera2.CameraDevice.StateCallback}\n     * is called when {@link CameraDevice} changes its state.\n     */\n    private CameraDevice.StateCallback stateCallback;\n\n    /**\n     * An additional thread for running tasks that shouldn't block the UI.\n     */\n    private HandlerThread backgroundThread;\n\n    /**\n     * A {@link Handler} for running tasks in the background.\n     */\n    private Handler backgroundHandler;\n\n    /**\n     * An {@link ImageReader} that handles preview frame capture.\n     */\n    private ImageReader previewReader;\n\n    /**\n     * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview\n     */\n    private CaptureRequest.Builder previewRequestBuilder;\n\n    /**\n     * {@link CaptureRequest} generated by {@link #previewRequestBuilder}\n     */\n    private CaptureRequest previewRequest;\n\n    /**\n     * A {@link Semaphore} to prevent the app from exiting before closing the camera.\n     */\n    private final Semaphore cameraOpenCloseLock = new Semaphore(1);\n\n    /**\n     * A {@link OnImageAvailableListener} to receive frames as they are available.\n     */\n    private OnImageAvailableListener imageListener = null;\n\n    /**\n     * The input size in pixels desired by TensorFlow (width and height of a square bitmap).\n     */\n    private Size inputSize = null;\n\n    /**\n     * The layout identifier to inflate for this Fragment.\n     */\n    private int layout = -1;\n    CameraOpenListener openListener;\n\n\n    private ConnectionCallback cameraConnectionCallback = null;\n\n    private CameraConnectionFragment(\n            final ConnectionCallback connectionCallback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize,\n            CameraOpenListener listener) {\n        this.cameraConnectionCallback = connectionCallback;\n        this.imageListener = imageListener;\n        this.layout = layout;\n        this.inputSize = inputSize;\n        this.openListener = listener;\n        this.stateCallback =\n                new CameraDevice.StateCallback() {\n                    @Override\n                    public void onOpened(final CameraDevice cd) {\n                        // This method is called when the camera is opened.  We start camera preview here.\n                        cameraOpenCloseLock.release();\n                        cameraDevice = cd;\n                        createCameraPreviewSession();\n                        openListener.onCameraOpened();\n                    }\n\n                    @Override\n                    public void onDisconnected(final CameraDevice cd) {\n                        cameraOpenCloseLock.release();\n                        cd.close();\n                        cameraDevice = null;\n                    }\n\n                    @Override\n                    public void onError(final CameraDevice cd, final int error) {\n                        cameraOpenCloseLock.release();\n                        cd.close();\n                        cameraDevice = null;\n                        final Activity activity = getActivity();\n                        if (null != activity) {\n                            activity.finish();\n                        }\n                    }\n                };\n    }\n\n    /**\n     * Shows a {@link Toast} on the UI thread.\n     *\n     * @param text The message to show\n     */\n    private void showToast(final String text) {\n        final Activity activity = getActivity();\n        if (activity != null) {\n            activity.runOnUiThread(\n                    new Runnable() {\n                        @Override\n                        public void run() {\n                            Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();\n                        }\n                    });\n        }\n    }\n\n    /**\n     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose\n     * width and height are at least as large as the minimum of both, or an exact match if possible.\n     *\n     * @param choices The list of sizes that the camera supports for the intended output class\n     * @param width   The minimum desired width\n     * @param height  The minimum desired height\n     * @return The optimal {@code Size}, or an arbitrary one if none were big enough\n     */\n    protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {\n        final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);\n        final Size desiredSize = new Size(width, height);\n\n        // Collect the supported resolutions that are at least as big as the preview Surface\n        boolean exactSizeFound = false;\n        final List<Size> bigEnough = new ArrayList<Size>();\n        final List<Size> tooSmall = new ArrayList<Size>();\n        for (final Size option : choices) {\n            if (option.equals(desiredSize)) {\n                // Set the size but don't return yet so that remaining sizes will still be logged.\n                exactSizeFound = true;\n            }\n\n            if (option.getHeight() >= minSize && option.getWidth() >= minSize) {\n                bigEnough.add(option);\n            } else {\n                tooSmall.add(option);\n            }\n        }\n\n        Log.d(TAG, \"Desired size: \" + desiredSize + \", min size: \" + minSize + \"x\" + minSize);\n        Log.d(TAG, \"Valid preview sizes: [\" + TextUtils.join(\", \", bigEnough) + \"]\");\n        Log.d(TAG, \"Rejected preview sizes: [\" + TextUtils.join(\", \", tooSmall) + \"]\");\n\n        if (exactSizeFound) {\n            Log.d(TAG, \"Exact size match found.\");\n            return desiredSize;\n        }\n\n        // Pick the smallest of those, assuming we found any\n        if (bigEnough.size() > 0) {\n            final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());\n            Log.d(TAG, \"Chosen size: \" + chosenSize.getWidth() + \"x\" + chosenSize.getHeight());\n            return chosenSize;\n        } else {\n            Log.e(TAG, \"Couldn't find any suitable preview size\");\n            return choices[0];\n        }\n    }\n\n    public static CameraConnectionFragment newInstance(\n            final ConnectionCallback callback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize,\n            CameraOpenListener openListener) {\n        return new CameraConnectionFragment(callback, imageListener, layout, inputSize, openListener);\n    }\n\n    @Override\n    public View onCreateView(\n            final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {\n        return inflater.inflate(layout, container, false);\n    }\n\n    @Override\n    public void onViewCreated(final View view, final Bundle savedInstanceState) {\n        textureView = (AutoFitTextureView) view.findViewById(R.id.texture);\n    }\n\n    @Override\n    public void onActivityCreated(final Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        startBackgroundThread();\n\n        // When the screen is turned off and turned back on, the SurfaceTexture is ai.fritz.heartbeat.ui.AutoFitTextureViewalready\n        // available, and \"onSurfaceTextureAvailable\" will not be called. In that case, we can open\n        // a camera and start preview from here (otherwise, we wait until the surface is ready in\n        // the SurfaceTextureListener).\n        if (textureView.isAvailable()) {\n            openCamera(textureView.getWidth(), textureView.getHeight());\n        } else {\n            textureView.setSurfaceTextureListener(surfaceTextureListener);\n        }\n    }\n\n    @Override\n    public void onPause() {\n        closeCamera();\n        stopBackgroundThread();\n        super.onPause();\n    }\n\n    public void setCamera(String cameraId) {\n        this.cameraId = cameraId;\n    }\n\n    public void switchCamera(String cameraId) {\n        closeCamera();\n        this.cameraId = cameraId;\n        openCamera(textureView.getWidth(), textureView.getHeight());\n    }\n\n    /**\n     * Sets up member variables related to camera.\n     */\n    private void setUpCameraOutputs() {\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n            final StreamConfigurationMap map =\n                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n            // For still image captures, we use the largest available size.\n            final Size largest =\n                    Collections.max(\n                            Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),\n                            new CompareSizesByArea());\n\n            sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);\n\n            // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera\n            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of\n            // garbage capture data.\n            previewSize =\n                    chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),\n                            inputSize.getWidth(),\n                            inputSize.getHeight());\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        } catch (final NullPointerException e) {\n            // Currently an NPE is thrown when the Camera2API is used but not supported on the\n            // device this code runs.\n            // TODO(andrewharp): abstract ErrorDialog/RuntimeException handling out into new method and\n            // reuse throughout app.\n            ErrorDialog.newInstance(getString(R.string.camera_error))\n                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);\n            throw new RuntimeException(getString(R.string.camera_error));\n        }\n\n        Size textureViewSize = new Size(textureView.getWidth(), textureView.getHeight());\n        cameraConnectionCallback.onPreviewSizeChosen(previewSize, textureViewSize, sensorOrientation);\n    }\n\n    /**\n     * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.\n     */\n    private void openCamera(final int width, final int height) {\n        setUpCameraOutputs();\n        configureTransform(width, height);\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\n                throw new RuntimeException(\"Time out waiting to lock camera opening.\");\n            }\n            manager.openCamera(cameraId, stateCallback, backgroundHandler);\n        } catch (final CameraAccessException | SecurityException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\n        }\n    }\n\n    /**\n     * Closes the current {@link CameraDevice}.\n     */\n    private void closeCamera() {\n        try {\n            cameraOpenCloseLock.acquire();\n            if (null != captureSession) {\n                captureSession.close();\n                captureSession = null;\n            }\n            if (null != cameraDevice) {\n                cameraDevice.close();\n                cameraDevice = null;\n            }\n            if (null != previewReader) {\n                previewReader.close();\n                previewReader = null;\n            }\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera closing.\", e);\n        } finally {\n            cameraOpenCloseLock.release();\n        }\n    }\n\n    /**\n     * Starts a background thread and its {@link Handler}.\n     */\n    private void startBackgroundThread() {\n        backgroundThread = new HandlerThread(\"ImageListener\");\n        backgroundThread.start();\n        backgroundHandler = new Handler(backgroundThread.getLooper());\n    }\n\n    /**\n     * Stops the background thread and its {@link Handler}.\n     */\n    private void stopBackgroundThread() {\n        backgroundThread.quitSafely();\n        try {\n            backgroundThread.join();\n            backgroundThread = null;\n            backgroundHandler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    private final CameraCaptureSession.CaptureCallback captureCallback =\n            new CameraCaptureSession.CaptureCallback() {\n                @Override\n                public void onCaptureProgressed(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final CaptureResult partialResult) {\n                }\n\n                @Override\n                public void onCaptureCompleted(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final TotalCaptureResult result) {\n                }\n            };\n\n    /**\n     * Creates a new {@link CameraCaptureSession} for camera preview.\n     */\n    private void createCameraPreviewSession() {\n        try {\n            final SurfaceTexture texture = textureView.getSurfaceTexture();\n            assert texture != null;\n\n            // We configure the size of default buffer to be the size of camera preview we want.\n            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());\n\n            // This is the output Surface we need to start preview.\n            final Surface surface = new Surface(texture);\n\n            // We set up a CaptureRequest.Builder with the output Surface.\n            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\n            previewRequestBuilder.addTarget(surface);\n\n            Log.i(TAG, \"Opening camera preview: \" + previewSize.getWidth() + \"x\" + previewSize.getHeight());\n\n            // Create the reader for the preview frames.\n            previewReader =\n                    ImageReader.newInstance(\n                            previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);\n\n            previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);\n            previewRequestBuilder.addTarget(previewReader.getSurface());\n\n            // Here, we create a CameraCaptureSession for camera preview.\n            cameraDevice.createCaptureSession(\n                    Arrays.asList(surface, previewReader.getSurface()),\n                    new CameraCaptureSession.StateCallback() {\n\n                        @Override\n                        public void onConfigured(final CameraCaptureSession cameraCaptureSession) {\n                            // The camera is already closed\n                            if (null == cameraDevice) {\n                                return;\n                            }\n\n                            // When the session is ready, we start displaying the preview.\n                            captureSession = cameraCaptureSession;\n                            try {\n                                // Auto focus should be continuous for camera preview.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AF_MODE,\n                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\n                                // Flash is automatically enabled when necessary.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);\n\n                                // Finally, we start displaying the camera preview.\n                                previewRequest = previewRequestBuilder.build();\n                                captureSession.setRepeatingRequest(\n                                        previewRequest, captureCallback, backgroundHandler);\n                            } catch (final CameraAccessException e) {\n                                Log.e(TAG, \"Exception!\" + e);\n                            }\n                        }\n\n                        @Override\n                        public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {\n                            showToast(\"Failed\");\n                        }\n                    },\n                    null);\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    /**\n     * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.\n     * This method should be called after the camera preview size is determined in\n     * setUpCameraOutputs and also the size of `mTextureView` is fixed.\n     *\n     * @param viewWidth  The width of `mTextureView`\n     * @param viewHeight The height of `mTextureView`\n     */\n    private void configureTransform(final int viewWidth, final int viewHeight) {\n        final Activity activity = getActivity();\n        if (null == textureView || null == previewSize || null == activity) {\n            return;\n        }\n        final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();\n        final Matrix matrix = new Matrix();\n        final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);\n        final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());\n        final float centerX = viewRect.centerX();\n        final float centerY = viewRect.centerY();\n        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {\n            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());\n            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);\n            final float scale =\n                    Math.max(\n                            (float) viewHeight / previewSize.getHeight(),\n                            (float) viewWidth / previewSize.getWidth());\n            matrix.postScale(scale, scale, centerX, centerY);\n            matrix.postRotate(90 * (rotation - 2), centerX, centerY);\n        } else if (Surface.ROTATION_180 == rotation) {\n            matrix.postRotate(180, centerX, centerY);\n        }\n        textureView.setTransform(matrix);\n    }\n\n    /**\n     * Compares two {@code Size}s based on their areas.\n     */\n    static class CompareSizesByArea implements Comparator<Size> {\n        @Override\n        public int compare(final Size lhs, final Size rhs) {\n            // We cast here to ensure the multiplications won't overflow\n            return Long.signum(\n                    (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());\n        }\n    }\n\n    /**\n     * Shows an error message dialog.\n     */\n    public static class ErrorDialog extends DialogFragment {\n        private static final String ARG_MESSAGE = \"message\";\n\n        public static ErrorDialog newInstance(final String message) {\n            final ErrorDialog dialog = new ErrorDialog();\n            final Bundle args = new Bundle();\n            args.putString(ARG_MESSAGE, message);\n            dialog.setArguments(args);\n            return dialog;\n        }\n\n        @Override\n        public Dialog onCreateDialog(final Bundle savedInstanceState) {\n            final Activity activity = getActivity();\n            return new AlertDialog.Builder(activity)\n                    .setMessage(getArguments().getString(ARG_MESSAGE))\n                    .setPositiveButton(\n                            android.R.string.ok,\n                            new DialogInterface.OnClickListener() {\n                                @Override\n                                public void onClick(final DialogInterface dialogInterface, final int i) {\n                                    activity.finish();\n                                }\n                            })\n                    .create();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/java/ai/fritz/haircoloring/views/OverlayView.java",
    "content": "package ai.fritz.haircoloring.views;\n/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n    http://www.apache.org/licenses/LICENSE-2.0\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n==============================================================================*/\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.util.AttributeSet;\nimport android.view.View;\n\n/**\n * A simple View providing a render callback to other classes.\n */\npublic class OverlayView extends View {\n    private DrawCallback callback;\n\n    public OverlayView(final Context context, final AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    /**\n     * Interface defining the callback for client classes.\n     */\n    public interface DrawCallback {\n        void drawCallback(final Canvas canvas);\n    }\n\n    public void setCallback(final DrawCallback callback) {\n        this.callback = callback;\n    }\n\n    @Override\n    public synchronized void draw(final Canvas canvas) {\n        super.draw(canvas);\n        if(callback != null) {\n            callback.drawCallback(canvas);\n        }\n    }\n}"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/drawable/ic_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24.0\"\n    android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        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\"/>\n</vector>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/drawable/round_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\">\n    <stroke\n        android:color=\"#FFFF\"\n        android:width=\"5dip\"/>\n    <size android:width=\"100dp\" android:height=\"100dp\"/>\n</shape>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/font/sf_display.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<font-family xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <font\n        android:font=\"@font/sf_ui_display_bold\"\n        android:fontStyle=\"normal\"\n        android:fontWeight=\"700\"\n        app:font=\"@font/sf_ui_display_bold\"\n        app:fontStyle=\"normal\"\n        app:fontWeight=\"700\" />\n    <font\n        android:font=\"@font/sf_ui_display_regular\"\n        android:fontStyle=\"normal\"\n        android:fontWeight=\"400\"\n        app:font=\"@font/sf_ui_display_regular\"\n        app:fontStyle=\"normal\"\n        app:fontWeight=\"400\" />\n    <font\n        android:font=\"@font/sf_ui_display_light\"\n        android:fontStyle=\"normal\"\n        android:fontWeight=\"200\"\n        app:font=\"@font/sf_ui_display_light\"\n        app:fontStyle=\"normal\"\n        app:fontWeight=\"200\" />\n</font-family>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/layout/activity_camera.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <FrameLayout\n        android:id=\"@+id/camera_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</androidx.constraintlayout.widget.ConstraintLayout>\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@color/colorPrimary\">\n\n    <ImageView\n        android:id=\"@+id/imageView\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginBottom=\"@android:dimen/thumbnail_height\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:srcCompat=\"@drawable/fritz_logo\" />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/demo_list_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:scrollbars=\"vertical\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/imageView\" />\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/layout/activity_video.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <VideoView\n        android:id=\"@+id/video_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n    <ProgressBar\n        android:id=\"@+id/export_progress\"\n        style=\"?android:attr/progressBarStyleHorizontal\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:progress=\"0\"\n        android:scaleY=\"3\"\n        android:layout_marginStart=\"@dimen/margin_xl\"\n        android:layout_marginEnd=\"@dimen/margin_xl\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n    <TextView\n        android:id=\"@+id/progress_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Processing...\"\n        android:textColor=\"@color/textColorPrimary\"\n        android:layout_marginTop=\"@dimen/margin_md\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/export_progress\" />\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/layout/camera_color_slider.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    xmlns:colorpicker=\"http://schemas.android.com/tools\"\n    android:orientation=\"vertical\">\n\n    <ai.fritz.haircoloring.views.AutoFitTextureView\n        android:id=\"@+id/texture\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\" />\n\n    <ai.fritz.vision.FritzSurfaceView\n        android:id=\"@+id/gpuimageview\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentTop=\"true\"\n        app:gpuimage_show_loading=\"false\"\n        app:gpuimage_surface_type=\"surface_view\" />\n\n    <ImageButton\n        android:id=\"@+id/camera_switch_btn\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentRight=\"true\"\n        android:background=\"@null\"\n        android:padding=\"@dimen/margin_sm\"\n        android:src=\"@drawable/ic_camera_switch\" />\n\n    <Button\n        android:id=\"@+id/chose_model_btn\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentBottom=\"true\"\n        android:background=\"@color/colorPrimary\"\n        android:foreground=\"?attr/selectableItemBackground\"\n        android:gravity=\"center_horizontal\"\n        android:paddingTop=\"10dp\"\n        android:paddingBottom=\"10dp\"\n        android:textAlignment=\"gravity\"\n        android:textColor=\"#FFF\"\n        android:textSize=\"18sp\"\n        android:textStyle=\"bold\"\n        android:visibility=\"gone\" />\n\n    <com.github.veritas1.verticalslidecolorpicker.VerticalSlideColorPicker\n        android:id=\"@+id/color_picker\"\n        android:layout_width=\"40dp\"\n        android:layout_height=\"300dp\"\n        android:layout_marginEnd=\"5dp\"\n        android:layout_alignParentEnd=\"true\"\n        android:layout_centerInParent=\"true\"\n        colorpicker:borderColor=\"@android:color/black\"\n        colorpicker:borderWidth=\"2dp\"/>\n\n</RelativeLayout>\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/layout/camera_connection_fragment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <ai.fritz.haircoloring.views.AutoFitTextureView\n        android:id=\"@+id/texture\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"/>\n\n    <ai.fritz.haircoloring.views.OverlayView\n        android:id=\"@+id/debug_overlay\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"/>\n\n    <ImageButton\n        android:id=\"@+id/camera_switch_btn\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentRight=\"true\"\n        android:background=\"@null\"\n        android:padding=\"@dimen/margin_sm\"\n        android:src=\"@drawable/ic_camera_switch\" />\n</RelativeLayout>\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/layout/list_item_demo.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:theme=\"@android:style/ThemeOverlay.Material.Dark\"\n    android:background=\"?android:selectableItemBackground\"\n    android:layout_height=\"wrap_content\"\n    android:layout_width=\"match_parent\"\n    android:padding=\"@dimen/margin_md\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/title\"\n        style=\"@style/HeaderText\"\n        android:layout_height=\"wrap_content\"\n        android:layout_width=\"wrap_content\"\n        android:text=\"Header\"\n        android:layout_marginBottom=\"@dimen/margin_sm\"/>\n\n    <TextView\n        android:id=\"@+id/description\"\n        style=\"@style/BodyText\"\n        android:layout_height=\"wrap_content\"\n        android:layout_width=\"wrap_content\"\n        android:text=\"Some Description\" />\n\n</LinearLayout>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/menu/video_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n    <item\n        android:id=\"@+id/export_button\"\n        android:icon=\"@drawable/export_icon\"\n        android:orderInCategory=\"100\"\n        app:showAsAction=\"always\"\n        android:title=\"\" />\n</menu>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#000</color>\n    <color name=\"colorPrimaryDark\">#000</color>\n    <color name=\"colorAccent\">#9E8D37</color>\n    <color name=\"textColorPrimary\">#fff</color>\n</resources>\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/values/dimens.xml",
    "content": "<!--\n  Copyright 2013 The Android Open Source Project\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n\n<resources>\n\n    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->\n\n    <dimen name=\"margin_xs\">4dp</dimen>\n    <dimen name=\"margin_sm\">8dp</dimen>\n    <dimen name=\"margin_md\">16dp</dimen>\n    <dimen name=\"margin_lg\">32dp</dimen>\n    <dimen name=\"margin_xl\">64dp</dimen>\n\n    <!-- Semantic definitions -->\n\n    <dimen name=\"horizontal_page_margin\">@dimen/margin_md</dimen>\n    <dimen name=\"vertical_page_margin\">@dimen/margin_md</dimen>\n\n</resources>"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Hair Coloring</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n\n    <string name=\"fritz_hair_color_title\">Run in Real-Time</string>\n    <string name=\"fritz_hair_color_description\">Using a live preview, change your hair color in real-time.</string>\n\n    <string name=\"fritz_video_hair_color_title\">Run on a Saved Video</string>\n    <string name=\"fritz_video_hair_color_description\">Choose a video you\\'ve already recorded and run hair coloring on each frame.</string>\n\n    <string name=\"video_path_key\">video</string>\n</resources>\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n    <!-- Text Themes -->\n    <style name=\"HeaderText\" parent=\"@android:style/TextAppearance.Medium\">\n        <item name=\"android:textColor\">@color/textColorPrimary</item>\n        <item name=\"android:textStyle\">normal</item>\n        <item name=\"android:fontFamily\">@font/sf_ui_display_regular</item>\n        <item name=\"android:textAllCaps\">true</item>\n        <item name=\"android:letterSpacing\">.12</item>\n    </style>\n\n    <style name=\"BodyText\" parent=\"@android:style/TextAppearance.Small\">\n        <item name=\"android:textColor\">@color/textColorPrimary</item>\n        <item name=\"android:textStyle\">normal</item>\n        <item name=\"android:fontFamily\">@font/sf_ui_display_light</item>\n        <item name=\"android:letterSpacing\">.05</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "Android/HairColoringApp/app/src/test/java/ai/fritz/haircoloring/ExampleUnitTest.java",
    "content": "package ai.fritz.haircoloring;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/HairColoringApp/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    \n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.4.0'\n        \n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n        maven { url 'https://jitpack.io' }\n\n        // ADD FOR FRITZ DEPENDENCIES\n        maven {\n            url \"https://fritz.mycloudrepo.io/public/repositories/android\"\n        }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "Android/HairColoringApp/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n\nandroid.useAndroidX = true\nandroid.enableJetifier = true"
  },
  {
    "path": "Android/HairColoringApp/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/HairColoringApp/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/HairColoringApp/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "Android/ImageLabelingApp/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea\n\n# Keystore files\n# Uncomment the following line if you do not want to check your keystore files in.\n#*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n# fastlane\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\nfastlane/readme.md\n"
  },
  {
    "path": "Android/ImageLabelingApp/README.md",
    "content": "# Image Labeling Demo App with Data Collection\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, the user labels images and records the result to Fritz. For an example of a real time implementation of image labeling, check out the [Fritz AI Studio app](https://github.com/fritzlabs/fritz-examples/blob/master/Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/vision/ImageLabelingActivity.java)\n\nThis example app uses the on-device Image Labeling API for Android.\n\n- [Overview](https://docs.fritz.ai/develop/vision/image-labeling/about.html)\n- [Documentation](https://docs.fritz.ai/develop/vision/image-labeling/android.html)\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Android Studio 3.2 or above\n- Android device in developer model (USB debugging enabled)\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nRegister the Android app in your Fritz account with the package id \"ai.fritz.imagelabelingdemo\". During registration, you'll receive an API key for the app. Save this for later. To find it in the webapp, you can go to Project Settings > Apps > Your App > Show API Key.\n\n**Step 2: Clone / Fork the fritz-examples repository and open the BackgroundReplacementApp app in Android Studio**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\nIn Android Studio, choose \"Open an existing Android Studio project\" and select `ImageLabelingApp`.\n\n**Step 3: Edit the fritz.xml file with your API Key**\n\nIn app/src/main/res/values/fritz.xml, change the fritz_api_key attribute with the one you received in step 1.\n\n**Step 4: Build the Android Studio Project**\n\nSelect \"Build > Make Project\" from the top nav. Download any missing libraries if applicable. This should sync the gradle dependencies so give the build a second to complete.\n\n**Step 5: Install the app onto your device**\n\nWith your Android device connected, select `Run > Run App` from the top nav. When running the app for the first time, you'll have to give permissions to access the camera. After the app is installed and running, take a picture of something and you'll see labels overlayed on the image. Afterwards you can choose to record the model predictions if your model is connected to an image collection in the webapp.\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to our [Help Center](https://docs.fritz.ai/help-center/index.html?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 29\n    defaultConfig {\n        // MUST MATCH THE APPLICATION YOU CREATE IN FRITZ\n        applicationId \"ai.fritz.imagelabelingdemo\"\n        minSdkVersion 24\n        targetSdkVersion 29\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n    compileOptions {\n        sourceCompatibility = 1.8\n        targetCompatibility = 1.8\n    }\n}\n\ndependencies {\n    implementation 'androidx.appcompat:appcompat:1.0.0'\n    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'\n    implementation 'androidx.recyclerview:recyclerview:1.0.0'\n\n    implementation \"ai.fritz:core:6.0.0\"\n    implementation \"ai.fritz:vision:6.0.0\"\n\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'com.android.support.test:runner:1.0.2'\n    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'\n}\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.imagelabelingdemo\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\"ai.fritz.camera.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <service\n            android:name=\"ai.fritz.core.FritzCustomModelService\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/assets/label_recording_model.json",
    "content": "{\n  \"model_path\": \"file:///android_asset/image_labeling_quantized_model.tflite\",\n  \"pinned_version\": 1,\n  \"model_version\": 1,\n  \"model_id\": \"Your model id\",\n  \"labels\": [\n    \"background\",\n    \"fish\",\n    \"fish\",\n    \"shark\",\n    \"shark\",\n    \"shark\",\n    \"ray\",\n    \"ray\",\n    \"chicken\",\n    \"chicken\",\n    \"ostrich\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"eagle\",\n    \"vulture\",\n    \"owl\",\n    \"lizard\",\n    \"lizard\",\n    \"lizard\",\n    \"salamander\",\n    \"salamander\",\n    \"frog\",\n    \"frog\",\n    \"frog\",\n    \"turtle\",\n    \"turtle\",\n    \"turtle\",\n    \"turtle\",\n    \"turtle\",\n    \"lizard\",\n    \"lizard\",\n    \"lizard\",\n    \"lizard\",\n    \"lizard\",\n    \"lizard\",\n    \"lizard\",\n    \"lizard\",\n    \"lizard\",\n    \"lizard\",\n    \"lizard\",\n    \"alligator\",\n    \"alligator\",\n    \"triceratops\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"snake\",\n    \"trilobite\",\n    \"spider\",\n    \"scorpion\",\n    \"spider\",\n    \"spider\",\n    \"spider\",\n    \"spider\",\n    \"spider\",\n    \"spider\",\n    \"tick\",\n    \"centipede\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"peacock\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"goose\",\n    \"swan\",\n    \"elaphant\",\n    \"anteaters\",\n    \"platypus\",\n    \"wallaby\",\n    \"koala\",\n    \"wombat\",\n    \"jellyfish\",\n    \"sea_anemone\",\n    \"coral\",\n    \"worm\",\n    \"worm\",\n    \"sea_shell\",\n    \"snail\",\n    \"slug\",\n    \"slug\",\n    \"mollusk\",\n    \"mollusk\",\n    \"crab\",\n    \"crab\",\n    \"crab\",\n    \"crab\",\n    \"lobster\",\n    \"lobster\",\n    \"crayfish\",\n    \"crab\",\n    \"crab\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"flamingo\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"bird\",\n    \"penguin\",\n    \"bird\",\n    \"whale\",\n    \"killer_whale\",\n    \"dugong\",\n    \"sea_lion\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"dog\",\n    \"wolf\",\n    \"wolf\",\n    \"wolf\",\n    \"coyote\",\n    \"dingo\",\n    \"dog\",\n    \"dog\",\n    \"hyena\",\n    \"fox\",\n    \"fox\",\n    \"fox\",\n    \"fox\",\n    \"cat\",\n    \"cat\",\n    \"cat\",\n    \"cat\",\n    \"cat\",\n    \"cougar\",\n    \"lynx\",\n    \"leopard\",\n    \"snow_leopard\",\n    \"jaguar\",\n    \"lion\",\n    \"tiger\",\n    \"cheetah\",\n    \"brown_bear\",\n    \"American_black_bear\",\n    \"polar_bear\",\n    \"bear\",\n    \"mongoose\",\n    \"meerkat\",\n    \"beetle\",\n    \"ladybug\",\n    \"beetle\",\n    \"beetle\",\n    \"beetle\",\n    \"beetle\",\n    \"beetle\",\n    \"beetle\",\n    \"fly\",\n    \"bee\",\n    \"ant\",\n    \"grasshopper\",\n    \"cricket\",\n    \"walking_stick\",\n    \"cockroach\",\n    \"mantis\",\n    \"cicada\",\n    \"bug\",\n    \"bug\",\n    \"dragonfly\",\n    \"dragonfly\",\n    \"butterfly\",\n    \"butterfly\",\n    \"butterfly\",\n    \"butterfly\",\n    \"butterfly\",\n    \"butterfly\",\n    \"starfish\",\n    \"sea_urchin\",\n    \"sea_cucumber\",\n    \"rabbit\",\n    \"rabbit\",\n    \"rabbit\",\n    \"hamster\",\n    \"porcupine\",\n    \"squirrel\",\n    \"marmot\",\n    \"beaver\",\n    \"guinea_pig\",\n    \"horse\",\n    \"zebra\",\n    \"pig\",\n    \"boar\",\n    \"boar\",\n    \"hippopotamus\",\n    \"ox\",\n    \"buffalo\",\n    \"bison\",\n    \"ram\",\n    \"sheep\",\n    \"antelope\",\n    \"antelope\",\n    \"antelope\",\n    \"antelope\",\n    \"camel\",\n    \"llama\",\n    \"weasel\",\n    \"mink\",\n    \"ferret\",\n    \"ferret\",\n    \"otter\",\n    \"skunk\",\n    \"badget\",\n    \"armadillo\",\n    \"sloth\",\n    \"orangutan\",\n    \"gorilla\",\n    \"chimpanzee\",\n    \"ape\",\n    \"ape\",\n    \"monkey\",\n    \"monkey\",\n    \"baboon\",\n    \"monkey\",\n    \"monkey\",\n    \"monkey\",\n    \"monkey\",\n    \"monkey\",\n    \"monkey\",\n    \"monkey\",\n    \"monkey\",\n    \"monkey\",\n    \"monkey\",\n    \"cat\",\n    \"lemur\",\n    \"elephant\",\n    \"elephant\",\n    \"panda\",\n    \"panda\",\n    \"fish\",\n    \"eel\",\n    \"fish\",\n    \"fish\",\n    \"fish\",\n    \"fish\",\n    \"fish\",\n    \"fish\",\n    \"puffer_fish\",\n    \"abacus\",\n    \"abaya\",\n    \"gown\",\n    \"accordion\",\n    \"acoustic_guitar\",\n    \"aircraft_carrier\",\n    \"airplane\",\n    \"blimp\",\n    \"altar\",\n    \"ambulance\",\n    \"amphibian\",\n    \"clock\",\n    \"bee_house\",\n    \"apron\",\n    \"trash_can\",\n    \"gun\",\n    \"backpack\",\n    \"bakery\",\n    \"balance_beam\",\n    \"balloon\",\n    \"pen\",\n    \"band_aid\",\n    \"banjo\",\n    \"bannister\",\n    \"barbell\",\n    \"barber_chair\",\n    \"barbershop\",\n    \"barn\",\n    \"barometer\",\n    \"barrel\",\n    \"barrow\",\n    \"baseball\",\n    \"basketball\",\n    \"bassinet\",\n    \"bassoon\",\n    \"shower_cap\",\n    \"towel\",\n    \"bathtub\",\n    \"station_wagon\",\n    \"beacon\",\n    \"beaker\",\n    \"bearskin\",\n    \"bottle\",\n    \"glass\",\n    \"bell_cote\",\n    \"bib\",\n    \"bicycle\",\n    \"bikini\",\n    \"binder\",\n    \"binoculars\",\n    \"birdhouse\",\n    \"boathouse\",\n    \"bobsled\",\n    \"bolo_tie\",\n    \"bonnet\",\n    \"bookcase\",\n    \"bookshop\",\n    \"bottlecap\",\n    \"bow\",\n    \"bow_tie\",\n    \"brass\",\n    \"brassiere\",\n    \"jetty\",\n    \"breastplate\",\n    \"broom\",\n    \"bucket\",\n    \"buckle\",\n    \"bulletproof_vest\",\n    \"bullet_train\",\n    \"butcher_shop\",\n    \"taxi\",\n    \"caldron\",\n    \"candle\",\n    \"cannon\",\n    \"canoe\",\n    \"can_opener\",\n    \"cardigan\",\n    \"car_mirror\",\n    \"carousel\",\n    \"tool_kit\",\n    \"carton\",\n    \"car_wheel\",\n    \"atm\",\n    \"cassette\",\n    \"cassette_player\",\n    \"castle\",\n    \"catamaran\",\n    \"cd_player\",\n    \"cello\",\n    \"mobile_phone\",\n    \"chain\",\n    \"chainlink_fence\",\n    \"chain_mail\",\n    \"chain_saw\",\n    \"chest\",\n    \"toilet\",\n    \"chime\",\n    \"china_cabinet\",\n    \"christmas_stocking\",\n    \"church\",\n    \"cinema\",\n    \"cleaver\",\n    \"cliff_dwelling\",\n    \"cloak\",\n    \"clog\",\n    \"cocktail_shaker\",\n    \"coffee_mug\",\n    \"coffeepot\",\n    \"coil\",\n    \"combination_lock\",\n    \"computer_keyboard\",\n    \"candy_store\",\n    \"container_ship\",\n    \"convertible\",\n    \"corkscrew\",\n    \"cornet\",\n    \"cowboy_boot\",\n    \"cowboy_hat\",\n    \"cradle\",\n    \"crane\",\n    \"crash_helmet\",\n    \"crate\",\n    \"crib\",\n    \"crock_pot\",\n    \"croquet_ball\",\n    \"crutch\",\n    \"cuirass\",\n    \"dam\",\n    \"desk\",\n    \"desktop_computer\",\n    \"telephone\",\n    \"diaper\",\n    \"clock\",\n    \"watch\",\n    \"dining_table\",\n    \"dishrag\",\n    \"dishwasher\",\n    \"disk_brake\",\n    \"dock\",\n    \"dogsled\",\n    \"dome\",\n    \"doormat\",\n    \"drilling_platform\",\n    \"drum\",\n    \"drumstick\",\n    \"dumbbell\",\n    \"dutch_oven\",\n    \"electric_fan\",\n    \"electric_guitar\",\n    \"train\",\n    \"entertainment_center\",\n    \"envelope\",\n    \"espresso_maker\",\n    \"face_powder\",\n    \"feather_boa\",\n    \"file\",\n    \"fireboat\",\n    \"fire_engine\",\n    \"fire_screen\",\n    \"flagpole\",\n    \"flute\",\n    \"folding_chair\",\n    \"football_helmet\",\n    \"forklift\",\n    \"fountain\",\n    \"pen\",\n    \"bed\",\n    \"freight_car\",\n    \"french_horn\",\n    \"frying_pan\",\n    \"fur_coat\",\n    \"garbage_truck\",\n    \"gasmask\",\n    \"gas_pump\",\n    \"goblet\",\n    \"go-kart\",\n    \"golf_ball\",\n    \"golfcart\",\n    \"gondola\",\n    \"gong\",\n    \"gown\",\n    \"grand_piano\",\n    \"greenhouse\",\n    \"grille\",\n    \"grocery_store\",\n    \"guillotine\",\n    \"hair_clip\",\n    \"hair_spray\",\n    \"truck\",\n    \"hammer\",\n    \"hamper\",\n    \"hair_dryer\",\n    \"smartphone\",\n    \"handkerchief\",\n    \"hard_disc\",\n    \"harmonica\",\n    \"harp\",\n    \"harvester\",\n    \"hatchet\",\n    \"holster\",\n    \"home_theater\",\n    \"honeycomb\",\n    \"hook\",\n    \"skirt\",\n    \"high_bar\",\n    \"horse_cart\",\n    \"hourglass\",\n    \"ipod\",\n    \"iron\",\n    \"jack-o'-lantern\",\n    \"blue_jeans\",\n    \"jeep\",\n    \"jersey\",\n    \"jigsaw_puzzle\",\n    \"rickshaw\",\n    \"joystick\",\n    \"kimono\",\n    \"knee_pad\",\n    \"knot\",\n    \"lab_coat\",\n    \"ladle\",\n    \"lampshade\",\n    \"laptop\",\n    \"lawn_mower\",\n    \"lens_cap\",\n    \"letter_opener\",\n    \"library\",\n    \"lifeboat\",\n    \"lighter\",\n    \"limousine\",\n    \"ship\",\n    \"lipstick\",\n    \"shoe\",\n    \"lotion\",\n    \"speaker\",\n    \"magnifying_glass\",\n    \"lumbermill\",\n    \"magnetic_compass\",\n    \"mailbag\",\n    \"mailbox\",\n    \"bathing_suit\",\n    \"bathing_suit\",\n    \"manhole_cover\",\n    \"maraca\",\n    \"marimba\",\n    \"mask\",\n    \"matchstick\",\n    \"maypole\",\n    \"maze\",\n    \"measuring_cup\",\n    \"medicine_cabinet\",\n    \"monument\",\n    \"microphone\",\n    \"microwave\",\n    \"military_uniform\",\n    \"milk_can\",\n    \"minibus\",\n    \"skirt\",\n    \"minivan\",\n    \"missile\",\n    \"mitten\",\n    \"mixing_bowl\",\n    \"mobile_home\",\n    \"old_car\",\n    \"modem\",\n    \"monastery\",\n    \"monitor\",\n    \"moped\",\n    \"mortar\",\n    \"mortarboard\",\n    \"mosque\",\n    \"mosquito_net\",\n    \"scooter_\",\n    \"bicycle\",\n    \"tent\",\n    \"mouse\",\n    \"mousetrap\",\n    \"moving_van\",\n    \"muzzle\",\n    \"nail\",\n    \"neck_brace\",\n    \"necklace\",\n    \"nipple\",\n    \"notebook\",\n    \"monument\",\n    \"oboe\",\n    \"ocarina\",\n    \"odometer\",\n    \"oil_filter\",\n    \"organ\",\n    \"oscilloscope\",\n    \"skirt\",\n    \"horse_cart\",\n    \"oxygen_mask\",\n    \"packet\",\n    \"paddle\",\n    \"paddlewheel\",\n    \"padlock\",\n    \"paintbrush\",\n    \"pajama\",\n    \"palace\",\n    \"panpipe\",\n    \"paper_towel\",\n    \"parachute\",\n    \"parallel_bars\",\n    \"park_bench\",\n    \"parking_meter\",\n    \"car\",\n    \"patio\",\n    \"pay_phone\",\n    \"pedestal\",\n    \"pencil_case\",\n    \"pencil_sharpener\",\n    \"perfume\",\n    \"petri_dish\",\n    \"photocopier\",\n    \"guitar_pick\",\n    \"helmet\",\n    \"fence\",\n    \"pickup_truck\",\n    \"pier\",\n    \"piggy_bank\",\n    \"pill_bottle\",\n    \"pillow\",\n    \"ping_pong_ball\",\n    \"pinwheel\",\n    \"pirate\",\n    \"pitcher\",\n    \"wood_plane\",\n    \"planetarium\",\n    \"plastic_bag\",\n    \"dish_rack\",\n    \"plot\",\n    \"plunger\",\n    \"camera\",\n    \"pole\",\n    \"police_van\",\n    \"poncho\",\n    \"pool_table\",\n    \"bottle\",\n    \"pot\",\n    \"potter's_wheel\",\n    \"power_drill\",\n    \"rug\",\n    \"printer\",\n    \"prison\",\n    \"missile\",\n    \"projector\",\n    \"puck\",\n    \"punching_bag\",\n    \"purse\",\n    \"quill\",\n    \"quilt\",\n    \"racer\",\n    \"racket\",\n    \"radiator\",\n    \"radio\",\n    \"telescope\",\n    \"barrel\",\n    \"recreational_vehicle\",\n    \"reel\",\n    \"camera\",\n    \"refrigerator\",\n    \"remote_control\",\n    \"restaurant\",\n    \"gun\",\n    \"gun\",\n    \"chair\",\n    \"rotisserie\",\n    \"rubber_eraser\",\n    \"ball\",\n    \"ruler\",\n    \"shoe\",\n    \"safe\",\n    \"safety_pin\",\n    \"saltshaker\",\n    \"sandal\",\n    \"skirt\",\n    \"saxophone\",\n    \"sword\",\n    \"scale\",\n    \"school_bus\",\n    \"ship\",\n    \"scoreboard\",\n    \"screen\",\n    \"screw\",\n    \"screwdriver\",\n    \"seat_belt\",\n    \"sewing_machine\",\n    \"shield\",\n    \"shoe_store\",\n    \"shoji\",\n    \"shopping_basket\",\n    \"shopping_cart\",\n    \"shovel\",\n    \"shower_cap\",\n    \"shower_curtain\",\n    \"ski\",\n    \"ski_mask\",\n    \"sleeping_bag\",\n    \"slide_rule\",\n    \"sliding_door\",\n    \"slot_machine\",\n    \"snorkel\",\n    \"snowmobile\",\n    \"snowplow\",\n    \"soap_dispenser\",\n    \"soccer_ball\",\n    \"sock\",\n    \"solar_dish\",\n    \"sombrero\",\n    \"soup_bowl\",\n    \"space_bar\",\n    \"space_heater\",\n    \"space_shuttle\",\n    \"spatula\",\n    \"boat\",\n    \"spider_web\",\n    \"spindle\",\n    \"car\",\n    \"spotlight\",\n    \"stage\",\n    \"train\",\n    \"bridge\",\n    \"barrel\",\n    \"stethoscope\",\n    \"stole\",\n    \"stone_wall\",\n    \"stopwatch\",\n    \"stove\",\n    \"strainer\",\n    \"streetcar\",\n    \"stretcher\",\n    \"sofa\",\n    \"stupa\",\n    \"submarine\",\n    \"suit\",\n    \"sundial\",\n    \"sunglasses\",\n    \"sunglasses\",\n    \"sunscreen\",\n    \"bridge\",\n    \"mop\",\n    \"sweatshirt\",\n    \"bathing_suit\",\n    \"swing\",\n    \"switch\",\n    \"syringe\",\n    \"lamp\",\n    \"tank\",\n    \"tape_player\",\n    \"teapot\",\n    \"teddy_bear\",\n    \"television\",\n    \"tennis_ball\",\n    \"thatched_roof\",\n    \"curtain\",\n    \"thimble\",\n    \"thresher\",\n    \"throne\",\n    \"tile_roof\",\n    \"toaster\",\n    \"tobacco_shop\",\n    \"toilet_seat\",\n    \"torch\",\n    \"totem_pole\",\n    \"tow_truck\",\n    \"toy_store\",\n    \"tractor\",\n    \"truck\",\n    \"tray\",\n    \"trench_coat\",\n    \"tricycle\",\n    \"boat\",\n    \"tripod\",\n    \"triumphal_arch\",\n    \"streetcar\",\n    \"trombone\",\n    \"tub\",\n    \"turnstile\",\n    \"typewriter_keyboard\",\n    \"umbrella\",\n    \"unicycle\",\n    \"piano\",\n    \"vacuum\",\n    \"vase\",\n    \"vault\",\n    \"velvet\",\n    \"vending_machine\",\n    \"robe\",\n    \"viaduct\",\n    \"violin\",\n    \"volleyball\",\n    \"waffle_iron\",\n    \"clock\",\n    \"wallet\",\n    \"wardrobe\",\n    \"fighter_jet\",\n    \"sink\",\n    \"washing_machine\",\n    \"water_bottle\",\n    \"jug\",\n    \"water_tower\",\n    \"jug\",\n    \"whistle\",\n    \"wig\",\n    \"window_screen\",\n    \"window_shade\",\n    \"tie\",\n    \"wine_bottle\",\n    \"wing\",\n    \"wok\",\n    \"wooden_spoon\",\n    \"wool\",\n    \"fence\",\n    \"shipwreck\",\n    \"boat\",\n    \"hut\",\n    \"web_site\",\n    \"comic_book\",\n    \"crossword_puzzle\",\n    \"street_sign\",\n    \"traffic_light\",\n    \"book\",\n    \"menu\",\n    \"plate\",\n    \"guacamole\",\n    \"soup\",\n    \"soup\",\n    \"cake\",\n    \"ice_cream\",\n    \"popcicle\",\n    \"bread\",\n    \"bagel\",\n    \"pretzel\",\n    \"hamburger\",\n    \"hotdog\",\n    \"mashed_potato\",\n    \"cabbage\",\n    \"broccoli\",\n    \"cauliflower\",\n    \"zucchini\",\n    \"squash\",\n    \"squash\",\n    \"squash\",\n    \"cucumber\",\n    \"artichoke\",\n    \"bell_pepper\",\n    \"artichoke\",\n    \"mushroom\",\n    \"apple\",\n    \"strawberry\",\n    \"orange\",\n    \"lemon\",\n    \"fig\",\n    \"pineapple\",\n    \"banana\",\n    \"jackfruit\",\n    \"custard_apple\",\n    \"pomegranate\",\n    \"hay\",\n    \"pasta\",\n    \"chocolate_sauce\",\n    \"dough\",\n    \"meat_loaf\",\n    \"pizza\",\n    \"potpie\",\n    \"burrito\",\n    \"red_wine\",\n    \"espresso\",\n    \"cup\",\n    \"eggnog\",\n    \"mountain\",\n    \"bubble\",\n    \"cliff\",\n    \"coral_reef\",\n    \"geyser\",\n    \"lakeside\",\n    \"sea_cliff\",\n    \"sandbar\",\n    \"beach\",\n    \"valley\",\n    \"volcano\",\n    \"baseball_player\",\n    \"groom\",\n    \"scuba_diver\",\n    \"flower\",\n    \"flower\",\n    \"flower\",\n    \"corn\",\n    \"acorn\",\n    \"rose_hip\",\n    \"nut\",\n    \"coral_reef\",\n    \"mushroom\",\n    \"mushroom\",\n    \"mushroom\",\n    \"mushroom\",\n    \"mushroom\",\n    \"mushroom\",\n    \"ear\",\n    \"toilet_paper\"\n  ]\n}"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/java/ai/fritz/camera/AutoFitTextureView.java",
    "content": "package ai.fritz.camera;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.TextureView;\n\n/**\n * A {@link TextureView} that can be adjusted to a specified aspect ratio.\n */\npublic class AutoFitTextureView extends TextureView {\n    private int ratioWidth = 0;\n    private int ratioHeight = 0;\n\n    public AutoFitTextureView(final Context context) {\n        this(context, null);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    /**\n     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio\n     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that\n     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.\n     *\n     * @param width  Relative horizontal size\n     * @param height Relative vertical size\n     */\n    public void setAspectRatio(final int width, final int height) {\n        if (width < 0 || height < 0) {\n            throw new IllegalArgumentException(\"Size cannot be negative.\");\n        }\n        ratioWidth = width;\n        ratioHeight = height;\n        requestLayout();\n    }\n}"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/java/ai/fritz/camera/BaseCameraActivity.java",
    "content": "package ai.fritz.camera;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport androidx.appcompat.app.AppCompatActivity;\nimport android.util.DisplayMetrics;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.KeyEvent;\nimport android.view.WindowManager;\nimport android.widget.Toast;\n\nimport ai.fritz.imagelabelingdemo.R;\n\n\npublic abstract class BaseCameraActivity extends AppCompatActivity implements OnImageAvailableListener {\n    private static final String TAG = BaseCameraActivity.class.getSimpleName();\n    private static int MAX_WIDTH = 500;\n    private static final int PERMISSIONS_REQUEST = 1;\n\n    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;\n    private boolean useCamera2API;\n\n    private boolean debug = false;\n\n    private Handler handler;\n    private HandlerThread handlerThread;\n\n    protected String cameraId;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        Log.d(TAG, \"onCreate \" + this);\n        super.onCreate(null);\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        setContentView(R.layout.activity_main);\n\n        if (hasPermission()) {\n            setFragment();\n        } else {\n            requestPermission();\n        }\n    }\n\n    @Override\n    public synchronized void onStart() {\n        Log.d(TAG, \"onStart \" + this);\n        super.onStart();\n    }\n\n    @Override\n    public synchronized void onResume() {\n        Log.d(TAG, \"onResume \" + this);\n        super.onResume();\n\n        handlerThread = new HandlerThread(\"inference\");\n        handlerThread.start();\n        handler = new Handler(handlerThread.getLooper());\n    }\n\n    @Override\n    public synchronized void onPause() {\n        Log.d(TAG, \"onPause \" + this);\n\n        if (!isFinishing()) {\n            Log.d(TAG, \"Requesting finish\");\n            finish();\n        }\n\n        handlerThread.quitSafely();\n        try {\n            handlerThread.join();\n            handlerThread = null;\n            handler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n\n        super.onPause();\n    }\n\n    @Override\n    public synchronized void onStop() {\n        Log.d(TAG, \"onStop \" + this);\n        super.onStop();\n    }\n\n    @Override\n    public synchronized void onDestroy() {\n        Log.d(TAG, \"onDestroy \" + this);\n        super.onDestroy();\n    }\n\n    protected synchronized void runInBackground(final Runnable r) {\n        if (handler != null) {\n            handler.post(r);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(\n            final int requestCode, final String[] permissions, final int[] grantResults) {\n        switch (requestCode) {\n            case PERMISSIONS_REQUEST: {\n                if (grantResults.length > 0\n                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {\n                    setFragment();\n                } else {\n                    requestPermission();\n                }\n            }\n        }\n    }\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            int permission = checkSelfPermission(PERMISSION_CAMERA);\n            return permission == PackageManager.PERMISSION_GRANTED;\n        } else {\n            return true;\n        }\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA)) {\n                Toast.makeText(BaseCameraActivity.this, \"Camera permission are required for this demo\", Toast.LENGTH_LONG).show();\n            }\n            requestPermissions(new String[]{PERMISSION_CAMERA}, PERMISSIONS_REQUEST);\n        }\n    }\n\n    protected void setFragment() {\n        cameraId = chooseCamera();\n        final CameraConnectionFragment fragment =\n                CameraConnectionFragment.newInstance(\n                        new CameraConnectionFragment.ConnectionCallback() {\n                            @Override\n                            public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n                                BaseCameraActivity.this.onPreviewSizeChosen(previewSize, cameraViewSize, rotation);\n                            }\n                        },\n                        this,\n                        getLayoutId(),\n                        getDesiredPreviewFrameSize());\n\n        fragment.setCamera(cameraId);\n\n        getFragmentManager()\n                .beginTransaction()\n                .replace(R.id.camera_container, fragment)\n                .commit();\n    }\n\n    private String chooseCamera() {\n        final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);\n        try {\n            for (final String cameraId : manager.getCameraIdList()) {\n                final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n                // We don't use a front facing camera in this sample.\n                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);\n                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {\n                    continue;\n                }\n\n                final StreamConfigurationMap map =\n                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n                if (map == null) {\n                    continue;\n                }\n\n                // Fallback to camera1 API for internal cameras that don't have full support.\n                // This should help with legacy situations where using the camera2 API causes\n                // distorted or otherwise broken previews.\n                useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)\n                        || isHardwareLevelSupported(characteristics,\n                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);\n                Log.i(TAG, \"Camera API lv2?: \" + useCamera2API);\n                return cameraId;\n            }\n        } catch (CameraAccessException e) {\n            Log.e(TAG, \"Not allowed to access camera: \" + e);\n        }\n\n        return null;\n    }\n\n    // Returns true if the device supports the required hardware level, or better.\n    private boolean isHardwareLevelSupported(\n            CameraCharacteristics characteristics, int requiredLevel) {\n        int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);\n        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {\n            return requiredLevel == deviceLevel;\n        }\n        // deviceLevel is not LEGACY, can use numerical sort\n        return requiredLevel <= deviceLevel;\n    }\n\n\n    public boolean isDebug() {\n        return debug;\n    }\n\n    public void requestRender() {\n        final OverlayView overlay = findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.postInvalidate();\n        }\n    }\n\n    public void setCallback(final OverlayView.DrawCallback callback) {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.setCallback(callback);\n        }\n    }\n\n    public void onSetDebug(final boolean debug) {\n    }\n\n    @Override\n    public boolean onKeyDown(final int keyCode, final KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {\n            debug = !debug;\n            requestRender();\n            onSetDebug(debug);\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    protected abstract void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation);\n\n    protected abstract int getLayoutId();\n\n    protected Size getDesiredPreviewFrameSize() {\n        DisplayMetrics metrics = getResources().getDisplayMetrics();\n        float ratio = (float) metrics.heightPixels / metrics.widthPixels;\n        return new Size(MAX_WIDTH, (int) ratio * MAX_WIDTH);\n    }\n}\n\n\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/java/ai/fritz/camera/CameraConnectionFragment.java",
    "content": "package ai.fritz.camera;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.app.DialogFragment;\nimport android.app.Fragment;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.graphics.ImageFormat;\nimport android.graphics.Matrix;\nimport android.graphics.RectF;\nimport android.graphics.SurfaceTexture;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCaptureSession;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraDevice;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.CaptureRequest;\nimport android.hardware.camera2.CaptureResult;\nimport android.hardware.camera2.TotalCaptureResult;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.LayoutInflater;\nimport android.view.Surface;\nimport android.view.TextureView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\n\nimport ai.fritz.imagelabelingdemo.R;\n\n\npublic class CameraConnectionFragment extends Fragment {\n    private static final String TAG = CameraConnectionFragment.class.getSimpleName();\n\n    public CameraConnectionFragment() {\n\n    }\n\n    /**\n     * The camera preview size will be chosen to be the smallest frame by pixel size capable of\n     * containing a DESIRED_SIZE x DESIRED_SIZE square.\n     */\n    private static final int MINIMUM_PREVIEW_SIZE = 320;\n\n    /**\n     * Conversion from screen rotation to JPEG orientation.\n     */\n    private static final String FRAGMENT_DIALOG = \"dialog\";\n\n    /**\n     * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a\n     * {@link TextureView}.\n     */\n    private final TextureView.SurfaceTextureListener surfaceTextureListener =\n            new TextureView.SurfaceTextureListener() {\n                @Override\n                public void onSurfaceTextureAvailable(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    openCamera(width, height);\n                }\n\n                @Override\n                public void onSurfaceTextureSizeChanged(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    configureTransform(width, height);\n                }\n\n                @Override\n                public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {\n                    return true;\n                }\n\n                @Override\n                public void onSurfaceTextureUpdated(final SurfaceTexture texture) {\n                }\n            };\n\n    /**\n     * Callback for Activities to use to initialize their data once the\n     * selected preview size is known.\n     */\n    public interface ConnectionCallback {\n        void onPreviewSizeChosen(Size size, Size cameraViewSize, int cameraRotation);\n    }\n\n    /**\n     * ID of the current {@link CameraDevice}.\n     */\n    private String cameraId;\n\n    /**\n     * An {@link AutoFitTextureView} for camera preview.\n     */\n    private AutoFitTextureView textureView;\n\n    /**\n     * A {@link CameraCaptureSession } for camera preview.\n     */\n    private CameraCaptureSession captureSession;\n\n    /**\n     * A reference to the opened {@link CameraDevice}.\n     */\n    private CameraDevice cameraDevice;\n\n    /**\n     * The rotation in degrees of the camera sensor from the display.\n     */\n    private Integer sensorOrientation;\n\n    /**\n     * The {@link android.util.Size} of camera preview.\n     */\n    private Size previewSize;\n\n    /**\n     * {@link android.hardware.camera2.CameraDevice.StateCallback}\n     * is called when {@link CameraDevice} changes its state.\n     */\n    private final CameraDevice.StateCallback stateCallback =\n            new CameraDevice.StateCallback() {\n                @Override\n                public void onOpened(final CameraDevice cd) {\n                    // This method is called when the camera is opened.  We start camera preview here.\n                    cameraOpenCloseLock.release();\n                    cameraDevice = cd;\n                    createCameraPreviewSession();\n                }\n\n                @Override\n                public void onDisconnected(final CameraDevice cd) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                }\n\n                @Override\n                public void onError(final CameraDevice cd, final int error) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                    final Activity activity = getActivity();\n                    if (null != activity) {\n                        activity.finish();\n                    }\n                }\n            };\n\n    /**\n     * An additional thread for running tasks that shouldn't block the UI.\n     */\n    private HandlerThread backgroundThread;\n\n    /**\n     * A {@link Handler} for running tasks in the background.\n     */\n    private Handler backgroundHandler;\n\n    /**\n     * An {@link ImageReader} that handles preview frame capture.\n     */\n    private ImageReader previewReader;\n\n    /**\n     * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview\n     */\n    private CaptureRequest.Builder previewRequestBuilder;\n\n    /**\n     * {@link CaptureRequest} generated by {@link #previewRequestBuilder}\n     */\n    private CaptureRequest previewRequest;\n\n    /**\n     * A {@link Semaphore} to prevent the app from exiting before closing the camera.\n     */\n    private final Semaphore cameraOpenCloseLock = new Semaphore(1);\n\n    /**\n     * A {@link OnImageAvailableListener} to receive frames as they are available.\n     */\n    private OnImageAvailableListener imageListener = null;\n\n    /**\n     * The input size in pixels desired by TensorFlow (width and height of a square bitmap).\n     */\n    private Size inputSize = null;\n\n    /**\n     * The layout identifier to inflate for this Fragment.\n     */\n    private int layout = -1;\n\n\n    private ConnectionCallback cameraConnectionCallback = null;\n\n    private CameraConnectionFragment(\n            final ConnectionCallback connectionCallback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        this.cameraConnectionCallback = connectionCallback;\n        this.imageListener = imageListener;\n        this.layout = layout;\n        this.inputSize = inputSize;\n    }\n\n    /**\n     * Shows a {@link Toast} on the UI thread.\n     *\n     * @param text The message to show\n     */\n    private void showToast(final String text) {\n        final Activity activity = getActivity();\n        if (activity != null) {\n            activity.runOnUiThread(\n                    new Runnable() {\n                        @Override\n                        public void run() {\n                            Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();\n                        }\n                    });\n        }\n    }\n\n    /**\n     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose\n     * width and height are at least as large as the minimum of both, or an exact match if possible.\n     *\n     * @param choices The list of sizes that the camera supports for the intended output class\n     * @param width   The minimum desired width\n     * @param height  The minimum desired height\n     * @return The optimal {@code Size}, or an arbitrary one if none were big enough\n     */\n    protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {\n        final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);\n        final Size desiredSize = new Size(width, height);\n\n        // Collect the supported resolutions that are at least as big as the preview Surface\n        boolean exactSizeFound = false;\n        final List<Size> bigEnough = new ArrayList<Size>();\n        final List<Size> tooSmall = new ArrayList<Size>();\n        for (final Size option : choices) {\n            if (option.equals(desiredSize)) {\n                // Set the size but don't return yet so that remaining sizes will still be logged.\n                exactSizeFound = true;\n            }\n\n            if (option.getHeight() >= minSize && option.getWidth() >= minSize) {\n                bigEnough.add(option);\n            } else {\n                tooSmall.add(option);\n            }\n        }\n\n        Log.d(TAG, \"Desired size: \" + desiredSize + \", min size: \" + minSize + \"x\" + minSize);\n        Log.d(TAG, \"Valid preview sizes: [\" + TextUtils.join(\", \", bigEnough) + \"]\");\n        Log.d(TAG, \"Rejected preview sizes: [\" + TextUtils.join(\", \", tooSmall) + \"]\");\n\n        if (exactSizeFound) {\n            Log.d(TAG, \"Exact size match found.\");\n            return desiredSize;\n        }\n\n        // Pick the smallest of those, assuming we found any\n        if (bigEnough.size() > 0) {\n            final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());\n            Log.d(TAG, \"Chosen size: \" + chosenSize.getWidth() + \"x\" + chosenSize.getHeight());\n            return chosenSize;\n        } else {\n            Log.e(TAG, \"Couldn't find any suitable preview size\");\n            return choices[0];\n        }\n    }\n\n    public static CameraConnectionFragment newInstance(\n            final ConnectionCallback callback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        return new CameraConnectionFragment(callback, imageListener, layout, inputSize);\n    }\n\n    @Override\n    public View onCreateView(\n            final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {\n        return inflater.inflate(layout, container, false);\n    }\n\n    @Override\n    public void onViewCreated(final View view, final Bundle savedInstanceState) {\n        textureView = (AutoFitTextureView) view.findViewById(R.id.texture);\n    }\n\n    @Override\n    public void onActivityCreated(final Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        startBackgroundThread();\n\n        // When the screen is turned off and turned back on, the SurfaceTexture is already\n        // available, and \"onSurfaceTextureAvailable\" will not be called. In that case, we can open\n        // a camera and start preview from here (otherwise, we wait until the surface is ready in\n        // the SurfaceTextureListener).\n        if (textureView.isAvailable()) {\n            openCamera(textureView.getWidth(), textureView.getHeight());\n        } else {\n            textureView.setSurfaceTextureListener(surfaceTextureListener);\n        }\n    }\n\n    @Override\n    public void onPause() {\n        closeCamera();\n        stopBackgroundThread();\n        super.onPause();\n    }\n\n    public void setCamera(String cameraId) {\n        this.cameraId = cameraId;\n    }\n\n    /**\n     * Sets up member variables related to camera.\n     */\n    private void setUpCameraOutputs() {\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n            final StreamConfigurationMap map =\n                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n            // For still image captures, we use the largest available size.\n            final Size largest =\n                    Collections.max(\n                            Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),\n                            new CompareSizesByArea());\n\n            sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);\n\n            // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera\n            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of\n            // garbage capture data.\n            previewSize =\n                    chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),\n                            inputSize.getWidth(),\n                            inputSize.getHeight());\n        } catch (final CameraAccessException e) {\n            Log.e(TAG,  \"Exception!\" + e);\n        } catch (final NullPointerException e) {\n            // Currently an NPE is thrown when the Camera2API is used but not supported on the\n            // device this code runs.\n            // TODO(andrewharp): abstract ErrorDialog/RuntimeException handling out into new method and\n            // reuse throughout app.\n            ErrorDialog.newInstance(getString(R.string.camera_error))\n                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);\n            throw new RuntimeException(getString(R.string.camera_error));\n        }\n\n        Size textureViewSize = new Size(textureView.getWidth(), textureView.getHeight());\n        cameraConnectionCallback.onPreviewSizeChosen(previewSize, textureViewSize, sensorOrientation);\n    }\n\n    /**\n     * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.\n     */\n    private void openCamera(final int width, final int height) {\n        setUpCameraOutputs();\n        configureTransform(width, height);\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\n                throw new RuntimeException(\"Time out waiting to lock camera opening.\");\n            }\n            manager.openCamera(cameraId, stateCallback, backgroundHandler);\n        } catch (final CameraAccessException | SecurityException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\n        }\n    }\n\n    /**\n     * Closes the current {@link CameraDevice}.\n     */\n    private void closeCamera() {\n        try {\n            cameraOpenCloseLock.acquire();\n            if (null != captureSession) {\n                captureSession.close();\n                captureSession = null;\n            }\n            if (null != cameraDevice) {\n                cameraDevice.close();\n                cameraDevice = null;\n            }\n            if (null != previewReader) {\n                previewReader.close();\n                previewReader = null;\n            }\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera closing.\", e);\n        } finally {\n            cameraOpenCloseLock.release();\n        }\n    }\n\n    /**\n     * Starts a background thread and its {@link Handler}.\n     */\n    private void startBackgroundThread() {\n        backgroundThread = new HandlerThread(\"ImageListener\");\n        backgroundThread.start();\n        backgroundHandler = new Handler(backgroundThread.getLooper());\n    }\n\n    /**\n     * Stops the background thread and its {@link Handler}.\n     */\n    private void stopBackgroundThread() {\n        backgroundThread.quitSafely();\n        try {\n            backgroundThread.join();\n            backgroundThread = null;\n            backgroundHandler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    private final CameraCaptureSession.CaptureCallback captureCallback =\n            new CameraCaptureSession.CaptureCallback() {\n                @Override\n                public void onCaptureProgressed(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final CaptureResult partialResult) {\n                }\n\n                @Override\n                public void onCaptureCompleted(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final TotalCaptureResult result) {\n                }\n            };\n\n    /**\n     * Creates a new {@link CameraCaptureSession} for camera preview.\n     */\n    private void createCameraPreviewSession() {\n        try {\n            final SurfaceTexture texture = textureView.getSurfaceTexture();\n            assert texture != null;\n\n            // We configure the size of default buffer to be the size of camera preview we want.\n            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());\n\n            // This is the output Surface we need to start preview.\n            final Surface surface = new Surface(texture);\n\n            // We set up a CaptureRequest.Builder with the output Surface.\n            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\n            previewRequestBuilder.addTarget(surface);\n\n            Log.i(TAG, \"Opening camera preview: \" + previewSize.getWidth() + \"x\" + previewSize.getHeight());\n\n            // Create the reader for the preview frames.\n            previewReader =\n                    ImageReader.newInstance(\n                            previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);\n\n            previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);\n            previewRequestBuilder.addTarget(previewReader.getSurface());\n\n            // Here, we create a CameraCaptureSession for camera preview.\n            cameraDevice.createCaptureSession(\n                    Arrays.asList(surface, previewReader.getSurface()),\n                    new CameraCaptureSession.StateCallback() {\n\n                        @Override\n                        public void onConfigured(final CameraCaptureSession cameraCaptureSession) {\n                            // The camera is already closed\n                            if (null == cameraDevice) {\n                                return;\n                            }\n\n                            // When the session is ready, we start displaying the preview.\n                            captureSession = cameraCaptureSession;\n                            try {\n                                // Auto focus should be continuous for camera preview.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AF_MODE,\n                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\n                                // Flash is automatically enabled when necessary.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);\n\n                                // Finally, we start displaying the camera preview.\n                                previewRequest = previewRequestBuilder.build();\n                                captureSession.setRepeatingRequest(\n                                        previewRequest, captureCallback, backgroundHandler);\n                            } catch (final CameraAccessException e) {\n                                Log.e(TAG, \"Exception!\" + e);\n                            }\n                        }\n\n                        @Override\n                        public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {\n                            showToast(\"Failed\");\n                        }\n                    },\n                    null);\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    /**\n     * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.\n     * This method should be called after the camera preview size is determined in\n     * setUpCameraOutputs and also the size of `mTextureView` is fixed.\n     *\n     * @param viewWidth  The width of `mTextureView`\n     * @param viewHeight The height of `mTextureView`\n     */\n    private void configureTransform(final int viewWidth, final int viewHeight) {\n        final Activity activity = getActivity();\n        if (null == textureView || null == previewSize || null == activity) {\n            return;\n        }\n        final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();\n        final Matrix matrix = new Matrix();\n        final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);\n        final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());\n        final float centerX = viewRect.centerX();\n        final float centerY = viewRect.centerY();\n        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {\n            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());\n            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);\n            final float scale =\n                    Math.max(\n                            (float) viewHeight / previewSize.getHeight(),\n                            (float) viewWidth / previewSize.getWidth());\n            matrix.postScale(scale, scale, centerX, centerY);\n            matrix.postRotate(90 * (rotation - 2), centerX, centerY);\n        } else if (Surface.ROTATION_180 == rotation) {\n            matrix.postRotate(180, centerX, centerY);\n        }\n        textureView.setTransform(matrix);\n    }\n\n    /**\n     * Compares two {@code Size}s based on their areas.\n     */\n    static class CompareSizesByArea implements Comparator<Size> {\n        @Override\n        public int compare(final Size lhs, final Size rhs) {\n            // We cast here to ensure the multiplications won't overflow\n            return Long.signum(\n                    (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());\n        }\n    }\n\n    /**\n     * Shows an error message dialog.\n     */\n    public static class ErrorDialog extends DialogFragment {\n        private static final String ARG_MESSAGE = \"message\";\n\n        public static ErrorDialog newInstance(final String message) {\n            final ErrorDialog dialog = new ErrorDialog();\n            final Bundle args = new Bundle();\n            args.putString(ARG_MESSAGE, message);\n            dialog.setArguments(args);\n            return dialog;\n        }\n\n        @Override\n        public Dialog onCreateDialog(final Bundle savedInstanceState) {\n            final Activity activity = getActivity();\n            return new AlertDialog.Builder(activity)\n                    .setMessage(getArguments().getString(ARG_MESSAGE))\n                    .setPositiveButton(\n                            android.R.string.ok,\n                            new DialogInterface.OnClickListener() {\n                                @Override\n                                public void onClick(final DialogInterface dialogInterface, final int i) {\n                                    activity.finish();\n                                }\n                            })\n                    .create();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/java/ai/fritz/camera/MainActivity.java",
    "content": "package ai.fritz.camera;\n\nimport android.graphics.Bitmap;\nimport android.graphics.RectF;\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.ProgressBar;\nimport android.widget.RelativeLayout;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.core.Fritz;\nimport ai.fritz.imagelabelingdemo.R;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionLabel;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.imagelabeling.FritzVisionLabelPredictor;\nimport ai.fritz.vision.imagelabeling.FritzVisionLabelPredictorOptions;\nimport ai.fritz.vision.imagelabeling.FritzVisionLabelResult;\nimport ai.fritz.vision.imagelabeling.LabelingOnDeviceModel;\n\n\n\npublic class MainActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n\n    private static final Size DESIRED_PREVIEW_SIZE = new Size(1280, 960);\n\n    private AtomicBoolean isComputing = new AtomicBoolean(false);\n    private AtomicBoolean shouldSample = new AtomicBoolean(true);\n    private ImageOrientation orientation;\n\n    FritzVisionLabelResult labelResult;\n    FritzVisionLabelPredictor predictor;\n    FritzVisionImage visionImage;\n\n    // Preview Frame\n    RelativeLayout previewFrame;\n    Button snapshotButton;\n    ProgressBar snapshotProcessingSpinner;\n\n    // Snapshot Frame\n    RelativeLayout snapshotFrame;\n    OverlayView snapshotOverlay;\n    Button closeButton;\n    Button recordButton;\n    ProgressBar recordSpinner;\n\n\n    @Override\n    public void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Fritz.configure(this);\n        // The code below loads a custom trained image labeling model and creates a predictor that will be used to label frames of live video.\n        // Custom image labeling models can be trained with the Fritz AI platform. To use a pre-trained image labeling model,\n        // see the FritzAIStudio demo in this repo.\n        LabelingOnDeviceModel imageLabelingOnDeviceModel = LabelingOnDeviceModel.buildFromModelConfigFile(\"label_recording_model.json\");\n        FritzVisionLabelPredictorOptions options = new FritzVisionLabelPredictorOptions();\n        options.confidenceThreshold = 0.1f;\n        predictor = FritzVision.ImageLabeling.getPredictor(imageLabelingOnDeviceModel, options);\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.main_camera;\n    }\n\n    @Override\n    protected Size getDesiredPreviewFrameSize() {\n        return DESIRED_PREVIEW_SIZE;\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n        orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n\n        // Preview View\n        previewFrame = findViewById(R.id.preview_frame);\n        snapshotProcessingSpinner = findViewById(R.id.snapshot_spinner);\n        snapshotButton = findViewById(R.id.take_picture_btn);\n        snapshotButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                if (!shouldSample.compareAndSet(true, false)) {\n                    return;\n                }\n\n                runInBackground(\n                        () -> {\n                            showSpinner();\n                            snapshotOverlay.postInvalidate();\n                            switchToSnapshotView();\n                            hideSpinner();\n                        });\n            }\n        });\n        setCallback(canvas -> {\n            if (labelResult != null) {\n                snapshotOverlay.setResult(labelResult.getVisionLabels());\n                snapshotOverlay.draw(canvas);\n            }\n            isComputing.set(false);\n        });\n\n        // Snapshot View\n        snapshotFrame = findViewById(R.id.snapshot_frame);\n        snapshotOverlay = findViewById(R.id.snapshot_view);\n        snapshotOverlay.setCallback(\n                canvas -> {\n                    if (labelResult != null) {\n                        canvas.drawBitmap(visionImage.buildOrientedBitmap(), null, new RectF(0, 0, cameraViewSize.getWidth(), cameraViewSize.getHeight()), null);\n                    }\n                });\n\n        recordSpinner = findViewById(R.id.record_spinner);\n        recordButton = findViewById(R.id.record_prediction_btn);\n        recordButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                recordSpinner.setVisibility(View.VISIBLE);\n                // To record predictions and send data back to Fritz AI via the Data Collection System, use the predictors's record method.\n                // In addition to the input image, predicted model results can be collected as well as user-modified annotations.\n                // This allows developers to both gather data on model performance and have users collect additional ground truth data for future model retraining.\n                // Note, the Data Collection System is only available on paid plans.\n                predictor.record(visionImage, labelResult, null, () -> {\n                    switchPreviewView();\n                    return null;\n                }, () -> {\n                    switchPreviewView();\n                    return null;\n                });\n            }\n        });\n        closeButton = findViewById(R.id.close_btn);\n        closeButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                switchPreviewView();\n            }\n        });\n\n    }\n\n    private void switchToSnapshotView() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                previewFrame.setVisibility(View.GONE);\n                snapshotFrame.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void switchPreviewView() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                recordSpinner.setVisibility(View.GONE);\n                snapshotFrame.setVisibility(View.GONE);\n                previewFrame.setVisibility(View.VISIBLE);\n                shouldSample.set(true);\n            }\n        });\n    }\n\n    private void showSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void hideSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.GONE);\n            }\n        });\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!shouldSample.get()) {\n            image.close();\n            return;\n        }\n\n        if (!isComputing.compareAndSet(false, true)) {\n            image.close();\n            return;\n        }\n\n        visionImage = FritzVisionImage.fromMediaImage(image, orientation);\n        image.close();\n\n        runInBackground(() -> {\n            labelResult = predictor.predict(visionImage);\n            requestRender();\n        });\n    }\n}\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/java/ai/fritz/camera/OverlayView.java",
    "content": "package ai.fritz.camera;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.util.AttributeSet;\nimport android.util.Log;\nimport android.util.TypedValue;\nimport android.view.View;\nimport androidx.core.content.ContextCompat;\nimport ai.fritz.imagelabelingdemo.R;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport ai.fritz.vision.FritzVisionLabel;\n\n/**\n * A simple View providing a render callback to other classes.\n */\npublic class OverlayView extends View {\n    private DrawCallback callback;\n\n    private static final float TEXT_SIZE_DIP = 24;\n    private List<FritzVisionLabel> labels = new ArrayList<>();\n    private final float textSizePx;\n    private final Paint fgPaint;\n    private final Paint bgPaint;\n\n    public OverlayView(final Context context, final AttributeSet attrs) {\n        super(context, attrs);\n\n        textSizePx =\n                TypedValue.applyDimension(\n                        TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DIP, getResources().getDisplayMetrics());\n        fgPaint = new Paint();\n        fgPaint.setTextSize(textSizePx);\n        fgPaint.setColor(ContextCompat.getColor(context, R.color.textColorPrimary));\n\n        bgPaint = new Paint();\n        bgPaint.setColor(Color.TRANSPARENT);\n    }\n\n    public void setResult(final List<FritzVisionLabel> labels) {\n        this.labels = labels;\n        postInvalidate();\n    }\n    /**\n     * Interface defining the callback for client classes.\n     */\n    public interface DrawCallback {\n        void drawCallback(final Canvas canvas);\n    }\n\n    public void setCallback(final DrawCallback callback) {\n        this.callback = callback;\n    }\n\n    @Override\n    public synchronized void draw(final Canvas canvas) {\n        super.draw(canvas);\n        if(callback != null) {\n            callback.drawCallback(canvas);\n        }\n\n        final int x = 10;\n        int y = (int) (fgPaint.getTextSize() * 1.5f);\n\n        canvas.drawPaint(bgPaint);\n\n        if (labels.size() > 0) {\n            for (final FritzVisionLabel label : labels) {\n                double confidence = Math.round(label.getConfidence() * 1000) / 10.0;\n                canvas.drawText(label.getText() + \": \" + confidence + \"%\", x, y, fgPaint);\n                y += fgPaint.getTextSize() * 1.5f;\n            }\n        }\n    }\n}"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/drawable/ic_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24.0\"\n    android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        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\"/>\n</vector>"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/drawable/round_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\">\n    <stroke\n        android:color=\"#FFFF\"\n        android:width=\"5dip\"/>\n    <size android:width=\"100dp\" android:height=\"100dp\"/>\n</shape>"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/layout/activity_main.xml",
    "content": "<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <FrameLayout\n        android:id=\"@+id/camera_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/layout/camera_connection_fragment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <ai.fritz.camera.AutoFitTextureView\n        android:id=\"@+id/texture\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"/>\n\n    <ai.fritz.camera.OverlayView\n        android:id=\"@+id/debug_overlay\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"/>\n</RelativeLayout>\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/layout/main_camera.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:id=\"@+id/preview_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n        <ai.fritz.camera.AutoFitTextureView\n            android:id=\"@+id/texture\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\" />\n        <ai.fritz.camera.OverlayView\n            android:id=\"@+id/debug_overlay\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\"/>\n    </RelativeLayout>\n\n    <include layout=\"@layout/snapshot_button\" />\n    <include layout=\"@layout/snapshot_overlay_frame\" />\n</RelativeLayout>\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/layout/snapshot_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_alignParentBottom=\"true\"\n    android:layout_marginTop=\"@dimen/margin_sm\"\n    android:layout_marginBottom=\"@dimen/margin_lg\">\n\n    <Button\n        android:id=\"@+id/take_picture_btn\"\n        android:layout_width=\"80dp\"\n        android:layout_height=\"80dp\"\n        android:layout_centerInParent=\"true\"\n        android:background=\"@drawable/round_button\"\n        android:textColor=\"#fff\" />\n\n    <ProgressBar\n        android:id=\"@+id/snapshot_spinner\"\n        style=\"?android:attr/progressBarStyleLarge\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:indeterminateTint=\"#fff\"\n        android:visibility=\"gone\" />\n</RelativeLayout>"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/layout/snapshot_overlay_frame.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/snapshot_frame\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:visibility=\"gone\">\n\n    <ai.fritz.camera.OverlayView\n        android:id=\"@+id/snapshot_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\" />\n\n    <ProgressBar\n        android:id=\"@+id/record_spinner\"\n        style=\"?android:attr/progressBarStyleLarge\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:indeterminateTint=\"#fff\"\n        android:visibility=\"gone\" />\n\n    <Button\n        android:id=\"@+id/record_prediction_btn\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentBottom=\"true\"\n        android:background=\"@color/colorPrimary\"\n        android:paddingTop=\"15dp\"\n        android:paddingBottom=\"15dp\"\n        android:text=\"Record Prediction\"\n        android:textAlignment=\"gravity\"\n        android:textColor=\"#fff\"\n        android:textStyle=\"bold\" />\n\n    <Button\n        android:id=\"@+id/close_btn\"\n        android:layout_width=\"50dp\"\n        android:layout_height=\"50dp\"\n        android:layout_alignParentTop=\"true\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_marginTop=\"@dimen/margin_sm\"\n        android:layout_marginRight=\"@dimen/margin_sm\"\n        android:background=\"@drawable/ic_close\" />\n\n</RelativeLayout>"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n    <color name=\"textColorPrimary\">#fff</color>\n</resources>\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/values/dimens.xml",
    "content": "<!--\n  Copyright 2013 The Android Open Source Project\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n\n<resources>\n\n    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->\n\n    <dimen name=\"margin_xs\">4dp</dimen>\n    <dimen name=\"margin_sm\">8dp</dimen>\n    <dimen name=\"margin_md\">16dp</dimen>\n    <dimen name=\"margin_lg\">32dp</dimen>\n    <dimen name=\"margin_xl\">64dp</dimen>\n\n    <!-- Semantic definitions -->\n\n    <dimen name=\"horizontal_page_margin\">@dimen/margin_md</dimen>\n    <dimen name=\"vertical_page_margin\">@dimen/margin_md</dimen>\n\n</resources>"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Image Labeling App</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n</resources>\n"
  },
  {
    "path": "Android/ImageLabelingApp/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "Android/ImageLabelingApp/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.6.0'\n\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n\n        // ADD FOR FRITZ DEPENDENCIES\n        maven { url \"https://fritz.mycloudrepo.io/public/repositories/android\" }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "Android/ImageLabelingApp/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n\nandroid.useAndroidX=true"
  },
  {
    "path": "Android/ImageLabelingApp/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/ImageLabelingApp/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/ImageLabelingApp/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "Android/ObjectDetectionApp/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea\n\n# Keystore files\n# Uncomment the following line if you do not want to check your keystore files in.\n#*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n# fastlane\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\nfastlane/readme.md\n"
  },
  {
    "path": "Android/ObjectDetectionApp/README.md",
    "content": "# Object Detection Demo App with Data Collection\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, the user can detects the bounding box of different objects and records the result to Fritz. For an example of a real time implementation of object detection, check out the [Fritz AI Studio app](https://github.com/fritzlabs/fritz-examples/blob/master/Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/vision/ObjectDetectionActivity.java)\n\nThis example app uses the on-device Object Detection API for Android.\n\n- [Overview](https://docs.fritz.ai/develop/vision/object-detection/about.html)\n- [Documentation](https://docs.fritz.ai/develop/vision/object-detection/android.html)\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Android Studio 3.2 or above\n- Android device in developer model (USB debugging enabled)\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nRegister the Android app in your Fritz account with the package id \"ai.fritz.objectdetectiondemo\". During registration, you'll receive an API key for the app. Save this for later. To find it in the webapp, you can go to Project Settings > Apps > Your App > Show API Key.\n\n**Step 2: Clone / Fork the fritz-examples repository and open the BackgroundReplacementApp app in Android Studio**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\nIn Android Studio, choose \"Open an existing Android Studio project\" and select `ObjectDetectionApp`.\n\n**Step 3: Edit the fritz.xml file with your API Key**\n\nIn app/src/main/res/values/fritz.xml, change the fritz_api_key attribute with the one you received in step 1.\n\n**Step 4: Build the Android Studio Project**\n\nSelect \"Build > Make Project\" from the top nav. Download any missing libraries if applicable. This should sync the gradle dependencies so give the build a second to complete.\n\n**Step 5: Install the app onto your device**\n\nWith your Android device connected, select `Run > Run App` from the top nav. When running the app for the first time, you'll have to give permissions to access the camera. After the app is installed and running, take a picture and you'll see the detected objects overlayed on the image. Afterwards you can choose to record the model predictions if your model is connected to an image collection in the webapp.\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 29\n    defaultConfig {\n        // MUST MATCH THE APPLICATION YOU CREATE IN FRITZ\n        applicationId \"ai.fritz.objectdetectiondemo\"\n        minSdkVersion 24\n        targetSdkVersion 29\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n    compileOptions {\n        sourceCompatibility = 1.8\n        targetCompatibility = 1.8\n    }\n    buildToolsVersion = '29.0.3'\n}\n\ndependencies {\n    implementation 'com.android.support:appcompat-v7:28.0.0'\n    implementation 'com.android.support.constraint:constraint-layout:1.1.3'\n\n    implementation \"ai.fritz:core:6.0.0\"\n    implementation \"ai.fritz:vision:6.0.0\"\n\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'com.android.support.test:runner:1.0.2'\n    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'\n}\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.objectdetection\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\"ai.fritz.camera.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <service\n            android:name=\"ai.fritz.core.FritzCustomModelService\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/assets/object_recording_model.json",
    "content": "{\n  \"model_path\": \"file:///android_asset/detect.tflite\",\n  \"pinned_version\": 1,\n  \"model_version\": 1,\n  \"model_id\": \"Your model id\",\n  \"isOutputNormalized\": true,\n  \"boxIndices\": [1, 0, 3, 2],\n  \"labels\": [\n    \"???\",\n    \"person\",\n    \"bicycle\",\n    \"car\",\n    \"motorcycle\",\n    \"airplane\",\n    \"bus\",\n    \"train\",\n    \"truck\",\n    \"boat\",\n    \"traffic light\",\n    \"fire hydrant\",\n    \"???\",\n    \"stop sign\",\n    \"parking meter\",\n    \"bench\",\n    \"bird\",\n    \"cat\",\n    \"dog\",\n    \"horse\",\n    \"sheep\",\n    \"cow\",\n    \"elephant\",\n    \"bear\",\n    \"zebra\",\n    \"giraffe\",\n    \"???\",\n    \"backpack\",\n    \"umbrella\",\n    \"???\",\n    \"???\",\n    \"handbag\",\n    \"tie\",\n    \"suitcase\",\n    \"frisbee\",\n    \"skis\",\n    \"snowboard\",\n    \"sports ball\",\n    \"kite\",\n    \"baseball bat\",\n    \"baseball glove\",\n    \"skateboard\",\n    \"surfboard\",\n    \"tennis racket\",\n    \"bottle\",\n    \"???\",\n    \"wine glass\",\n    \"cup\",\n    \"fork\",\n    \"knife\",\n    \"spoon\",\n    \"bowl\",\n    \"banana\",\n    \"apple\",\n    \"sandwich\",\n    \"orange\",\n    \"broccoli\",\n    \"carrot\",\n    \"hot dog\",\n    \"pizza\",\n    \"donut\",\n    \"cake\",\n    \"chair\",\n    \"couch\",\n    \"potted plant\",\n    \"bed\",\n    \"???\",\n    \"dining table\",\n    \"???\",\n    \"???\",\n    \"toilet\",\n    \"???\",\n    \"tv\",\n    \"laptop\",\n    \"mouse\",\n    \"remote\",\n    \"keyboard\",\n    \"cell phone\",\n    \"microwave\",\n    \"oven\",\n    \"toaster\",\n    \"sink\",\n    \"refrigerator\",\n    \"???\",\n    \"book\",\n    \"clock\",\n    \"vase\",\n    \"scissors\",\n    \"teddy bear\",\n    \"hair drier\",\n    \"toothbrush\"\n  ]\n}"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/java/ai/fritz/camera/AutoFitTextureView.java",
    "content": "package ai.fritz.camera;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.TextureView;\n\n/**\n * A {@link TextureView} that can be adjusted to a specified aspect ratio.\n */\npublic class AutoFitTextureView extends TextureView {\n    private int ratioWidth = 0;\n    private int ratioHeight = 0;\n\n    public AutoFitTextureView(final Context context) {\n        this(context, null);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    /**\n     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio\n     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that\n     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.\n     *\n     * @param width  Relative horizontal size\n     * @param height Relative vertical size\n     */\n    public void setAspectRatio(final int width, final int height) {\n        if (width < 0 || height < 0) {\n            throw new IllegalArgumentException(\"Size cannot be negative.\");\n        }\n        ratioWidth = width;\n        ratioHeight = height;\n        requestLayout();\n    }\n}"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/java/ai/fritz/camera/BaseCameraActivity.java",
    "content": "package ai.fritz.camera;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.support.v7.app.AppCompatActivity;\nimport android.util.DisplayMetrics;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.KeyEvent;\nimport android.view.WindowManager;\nimport android.widget.Toast;\n\nimport ai.fritz.objectdetection.R;\n\n\npublic abstract class BaseCameraActivity extends AppCompatActivity implements OnImageAvailableListener {\n    private static final String TAG = BaseCameraActivity.class.getSimpleName();\n    private static int MAX_WIDTH = 500;\n    private static final int PERMISSIONS_REQUEST = 1;\n\n    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;\n    private boolean useCamera2API;\n\n    private boolean debug = false;\n\n    private Handler handler;\n    private HandlerThread handlerThread;\n\n    protected String cameraId;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        Log.d(TAG, \"onCreate \" + this);\n        super.onCreate(null);\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        setContentView(R.layout.activity_main);\n\n        if (hasPermission()) {\n            setFragment();\n        } else {\n            requestPermission();\n        }\n    }\n\n    @Override\n    public synchronized void onStart() {\n        Log.d(TAG, \"onStart \" + this);\n        super.onStart();\n    }\n\n    @Override\n    public synchronized void onResume() {\n        Log.d(TAG, \"onResume \" + this);\n        super.onResume();\n\n        handlerThread = new HandlerThread(\"inference\");\n        handlerThread.start();\n        handler = new Handler(handlerThread.getLooper());\n    }\n\n    @Override\n    public synchronized void onPause() {\n        Log.d(TAG, \"onPause \" + this);\n\n//        if (!isFinishing()) {\n//            Log.d(TAG, \"Requesting finish\");\n//            finish();\n//        }\n//\n//        handlerThread.quitSafely();\n//        try {\n//            handlerThread.join();\n//            handlerThread = null;\n//            handler = null;\n//        } catch (final InterruptedException e) {\n//            Log.e(TAG, \"Exception!\" + e);\n//        }\n\n        super.onPause();\n    }\n\n    @Override\n    public synchronized void onStop() {\n        Log.d(TAG, \"onStop \" + this);\n        super.onStop();\n    }\n\n    @Override\n    public synchronized void onDestroy() {\n        Log.d(TAG, \"onDestroy \" + this);\n        super.onDestroy();\n    }\n\n    protected synchronized void runInBackground(final Runnable r) {\n        if (handler != null) {\n            handler.post(r);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(\n            final int requestCode, final String[] permissions, final int[] grantResults) {\n        switch (requestCode) {\n            case PERMISSIONS_REQUEST: {\n                if (grantResults.length > 0\n                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {\n                    setFragment();\n                } else {\n                    requestPermission();\n                }\n            }\n        }\n    }\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            int permission = checkSelfPermission(PERMISSION_CAMERA);\n            return permission == PackageManager.PERMISSION_GRANTED;\n        } else {\n            return true;\n        }\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA)) {\n                Toast.makeText(BaseCameraActivity.this, \"Camera permission are required for this demo\", Toast.LENGTH_LONG).show();\n            }\n            requestPermissions(new String[]{PERMISSION_CAMERA}, PERMISSIONS_REQUEST);\n        }\n    }\n\n    protected void setFragment() {\n        cameraId = chooseCamera();\n        final CameraConnectionFragment fragment =\n                CameraConnectionFragment.newInstance(\n                        new CameraConnectionFragment.ConnectionCallback() {\n                            @Override\n                            public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n                                BaseCameraActivity.this.onPreviewSizeChosen(previewSize, cameraViewSize, rotation);\n                            }\n                        },\n                        this,\n                        getLayoutId(),\n                        getDesiredPreviewFrameSize());\n\n        fragment.setCamera(cameraId);\n\n        getFragmentManager()\n                .beginTransaction()\n                .replace(R.id.camera_container, fragment)\n                .commit();\n    }\n\n    private String chooseCamera() {\n        final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);\n        try {\n            for (final String cameraId : manager.getCameraIdList()) {\n                final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n                // We don't use a front facing camera in this sample.\n                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);\n                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {\n                    continue;\n                }\n\n                final StreamConfigurationMap map =\n                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n                if (map == null) {\n                    continue;\n                }\n\n                // Fallback to camera1 API for internal cameras that don't have full support.\n                // This should help with legacy situations where using the camera2 API causes\n                // distorted or otherwise broken previews.\n                useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)\n                        || isHardwareLevelSupported(characteristics,\n                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);\n                Log.i(TAG, \"Camera API lv2?: \" + useCamera2API);\n                return cameraId;\n            }\n        } catch (CameraAccessException e) {\n            Log.e(TAG, \"Not allowed to access camera: \" + e);\n        }\n\n        return null;\n    }\n\n    // Returns true if the device supports the required hardware level, or better.\n    private boolean isHardwareLevelSupported(\n            CameraCharacteristics characteristics, int requiredLevel) {\n        int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);\n        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {\n            return requiredLevel == deviceLevel;\n        }\n        // deviceLevel is not LEGACY, can use numerical sort\n        return requiredLevel <= deviceLevel;\n    }\n\n\n    public boolean isDebug() {\n        return debug;\n    }\n\n    public void requestRender() {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.postInvalidate();\n        }\n    }\n\n    public void setCallback(final OverlayView.DrawCallback callback) {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.setCallback(callback);\n        }\n    }\n\n    public void onSetDebug(final boolean debug) {\n    }\n\n    @Override\n    public boolean onKeyDown(final int keyCode, final KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {\n            debug = !debug;\n            requestRender();\n            onSetDebug(debug);\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    protected abstract void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation);\n\n    protected abstract int getLayoutId();\n\n    protected Size getDesiredPreviewFrameSize() {\n        DisplayMetrics metrics = getResources().getDisplayMetrics();\n        float ratio = (float) metrics.heightPixels / metrics.widthPixels;\n        return new Size(MAX_WIDTH, (int) ratio * MAX_WIDTH);\n    }\n}\n\n\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/java/ai/fritz/camera/CameraConnectionFragment.java",
    "content": "package ai.fritz.camera;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.app.DialogFragment;\nimport android.app.Fragment;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.graphics.ImageFormat;\nimport android.graphics.Matrix;\nimport android.graphics.RectF;\nimport android.graphics.SurfaceTexture;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCaptureSession;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraDevice;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.CaptureRequest;\nimport android.hardware.camera2.CaptureResult;\nimport android.hardware.camera2.TotalCaptureResult;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.LayoutInflater;\nimport android.view.Surface;\nimport android.view.TextureView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\n\nimport ai.fritz.objectdetection.R;\n\n\npublic class CameraConnectionFragment extends Fragment {\n    private static final String TAG = CameraConnectionFragment.class.getSimpleName();\n\n    public CameraConnectionFragment() {\n\n    }\n\n    /**\n     * The camera preview size will be chosen to be the smallest frame by pixel size capable of\n     * containing a DESIRED_SIZE x DESIRED_SIZE square.\n     */\n    private static final int MINIMUM_PREVIEW_SIZE = 320;\n\n    /**\n     * Conversion from screen rotation to JPEG orientation.\n     */\n    private static final String FRAGMENT_DIALOG = \"dialog\";\n\n    /**\n     * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a\n     * {@link TextureView}.\n     */\n    private final TextureView.SurfaceTextureListener surfaceTextureListener =\n            new TextureView.SurfaceTextureListener() {\n                @Override\n                public void onSurfaceTextureAvailable(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    openCamera(width, height);\n                }\n\n                @Override\n                public void onSurfaceTextureSizeChanged(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    configureTransform(width, height);\n                }\n\n                @Override\n                public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {\n                    return true;\n                }\n\n                @Override\n                public void onSurfaceTextureUpdated(final SurfaceTexture texture) {\n                }\n            };\n\n    /**\n     * Callback for Activities to use to initialize their data once the\n     * selected preview size is known.\n     */\n    public interface ConnectionCallback {\n        void onPreviewSizeChosen(Size size, Size cameraViewSize, int cameraRotation);\n    }\n\n    /**\n     * ID of the current {@link CameraDevice}.\n     */\n    private String cameraId;\n\n    /**\n     * An {@link AutoFitTextureView} for camera preview.\n     */\n    private AutoFitTextureView textureView;\n\n    /**\n     * A {@link CameraCaptureSession } for camera preview.\n     */\n    private CameraCaptureSession captureSession;\n\n    /**\n     * A reference to the opened {@link CameraDevice}.\n     */\n    private CameraDevice cameraDevice;\n\n    /**\n     * The rotation in degrees of the camera sensor from the display.\n     */\n    private Integer sensorOrientation;\n\n    /**\n     * The {@link android.util.Size} of camera preview.\n     */\n    private Size previewSize;\n\n    /**\n     * {@link android.hardware.camera2.CameraDevice.StateCallback}\n     * is called when {@link CameraDevice} changes its state.\n     */\n    private final CameraDevice.StateCallback stateCallback =\n            new CameraDevice.StateCallback() {\n                @Override\n                public void onOpened(final CameraDevice cd) {\n                    // This method is called when the camera is opened.  We start camera preview here.\n                    cameraOpenCloseLock.release();\n                    cameraDevice = cd;\n                    createCameraPreviewSession();\n                }\n\n                @Override\n                public void onDisconnected(final CameraDevice cd) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                }\n\n                @Override\n                public void onError(final CameraDevice cd, final int error) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                    final Activity activity = getActivity();\n                    if (null != activity) {\n                        activity.finish();\n                    }\n                }\n            };\n\n    /**\n     * An additional thread for running tasks that shouldn't block the UI.\n     */\n    private HandlerThread backgroundThread;\n\n    /**\n     * A {@link Handler} for running tasks in the background.\n     */\n    private Handler backgroundHandler;\n\n    /**\n     * An {@link ImageReader} that handles preview frame capture.\n     */\n    private ImageReader previewReader;\n\n    /**\n     * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview\n     */\n    private CaptureRequest.Builder previewRequestBuilder;\n\n    /**\n     * {@link CaptureRequest} generated by {@link #previewRequestBuilder}\n     */\n    private CaptureRequest previewRequest;\n\n    /**\n     * A {@link Semaphore} to prevent the app from exiting before closing the camera.\n     */\n    private final Semaphore cameraOpenCloseLock = new Semaphore(1);\n\n    /**\n     * A {@link OnImageAvailableListener} to receive frames as they are available.\n     */\n    private OnImageAvailableListener imageListener = null;\n\n    /**\n     * The input size in pixels desired by TensorFlow (width and height of a square bitmap).\n     */\n    private Size inputSize = null;\n\n    /**\n     * The layout identifier to inflate for this Fragment.\n     */\n    private int layout = -1;\n\n\n    private ConnectionCallback cameraConnectionCallback = null;\n\n    private CameraConnectionFragment(\n            final ConnectionCallback connectionCallback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        this.cameraConnectionCallback = connectionCallback;\n        this.imageListener = imageListener;\n        this.layout = layout;\n        this.inputSize = inputSize;\n    }\n\n    /**\n     * Shows a {@link Toast} on the UI thread.\n     *\n     * @param text The message to show\n     */\n    private void showToast(final String text) {\n        final Activity activity = getActivity();\n        if (activity != null) {\n            activity.runOnUiThread(\n                    new Runnable() {\n                        @Override\n                        public void run() {\n                            Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();\n                        }\n                    });\n        }\n    }\n\n    /**\n     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose\n     * width and height are at least as large as the minimum of both, or an exact match if possible.\n     *\n     * @param choices The list of sizes that the camera supports for the intended output class\n     * @param width   The minimum desired width\n     * @param height  The minimum desired height\n     * @return The optimal {@code Size}, or an arbitrary one if none were big enough\n     */\n    protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {\n        final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);\n        final Size desiredSize = new Size(width, height);\n\n        // Collect the supported resolutions that are at least as big as the preview Surface\n        boolean exactSizeFound = false;\n        final List<Size> bigEnough = new ArrayList<Size>();\n        final List<Size> tooSmall = new ArrayList<Size>();\n        for (final Size option : choices) {\n            if (option.equals(desiredSize)) {\n                // Set the size but don't return yet so that remaining sizes will still be logged.\n                exactSizeFound = true;\n            }\n\n            if (option.getHeight() >= minSize && option.getWidth() >= minSize) {\n                bigEnough.add(option);\n            } else {\n                tooSmall.add(option);\n            }\n        }\n\n        Log.d(TAG, \"Desired size: \" + desiredSize + \", min size: \" + minSize + \"x\" + minSize);\n        Log.d(TAG, \"Valid preview sizes: [\" + TextUtils.join(\", \", bigEnough) + \"]\");\n        Log.d(TAG, \"Rejected preview sizes: [\" + TextUtils.join(\", \", tooSmall) + \"]\");\n\n        if (exactSizeFound) {\n            Log.d(TAG, \"Exact size match found.\");\n            return desiredSize;\n        }\n\n        // Pick the smallest of those, assuming we found any\n        if (bigEnough.size() > 0) {\n            final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());\n            Log.d(TAG, \"Chosen size: \" + chosenSize.getWidth() + \"x\" + chosenSize.getHeight());\n            return chosenSize;\n        } else {\n            Log.e(TAG, \"Couldn't find any suitable preview size\");\n            return choices[0];\n        }\n    }\n\n    public static CameraConnectionFragment newInstance(\n            final ConnectionCallback callback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        return new CameraConnectionFragment(callback, imageListener, layout, inputSize);\n    }\n\n    @Override\n    public View onCreateView(\n            final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {\n        return inflater.inflate(layout, container, false);\n    }\n\n    @Override\n    public void onViewCreated(final View view, final Bundle savedInstanceState) {\n        textureView = (AutoFitTextureView) view.findViewById(R.id.texture);\n    }\n\n    @Override\n    public void onActivityCreated(final Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        startBackgroundThread();\n\n        // When the screen is turned off and turned back on, the SurfaceTexture is already\n        // available, and \"onSurfaceTextureAvailable\" will not be called. In that case, we can open\n        // a camera and start preview from here (otherwise, we wait until the surface is ready in\n        // the SurfaceTextureListener).\n        if (textureView.isAvailable()) {\n            openCamera(textureView.getWidth(), textureView.getHeight());\n        } else {\n            textureView.setSurfaceTextureListener(surfaceTextureListener);\n        }\n    }\n\n    @Override\n    public void onPause() {\n        closeCamera();\n        stopBackgroundThread();\n        super.onPause();\n    }\n\n    public void setCamera(String cameraId) {\n        this.cameraId = cameraId;\n    }\n\n    /**\n     * Sets up member variables related to camera.\n     */\n    private void setUpCameraOutputs() {\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n            final StreamConfigurationMap map =\n                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n            // For still image captures, we use the largest available size.\n            final Size largest =\n                    Collections.max(\n                            Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),\n                            new CompareSizesByArea());\n\n            sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);\n\n            // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera\n            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of\n            // garbage capture data.\n            previewSize =\n                    chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),\n                            inputSize.getWidth(),\n                            inputSize.getHeight());\n        } catch (final CameraAccessException e) {\n            Log.e(TAG,  \"Exception!\" + e);\n        } catch (final NullPointerException e) {\n            // Currently an NPE is thrown when the Camera2API is used but not supported on the\n            // device this code runs.\n            // TODO(andrewharp): abstract ErrorDialog/RuntimeException handling out into new method and\n            // reuse throughout app.\n            ErrorDialog.newInstance(getString(R.string.camera_error))\n                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);\n            throw new RuntimeException(getString(R.string.camera_error));\n        }\n\n        Size textureViewSize = new Size(textureView.getWidth(), textureView.getHeight());\n        cameraConnectionCallback.onPreviewSizeChosen(previewSize, textureViewSize, sensorOrientation);\n    }\n\n    /**\n     * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.\n     */\n    private void openCamera(final int width, final int height) {\n        setUpCameraOutputs();\n        configureTransform(width, height);\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\n                throw new RuntimeException(\"Time out waiting to lock camera opening.\");\n            }\n            manager.openCamera(cameraId, stateCallback, backgroundHandler);\n        } catch (final CameraAccessException | SecurityException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\n        }\n    }\n\n    /**\n     * Closes the current {@link CameraDevice}.\n     */\n    private void closeCamera() {\n        try {\n            cameraOpenCloseLock.acquire();\n            if (null != captureSession) {\n                captureSession.close();\n                captureSession = null;\n            }\n            if (null != cameraDevice) {\n                cameraDevice.close();\n                cameraDevice = null;\n            }\n            if (null != previewReader) {\n                previewReader.close();\n                previewReader = null;\n            }\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera closing.\", e);\n        } finally {\n            cameraOpenCloseLock.release();\n        }\n    }\n\n    /**\n     * Starts a background thread and its {@link Handler}.\n     */\n    private void startBackgroundThread() {\n        backgroundThread = new HandlerThread(\"ImageListener\");\n        backgroundThread.start();\n        backgroundHandler = new Handler(backgroundThread.getLooper());\n    }\n\n    /**\n     * Stops the background thread and its {@link Handler}.\n     */\n    private void stopBackgroundThread() {\n        backgroundThread.quitSafely();\n        try {\n            backgroundThread.join();\n            backgroundThread = null;\n            backgroundHandler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    private final CameraCaptureSession.CaptureCallback captureCallback =\n            new CameraCaptureSession.CaptureCallback() {\n                @Override\n                public void onCaptureProgressed(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final CaptureResult partialResult) {\n                }\n\n                @Override\n                public void onCaptureCompleted(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final TotalCaptureResult result) {\n                }\n            };\n\n    /**\n     * Creates a new {@link CameraCaptureSession} for camera preview.\n     */\n    private void createCameraPreviewSession() {\n        try {\n            final SurfaceTexture texture = textureView.getSurfaceTexture();\n            assert texture != null;\n\n            // We configure the size of default buffer to be the size of camera preview we want.\n            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());\n\n            // This is the output Surface we need to start preview.\n            final Surface surface = new Surface(texture);\n\n            // We set up a CaptureRequest.Builder with the output Surface.\n            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\n            previewRequestBuilder.addTarget(surface);\n\n            Log.i(TAG, \"Opening camera preview: \" + previewSize.getWidth() + \"x\" + previewSize.getHeight());\n\n            // Create the reader for the preview frames.\n            previewReader =\n                    ImageReader.newInstance(\n                            previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);\n\n            previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);\n            previewRequestBuilder.addTarget(previewReader.getSurface());\n\n            // Here, we create a CameraCaptureSession for camera preview.\n            cameraDevice.createCaptureSession(\n                    Arrays.asList(surface, previewReader.getSurface()),\n                    new CameraCaptureSession.StateCallback() {\n\n                        @Override\n                        public void onConfigured(final CameraCaptureSession cameraCaptureSession) {\n                            // The camera is already closed\n                            if (null == cameraDevice) {\n                                return;\n                            }\n\n                            // When the session is ready, we start displaying the preview.\n                            captureSession = cameraCaptureSession;\n                            try {\n                                // Auto focus should be continuous for camera preview.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AF_MODE,\n                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\n                                // Flash is automatically enabled when necessary.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);\n\n                                // Finally, we start displaying the camera preview.\n                                previewRequest = previewRequestBuilder.build();\n                                captureSession.setRepeatingRequest(\n                                        previewRequest, captureCallback, backgroundHandler);\n                            } catch (final CameraAccessException e) {\n                                Log.e(TAG, \"Exception!\" + e);\n                            }\n                        }\n\n                        @Override\n                        public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {\n                            showToast(\"Failed\");\n                        }\n                    },\n                    null);\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    /**\n     * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.\n     * This method should be called after the camera preview size is determined in\n     * setUpCameraOutputs and also the size of `mTextureView` is fixed.\n     *\n     * @param viewWidth  The width of `mTextureView`\n     * @param viewHeight The height of `mTextureView`\n     */\n    private void configureTransform(final int viewWidth, final int viewHeight) {\n        final Activity activity = getActivity();\n        if (null == textureView || null == previewSize || null == activity) {\n            return;\n        }\n        final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();\n        final Matrix matrix = new Matrix();\n        final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);\n        final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());\n        final float centerX = viewRect.centerX();\n        final float centerY = viewRect.centerY();\n        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {\n            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());\n            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);\n            final float scale =\n                    Math.max(\n                            (float) viewHeight / previewSize.getHeight(),\n                            (float) viewWidth / previewSize.getWidth());\n            matrix.postScale(scale, scale, centerX, centerY);\n            matrix.postRotate(90 * (rotation - 2), centerX, centerY);\n        } else if (Surface.ROTATION_180 == rotation) {\n            matrix.postRotate(180, centerX, centerY);\n        }\n        textureView.setTransform(matrix);\n    }\n\n    /**\n     * Compares two {@code Size}s based on their areas.\n     */\n    static class CompareSizesByArea implements Comparator<Size> {\n        @Override\n        public int compare(final Size lhs, final Size rhs) {\n            // We cast here to ensure the multiplications won't overflow\n            return Long.signum(\n                    (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());\n        }\n    }\n\n    /**\n     * Shows an error message dialog.\n     */\n    public static class ErrorDialog extends DialogFragment {\n        private static final String ARG_MESSAGE = \"message\";\n\n        public static ErrorDialog newInstance(final String message) {\n            final ErrorDialog dialog = new ErrorDialog();\n            final Bundle args = new Bundle();\n            args.putString(ARG_MESSAGE, message);\n            dialog.setArguments(args);\n            return dialog;\n        }\n\n        @Override\n        public Dialog onCreateDialog(final Bundle savedInstanceState) {\n            final Activity activity = getActivity();\n            return new AlertDialog.Builder(activity)\n                    .setMessage(getArguments().getString(ARG_MESSAGE))\n                    .setPositiveButton(\n                            android.R.string.ok,\n                            new DialogInterface.OnClickListener() {\n                                @Override\n                                public void onClick(final DialogInterface dialogInterface, final int i) {\n                                    activity.finish();\n                                }\n                            })\n                    .create();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/java/ai/fritz/camera/MainActivity.java",
    "content": "package ai.fritz.camera;\n\nimport android.graphics.Bitmap;\nimport android.graphics.RectF;\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.os.Bundle;\nimport android.util.Size;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.ProgressBar;\nimport android.widget.RelativeLayout;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.core.Fritz;\nimport ai.fritz.objectdetection.R;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.FritzVisionObject;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\nimport ai.fritz.vision.objectdetection.FritzVisionObjectPredictor;\nimport ai.fritz.vision.objectdetection.FritzVisionObjectResult;\nimport ai.fritz.vision.objectdetection.ObjectDetectionOnDeviceModel;\n\n\npublic class MainActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n\n    private static final Size DESIRED_PREVIEW_SIZE = new Size(1280, 960);\n\n    private AtomicBoolean isComputing = new AtomicBoolean(false);\n    private AtomicBoolean shouldSample = new AtomicBoolean(true);\n    private ImageOrientation orientation;\n\n    FritzVisionObjectResult objectResult;\n    FritzVisionObjectPredictor predictor;\n    FritzVisionImage visionImage;\n\n    // Preview Frame\n    RelativeLayout previewFrame;\n    Button snapshotButton;\n    ProgressBar snapshotProcessingSpinner;\n\n    // Snapshot Frame\n    RelativeLayout snapshotFrame;\n    OverlayView snapshotOverlay;\n    Button closeButton;\n    Button recordButton;\n    ProgressBar recordSpinner;\n\n\n    @Override\n    public void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Fritz.configure(this);\n        // The code below loads a custom trained object detection model and creates a predictor that will be used to identify objects in live video.\n        // Custom object detection models can be trained with the Fritz AI platform. To use a pre-trained object detection model,\n        // see the FritzAIStudio demo in this repo.\n        ObjectDetectionOnDeviceModel objectOnDeviceModel = ObjectDetectionOnDeviceModel.buildFromModelConfigFile(\"object_recording_model.json\");\n        predictor = FritzVision.ObjectDetection.getPredictor(objectOnDeviceModel);\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.main_camera;\n    }\n\n    @Override\n    protected Size getDesiredPreviewFrameSize() {\n        return DESIRED_PREVIEW_SIZE;\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n        orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n\n        // Preview View\n        previewFrame = findViewById(R.id.preview_frame);\n        snapshotProcessingSpinner = findViewById(R.id.snapshot_spinner);\n        snapshotButton = findViewById(R.id.take_picture_btn);\n        snapshotButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                if (!shouldSample.compareAndSet(true, false)) {\n                    return;\n                }\n\n                runInBackground(\n                        () -> {\n                            showSpinner();\n                            snapshotOverlay.postInvalidate();\n                            switchToSnapshotView();\n                            hideSpinner();\n                        });\n            }\n        });\n        setCallback(canvas -> {\n            if (objectResult != null) {\n                for (FritzVisionObject visionObject : objectResult.getObjects()) {\n                    visionObject.draw(canvas);\n                }\n            }\n            isComputing.set(false);\n        });\n\n        // Snapshot View\n        snapshotFrame = findViewById(R.id.snapshot_frame);\n        snapshotOverlay = findViewById(R.id.snapshot_view);\n        snapshotOverlay.setCallback(\n                canvas -> {\n                    if (objectResult != null) {\n                        Bitmap bitmap = visionImage.overlayBoundingBoxes(objectResult.getObjects());\n                        canvas.drawBitmap(bitmap, null, new RectF(0, 0, cameraViewSize.getWidth(), cameraViewSize.getHeight()), null);\n                    }\n                });\n\n        recordSpinner = findViewById(R.id.record_spinner);\n        recordButton = findViewById(R.id.record_prediction_btn);\n        recordButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                recordSpinner.setVisibility(View.VISIBLE);\n                // To record predictions and send data back to Fritz AI via the Data Collection System, use the predictors's record method.\n                // In addition to the input image, predicted model results can be collected as well as user-modified annotations.\n                // This allows developers to both gather data on model performance and have users collect additional ground truth data for future model retraining.\n                // Note, the Data Collection System is only available on paid plans.\n                predictor.record(visionImage, objectResult, null, () -> {\n                    switchPreviewView();\n                    return null;\n                }, () -> {\n                    switchPreviewView();\n                    return null;\n                });\n            }\n        });\n        closeButton = findViewById(R.id.close_btn);\n        closeButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                switchPreviewView();\n            }\n        });\n\n    }\n\n    private void switchToSnapshotView() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                previewFrame.setVisibility(View.GONE);\n                snapshotFrame.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void switchPreviewView() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                recordSpinner.setVisibility(View.GONE);\n                snapshotFrame.setVisibility(View.GONE);\n                previewFrame.setVisibility(View.VISIBLE);\n                shouldSample.set(true);\n            }\n        });\n    }\n\n    private void showSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void hideSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.GONE);\n            }\n        });\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!shouldSample.get()) {\n            image.close();\n            return;\n        }\n\n        if (!isComputing.compareAndSet(false, true)) {\n            image.close();\n            return;\n        }\n\n        visionImage = FritzVisionImage.fromMediaImage(image, orientation);\n        image.close();\n\n        runInBackground(() -> {\n            objectResult = predictor.predict(visionImage);\n            requestRender();\n        });\n    }\n}\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/java/ai/fritz/camera/OverlayView.java",
    "content": "package ai.fritz.camera;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.util.AttributeSet;\nimport android.view.View;\n\n/**\n * A simple View providing a render callback to other classes.\n */\npublic class OverlayView extends View {\n    private DrawCallback callback;\n\n    public OverlayView(final Context context, final AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    /**\n     * Interface defining the callback for client classes.\n     */\n    public interface DrawCallback {\n        void drawCallback(final Canvas canvas);\n    }\n\n    public void setCallback(final DrawCallback callback) {\n        this.callback = callback;\n    }\n\n    @Override\n    public synchronized void draw(final Canvas canvas) {\n        super.draw(canvas);\n        if(callback != null) {\n            callback.drawCallback(canvas);\n        }\n    }\n}"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/drawable/ic_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24.0\"\n    android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        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\"/>\n</vector>"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/drawable/round_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\">\n    <stroke\n        android:color=\"#FFFF\"\n        android:width=\"5dip\"/>\n    <size android:width=\"100dp\" android:height=\"100dp\"/>\n</shape>"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/layout/activity_main.xml",
    "content": "<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <FrameLayout\n        android:id=\"@+id/camera_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</android.support.constraint.ConstraintLayout>"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/layout/camera_connection_fragment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <ai.fritz.camera.AutoFitTextureView\n        android:id=\"@+id/texture\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"/>\n\n    <ai.fritz.camera.OverlayView\n        android:id=\"@+id/debug_overlay\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"/>\n</RelativeLayout>\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/layout/main_camera.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:id=\"@+id/preview_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n        <ai.fritz.camera.AutoFitTextureView\n            android:id=\"@+id/texture\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\" />\n        <ai.fritz.camera.OverlayView\n            android:id=\"@+id/debug_overlay\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\"/>\n    </RelativeLayout>\n\n    <include layout=\"@layout/snapshot_button\" />\n\n    <include layout=\"@layout/snapshot_overlay_frame\" />\n</RelativeLayout>\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/layout/snapshot_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_alignParentBottom=\"true\"\n    android:layout_marginTop=\"@dimen/margin_sm\"\n    android:layout_marginBottom=\"@dimen/margin_lg\">\n\n    <Button\n        android:id=\"@+id/take_picture_btn\"\n        android:layout_width=\"80dp\"\n        android:layout_height=\"80dp\"\n        android:layout_centerInParent=\"true\"\n        android:background=\"@drawable/round_button\"\n        android:textColor=\"#fff\" />\n\n    <ProgressBar\n        android:id=\"@+id/snapshot_spinner\"\n        style=\"?android:attr/progressBarStyleLarge\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:indeterminateTint=\"#fff\"\n        android:visibility=\"gone\" />\n</RelativeLayout>"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/layout/snapshot_overlay_frame.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/snapshot_frame\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:visibility=\"gone\">\n\n    <ai.fritz.camera.OverlayView\n        android:id=\"@+id/snapshot_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\" />\n\n    <ProgressBar\n        android:id=\"@+id/record_spinner\"\n        style=\"?android:attr/progressBarStyleLarge\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:indeterminateTint=\"#fff\"\n        android:visibility=\"gone\" />\n\n    <Button\n        android:id=\"@+id/record_prediction_btn\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentBottom=\"true\"\n        android:background=\"@color/colorPrimary\"\n        android:paddingTop=\"15dp\"\n        android:paddingBottom=\"15dp\"\n        android:text=\"Record Prediction\"\n        android:textAlignment=\"gravity\"\n        android:textColor=\"#fff\"\n        android:textStyle=\"bold\" />\n\n    <Button\n        android:id=\"@+id/close_btn\"\n        android:layout_width=\"50dp\"\n        android:layout_height=\"50dp\"\n        android:layout_alignParentTop=\"true\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_marginTop=\"@dimen/margin_sm\"\n        android:layout_marginRight=\"@dimen/margin_sm\"\n        android:background=\"@drawable/ic_close\" />\n\n</RelativeLayout>"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/values/dimens.xml",
    "content": "<!--\n  Copyright 2013 The Android Open Source Project\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n\n<resources>\n\n    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->\n\n    <dimen name=\"margin_xs\">4dp</dimen>\n    <dimen name=\"margin_sm\">8dp</dimen>\n    <dimen name=\"margin_md\">16dp</dimen>\n    <dimen name=\"margin_lg\">32dp</dimen>\n    <dimen name=\"margin_xl\">64dp</dimen>\n\n    <!-- Semantic definitions -->\n\n    <dimen name=\"horizontal_page_margin\">@dimen/margin_md</dimen>\n    <dimen name=\"vertical_page_margin\">@dimen/margin_md</dimen>\n\n</resources>"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Object Detection App</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n</resources>\n"
  },
  {
    "path": "Android/ObjectDetectionApp/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "Android/ObjectDetectionApp/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.6.0'\n\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n\n        // ADD FOR FRITZ DEPENDENCIES\n        maven { url \"https://fritz.mycloudrepo.io/public/repositories/android\" }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "Android/ObjectDetectionApp/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n\n"
  },
  {
    "path": "Android/ObjectDetectionApp/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/ObjectDetectionApp/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/ObjectDetectionApp/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "Android/PetMonitoringApp/README.md",
    "content": "# Pet Monitoring with Object Detection\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we track cats and dogs from a camera feed.\n\n![](images/pet_detection.png)\n\nFor the full tutorial, visit [our post on Heartbeat](https://medium.freecodecamp.org/a-guide-to-object-detection-with-fritz-build-a-pet-monitoring-app-in-android-with-machine-learning-a8ed500978e5).\n\nThis example app uses the on-device Object Detection API for Android.\n\n- [Overview](https://www.fritz.ai/features/object-detection.html)\n- [Documentation](https://docs.fritz.ai/develop/vision/object-detection/android.html)\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Android Studio 3.2 or above\n- Android device in developer model (USB debugging enabled)\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nRegister the Android app in your Fritz account with the package id \"ai.fritz.petmonitoring\". During registration, you'll receive an API key for the app. Save this for later. To find it in the webapp, you can go to Project Settings > Apps > Your App > Show API Key.\n\n**Step 2: Clone / Fork the fritz-examples repository and open the PetMonitoringApp in Android Studio**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\nIn Android Studio, choose \"Open an existing Android Studio project\" and select `PetMonitoringApp`.\n\n**Step 3: Edit the fritz.xml file with your API Key**\n\nIn app/src/main/res/values/fritz.xml, change the fritz_api_key attribute with the one you received in step 1.\n\n**Step 4: Build the Android Studio Project**\n\nSelect \"Build > Make Project\" from the top nav. Download any missing libraries if applicable. This should sync the gradle dependencies so give the build a second to complete.\n\n**Step 5: Install the app onto your device**\n\nWith your Android device connected, select `Run > Run App` from the top nav. When running the app for the first time, you'll have to give permissions to access the camera. After the app is installed and running, point your camera at a dog or cat to see the result.\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 28\n    defaultConfig {\n        // MUST MATCH THE APPLICATION YOU CREATE IN FRITZ\n        applicationId \"ai.fritz.petmonitoring\"\n        minSdkVersion 24\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n}\n\ndependencies {\n    implementation 'com.android.support:appcompat-v7:28.0.0-rc02'\n    implementation 'com.android.support.constraint:constraint-layout:1.1.2'\n\n    implementation \"ai.fritz:core:6.0.3\"\n    implementation \"ai.fritz:vision:6.0.3\"\n    implementation \"ai.fritz:vision-object-detection-model-fast:3.0.0\"\n\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'com.android.support.test:runner:1.0.2'\n    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'\n}\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.petdetector\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\"ai.fritz.petdetector.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <meta-data\n            android:name=\"fritz_api_key\"\n            android:value=\"56b32ce23ee34677871049b1df54b71c\" />\n        <service\n            android:name=\"ai.fritz.core.FritzCustomModelService\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/java/ai/fritz/petdetector/AutoFitTextureView.java",
    "content": "package ai.fritz.petdetector;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.TextureView;\n\n/**\n * A {@link TextureView} that can be adjusted to a specified aspect ratio.\n */\npublic class AutoFitTextureView extends TextureView {\n    private int ratioWidth = 0;\n    private int ratioHeight = 0;\n\n    public AutoFitTextureView(final Context context) {\n        this(context, null);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    /**\n     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio\n     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that\n     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.\n     *\n     * @param width  Relative horizontal size\n     * @param height Relative vertical size\n     */\n    public void setAspectRatio(final int width, final int height) {\n        if (width < 0 || height < 0) {\n            throw new IllegalArgumentException(\"Size cannot be negative.\");\n        }\n        ratioWidth = width;\n        ratioHeight = height;\n        requestLayout();\n    }\n}"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/java/ai/fritz/petdetector/BaseCameraActivity.java",
    "content": "package ai.fritz.petdetector;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.KeyEvent;\nimport android.view.WindowManager;\nimport android.widget.Toast;\n\n\npublic abstract class BaseCameraActivity extends Activity implements OnImageAvailableListener {\n    private static final String TAG = BaseCameraActivity.class.getSimpleName();\n\n    private static final int PERMISSIONS_REQUEST = 1;\n\n    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;\n    private static final String PERMISSION_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;\n    private boolean useCamera2API;\n\n    private boolean debug = false;\n\n    private Handler handler;\n    private HandlerThread handlerThread;\n\n    protected String cameraId;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        Log.d(TAG, \"onCreate \" + this);\n        super.onCreate(null);\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        setContentView(R.layout.activity_main);\n\n        if (hasPermission()) {\n            setFragment();\n        } else {\n            requestPermission();\n        }\n    }\n\n    @Override\n    public synchronized void onStart() {\n        Log.d(TAG, \"onStart \" + this);\n        super.onStart();\n    }\n\n    @Override\n    public synchronized void onResume() {\n        Log.d(TAG, \"onResume \" + this);\n        super.onResume();\n\n        handlerThread = new HandlerThread(\"inference\");\n        handlerThread.start();\n        handler = new Handler(handlerThread.getLooper());\n    }\n\n    @Override\n    public synchronized void onPause() {\n        Log.d(TAG, \"onPause \" + this);\n\n        if (!isFinishing()) {\n            Log.d(TAG, \"Requesting finish\");\n            finish();\n        }\n\n        handlerThread.quitSafely();\n        try {\n            handlerThread.join();\n            handlerThread = null;\n            handler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n\n        super.onPause();\n    }\n\n    @Override\n    public synchronized void onStop() {\n        Log.d(TAG, \"onStop \" + this);\n        super.onStop();\n    }\n\n    @Override\n    public synchronized void onDestroy() {\n        Log.d(TAG, \"onDestroy \" + this);\n        super.onDestroy();\n    }\n\n    protected synchronized void runInBackground(final Runnable r) {\n        if (handler != null) {\n            handler.post(r);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(\n            final int requestCode, final String[] permissions, final int[] grantResults) {\n        switch (requestCode) {\n            case PERMISSIONS_REQUEST: {\n                if (grantResults.length > 0\n                        && grantResults[0] == PackageManager.PERMISSION_GRANTED\n                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {\n                    setFragment();\n                } else {\n                    requestPermission();\n                }\n            }\n        }\n    }\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            return checkSelfPermission(PERMISSION_CAMERA) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(PERMISSION_STORAGE) == PackageManager.PERMISSION_GRANTED;\n        } else {\n            return true;\n        }\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA) || shouldShowRequestPermissionRationale(PERMISSION_STORAGE)) {\n                Toast.makeText(BaseCameraActivity.this, \"Camera AND storage permission are required for this demo\", Toast.LENGTH_LONG).show();\n            }\n            requestPermissions(new String[]{PERMISSION_CAMERA, PERMISSION_STORAGE}, PERMISSIONS_REQUEST);\n        }\n    }\n\n    protected void setFragment() {\n        cameraId = chooseCamera();\n        final CameraConnectionFragment fragment =\n                CameraConnectionFragment.newInstance(\n                        new CameraConnectionFragment.ConnectionCallback() {\n                            @Override\n                            public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n                                BaseCameraActivity.this.onPreviewSizeChosen(previewSize, cameraViewSize, rotation);\n                            }\n                        },\n                        this,\n                        getLayoutId(),\n                        getDesiredPreviewFrameSize());\n\n        fragment.setCamera(cameraId);\n\n        getFragmentManager()\n                .beginTransaction()\n                .replace(R.id.camera_container, fragment)\n                .commit();\n    }\n\n    private String chooseCamera() {\n        final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);\n        try {\n            for (final String cameraId : manager.getCameraIdList()) {\n                final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n                // We don't use a front facing camera in this sample.\n                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);\n                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {\n                    continue;\n                }\n\n                final StreamConfigurationMap map =\n                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n                if (map == null) {\n                    continue;\n                }\n\n                // Fallback to camera1 API for internal cameras that don't have full support.\n                // This should help with legacy situations where using the camera2 API causes\n                // distorted or otherwise broken previews.\n                useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)\n                        || isHardwareLevelSupported(characteristics,\n                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);\n                Log.i(TAG, \"Camera API lv2?: \" + useCamera2API);\n                return cameraId;\n            }\n        } catch (CameraAccessException e) {\n            Log.e(TAG, \"Not allowed to access camera: \" + e);\n        }\n\n        return null;\n    }\n\n    // Returns true if the device supports the required hardware level, or better.\n    private boolean isHardwareLevelSupported(\n            CameraCharacteristics characteristics, int requiredLevel) {\n        int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);\n        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {\n            return requiredLevel == deviceLevel;\n        }\n        // deviceLevel is not LEGACY, can use numerical sort\n        return requiredLevel <= deviceLevel;\n    }\n\n\n    public boolean isDebug() {\n        return debug;\n    }\n\n    public void requestRender() {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.postInvalidate();\n        }\n    }\n\n    public void addCallback(final OverlayView.DrawCallback callback) {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.addCallback(callback);\n        }\n    }\n\n    public void onSetDebug(final boolean debug) {\n    }\n\n    @Override\n    public boolean onKeyDown(final int keyCode, final KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {\n            debug = !debug;\n            requestRender();\n            onSetDebug(debug);\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    protected abstract void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation);\n\n    protected abstract int getLayoutId();\n\n    protected abstract Size getDesiredPreviewFrameSize();\n}\n\n\n\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/java/ai/fritz/petdetector/CameraConnectionFragment.java",
    "content": "package ai.fritz.petdetector;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.app.DialogFragment;\nimport android.app.Fragment;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.graphics.ImageFormat;\nimport android.graphics.Matrix;\nimport android.graphics.RectF;\nimport android.graphics.SurfaceTexture;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCaptureSession;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraDevice;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.CaptureRequest;\nimport android.hardware.camera2.CaptureResult;\nimport android.hardware.camera2.TotalCaptureResult;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.LayoutInflater;\nimport android.view.Surface;\nimport android.view.TextureView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\n\n\npublic class CameraConnectionFragment extends Fragment {\n    private static final String TAG = CameraConnectionFragment.class.getSimpleName();\n\n    public CameraConnectionFragment() {\n\n    }\n\n    /**\n     * The camera preview size will be chosen to be the smallest frame by pixel size capable of\n     * containing a DESIRED_SIZE x DESIRED_SIZE square.\n     */\n    private static final int MINIMUM_PREVIEW_SIZE = 320;\n\n    /**\n     * Conversion from screen rotation to JPEG orientation.\n     */\n    private static final String FRAGMENT_DIALOG = \"dialog\";\n\n    /**\n     * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a\n     * {@link TextureView}.\n     */\n    private final TextureView.SurfaceTextureListener surfaceTextureListener =\n            new TextureView.SurfaceTextureListener() {\n                @Override\n                public void onSurfaceTextureAvailable(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    openCamera(width, height);\n                }\n\n                @Override\n                public void onSurfaceTextureSizeChanged(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    configureTransform(width, height);\n                }\n\n                @Override\n                public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {\n                    return true;\n                }\n\n                @Override\n                public void onSurfaceTextureUpdated(final SurfaceTexture texture) {\n                }\n            };\n\n    /**\n     * Callback for Activities to use to initialize their data once the\n     * selected preview size is known.\n     */\n    public interface ConnectionCallback {\n        void onPreviewSizeChosen(Size size, Size cameraViewSize, int cameraRotation);\n    }\n\n    /**\n     * ID of the current {@link CameraDevice}.\n     */\n    private String cameraId;\n\n    /**\n     * An {@link AutoFitTextureView} for camera preview.\n     */\n    private AutoFitTextureView textureView;\n\n    /**\n     * A {@link CameraCaptureSession } for camera preview.\n     */\n    private CameraCaptureSession captureSession;\n\n    /**\n     * A reference to the opened {@link CameraDevice}.\n     */\n    private CameraDevice cameraDevice;\n\n    /**\n     * The rotation in degrees of the camera sensor from the display.\n     */\n    private Integer sensorOrientation;\n\n    /**\n     * The {@link android.util.Size} of camera preview.\n     */\n    private Size previewSize;\n\n    /**\n     * {@link android.hardware.camera2.CameraDevice.StateCallback}\n     * is called when {@link CameraDevice} changes its state.\n     */\n    private final CameraDevice.StateCallback stateCallback =\n            new CameraDevice.StateCallback() {\n                @Override\n                public void onOpened(final CameraDevice cd) {\n                    // This method is called when the camera is opened.  We start camera preview here.\n                    cameraOpenCloseLock.release();\n                    cameraDevice = cd;\n                    createCameraPreviewSession();\n                }\n\n                @Override\n                public void onDisconnected(final CameraDevice cd) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                }\n\n                @Override\n                public void onError(final CameraDevice cd, final int error) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                    final Activity activity = getActivity();\n                    if (null != activity) {\n                        activity.finish();\n                    }\n                }\n            };\n\n    /**\n     * An additional thread for running tasks that shouldn't block the UI.\n     */\n    private HandlerThread backgroundThread;\n\n    /**\n     * A {@link Handler} for running tasks in the background.\n     */\n    private Handler backgroundHandler;\n\n    /**\n     * An {@link ImageReader} that handles preview frame capture.\n     */\n    private ImageReader previewReader;\n\n    /**\n     * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview\n     */\n    private CaptureRequest.Builder previewRequestBuilder;\n\n    /**\n     * {@link CaptureRequest} generated by {@link #previewRequestBuilder}\n     */\n    private CaptureRequest previewRequest;\n\n    /**\n     * A {@link Semaphore} to prevent the app from exiting before closing the camera.\n     */\n    private final Semaphore cameraOpenCloseLock = new Semaphore(1);\n\n    /**\n     * A {@link OnImageAvailableListener} to receive frames as they are available.\n     */\n    private OnImageAvailableListener imageListener = null;\n\n    /**\n     * The input size in pixels desired by TensorFlow (width and height of a square bitmap).\n     */\n    private Size inputSize = null;\n\n    /**\n     * The layout identifier to inflate for this Fragment.\n     */\n    private int layout = -1;\n\n\n    private ConnectionCallback cameraConnectionCallback = null;\n\n    private CameraConnectionFragment(\n            final ConnectionCallback connectionCallback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        this.cameraConnectionCallback = connectionCallback;\n        this.imageListener = imageListener;\n        this.layout = layout;\n        this.inputSize = inputSize;\n    }\n\n    /**\n     * Shows a {@link Toast} on the UI thread.\n     *\n     * @param text The message to show\n     */\n    private void showToast(final String text) {\n        final Activity activity = getActivity();\n        if (activity != null) {\n            activity.runOnUiThread(\n                    new Runnable() {\n                        @Override\n                        public void run() {\n                            Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();\n                        }\n                    });\n        }\n    }\n\n    /**\n     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose\n     * width and height are at least as large as the minimum of both, or an exact match if possible.\n     *\n     * @param choices The list of sizes that the camera supports for the intended output class\n     * @param width   The minimum desired width\n     * @param height  The minimum desired height\n     * @return The optimal {@code Size}, or an arbitrary one if none were big enough\n     */\n    protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {\n        final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);\n        final Size desiredSize = new Size(width, height);\n\n        // Collect the supported resolutions that are at least as big as the preview Surface\n        boolean exactSizeFound = false;\n        final List<Size> bigEnough = new ArrayList<Size>();\n        final List<Size> tooSmall = new ArrayList<Size>();\n        for (final Size option : choices) {\n            if (option.equals(desiredSize)) {\n                // Set the size but don't return yet so that remaining sizes will still be logged.\n                exactSizeFound = true;\n            }\n\n            if (option.getHeight() >= minSize && option.getWidth() >= minSize) {\n                bigEnough.add(option);\n            } else {\n                tooSmall.add(option);\n            }\n        }\n\n        Log.d(TAG, \"Desired size: \" + desiredSize + \", min size: \" + minSize + \"x\" + minSize);\n        Log.d(TAG, \"Valid preview sizes: [\" + TextUtils.join(\", \", bigEnough) + \"]\");\n        Log.d(TAG, \"Rejected preview sizes: [\" + TextUtils.join(\", \", tooSmall) + \"]\");\n\n        if (exactSizeFound) {\n            Log.d(TAG, \"Exact size match found.\");\n            return desiredSize;\n        }\n\n        // Pick the smallest of those, assuming we found any\n        if (bigEnough.size() > 0) {\n            final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());\n            Log.d(TAG, \"Chosen size: \" + chosenSize.getWidth() + \"x\" + chosenSize.getHeight());\n            return chosenSize;\n        } else {\n            Log.e(TAG, \"Couldn't find any suitable preview size\");\n            return choices[0];\n        }\n    }\n\n    public static CameraConnectionFragment newInstance(\n            final ConnectionCallback callback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        return new CameraConnectionFragment(callback, imageListener, layout, inputSize);\n    }\n\n    @Override\n    public View onCreateView(\n            final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {\n        return inflater.inflate(layout, container, false);\n    }\n\n    @Override\n    public void onViewCreated(final View view, final Bundle savedInstanceState) {\n        textureView = (AutoFitTextureView) view.findViewById(R.id.texture);\n    }\n\n    @Override\n    public void onActivityCreated(final Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        startBackgroundThread();\n\n        // When the screen is turned off and turned back on, the SurfaceTexture is already\n        // available, and \"onSurfaceTextureAvailable\" will not be called. In that case, we can open\n        // a camera and start preview from here (otherwise, we wait until the surface is ready in\n        // the SurfaceTextureListener).\n        if (textureView.isAvailable()) {\n            openCamera(textureView.getWidth(), textureView.getHeight());\n        } else {\n            textureView.setSurfaceTextureListener(surfaceTextureListener);\n        }\n    }\n\n    @Override\n    public void onPause() {\n        closeCamera();\n        stopBackgroundThread();\n        super.onPause();\n    }\n\n    public void setCamera(String cameraId) {\n        this.cameraId = cameraId;\n    }\n\n    /**\n     * Sets up member variables related to camera.\n     */\n    private void setUpCameraOutputs() {\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n            final StreamConfigurationMap map =\n                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n            // For still image captures, we use the largest available size.\n            final Size largest =\n                    Collections.max(\n                            Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),\n                            new CompareSizesByArea());\n\n            sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);\n\n            // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera\n            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of\n            // garbage capture data.\n            previewSize =\n                    chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),\n                            inputSize.getWidth(),\n                            inputSize.getHeight());\n        } catch (final CameraAccessException e) {\n            Log.e(TAG,  \"Exception!\" + e);\n        } catch (final NullPointerException e) {\n            // Currently an NPE is thrown when the Camera2API is used but not supported on the\n            // device this code runs.\n            // TODO(andrewharp): abstract ErrorDialog/RuntimeException handling out into new method and\n            // reuse throughout app.\n            ErrorDialog.newInstance(getString(R.string.camera_error))\n                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);\n            throw new RuntimeException(getString(R.string.camera_error));\n        }\n\n        Size textureViewSize = new Size(textureView.getWidth(), textureView.getHeight());\n        cameraConnectionCallback.onPreviewSizeChosen(previewSize, textureViewSize, sensorOrientation);\n    }\n\n    /**\n     * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.\n     */\n    private void openCamera(final int width, final int height) {\n        setUpCameraOutputs();\n        configureTransform(width, height);\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\n                throw new RuntimeException(\"Time out waiting to lock camera opening.\");\n            }\n            manager.openCamera(cameraId, stateCallback, backgroundHandler);\n        } catch (final CameraAccessException | SecurityException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\n        }\n    }\n\n    /**\n     * Closes the current {@link CameraDevice}.\n     */\n    private void closeCamera() {\n        try {\n            cameraOpenCloseLock.acquire();\n            if (null != captureSession) {\n                captureSession.close();\n                captureSession = null;\n            }\n            if (null != cameraDevice) {\n                cameraDevice.close();\n                cameraDevice = null;\n            }\n            if (null != previewReader) {\n                previewReader.close();\n                previewReader = null;\n            }\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera closing.\", e);\n        } finally {\n            cameraOpenCloseLock.release();\n        }\n    }\n\n    /**\n     * Starts a background thread and its {@link Handler}.\n     */\n    private void startBackgroundThread() {\n        backgroundThread = new HandlerThread(\"ImageListener\");\n        backgroundThread.start();\n        backgroundHandler = new Handler(backgroundThread.getLooper());\n    }\n\n    /**\n     * Stops the background thread and its {@link Handler}.\n     */\n    private void stopBackgroundThread() {\n        backgroundThread.quitSafely();\n        try {\n            backgroundThread.join();\n            backgroundThread = null;\n            backgroundHandler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    private final CameraCaptureSession.CaptureCallback captureCallback =\n            new CameraCaptureSession.CaptureCallback() {\n                @Override\n                public void onCaptureProgressed(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final CaptureResult partialResult) {\n                }\n\n                @Override\n                public void onCaptureCompleted(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final TotalCaptureResult result) {\n                }\n            };\n\n    /**\n     * Creates a new {@link CameraCaptureSession} for camera preview.\n     */\n    private void createCameraPreviewSession() {\n        try {\n            final SurfaceTexture texture = textureView.getSurfaceTexture();\n            assert texture != null;\n\n            // We configure the size of default buffer to be the size of camera preview we want.\n            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());\n\n            // This is the output Surface we need to start preview.\n            final Surface surface = new Surface(texture);\n\n            // We set up a CaptureRequest.Builder with the output Surface.\n            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\n            previewRequestBuilder.addTarget(surface);\n\n            Log.i(TAG, \"Opening camera preview: \" + previewSize.getWidth() + \"x\" + previewSize.getHeight());\n\n            // Create the reader for the preview frames.\n            previewReader =\n                    ImageReader.newInstance(\n                            previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);\n\n            previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);\n            previewRequestBuilder.addTarget(previewReader.getSurface());\n\n            // Here, we create a CameraCaptureSession for camera preview.\n            cameraDevice.createCaptureSession(\n                    Arrays.asList(surface, previewReader.getSurface()),\n                    new CameraCaptureSession.StateCallback() {\n\n                        @Override\n                        public void onConfigured(final CameraCaptureSession cameraCaptureSession) {\n                            // The camera is already closed\n                            if (null == cameraDevice) {\n                                return;\n                            }\n\n                            // When the session is ready, we start displaying the preview.\n                            captureSession = cameraCaptureSession;\n                            try {\n                                // Auto focus should be continuous for camera preview.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AF_MODE,\n                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\n                                // Flash is automatically enabled when necessary.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);\n\n                                // Finally, we start displaying the camera preview.\n                                previewRequest = previewRequestBuilder.build();\n                                captureSession.setRepeatingRequest(\n                                        previewRequest, captureCallback, backgroundHandler);\n                            } catch (final CameraAccessException e) {\n                                Log.e(TAG, \"Exception!\" + e);\n                            }\n                        }\n\n                        @Override\n                        public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {\n                            showToast(\"Failed\");\n                        }\n                    },\n                    null);\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    /**\n     * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.\n     * This method should be called after the camera preview size is determined in\n     * setUpCameraOutputs and also the size of `mTextureView` is fixed.\n     *\n     * @param viewWidth  The width of `mTextureView`\n     * @param viewHeight The height of `mTextureView`\n     */\n    private void configureTransform(final int viewWidth, final int viewHeight) {\n        final Activity activity = getActivity();\n        if (null == textureView || null == previewSize || null == activity) {\n            return;\n        }\n        final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();\n        final Matrix matrix = new Matrix();\n        final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);\n        final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());\n        final float centerX = viewRect.centerX();\n        final float centerY = viewRect.centerY();\n        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {\n            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());\n            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);\n            final float scale =\n                    Math.max(\n                            (float) viewHeight / previewSize.getHeight(),\n                            (float) viewWidth / previewSize.getWidth());\n            matrix.postScale(scale, scale, centerX, centerY);\n            matrix.postRotate(90 * (rotation - 2), centerX, centerY);\n        } else if (Surface.ROTATION_180 == rotation) {\n            matrix.postRotate(180, centerX, centerY);\n        }\n        textureView.setTransform(matrix);\n    }\n\n    /**\n     * Compares two {@code Size}s based on their areas.\n     */\n    static class CompareSizesByArea implements Comparator<Size> {\n        @Override\n        public int compare(final Size lhs, final Size rhs) {\n            // We cast here to ensure the multiplications won't overflow\n            return Long.signum(\n                    (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());\n        }\n    }\n\n    /**\n     * Shows an error message dialog.\n     */\n    public static class ErrorDialog extends DialogFragment {\n        private static final String ARG_MESSAGE = \"message\";\n\n        public static ErrorDialog newInstance(final String message) {\n            final ErrorDialog dialog = new ErrorDialog();\n            final Bundle args = new Bundle();\n            args.putString(ARG_MESSAGE, message);\n            dialog.setArguments(args);\n            return dialog;\n        }\n\n        @Override\n        public Dialog onCreateDialog(final Bundle savedInstanceState) {\n            final Activity activity = getActivity();\n            return new AlertDialog.Builder(activity)\n                    .setMessage(getArguments().getString(ARG_MESSAGE))\n                    .setPositiveButton(\n                            android.R.string.ok,\n                            new DialogInterface.OnClickListener() {\n                                @Override\n                                public void onClick(final DialogInterface dialogInterface, final int i) {\n                                    activity.finish();\n                                }\n                            })\n                    .create();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/java/ai/fritz/petdetector/MainActivity.java",
    "content": "package ai.fritz.petdetector;\n\nimport android.graphics.Canvas;\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.os.Bundle;\nimport android.util.Size;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.core.Fritz;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.FritzVisionObject;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\nimport ai.fritz.vision.ImageRotation;\nimport ai.fritz.vision.objectdetection.FritzVisionObjectPredictor;\nimport ai.fritz.vision.objectdetection.FritzVisionObjectPredictorOptions;\nimport ai.fritz.vision.objectdetection.FritzVisionObjectResult;\nimport ai.fritz.vision.objectdetection.ObjectDetectionOnDeviceModel;\n\npublic class MainActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n\n    private static final String TAG = MainActivity.class.getSimpleName();\n\n    private static final Size DESIRED_PREVIEW_SIZE = new Size(1280, 960);\n\n    private AtomicBoolean computing = new AtomicBoolean(false);\n\n    private Toast toast;\n\n    // STEP 1:\n    // TODO: Define the predictor variable\n    private FritzVisionObjectPredictor predictor;\n    // END STEP 1\n\n    FritzVisionObjectResult result;\n    FritzVisionImage visionImage;\n\n    @Override\n    public void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n\n        // Initialize Fritz\n        Fritz.configure(this);\n\n        // STEP 1: Get the predictor and set the options.\n        // ----------------------------------------------\n        // TODO: Add the predictor snippet here\n        FritzVisionObjectPredictorOptions options = new FritzVisionObjectPredictorOptions();\n        options.confidenceThreshold = .4f;\n        ObjectDetectionOnDeviceModel onDeviceModel = FritzVisionModels.getObjectDetectionOnDeviceModel();\n        predictor = FritzVision.ObjectDetection.getPredictor(onDeviceModel, options);\n        // ----------------------------------------------\n        // END STEP 1\n\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.camera_connection_fragment_stylize;\n    }\n\n    @Override\n    protected Size getDesiredPreviewFrameSize() {\n        return DESIRED_PREVIEW_SIZE;\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n        final List<String> filteredObjects = new ArrayList<>();\n        filteredObjects.add(\"cat\");\n        filteredObjects.add(\"dog\");\n\n        // Callback draws a canvas on the OverlayView\n        addCallback(\n                new OverlayView.DrawCallback() {\n                    @Override\n                    public void drawCallback(final Canvas canvas) {\n                        // STEP 4: Draw the prediction result\n                        // ----------------------------------\n                        if (result == null) {\n                            return;\n                        }\n\n                        boolean hasCat = false;\n                        boolean hasDog = false;\n\n                        // Go through all results\n                        for (FritzVisionObject object : result.getObjects()) {\n                            String labelText = object.getVisionLabel().getText();\n\n                            // Only show results for dogs and cats\n                            if (filteredObjects.contains(labelText)) {\n                                object.draw(canvas);\n\n                                if (labelText.equalsIgnoreCase(\"cat\")) {\n                                    hasCat = true;\n                                }\n\n                                if (labelText.equalsIgnoreCase(\"dog\")) {\n                                    hasDog = true;\n                                }\n                            }\n                        }\n\n                        if (toast == null || !toast.getView().isShown()) {\n                            if (hasDog && hasCat) {\n                                toast = Toast.makeText(getApplicationContext(), \"Dogs and cats make good friends.\", Toast.LENGTH_LONG);\n                                toast.show();\n                            } else if (hasDog) {\n                                toast = Toast.makeText(getApplicationContext(), \"Dogs are cool\", Toast.LENGTH_LONG);\n                                toast.show();\n                                ;\n                            } else if (hasCat) {\n                                toast = Toast.makeText(getApplicationContext(), \"Cats are cute\", Toast.LENGTH_LONG);\n                                toast.show();\n                            }\n                        }\n                        // ----------------------------------\n                        // END STEP 4\n                    }\n                });\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!computing.compareAndSet(false, true)) {\n            image.close();\n            return;\n        }\n\n        // STEP 2: Create the FritzVisionImage object from media.Image\n        // ------------------------------------------------------------------------\n        // TODO: Add code for creating FritzVisionImage from a media.Image object\n        ImageOrientation orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n        visionImage = FritzVisionImage.fromMediaImage(image, orientation);\n        // ------------------------------------------------------------------------\n        // END STEP 2\n\n        image.close();\n\n        runInBackground(\n                new Runnable() {\n                    @Override\n                    public void run() {\n                        // STEP 3: Run predict on the image\n                        // ---------------------------------------------------\n                        // TODO: Add code for running prediction on the image\n                        // final long startTime = SystemClock.uptimeMillis();\n                        result = predictor.predict(visionImage);\n                        // ----------------------------------------------------\n                        // END STEP 3\n\n\n                        // Fire callback to change the OverlayView\n                        requestRender();\n                        computing.set(false);\n                    }\n                });\n    }\n}\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/java/ai/fritz/petdetector/OverlayView.java",
    "content": "package ai.fritz.petdetector;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.util.AttributeSet;\nimport android.view.View;\n\nimport java.util.LinkedList;\nimport java.util.List;\n\n/**\n * A simple View providing a render callback to other classes.\n */\npublic class OverlayView extends View {\n    private final List<DrawCallback> callbacks = new LinkedList<DrawCallback>();\n\n    public OverlayView(final Context context, final AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    /**\n     * Interface defining the callback for client classes.\n     */\n    public interface DrawCallback {\n        public void drawCallback(final Canvas canvas);\n    }\n\n    public void addCallback(final DrawCallback callback) {\n        callbacks.add(callback);\n    }\n\n    @Override\n    public synchronized void draw(final Canvas canvas) {\n        super.draw(canvas);\n        for (final DrawCallback callback : callbacks) {\n            callback.drawCallback(canvas);\n        }\n    }\n}"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/drawable/ic_warning.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"60dp\"\n    android:height=\"60dp\"\n    android:viewportWidth=\"24.0\"\n    android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z\"/>\n</vector>"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/layout/activity_main.xml",
    "content": "<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <FrameLayout\n        android:id=\"@+id/camera_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</android.support.constraint.ConstraintLayout>"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/layout/camera_connection_fragment_stylize.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <ai.fritz.petdetector.AutoFitTextureView\n        android:id=\"@+id/texture\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\" />\n\n    <ai.fritz.petdetector.OverlayView\n        android:id=\"@+id/debug_overlay\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\" />\n</RelativeLayout>\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Pet Monitoring App</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n</resources>\n"
  },
  {
    "path": "Android/PetMonitoringApp/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "Android/PetMonitoringApp/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.1.4'\n\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n\n        // ADD FOR FRITZ DEPENDENCIES\n        maven { url \"https://fritz.mycloudrepo.io/public/repositories/android\" }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "Android/PetMonitoringApp/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n"
  },
  {
    "path": "Android/PetMonitoringApp/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/PetMonitoringApp/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/PetMonitoringApp/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "Android/PetStickerApp/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea\n\n# Keystore files\n# Uncomment the following line if you do not want to check your keystore files in.\n#*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n# fastlane\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\nfastlane/readme.md\n"
  },
  {
    "path": "Android/PetStickerApp/README.md",
    "content": "# Creating Stickers with Pet Segmentation\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, the user can automatically create a sticker of their pet and save it in their camera roll.\n\nThis example app uses the on-device Pet Segmentation API for Android.\n\n- [Overview](https://www.fritz.ai/features/image-segmentation.html)\n- [Documentation](https://docs.fritz.ai/develop/vision/image-segmentation/android.html)\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Android Studio 3.2 or above\n- Android device in developer model (USB debugging enabled)\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nRegister the Android app in your Fritz account with the package id \"ai.fritz.petSticker\". During registration, you'll receive an API key for the app. Save this for later. To find it in the webapp, you can go to Project Settings > Apps > Your App > Show API Key.\n\n**Step 2: Clone / Fork the fritz-examples repository and open the BackgroundReplacementApp app in Android Studio**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\nIn Android Studio, choose \"Open an existing Android Studio project\" and select `PetStickerApp`.\n\n**Step 3: Edit the fritz.xml file with your API Key**\n\nIn app/src/main/res/values/fritz.xml, change the fritz_api_key attribute with the one you received in step 1.\n\n**Step 4: Build the Android Studio Project**\n\nSelect \"Build > Make Project\" from the top nav. Download any missing libraries if applicable. This should sync the gradle dependencies so give the build a second to complete.\n\n**Step 5: Install the app onto your device**\n\nWith your Android device connected, select `Run > Run App` from the top nav. When running the app for the first time, you'll have to give permissions to access the camera. After the app is installed and running, take a picture of a pet and you'll see a preview of the sticker. You can then save the sticker to your photo gallery.\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "Android/PetStickerApp/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "Android/PetStickerApp/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 28\n    defaultConfig {\n        // MUST MATCH THE APPLICATION YOU CREATE IN FRITZ\n        applicationId \"ai.fritz.petSticker\"\n        minSdkVersion 24\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n}\n\ndependencies {\n    implementation 'com.android.support:appcompat-v7:28.0.0'\n    implementation 'com.android.support.constraint:constraint-layout:1.1.3'\n\n    implementation \"ai.fritz:vision:6.0.3\"\n    implementation \"ai.fritz:vision-pet-segmentation-model-fast:3.0.0\"\n\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'com.android.support.test:runner:1.0.2'\n    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'\n}\n"
  },
  {
    "path": "Android/PetStickerApp/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.petSticker\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\"ai.fritz.petSticker.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <service\n            android:name=\"ai.fritz.core.FritzCustomModelService\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/java/ai/fritz/petSticker/AutoFitTextureView.java",
    "content": "package ai.fritz.petSticker;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.TextureView;\n\n/**\n * A {@link TextureView} that can be adjusted to a specified aspect ratio.\n */\npublic class AutoFitTextureView extends TextureView {\n    private int ratioWidth = 0;\n    private int ratioHeight = 0;\n\n    public AutoFitTextureView(final Context context) {\n        this(context, null);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    /**\n     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio\n     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that\n     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.\n     *\n     * @param width  Relative horizontal size\n     * @param height Relative vertical size\n     */\n    public void setAspectRatio(final int width, final int height) {\n        if (width < 0 || height < 0) {\n            throw new IllegalArgumentException(\"Size cannot be negative.\");\n        }\n        ratioWidth = width;\n        ratioHeight = height;\n        requestLayout();\n    }\n}"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/java/ai/fritz/petSticker/BaseCameraActivity.java",
    "content": "package ai.fritz.petSticker;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.support.v7.app.AppCompatActivity;\nimport android.util.DisplayMetrics;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.KeyEvent;\nimport android.view.WindowManager;\nimport android.widget.Toast;\n\n\npublic abstract class BaseCameraActivity extends AppCompatActivity implements OnImageAvailableListener {\n    private static final String TAG = BaseCameraActivity.class.getSimpleName();\n    private static int MAX_WIDTH = 500;\n    private static final int PERMISSIONS_REQUEST = 1;\n\n    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;\n    private static final String PERMISSION_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;\n    private boolean useCamera2API;\n\n    private boolean debug = false;\n\n    private Handler handler;\n    private HandlerThread handlerThread;\n\n    protected String cameraId;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        Log.d(TAG, \"onCreate \" + this);\n        super.onCreate(null);\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        setContentView(R.layout.activity_main);\n\n        if (hasPermission()) {\n            setFragment();\n        } else {\n            requestPermission();\n        }\n    }\n\n    @Override\n    public synchronized void onStart() {\n        Log.d(TAG, \"onStart \" + this);\n        super.onStart();\n    }\n\n    @Override\n    public synchronized void onResume() {\n        Log.d(TAG, \"onResume \" + this);\n        super.onResume();\n\n        handlerThread = new HandlerThread(\"inference\");\n        handlerThread.start();\n        handler = new Handler(handlerThread.getLooper());\n    }\n\n    @Override\n    public synchronized void onPause() {\n        Log.d(TAG, \"onPause \" + this);\n\n        handlerThread.quitSafely();\n        try {\n            handlerThread.join();\n            handlerThread = null;\n            handler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n\n        super.onPause();\n    }\n\n    @Override\n    public synchronized void onStop() {\n        Log.d(TAG, \"onStop \" + this);\n        super.onStop();\n    }\n\n    @Override\n    public synchronized void onDestroy() {\n        Log.d(TAG, \"onDestroy \" + this);\n        super.onDestroy();\n    }\n\n    protected synchronized void runInBackground(final Runnable r) {\n        if (handler != null) {\n            handler.post(r);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(\n            final int requestCode, final String[] permissions, final int[] grantResults) {\n        switch (requestCode) {\n            case PERMISSIONS_REQUEST: {\n                if (grantResults.length > 0\n                        && grantResults[0] == PackageManager.PERMISSION_GRANTED\n                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {\n                    setFragment();\n                } else {\n                    requestPermission();\n                }\n            }\n        }\n    }\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            return checkSelfPermission(PERMISSION_CAMERA) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(PERMISSION_STORAGE) == PackageManager.PERMISSION_GRANTED;\n        } else {\n            return true;\n        }\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA) || shouldShowRequestPermissionRationale(PERMISSION_STORAGE)) {\n                Toast.makeText(BaseCameraActivity.this, \"Camera AND storage permission are required for this demo\", Toast.LENGTH_LONG).show();\n            }\n            requestPermissions(new String[]{PERMISSION_CAMERA, PERMISSION_STORAGE}, PERMISSIONS_REQUEST);\n        }\n    }\n\n    protected void setFragment() {\n        cameraId = chooseCamera();\n        final CameraConnectionFragment fragment =\n                CameraConnectionFragment.newInstance(\n                        new CameraConnectionFragment.ConnectionCallback() {\n                            @Override\n                            public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n                                BaseCameraActivity.this.onPreviewSizeChosen(previewSize, cameraViewSize, rotation);\n                            }\n                        },\n                        this,\n                        getLayoutId(),\n                        getDesiredPreviewFrameSize());\n\n        fragment.setCamera(cameraId);\n\n        getFragmentManager()\n                .beginTransaction()\n                .replace(R.id.camera_container, fragment)\n                .commit();\n    }\n\n    private String chooseCamera() {\n        final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);\n        try {\n            for (final String cameraId : manager.getCameraIdList()) {\n                final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n                // We don't use a front facing camera in this sample.\n                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);\n                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {\n                    continue;\n                }\n\n                final StreamConfigurationMap map =\n                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n                if (map == null) {\n                    continue;\n                }\n\n                // Fallback to camera1 API for internal cameras that don't have full support.\n                // This should help with legacy situations where using the camera2 API causes\n                // distorted or otherwise broken previews.\n                useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)\n                        || isHardwareLevelSupported(characteristics,\n                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);\n                Log.i(TAG, \"Camera API lv2?: \" + useCamera2API);\n                return cameraId;\n            }\n        } catch (CameraAccessException e) {\n            Log.e(TAG, \"Not allowed to access camera: \" + e);\n        }\n\n        return null;\n    }\n\n    // Returns true if the device supports the required hardware level, or better.\n    private boolean isHardwareLevelSupported(\n            CameraCharacteristics characteristics, int requiredLevel) {\n        int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);\n        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {\n            return requiredLevel == deviceLevel;\n        }\n        // deviceLevel is not LEGACY, can use numerical sort\n        return requiredLevel <= deviceLevel;\n    }\n\n\n    public boolean isDebug() {\n        return debug;\n    }\n\n    public void requestRender() {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.postInvalidate();\n        }\n    }\n\n    public void setCallback(final OverlayView.DrawCallback callback) {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.setCallback(callback);\n        }\n    }\n\n    public void onSetDebug(final boolean debug) {\n    }\n\n    @Override\n    public boolean onKeyDown(final int keyCode, final KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {\n            debug = !debug;\n            requestRender();\n            onSetDebug(debug);\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    protected abstract void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation);\n\n    protected abstract int getLayoutId();\n\n    protected Size getDesiredPreviewFrameSize() {\n        DisplayMetrics metrics = getResources().getDisplayMetrics();\n        float ratio = (float) metrics.heightPixels / metrics.widthPixels;\n        return new Size(MAX_WIDTH, (int) ratio * MAX_WIDTH);\n    }\n}\n\n\n"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/java/ai/fritz/petSticker/CameraConnectionFragment.java",
    "content": "package ai.fritz.petSticker;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.app.DialogFragment;\nimport android.app.Fragment;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.graphics.ImageFormat;\nimport android.graphics.Matrix;\nimport android.graphics.RectF;\nimport android.graphics.SurfaceTexture;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCaptureSession;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraDevice;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.CaptureRequest;\nimport android.hardware.camera2.CaptureResult;\nimport android.hardware.camera2.TotalCaptureResult;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.LayoutInflater;\nimport android.view.Surface;\nimport android.view.TextureView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\n\n\npublic class CameraConnectionFragment extends Fragment {\n    private static final String TAG = CameraConnectionFragment.class.getSimpleName();\n\n    public CameraConnectionFragment() {\n\n    }\n\n    /**\n     * The camera preview size will be chosen to be the smallest frame by pixel size capable of\n     * containing a DESIRED_SIZE x DESIRED_SIZE square.\n     */\n    private static final int MINIMUM_PREVIEW_SIZE = 320;\n\n    /**\n     * Conversion from screen rotation to JPEG orientation.\n     */\n    private static final String FRAGMENT_DIALOG = \"dialog\";\n\n    /**\n     * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a\n     * {@link TextureView}.\n     */\n    private final TextureView.SurfaceTextureListener surfaceTextureListener =\n            new TextureView.SurfaceTextureListener() {\n                @Override\n                public void onSurfaceTextureAvailable(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    openCamera(width, height);\n                }\n\n                @Override\n                public void onSurfaceTextureSizeChanged(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    configureTransform(width, height);\n                }\n\n                @Override\n                public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {\n                    return true;\n                }\n\n                @Override\n                public void onSurfaceTextureUpdated(final SurfaceTexture texture) {\n                }\n            };\n\n    /**\n     * Callback for Activities to use to initialize their data once the\n     * selected preview size is known.\n     */\n    public interface ConnectionCallback {\n        void onPreviewSizeChosen(Size size, Size cameraViewSize, int cameraRotation);\n    }\n\n    /**\n     * ID of the current {@link CameraDevice}.\n     */\n    private String cameraId;\n\n    /**\n     * An {@link AutoFitTextureView} for camera preview.\n     */\n    private AutoFitTextureView textureView;\n\n    /**\n     * A {@link CameraCaptureSession } for camera preview.\n     */\n    private CameraCaptureSession captureSession;\n\n    /**\n     * A reference to the opened {@link CameraDevice}.\n     */\n    private CameraDevice cameraDevice;\n\n    /**\n     * The rotation in degrees of the camera sensor from the display.\n     */\n    private Integer sensorOrientation;\n\n    /**\n     * The {@link android.util.Size} of camera preview.\n     */\n    private Size previewSize;\n\n    /**\n     * {@link android.hardware.camera2.CameraDevice.StateCallback}\n     * is called when {@link CameraDevice} changes its state.\n     */\n    private final CameraDevice.StateCallback stateCallback =\n            new CameraDevice.StateCallback() {\n                @Override\n                public void onOpened(final CameraDevice cd) {\n                    // This method is called when the camera is opened.  We start camera preview here.\n                    cameraOpenCloseLock.release();\n                    cameraDevice = cd;\n                    createCameraPreviewSession();\n                }\n\n                @Override\n                public void onDisconnected(final CameraDevice cd) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                }\n\n                @Override\n                public void onError(final CameraDevice cd, final int error) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                    final Activity activity = getActivity();\n                    if (null != activity) {\n                        activity.finish();\n                    }\n                }\n            };\n\n    /**\n     * An additional thread for running tasks that shouldn't block the UI.\n     */\n    private HandlerThread backgroundThread;\n\n    /**\n     * A {@link Handler} for running tasks in the background.\n     */\n    private Handler backgroundHandler;\n\n    /**\n     * An {@link ImageReader} that handles preview frame capture.\n     */\n    private ImageReader previewReader;\n\n    /**\n     * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview\n     */\n    private CaptureRequest.Builder previewRequestBuilder;\n\n    /**\n     * {@link CaptureRequest} generated by {@link #previewRequestBuilder}\n     */\n    private CaptureRequest previewRequest;\n\n    /**\n     * A {@link Semaphore} to prevent the app from exiting before closing the camera.\n     */\n    private final Semaphore cameraOpenCloseLock = new Semaphore(1);\n\n    /**\n     * A {@link OnImageAvailableListener} to receive frames as they are available.\n     */\n    private OnImageAvailableListener imageListener = null;\n\n    /**\n     * The input size in pixels desired by TensorFlow (width and height of a square bitmap).\n     */\n    private Size inputSize = null;\n\n    /**\n     * The layout identifier to inflate for this Fragment.\n     */\n    private int layout = -1;\n\n\n    private ConnectionCallback cameraConnectionCallback = null;\n\n    private CameraConnectionFragment(\n            final ConnectionCallback connectionCallback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        this.cameraConnectionCallback = connectionCallback;\n        this.imageListener = imageListener;\n        this.layout = layout;\n        this.inputSize = inputSize;\n    }\n\n    /**\n     * Shows a {@link Toast} on the UI thread.\n     *\n     * @param text The message to show\n     */\n    private void showToast(final String text) {\n        final Activity activity = getActivity();\n        if (activity != null) {\n            activity.runOnUiThread(\n                    new Runnable() {\n                        @Override\n                        public void run() {\n                            Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();\n                        }\n                    });\n        }\n    }\n\n    /**\n     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose\n     * width and height are at least as large as the minimum of both, or an exact match if possible.\n     *\n     * @param choices The list of sizes that the camera supports for the intended output class\n     * @param width   The minimum desired width\n     * @param height  The minimum desired height\n     * @return The optimal {@code Size}, or an arbitrary one if none were big enough\n     */\n    protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {\n        final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);\n        final Size desiredSize = new Size(width, height);\n\n        // Collect the supported resolutions that are at least as big as the preview Surface\n        boolean exactSizeFound = false;\n        final List<Size> bigEnough = new ArrayList<Size>();\n        final List<Size> tooSmall = new ArrayList<Size>();\n        for (final Size option : choices) {\n            if (option.equals(desiredSize)) {\n                // Set the size but don't return yet so that remaining sizes will still be logged.\n                exactSizeFound = true;\n            }\n\n            if (option.getHeight() >= minSize && option.getWidth() >= minSize) {\n                bigEnough.add(option);\n            } else {\n                tooSmall.add(option);\n            }\n        }\n\n        Log.d(TAG, \"Desired size: \" + desiredSize + \", min size: \" + minSize + \"x\" + minSize);\n        Log.d(TAG, \"Valid preview sizes: [\" + TextUtils.join(\", \", bigEnough) + \"]\");\n        Log.d(TAG, \"Rejected preview sizes: [\" + TextUtils.join(\", \", tooSmall) + \"]\");\n\n        if (exactSizeFound) {\n            Log.d(TAG, \"Exact size match found.\");\n            return desiredSize;\n        }\n\n        // Pick the smallest of those, assuming we found any\n        if (bigEnough.size() > 0) {\n            final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());\n            Log.d(TAG, \"Chosen size: \" + chosenSize.getWidth() + \"x\" + chosenSize.getHeight());\n            return chosenSize;\n        } else {\n            Log.e(TAG, \"Couldn't find any suitable preview size\");\n            return choices[0];\n        }\n    }\n\n    public static CameraConnectionFragment newInstance(\n            final ConnectionCallback callback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        return new CameraConnectionFragment(callback, imageListener, layout, inputSize);\n    }\n\n    @Override\n    public View onCreateView(\n            final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {\n        return inflater.inflate(layout, container, false);\n    }\n\n    @Override\n    public void onViewCreated(final View view, final Bundle savedInstanceState) {\n        textureView = (AutoFitTextureView) view.findViewById(R.id.texture);\n    }\n\n    @Override\n    public void onActivityCreated(final Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        startBackgroundThread();\n\n        // When the screen is turned off and turned back on, the SurfaceTexture is already\n        // available, and \"onSurfaceTextureAvailable\" will not be called. In that case, we can open\n        // a camera and start preview from here (otherwise, we wait until the surface is ready in\n        // the SurfaceTextureListener).\n        if (textureView.isAvailable()) {\n            openCamera(textureView.getWidth(), textureView.getHeight());\n        } else {\n            textureView.setSurfaceTextureListener(surfaceTextureListener);\n        }\n    }\n\n    @Override\n    public void onPause() {\n        closeCamera();\n        stopBackgroundThread();\n        super.onPause();\n    }\n\n    public void setCamera(String cameraId) {\n        this.cameraId = cameraId;\n    }\n\n    /**\n     * Sets up member variables related to camera.\n     */\n    private void setUpCameraOutputs() {\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n            final StreamConfigurationMap map =\n                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n            // For still image captures, we use the largest available size.\n            final Size largest =\n                    Collections.max(\n                            Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),\n                            new CompareSizesByArea());\n\n            sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);\n\n            // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera\n            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of\n            // garbage capture data.\n            previewSize =\n                    chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),\n                            inputSize.getWidth(),\n                            inputSize.getHeight());\n        } catch (final CameraAccessException e) {\n            Log.e(TAG,  \"Exception!\" + e);\n        } catch (final NullPointerException e) {\n            // Currently an NPE is thrown when the Camera2API is used but not supported on the\n            // device this code runs.\n            // TODO(andrewharp): abstract ErrorDialog/RuntimeException handling out into new method and\n            // reuse throughout app.\n            ErrorDialog.newInstance(getString(R.string.camera_error))\n                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);\n            throw new RuntimeException(getString(R.string.camera_error));\n        }\n\n        Size textureViewSize = new Size(textureView.getWidth(), textureView.getHeight());\n        cameraConnectionCallback.onPreviewSizeChosen(previewSize, textureViewSize, sensorOrientation);\n    }\n\n    /**\n     * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.\n     */\n    private void openCamera(final int width, final int height) {\n        setUpCameraOutputs();\n        configureTransform(width, height);\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\n                throw new RuntimeException(\"Time out waiting to lock camera opening.\");\n            }\n            manager.openCamera(cameraId, stateCallback, backgroundHandler);\n        } catch (final CameraAccessException | SecurityException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\n        }\n    }\n\n    /**\n     * Closes the current {@link CameraDevice}.\n     */\n    private void closeCamera() {\n        try {\n            cameraOpenCloseLock.acquire();\n            if (null != captureSession) {\n                captureSession.close();\n                captureSession = null;\n            }\n            if (null != cameraDevice) {\n                cameraDevice.close();\n                cameraDevice = null;\n            }\n            if (null != previewReader) {\n                previewReader.close();\n                previewReader = null;\n            }\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera closing.\", e);\n        } finally {\n            cameraOpenCloseLock.release();\n        }\n    }\n\n    /**\n     * Starts a background thread and its {@link Handler}.\n     */\n    private void startBackgroundThread() {\n        backgroundThread = new HandlerThread(\"ImageListener\");\n        backgroundThread.start();\n        backgroundHandler = new Handler(backgroundThread.getLooper());\n    }\n\n    /**\n     * Stops the background thread and its {@link Handler}.\n     */\n    private void stopBackgroundThread() {\n        backgroundThread.quitSafely();\n        try {\n            backgroundThread.join();\n            backgroundThread = null;\n            backgroundHandler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    private final CameraCaptureSession.CaptureCallback captureCallback =\n            new CameraCaptureSession.CaptureCallback() {\n                @Override\n                public void onCaptureProgressed(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final CaptureResult partialResult) {\n                }\n\n                @Override\n                public void onCaptureCompleted(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final TotalCaptureResult result) {\n                }\n            };\n\n    /**\n     * Creates a new {@link CameraCaptureSession} for camera preview.\n     */\n    private void createCameraPreviewSession() {\n        try {\n            final SurfaceTexture texture = textureView.getSurfaceTexture();\n            assert texture != null;\n\n            // We configure the size of default buffer to be the size of camera preview we want.\n            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());\n\n            // This is the output Surface we need to start preview.\n            final Surface surface = new Surface(texture);\n\n            // We set up a CaptureRequest.Builder with the output Surface.\n            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\n            previewRequestBuilder.addTarget(surface);\n\n            Log.i(TAG, \"Opening camera preview: \" + previewSize.getWidth() + \"x\" + previewSize.getHeight());\n\n            // Create the reader for the preview frames.\n            previewReader =\n                    ImageReader.newInstance(\n                            previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);\n\n            previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);\n            previewRequestBuilder.addTarget(previewReader.getSurface());\n\n            // Here, we create a CameraCaptureSession for camera preview.\n            cameraDevice.createCaptureSession(\n                    Arrays.asList(surface, previewReader.getSurface()),\n                    new CameraCaptureSession.StateCallback() {\n\n                        @Override\n                        public void onConfigured(final CameraCaptureSession cameraCaptureSession) {\n                            // The camera is already closed\n                            if (null == cameraDevice) {\n                                return;\n                            }\n\n                            // When the session is ready, we start displaying the preview.\n                            captureSession = cameraCaptureSession;\n                            try {\n                                // Auto focus should be continuous for camera preview.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AF_MODE,\n                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\n                                // Flash is automatically enabled when necessary.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);\n\n                                // Finally, we start displaying the camera preview.\n                                previewRequest = previewRequestBuilder.build();\n                                captureSession.setRepeatingRequest(\n                                        previewRequest, captureCallback, backgroundHandler);\n                            } catch (final CameraAccessException e) {\n                                Log.e(TAG, \"Exception!\" + e);\n                            }\n                        }\n\n                        @Override\n                        public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {\n                            showToast(\"Failed\");\n                        }\n                    },\n                    null);\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    /**\n     * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.\n     * This method should be called after the camera preview size is determined in\n     * setUpCameraOutputs and also the size of `mTextureView` is fixed.\n     *\n     * @param viewWidth  The width of `mTextureView`\n     * @param viewHeight The height of `mTextureView`\n     */\n    private void configureTransform(final int viewWidth, final int viewHeight) {\n        final Activity activity = getActivity();\n        if (null == textureView || null == previewSize || null == activity) {\n            return;\n        }\n        final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();\n        final Matrix matrix = new Matrix();\n        final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);\n        final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());\n        final float centerX = viewRect.centerX();\n        final float centerY = viewRect.centerY();\n        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {\n            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());\n            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);\n            final float scale =\n                    Math.max(\n                            (float) viewHeight / previewSize.getHeight(),\n                            (float) viewWidth / previewSize.getWidth());\n            matrix.postScale(scale, scale, centerX, centerY);\n            matrix.postRotate(90 * (rotation - 2), centerX, centerY);\n        } else if (Surface.ROTATION_180 == rotation) {\n            matrix.postRotate(180, centerX, centerY);\n        }\n        textureView.setTransform(matrix);\n    }\n\n    /**\n     * Compares two {@code Size}s based on their areas.\n     */\n    static class CompareSizesByArea implements Comparator<Size> {\n        @Override\n        public int compare(final Size lhs, final Size rhs) {\n            // We cast here to ensure the multiplications won't overflow\n            return Long.signum(\n                    (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());\n        }\n    }\n\n    /**\n     * Shows an error message dialog.\n     */\n    public static class ErrorDialog extends DialogFragment {\n        private static final String ARG_MESSAGE = \"message\";\n\n        public static ErrorDialog newInstance(final String message) {\n            final ErrorDialog dialog = new ErrorDialog();\n            final Bundle args = new Bundle();\n            args.putString(ARG_MESSAGE, message);\n            dialog.setArguments(args);\n            return dialog;\n        }\n\n        @Override\n        public Dialog onCreateDialog(final Bundle savedInstanceState) {\n            final Activity activity = getActivity();\n            return new AlertDialog.Builder(activity)\n                    .setMessage(getArguments().getString(ARG_MESSAGE))\n                    .setPositiveButton(\n                            android.R.string.ok,\n                            new DialogInterface.OnClickListener() {\n                                @Override\n                                public void onClick(final DialogInterface dialogInterface, final int i) {\n                                    activity.finish();\n                                }\n                            })\n                    .create();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/java/ai/fritz/petSticker/MainActivity.java",
    "content": "package ai.fritz.petSticker;\n\nimport android.app.Activity;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.os.Bundle;\nimport android.provider.MediaStore;\nimport android.util.Size;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.ProgressBar;\nimport android.widget.RelativeLayout;\nimport android.widget.Toast;\n\nimport java.util.UUID;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.core.Fritz;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\nimport ai.fritz.vision.ImageRotation;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictor;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationPredictorOptions;\nimport ai.fritz.vision.imagesegmentation.FritzVisionSegmentationResult;\nimport ai.fritz.vision.imagesegmentation.MaskClass;\nimport ai.fritz.vision.imagesegmentation.SegmentationOnDeviceModel;\n\n\npublic class MainActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n    private static final String TAG = MainActivity.class.getSimpleName();\n\n    private AtomicBoolean shouldSample = new AtomicBoolean(true);\n    private FritzVisionSegmentationPredictor predictor;\n    private ImageOrientation orientation;\n\n    private FritzVisionSegmentationResult segmentResult;\n    private FritzVisionImage visionImage;\n\n    Button snapshotButton;\n    Button saveStickerBtn;\n    RelativeLayout previewLayout;\n    RelativeLayout snapshotLayout;\n    OverlayView snapshotOverlay;\n    ProgressBar snapshotProcessingSpinner;\n    Button closeButton;\n    FritzVisionSegmentationPredictorOptions options;\n\n    Bitmap petBitmapToSave;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Fritz.configure(this);\n\n        SegmentationOnDeviceModel onDeviceModel = FritzVisionModels.getPetSegmentationOnDeviceModel(ModelVariant.FAST);\n        options = new FritzVisionSegmentationPredictorOptions();\n        options.confidenceThreshold = .4f;\n        predictor = FritzVision.ImageSegmentation.getPredictor(onDeviceModel, options);\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.camera_connection_fragment_pet_sticker;\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size size, final Size cameraSize, final int rotation) {\n        orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n\n        snapshotButton = findViewById(R.id.take_picture_btn);\n        previewLayout = findViewById(R.id.preview_frame);\n        snapshotLayout = findViewById(R.id.snapshot_frame);\n        snapshotOverlay = findViewById(R.id.snapshot_view);\n        closeButton = findViewById(R.id.close_btn);\n        snapshotProcessingSpinner = findViewById(R.id.snapshotProcessingSpinner);\n        saveStickerBtn = findViewById(R.id.saveStickerBtn);\n\n        snapshotOverlay.setCallback(new OverlayView.DrawCallback() {\n            @Override\n            public void drawCallback(final Canvas canvas) {\n\n                if (segmentResult == null) {\n                    return;\n                }\n\n                Bitmap maskBitmap = segmentResult.buildSingleClassMask(MaskClass.PET, 255, options.confidenceThreshold, options.confidenceThreshold);\n                Bitmap petBitmap = visionImage.mask(maskBitmap, true);\n\n                if (petBitmap == null) {\n                    return;\n                }\n                // Scale the result\n                float scaleWidth = ((float) cameraSize.getWidth()) / petBitmap.getWidth();\n                float scaleHeight = ((float) cameraSize.getWidth()) / petBitmap.getHeight();\n\n                final Matrix matrix = new Matrix();\n                float scale = Math.min(scaleWidth, scaleHeight);\n                matrix.postScale(scale, scale);\n\n                petBitmapToSave = Bitmap.createBitmap(petBitmap, 0, 0, petBitmap.getWidth(), petBitmap.getHeight(), matrix, false);\n\n                int leftOffset = (cameraSize.getWidth() - petBitmapToSave.getWidth()) / 2;\n                int topOffset = (cameraSize.getHeight() - petBitmapToSave.getHeight()) / 2;\n\n                // Draw pet mask\n                canvas.drawBitmap(petBitmapToSave, leftOffset, topOffset, new Paint());\n            }\n        });\n\n        snapshotButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                if (!shouldSample.compareAndSet(true, false)) {\n                    return;\n                }\n\n                snapshotOverlay.postInvalidate();\n\n                runInBackground(\n                        new Runnable() {\n                            @Override\n                            public void run() {\n                                showSpinner();\n                                segmentResult = predictor.predict(visionImage);\n                                showSnapshotLayout();\n                                hideSpinner();\n                                snapshotOverlay.postInvalidate();\n                            }\n                        });\n            }\n        });\n\n        final Activity activity = this;\n        saveStickerBtn.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                if (petBitmapToSave == null) {\n                    Toast.makeText(activity, R.string.error_saving_sticker, Toast.LENGTH_LONG).show();\n                    return;\n                }\n\n                // Save the sticker\n                Toast.makeText(activity, R.string.saved_sticker, Toast.LENGTH_LONG).show();\n                MediaStore.Images.Media.insertImage(\n                        getContentResolver(), petBitmapToSave,\n                        UUID.randomUUID().toString() + \".png\",\n                        \"Pet Sticker\");\n                saveStickerBtn.setVisibility(View.GONE);\n            }\n        });\n\n        closeButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                showPreviewLayout();\n                shouldSample.set(true);\n                petBitmapToSave = null;\n            }\n        });\n    }\n\n    private void showSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void hideSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.GONE);\n            }\n        });\n    }\n\n    private void showSnapshotLayout() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                previewLayout.setVisibility(View.GONE);\n                snapshotLayout.setVisibility(View.VISIBLE);\n                saveStickerBtn.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void showPreviewLayout() {\n        previewLayout.setVisibility(View.VISIBLE);\n        snapshotLayout.setVisibility(View.GONE);\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!shouldSample.get()) {\n            image.close();\n            return;\n        }\n        visionImage = FritzVisionImage.fromMediaImage(image, orientation);\n        image.close();\n    }\n}"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/java/ai/fritz/petSticker/OverlayView.java",
    "content": "package ai.fritz.petSticker;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.util.AttributeSet;\nimport android.view.View;\n\n/**\n * A simple View providing a render callback to other classes.\n */\npublic class OverlayView extends View {\n    private DrawCallback callback;\n\n    public OverlayView(final Context context, final AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    /**\n     * Interface defining the callback for client classes.\n     */\n    public interface DrawCallback {\n        public void drawCallback(final Canvas canvas);\n    }\n\n    public void setCallback(final DrawCallback callback) {\n        this.callback = callback;\n    }\n\n    @Override\n    public synchronized void draw(final Canvas canvas) {\n        super.draw(canvas);\n        if(callback != null) {\n            callback.drawCallback(canvas);\n        }\n    }\n}"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/drawable/ic_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24.0\"\n    android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#000\"\n        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\"/>\n</vector>"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/drawable/round_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\">\n    <stroke\n        android:color=\"#FFFF\"\n        android:width=\"5dip\"/>\n    <size android:width=\"100dp\" android:height=\"100dp\"/>\n</shape>"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/layout/activity_main.xml",
    "content": "<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <FrameLayout\n        android:id=\"@+id/camera_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</android.support.constraint.ConstraintLayout>"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/layout/camera_connection_fragment_pet_sticker.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n Copyright 2016 The TensorFlow Authors. All Rights Reserved.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:id=\"@+id/preview_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <ai.fritz.petSticker.AutoFitTextureView\n            android:id=\"@+id/texture\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\" />\n\n        <ai.fritz.petSticker.OverlayView\n            android:id=\"@+id/debug_overlay\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\" />\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginTop=\"@dimen/margin_sm\"\n            android:layout_marginBottom=\"@dimen/margin_lg\">\n\n            <Button\n                android:id=\"@+id/take_picture_btn\"\n                android:layout_width=\"80dp\"\n                android:layout_height=\"80dp\"\n                android:layout_centerInParent=\"true\"\n                android:background=\"@drawable/round_button\"\n                android:textColor=\"#fff\" />\n\n            <ProgressBar\n                android:id=\"@+id/snapshotProcessingSpinner\"\n                style=\"?android:attr/progressBarStyleLarge\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerInParent=\"true\"\n                android:indeterminateTint=\"#fff\"\n                android:visibility=\"gone\" />\n        </RelativeLayout>\n    </RelativeLayout>\n\n    <RelativeLayout\n        android:id=\"@+id/snapshot_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\">\n\n        <ai.fritz.petSticker.OverlayView\n            android:id=\"@+id/snapshot_view\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\" />\n\n        <Button\n            android:id=\"@+id/saveStickerBtn\"\n            android:text=\"@string/save_sticker_btn\"\n            android:textAlignment=\"gravity\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:background=\"@color/colorPrimary\"\n            android:paddingTop=\"15dp\"\n            android:paddingBottom=\"15dp\"\n            android:textStyle=\"bold\"\n            android:textColor=\"#fff\" />\n\n        <Button\n            android:id=\"@+id/close_btn\"\n            android:layout_width=\"50dp\"\n            android:layout_height=\"50dp\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_alignParentRight=\"true\"\n            android:layout_marginTop=\"@dimen/margin_sm\"\n            android:layout_marginRight=\"@dimen/margin_sm\"\n            android:background=\"@drawable/ic_close\" />\n\n    </RelativeLayout>\n\n\n</RelativeLayout>\n"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/values/dimen.xml",
    "content": "<!--\n  Copyright 2013 The Android Open Source Project\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n\n<resources>\n\n    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->\n\n    <dimen name=\"margin_xs\">4dp</dimen>\n    <dimen name=\"margin_sm\">8dp</dimen>\n    <dimen name=\"margin_md\">16dp</dimen>\n    <dimen name=\"margin_lg\">32dp</dimen>\n    <dimen name=\"margin_xl\">64dp</dimen>\n\n    <!-- Semantic definitions -->\n\n    <dimen name=\"horizontal_page_margin\">@dimen/margin_md</dimen>\n    <dimen name=\"vertical_page_margin\">@dimen/margin_md</dimen>\n\n</resources>"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Pet Stickers</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n    <string name=\"save_sticker_btn\">Save Sticker</string>\n    <string name=\"error_saving_sticker\">There was an error saving your sticker</string>\n    <string name=\"saved_sticker\">Saved Sticker!</string>\n</resources>\n"
  },
  {
    "path": "Android/PetStickerApp/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "Android/PetStickerApp/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.4.1'\n\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n\n        // ADD FOR FRITZ DEPENDENCIES\n        maven { url \"https://fritz.mycloudrepo.io/public/repositories/android\" }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "Android/PetStickerApp/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n"
  },
  {
    "path": "Android/PetStickerApp/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/PetStickerApp/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/PetStickerApp/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "Android/PoseEstimationApp/.gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea\n\n# Keystore files\n# Uncomment the following line if you do not want to check your keystore files in.\n#*.jks\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n\n# Google Services (e.g. APIs or Firebase)\ngoogle-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n# fastlane\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\nfastlane/readme.md\n"
  },
  {
    "path": "Android/PoseEstimationApp/README.md",
    "content": "# Pose Estimation Demo App with Data Collection\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, the user detects human poses and records the result to Fritz. For an example of a real time implementation of pose estimation, check out the [Fritz AI Studio app](https://github.com/fritzlabs/fritz-examples/blob/master/Android/FritzAIStudio/app/src/main/java/ai/fritz/aistudio/activities/vision/PoseEstimationActivity.java)\n\nThis example app uses the on-device Pose Estimation API for Android.\n\n- [Overview](https://docs.fritz.ai/develop/vision/pose-estimation/human-pose-estimation/about.html)\n- [Documentation](https://docs.fritz.ai/develop/vision/pose-estimation/human-pose-estimation/android.html)\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Android Studio 3.2 or above\n- Android device in developer model (USB debugging enabled)\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nRegister the Android app in your Fritz account with the package id \"ai.fritz.poseestimationdemo\". During registration, you'll receive an API key for the app. Save this for later. To find it in the webapp, you can go to Project Settings > Apps > Your App > Show API Key.\n\n**Step 2: Clone / Fork the fritz-examples repository and open the BackgroundReplacementApp app in Android Studio**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\nIn Android Studio, choose \"Open an existing Android Studio project\" and select `PoseEstimationApp`.\n\n**Step 3: Edit the fritz.xml file with your API Key**\n\nIn app/src/main/res/values/fritz.xml, change the fritz_api_key attribute with the one you received in step 1.\n\n**Step 4: Build the Android Studio Project**\n\nSelect \"Build > Make Project\" from the top nav. Download any missing libraries if applicable. This should sync the gradle dependencies so give the build a second to complete.\n\n**Step 5: Install the app onto your device**\n\nWith your Android device connected, select `Run > Run App` from the top nav. When running the app for the first time, you'll have to give permissions to access the camera. After the app is installed and running, take a picture of a person and you'll see a detected pose overlayed on the image. Afterwards you can choose to record the model predictions if your model is connected to an image collection in the webapp.\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 29\n    defaultConfig {\n        // MUST MATCH THE APPLICATION YOU CREATE IN FRITZ\n        applicationId \"ai.fritz.poseestimationdemo\"\n        minSdkVersion 24\n        targetSdkVersion 29\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        debug {\n            debuggable true\n        }\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    aaptOptions {\n        noCompress \"tflite\"\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n    compileOptions {\n        sourceCompatibility = 1.8\n        targetCompatibility = 1.8\n    }\n}\n\ndependencies {\n    implementation 'com.android.support:appcompat-v7:28.0.0'\n    implementation 'com.android.support.constraint:constraint-layout:1.1.3'\n\n    implementation \"ai.fritz:core:6.0.0\"\n    implementation \"ai.fritz:vision:6.0.0\"\n\n    testImplementation 'junit:junit:4.12'\n    androidTestImplementation 'com.android.support.test:runner:1.0.2'\n    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'\n}\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"ai.fritz.poseestimationdemo\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:largeHeap=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\"ai.fritz.camera.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <service\n            android:name=\"ai.fritz.core.FritzCustomModelService\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/assets/pose_recording_model.json",
    "content": "{\n  \"model_path\": \"file:///android_asset/PoseMobilenet353x25758Large1565627685.tflite\",\n  \"pinned_version\": 1,\n  \"model_version\": 1,\n  \"model_id\": \"Your model id\",\n  \"use_displacements\": true,\n  \"output_stride\": 8\n}"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/java/ai/fritz/camera/AutoFitTextureView.java",
    "content": "package ai.fritz.camera;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.view.TextureView;\n\n/**\n * A {@link TextureView} that can be adjusted to a specified aspect ratio.\n */\npublic class AutoFitTextureView extends TextureView {\n    private int ratioWidth = 0;\n    private int ratioHeight = 0;\n\n    public AutoFitTextureView(final Context context) {\n        this(context, null);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {\n        super(context, attrs, defStyle);\n    }\n\n    /**\n     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio\n     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that\n     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.\n     *\n     * @param width  Relative horizontal size\n     * @param height Relative vertical size\n     */\n    public void setAspectRatio(final int width, final int height) {\n        if (width < 0 || height < 0) {\n            throw new IllegalArgumentException(\"Size cannot be negative.\");\n        }\n        ratioWidth = width;\n        ratioHeight = height;\n        requestLayout();\n    }\n}"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/java/ai/fritz/camera/BaseCameraActivity.java",
    "content": "package ai.fritz.camera;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.support.v7.app.AppCompatActivity;\nimport android.util.DisplayMetrics;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.KeyEvent;\nimport android.view.WindowManager;\nimport android.widget.Toast;\n\nimport ai.fritz.poseestimationdemo.R;\n\n\npublic abstract class BaseCameraActivity extends AppCompatActivity implements OnImageAvailableListener {\n    private static final String TAG = BaseCameraActivity.class.getSimpleName();\n    private static int MAX_WIDTH = 500;\n    private static final int PERMISSIONS_REQUEST = 1;\n\n    private static final String PERMISSION_CAMERA = Manifest.permission.CAMERA;\n    private boolean useCamera2API;\n\n    private boolean debug = false;\n\n    private Handler handler;\n    private HandlerThread handlerThread;\n\n    protected String cameraId;\n\n    @Override\n    protected void onCreate(final Bundle savedInstanceState) {\n        Log.d(TAG, \"onCreate \" + this);\n        super.onCreate(null);\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n\n        setContentView(R.layout.activity_main);\n\n        if (hasPermission()) {\n            setFragment();\n        } else {\n            requestPermission();\n        }\n    }\n\n    @Override\n    public synchronized void onStart() {\n        Log.d(TAG, \"onStart \" + this);\n        super.onStart();\n    }\n\n    @Override\n    public synchronized void onResume() {\n        Log.d(TAG, \"onResume \" + this);\n        super.onResume();\n\n        handlerThread = new HandlerThread(\"inference\");\n        handlerThread.start();\n        handler = new Handler(handlerThread.getLooper());\n    }\n\n    @Override\n    public synchronized void onPause() {\n        Log.d(TAG, \"onPause \" + this);\n\n        if (!isFinishing()) {\n            Log.d(TAG, \"Requesting finish\");\n            finish();\n        }\n\n        handlerThread.quitSafely();\n        try {\n            handlerThread.join();\n            handlerThread = null;\n            handler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n\n        super.onPause();\n    }\n\n    @Override\n    public synchronized void onStop() {\n        Log.d(TAG, \"onStop \" + this);\n        super.onStop();\n    }\n\n    @Override\n    public synchronized void onDestroy() {\n        Log.d(TAG, \"onDestroy \" + this);\n        super.onDestroy();\n    }\n\n    protected synchronized void runInBackground(final Runnable r) {\n        if (handler != null) {\n            handler.post(r);\n        }\n    }\n\n    @Override\n    public void onRequestPermissionsResult(\n            final int requestCode, final String[] permissions, final int[] grantResults) {\n        switch (requestCode) {\n            case PERMISSIONS_REQUEST: {\n                if (grantResults.length > 0\n                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {\n                    setFragment();\n                } else {\n                    requestPermission();\n                }\n            }\n        }\n    }\n\n    private boolean hasPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            int permission = checkSelfPermission(PERMISSION_CAMERA);\n            return permission == PackageManager.PERMISSION_GRANTED;\n        } else {\n            return true;\n        }\n    }\n\n    private void requestPermission() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            if (shouldShowRequestPermissionRationale(PERMISSION_CAMERA)) {\n                Toast.makeText(BaseCameraActivity.this, \"Camera permission are required for this demo\", Toast.LENGTH_LONG).show();\n            }\n            requestPermissions(new String[]{PERMISSION_CAMERA}, PERMISSIONS_REQUEST);\n        }\n    }\n\n    protected void setFragment() {\n        cameraId = chooseCamera();\n        final CameraConnectionFragment fragment =\n                CameraConnectionFragment.newInstance(\n                        new CameraConnectionFragment.ConnectionCallback() {\n                            @Override\n                            public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n                                BaseCameraActivity.this.onPreviewSizeChosen(previewSize, cameraViewSize, rotation);\n                            }\n                        },\n                        this,\n                        getLayoutId(),\n                        getDesiredPreviewFrameSize());\n\n        fragment.setCamera(cameraId);\n\n        getFragmentManager()\n                .beginTransaction()\n                .replace(R.id.camera_container, fragment)\n                .commit();\n    }\n\n    private String chooseCamera() {\n        final CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);\n        try {\n            for (final String cameraId : manager.getCameraIdList()) {\n                final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n                // We don't use a front facing camera in this sample.\n                final Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);\n                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {\n                    continue;\n                }\n\n                final StreamConfigurationMap map =\n                        characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n                if (map == null) {\n                    continue;\n                }\n\n                // Fallback to camera1 API for internal cameras that don't have full support.\n                // This should help with legacy situations where using the camera2 API causes\n                // distorted or otherwise broken previews.\n                useCamera2API = (facing == CameraCharacteristics.LENS_FACING_EXTERNAL)\n                        || isHardwareLevelSupported(characteristics,\n                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL);\n                Log.i(TAG, \"Camera API lv2?: \" + useCamera2API);\n                return cameraId;\n            }\n        } catch (CameraAccessException e) {\n            Log.e(TAG, \"Not allowed to access camera: \" + e);\n        }\n\n        return null;\n    }\n\n    // Returns true if the device supports the required hardware level, or better.\n    private boolean isHardwareLevelSupported(\n            CameraCharacteristics characteristics, int requiredLevel) {\n        int deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);\n        if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {\n            return requiredLevel == deviceLevel;\n        }\n        // deviceLevel is not LEGACY, can use numerical sort\n        return requiredLevel <= deviceLevel;\n    }\n\n\n    public boolean isDebug() {\n        return debug;\n    }\n\n    public void requestRender() {\n        final OverlayView overlay = findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.postInvalidate();\n        }\n    }\n\n    public void setCallback(final OverlayView.DrawCallback callback) {\n        final OverlayView overlay = (OverlayView) findViewById(R.id.debug_overlay);\n        if (overlay != null) {\n            overlay.setCallback(callback);\n        }\n    }\n\n    public void onSetDebug(final boolean debug) {\n    }\n\n    @Override\n    public boolean onKeyDown(final int keyCode, final KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {\n            debug = !debug;\n            requestRender();\n            onSetDebug(debug);\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    protected abstract void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation);\n\n    protected abstract int getLayoutId();\n\n    protected Size getDesiredPreviewFrameSize() {\n        DisplayMetrics metrics = getResources().getDisplayMetrics();\n        float ratio = (float) metrics.heightPixels / metrics.widthPixels;\n        return new Size(MAX_WIDTH, (int) ratio * MAX_WIDTH);\n    }\n}\n\n\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/java/ai/fritz/camera/CameraConnectionFragment.java",
    "content": "package ai.fritz.camera;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.app.DialogFragment;\nimport android.app.Fragment;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.graphics.ImageFormat;\nimport android.graphics.Matrix;\nimport android.graphics.RectF;\nimport android.graphics.SurfaceTexture;\nimport android.hardware.camera2.CameraAccessException;\nimport android.hardware.camera2.CameraCaptureSession;\nimport android.hardware.camera2.CameraCharacteristics;\nimport android.hardware.camera2.CameraDevice;\nimport android.hardware.camera2.CameraManager;\nimport android.hardware.camera2.CaptureRequest;\nimport android.hardware.camera2.CaptureResult;\nimport android.hardware.camera2.TotalCaptureResult;\nimport android.hardware.camera2.params.StreamConfigurationMap;\nimport android.media.ImageReader;\nimport android.media.ImageReader.OnImageAvailableListener;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.HandlerThread;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.util.Size;\nimport android.view.LayoutInflater;\nimport android.view.Surface;\nimport android.view.TextureView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.concurrent.Semaphore;\nimport java.util.concurrent.TimeUnit;\n\nimport ai.fritz.poseestimationdemo.R;\n\n\npublic class CameraConnectionFragment extends Fragment {\n    private static final String TAG = CameraConnectionFragment.class.getSimpleName();\n\n    public CameraConnectionFragment() {\n\n    }\n\n    /**\n     * The camera preview size will be chosen to be the smallest frame by pixel size capable of\n     * containing a DESIRED_SIZE x DESIRED_SIZE square.\n     */\n    private static final int MINIMUM_PREVIEW_SIZE = 320;\n\n    /**\n     * Conversion from screen rotation to JPEG orientation.\n     */\n    private static final String FRAGMENT_DIALOG = \"dialog\";\n\n    /**\n     * {@link android.view.TextureView.SurfaceTextureListener} handles several lifecycle events on a\n     * {@link TextureView}.\n     */\n    private final TextureView.SurfaceTextureListener surfaceTextureListener =\n            new TextureView.SurfaceTextureListener() {\n                @Override\n                public void onSurfaceTextureAvailable(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    openCamera(width, height);\n                }\n\n                @Override\n                public void onSurfaceTextureSizeChanged(\n                        final SurfaceTexture texture, final int width, final int height) {\n                    configureTransform(width, height);\n                }\n\n                @Override\n                public boolean onSurfaceTextureDestroyed(final SurfaceTexture texture) {\n                    return true;\n                }\n\n                @Override\n                public void onSurfaceTextureUpdated(final SurfaceTexture texture) {\n                }\n            };\n\n    /**\n     * Callback for Activities to use to initialize their data once the\n     * selected preview size is known.\n     */\n    public interface ConnectionCallback {\n        void onPreviewSizeChosen(Size size, Size cameraViewSize, int cameraRotation);\n    }\n\n    /**\n     * ID of the current {@link CameraDevice}.\n     */\n    private String cameraId;\n\n    /**\n     * An {@link AutoFitTextureView} for camera preview.\n     */\n    private AutoFitTextureView textureView;\n\n    /**\n     * A {@link CameraCaptureSession } for camera preview.\n     */\n    private CameraCaptureSession captureSession;\n\n    /**\n     * A reference to the opened {@link CameraDevice}.\n     */\n    private CameraDevice cameraDevice;\n\n    /**\n     * The rotation in degrees of the camera sensor from the display.\n     */\n    private Integer sensorOrientation;\n\n    /**\n     * The {@link android.util.Size} of camera preview.\n     */\n    private Size previewSize;\n\n    /**\n     * {@link android.hardware.camera2.CameraDevice.StateCallback}\n     * is called when {@link CameraDevice} changes its state.\n     */\n    private final CameraDevice.StateCallback stateCallback =\n            new CameraDevice.StateCallback() {\n                @Override\n                public void onOpened(final CameraDevice cd) {\n                    // This method is called when the camera is opened.  We start camera preview here.\n                    cameraOpenCloseLock.release();\n                    cameraDevice = cd;\n                    createCameraPreviewSession();\n                }\n\n                @Override\n                public void onDisconnected(final CameraDevice cd) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                }\n\n                @Override\n                public void onError(final CameraDevice cd, final int error) {\n                    cameraOpenCloseLock.release();\n                    cd.close();\n                    cameraDevice = null;\n                    final Activity activity = getActivity();\n                    if (null != activity) {\n                        activity.finish();\n                    }\n                }\n            };\n\n    /**\n     * An additional thread for running tasks that shouldn't block the UI.\n     */\n    private HandlerThread backgroundThread;\n\n    /**\n     * A {@link Handler} for running tasks in the background.\n     */\n    private Handler backgroundHandler;\n\n    /**\n     * An {@link ImageReader} that handles preview frame capture.\n     */\n    private ImageReader previewReader;\n\n    /**\n     * {@link android.hardware.camera2.CaptureRequest.Builder} for the camera preview\n     */\n    private CaptureRequest.Builder previewRequestBuilder;\n\n    /**\n     * {@link CaptureRequest} generated by {@link #previewRequestBuilder}\n     */\n    private CaptureRequest previewRequest;\n\n    /**\n     * A {@link Semaphore} to prevent the app from exiting before closing the camera.\n     */\n    private final Semaphore cameraOpenCloseLock = new Semaphore(1);\n\n    /**\n     * A {@link OnImageAvailableListener} to receive frames as they are available.\n     */\n    private OnImageAvailableListener imageListener = null;\n\n    /**\n     * The input size in pixels desired by TensorFlow (width and height of a square bitmap).\n     */\n    private Size inputSize = null;\n\n    /**\n     * The layout identifier to inflate for this Fragment.\n     */\n    private int layout = -1;\n\n\n    private ConnectionCallback cameraConnectionCallback = null;\n\n    private CameraConnectionFragment(\n            final ConnectionCallback connectionCallback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        this.cameraConnectionCallback = connectionCallback;\n        this.imageListener = imageListener;\n        this.layout = layout;\n        this.inputSize = inputSize;\n    }\n\n    /**\n     * Shows a {@link Toast} on the UI thread.\n     *\n     * @param text The message to show\n     */\n    private void showToast(final String text) {\n        final Activity activity = getActivity();\n        if (activity != null) {\n            activity.runOnUiThread(\n                    new Runnable() {\n                        @Override\n                        public void run() {\n                            Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();\n                        }\n                    });\n        }\n    }\n\n    /**\n     * Given {@code choices} of {@code Size}s supported by a camera, chooses the smallest one whose\n     * width and height are at least as large as the minimum of both, or an exact match if possible.\n     *\n     * @param choices The list of sizes that the camera supports for the intended output class\n     * @param width   The minimum desired width\n     * @param height  The minimum desired height\n     * @return The optimal {@code Size}, or an arbitrary one if none were big enough\n     */\n    protected static Size chooseOptimalSize(final Size[] choices, final int width, final int height) {\n        final int minSize = Math.max(Math.min(width, height), MINIMUM_PREVIEW_SIZE);\n        final Size desiredSize = new Size(width, height);\n\n        // Collect the supported resolutions that are at least as big as the preview Surface\n        boolean exactSizeFound = false;\n        final List<Size> bigEnough = new ArrayList<Size>();\n        final List<Size> tooSmall = new ArrayList<Size>();\n        for (final Size option : choices) {\n            if (option.equals(desiredSize)) {\n                // Set the size but don't return yet so that remaining sizes will still be logged.\n                exactSizeFound = true;\n            }\n\n            if (option.getHeight() >= minSize && option.getWidth() >= minSize) {\n                bigEnough.add(option);\n            } else {\n                tooSmall.add(option);\n            }\n        }\n\n        Log.d(TAG, \"Desired size: \" + desiredSize + \", min size: \" + minSize + \"x\" + minSize);\n        Log.d(TAG, \"Valid preview sizes: [\" + TextUtils.join(\", \", bigEnough) + \"]\");\n        Log.d(TAG, \"Rejected preview sizes: [\" + TextUtils.join(\", \", tooSmall) + \"]\");\n\n        if (exactSizeFound) {\n            Log.d(TAG, \"Exact size match found.\");\n            return desiredSize;\n        }\n\n        // Pick the smallest of those, assuming we found any\n        if (bigEnough.size() > 0) {\n            final Size chosenSize = Collections.min(bigEnough, new CompareSizesByArea());\n            Log.d(TAG, \"Chosen size: \" + chosenSize.getWidth() + \"x\" + chosenSize.getHeight());\n            return chosenSize;\n        } else {\n            Log.e(TAG, \"Couldn't find any suitable preview size\");\n            return choices[0];\n        }\n    }\n\n    public static CameraConnectionFragment newInstance(\n            final ConnectionCallback callback,\n            final OnImageAvailableListener imageListener,\n            final int layout,\n            final Size inputSize) {\n        return new CameraConnectionFragment(callback, imageListener, layout, inputSize);\n    }\n\n    @Override\n    public View onCreateView(\n            final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {\n        return inflater.inflate(layout, container, false);\n    }\n\n    @Override\n    public void onViewCreated(final View view, final Bundle savedInstanceState) {\n        textureView = (AutoFitTextureView) view.findViewById(R.id.texture);\n    }\n\n    @Override\n    public void onActivityCreated(final Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n    }\n\n    @Override\n    public void onResume() {\n        super.onResume();\n        startBackgroundThread();\n\n        // When the screen is turned off and turned back on, the SurfaceTexture is already\n        // available, and \"onSurfaceTextureAvailable\" will not be called. In that case, we can open\n        // a camera and start preview from here (otherwise, we wait until the surface is ready in\n        // the SurfaceTextureListener).\n        if (textureView.isAvailable()) {\n            openCamera(textureView.getWidth(), textureView.getHeight());\n        } else {\n            textureView.setSurfaceTextureListener(surfaceTextureListener);\n        }\n    }\n\n    @Override\n    public void onPause() {\n        closeCamera();\n        stopBackgroundThread();\n        super.onPause();\n    }\n\n    public void setCamera(String cameraId) {\n        this.cameraId = cameraId;\n    }\n\n    /**\n     * Sets up member variables related to camera.\n     */\n    private void setUpCameraOutputs() {\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            final CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\n\n            final StreamConfigurationMap map =\n                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n\n            // For still image captures, we use the largest available size.\n            final Size largest =\n                    Collections.max(\n                            Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),\n                            new CompareSizesByArea());\n\n            sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);\n\n            // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera\n            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of\n            // garbage capture data.\n            previewSize =\n                    chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),\n                            inputSize.getWidth(),\n                            inputSize.getHeight());\n        } catch (final CameraAccessException e) {\n            Log.e(TAG,  \"Exception!\" + e);\n        } catch (final NullPointerException e) {\n            // Currently an NPE is thrown when the Camera2API is used but not supported on the\n            // device this code runs.\n            // TODO(andrewharp): abstract ErrorDialog/RuntimeException handling out into new method and\n            // reuse throughout app.\n            ErrorDialog.newInstance(getString(R.string.camera_error))\n                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);\n            throw new RuntimeException(getString(R.string.camera_error));\n        }\n\n        Size textureViewSize = new Size(textureView.getWidth(), textureView.getHeight());\n        cameraConnectionCallback.onPreviewSizeChosen(previewSize, textureViewSize, sensorOrientation);\n    }\n\n    /**\n     * Opens the camera specified by {@link CameraConnectionFragment#cameraId}.\n     */\n    private void openCamera(final int width, final int height) {\n        setUpCameraOutputs();\n        configureTransform(width, height);\n        final Activity activity = getActivity();\n        final CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n        try {\n            if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\n                throw new RuntimeException(\"Time out waiting to lock camera opening.\");\n            }\n            manager.openCamera(cameraId, stateCallback, backgroundHandler);\n        } catch (final CameraAccessException | SecurityException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\n        }\n    }\n\n    /**\n     * Closes the current {@link CameraDevice}.\n     */\n    private void closeCamera() {\n        try {\n            cameraOpenCloseLock.acquire();\n            if (null != captureSession) {\n                captureSession.close();\n                captureSession = null;\n            }\n            if (null != cameraDevice) {\n                cameraDevice.close();\n                cameraDevice = null;\n            }\n            if (null != previewReader) {\n                previewReader.close();\n                previewReader = null;\n            }\n        } catch (final InterruptedException e) {\n            throw new RuntimeException(\"Interrupted while trying to lock camera closing.\", e);\n        } finally {\n            cameraOpenCloseLock.release();\n        }\n    }\n\n    /**\n     * Starts a background thread and its {@link Handler}.\n     */\n    private void startBackgroundThread() {\n        backgroundThread = new HandlerThread(\"ImageListener\");\n        backgroundThread.start();\n        backgroundHandler = new Handler(backgroundThread.getLooper());\n    }\n\n    /**\n     * Stops the background thread and its {@link Handler}.\n     */\n    private void stopBackgroundThread() {\n        backgroundThread.quitSafely();\n        try {\n            backgroundThread.join();\n            backgroundThread = null;\n            backgroundHandler = null;\n        } catch (final InterruptedException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    private final CameraCaptureSession.CaptureCallback captureCallback =\n            new CameraCaptureSession.CaptureCallback() {\n                @Override\n                public void onCaptureProgressed(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final CaptureResult partialResult) {\n                }\n\n                @Override\n                public void onCaptureCompleted(\n                        final CameraCaptureSession session,\n                        final CaptureRequest request,\n                        final TotalCaptureResult result) {\n                }\n            };\n\n    /**\n     * Creates a new {@link CameraCaptureSession} for camera preview.\n     */\n    private void createCameraPreviewSession() {\n        try {\n            final SurfaceTexture texture = textureView.getSurfaceTexture();\n            assert texture != null;\n\n            // We configure the size of default buffer to be the size of camera preview we want.\n            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());\n\n            // This is the output Surface we need to start preview.\n            final Surface surface = new Surface(texture);\n\n            // We set up a CaptureRequest.Builder with the output Surface.\n            previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\n            previewRequestBuilder.addTarget(surface);\n\n            Log.i(TAG, \"Opening camera preview: \" + previewSize.getWidth() + \"x\" + previewSize.getHeight());\n\n            // Create the reader for the preview frames.\n            previewReader =\n                    ImageReader.newInstance(\n                            previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);\n\n            previewReader.setOnImageAvailableListener(imageListener, backgroundHandler);\n            previewRequestBuilder.addTarget(previewReader.getSurface());\n\n            // Here, we create a CameraCaptureSession for camera preview.\n            cameraDevice.createCaptureSession(\n                    Arrays.asList(surface, previewReader.getSurface()),\n                    new CameraCaptureSession.StateCallback() {\n\n                        @Override\n                        public void onConfigured(final CameraCaptureSession cameraCaptureSession) {\n                            // The camera is already closed\n                            if (null == cameraDevice) {\n                                return;\n                            }\n\n                            // When the session is ready, we start displaying the preview.\n                            captureSession = cameraCaptureSession;\n                            try {\n                                // Auto focus should be continuous for camera preview.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AF_MODE,\n                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\n                                // Flash is automatically enabled when necessary.\n                                previewRequestBuilder.set(\n                                        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);\n\n                                // Finally, we start displaying the camera preview.\n                                previewRequest = previewRequestBuilder.build();\n                                captureSession.setRepeatingRequest(\n                                        previewRequest, captureCallback, backgroundHandler);\n                            } catch (final CameraAccessException e) {\n                                Log.e(TAG, \"Exception!\" + e);\n                            }\n                        }\n\n                        @Override\n                        public void onConfigureFailed(final CameraCaptureSession cameraCaptureSession) {\n                            showToast(\"Failed\");\n                        }\n                    },\n                    null);\n        } catch (final CameraAccessException e) {\n            Log.e(TAG, \"Exception!\" + e);\n        }\n    }\n\n    /**\n     * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.\n     * This method should be called after the camera preview size is determined in\n     * setUpCameraOutputs and also the size of `mTextureView` is fixed.\n     *\n     * @param viewWidth  The width of `mTextureView`\n     * @param viewHeight The height of `mTextureView`\n     */\n    private void configureTransform(final int viewWidth, final int viewHeight) {\n        final Activity activity = getActivity();\n        if (null == textureView || null == previewSize || null == activity) {\n            return;\n        }\n        final int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();\n        final Matrix matrix = new Matrix();\n        final RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);\n        final RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());\n        final float centerX = viewRect.centerX();\n        final float centerY = viewRect.centerY();\n        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {\n            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());\n            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);\n            final float scale =\n                    Math.max(\n                            (float) viewHeight / previewSize.getHeight(),\n                            (float) viewWidth / previewSize.getWidth());\n            matrix.postScale(scale, scale, centerX, centerY);\n            matrix.postRotate(90 * (rotation - 2), centerX, centerY);\n        } else if (Surface.ROTATION_180 == rotation) {\n            matrix.postRotate(180, centerX, centerY);\n        }\n        textureView.setTransform(matrix);\n    }\n\n    /**\n     * Compares two {@code Size}s based on their areas.\n     */\n    static class CompareSizesByArea implements Comparator<Size> {\n        @Override\n        public int compare(final Size lhs, final Size rhs) {\n            // We cast here to ensure the multiplications won't overflow\n            return Long.signum(\n                    (long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());\n        }\n    }\n\n    /**\n     * Shows an error message dialog.\n     */\n    public static class ErrorDialog extends DialogFragment {\n        private static final String ARG_MESSAGE = \"message\";\n\n        public static ErrorDialog newInstance(final String message) {\n            final ErrorDialog dialog = new ErrorDialog();\n            final Bundle args = new Bundle();\n            args.putString(ARG_MESSAGE, message);\n            dialog.setArguments(args);\n            return dialog;\n        }\n\n        @Override\n        public Dialog onCreateDialog(final Bundle savedInstanceState) {\n            final Activity activity = getActivity();\n            return new AlertDialog.Builder(activity)\n                    .setMessage(getArguments().getString(ARG_MESSAGE))\n                    .setPositiveButton(\n                            android.R.string.ok,\n                            new DialogInterface.OnClickListener() {\n                                @Override\n                                public void onClick(final DialogInterface dialogInterface, final int i) {\n                                    activity.finish();\n                                }\n                            })\n                    .create();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/java/ai/fritz/camera/MainActivity.java",
    "content": "package ai.fritz.camera;\n\nimport android.graphics.Bitmap;\nimport android.graphics.RectF;\nimport android.media.Image;\nimport android.media.ImageReader;\nimport android.os.Bundle;\nimport android.util.Size;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.ProgressBar;\nimport android.widget.RelativeLayout;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport ai.fritz.core.Fritz;\nimport ai.fritz.poseestimationdemo.R;\nimport ai.fritz.vision.FritzVision;\nimport ai.fritz.vision.FritzVisionImage;\nimport ai.fritz.vision.FritzVisionModels;\nimport ai.fritz.vision.FritzVisionOrientation;\nimport ai.fritz.vision.ImageOrientation;\nimport ai.fritz.vision.ModelVariant;\nimport ai.fritz.vision.poseestimation.FritzVisionPosePredictor;\nimport ai.fritz.vision.poseestimation.FritzVisionPoseResult;\nimport ai.fritz.vision.poseestimation.HumanSkeleton;\nimport ai.fritz.vision.poseestimation.Pose;\nimport ai.fritz.vision.poseestimation.PoseOnDeviceModel;\n\n\npublic class MainActivity extends BaseCameraActivity implements ImageReader.OnImageAvailableListener {\n\n    private static final Size DESIRED_PREVIEW_SIZE = new Size(1280, 960);\n\n    private AtomicBoolean isComputing = new AtomicBoolean(false);\n    private AtomicBoolean shouldSample = new AtomicBoolean(true);\n    private ImageOrientation orientation;\n\n    FritzVisionPoseResult poseResult;\n    FritzVisionPosePredictor predictor;\n    FritzVisionImage visionImage;\n\n    // Preview Frame\n    RelativeLayout previewFrame;\n    Button snapshotButton;\n    ProgressBar snapshotProcessingSpinner;\n\n    // Snapshot Frame\n    RelativeLayout snapshotFrame;\n    OverlayView snapshotOverlay;\n    Button closeButton;\n    Button recordButton;\n    ProgressBar recordSpinner;\n\n\n    @Override\n    public void onCreate(final Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        Fritz.configure(this);\n        // The code below loads a custom trained pose estimation model and creates a predictor that will be used to identify poses in live video.\n        // Custom pose estimation models can be trained with the Fritz AI platform. To use a pre-trained pose estimation model,\n        // see the FritzAIStudio demo in this repo.\n        PoseOnDeviceModel poseEstimationOnDeviceModel = PoseOnDeviceModel.buildFromModelConfigFile(\"pose_recording_model.json\", new HumanSkeleton());\n        predictor = FritzVision.PoseEstimation.getPredictor(poseEstimationOnDeviceModel);\n    }\n\n    @Override\n    protected int getLayoutId() {\n        return R.layout.main_camera;\n    }\n\n    @Override\n    protected Size getDesiredPreviewFrameSize() {\n        return DESIRED_PREVIEW_SIZE;\n    }\n\n    @Override\n    public void onPreviewSizeChosen(final Size previewSize, final Size cameraViewSize, final int rotation) {\n        orientation = FritzVisionOrientation.getImageOrientationFromCamera(this, cameraId);\n\n        // Preview View\n        previewFrame = findViewById(R.id.preview_frame);\n        snapshotProcessingSpinner = findViewById(R.id.snapshot_spinner);\n        snapshotButton = findViewById(R.id.take_picture_btn);\n        snapshotButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                if (!shouldSample.compareAndSet(true, false)) {\n                    return;\n                }\n\n                runInBackground(\n                        () -> {\n                            showSpinner();\n                            snapshotOverlay.postInvalidate();\n                            switchToSnapshotView();\n                            hideSpinner();\n                        });\n            }\n        });\n        setCallback(canvas -> {\n            if (poseResult != null) {\n                for (Pose pose : poseResult.getPoses()) {\n                    pose.draw(canvas);\n                }\n            }\n            isComputing.set(false);\n        });\n\n        // Snapshot View\n        snapshotFrame = findViewById(R.id.snapshot_frame);\n        snapshotOverlay = findViewById(R.id.snapshot_view);\n        snapshotOverlay.setCallback(\n                canvas -> {\n                    if (poseResult != null) {\n                        Bitmap bitmap = visionImage.overlaySkeletons(poseResult.getPoses());\n                        canvas.drawBitmap(bitmap, null, new RectF(0, 0, cameraViewSize.getWidth(), cameraViewSize.getHeight()), null);\n                    }\n                });\n\n        recordSpinner = findViewById(R.id.record_spinner);\n        recordButton = findViewById(R.id.record_prediction_btn);\n        recordButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                recordSpinner.setVisibility(View.VISIBLE);\n                // To record predictions and send data back to Fritz AI via the Data Collection System, use the predictors's record method.\n                // In addition to the input image, predicted model results can be collected as well as user-modified annotations.\n                // This allows developers to both gather data on model performance and have users collect additional ground truth data for future model retraining.\n                // Note, the Data Collection System is only available on paid plans.\n                predictor.record(visionImage, poseResult, null, () -> {\n                    switchPreviewView();\n                    return null;\n                }, () -> {\n                    switchPreviewView();\n                    return null;\n                });\n            }\n        });\n        closeButton = findViewById(R.id.close_btn);\n        closeButton.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                switchPreviewView();\n            }\n        });\n\n    }\n\n    private void switchToSnapshotView() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                previewFrame.setVisibility(View.GONE);\n                snapshotFrame.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void switchPreviewView() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                recordSpinner.setVisibility(View.GONE);\n                snapshotFrame.setVisibility(View.GONE);\n                previewFrame.setVisibility(View.VISIBLE);\n                shouldSample.set(true);\n            }\n        });\n    }\n\n    private void showSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.VISIBLE);\n            }\n        });\n    }\n\n    private void hideSpinner() {\n        runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                snapshotProcessingSpinner.setVisibility(View.GONE);\n            }\n        });\n    }\n\n    @Override\n    public void onImageAvailable(final ImageReader reader) {\n        Image image = reader.acquireLatestImage();\n\n        if (image == null) {\n            return;\n        }\n\n        if (!shouldSample.get()) {\n            image.close();\n            return;\n        }\n\n        if (!isComputing.compareAndSet(false, true)) {\n            image.close();\n            return;\n        }\n\n        visionImage = FritzVisionImage.fromMediaImage(image, orientation);\n        image.close();\n\n        runInBackground(() -> {\n            poseResult = predictor.predict(visionImage);\n            requestRender();\n        });\n    }\n}\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/java/ai/fritz/camera/OverlayView.java",
    "content": "package ai.fritz.camera;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.util.AttributeSet;\nimport android.view.View;\n\n/**\n * A simple View providing a render callback to other classes.\n */\npublic class OverlayView extends View {\n    private DrawCallback callback;\n\n    public OverlayView(final Context context, final AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    /**\n     * Interface defining the callback for client classes.\n     */\n    public interface DrawCallback {\n        void drawCallback(final Canvas canvas);\n    }\n\n    public void setCallback(final DrawCallback callback) {\n        this.callback = callback;\n    }\n\n    @Override\n    public synchronized void draw(final Canvas canvas) {\n        super.draw(canvas);\n        if(callback != null) {\n            callback.drawCallback(canvas);\n        }\n    }\n}"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/drawable/ic_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24.0\"\n    android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        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\"/>\n</vector>"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/drawable/round_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"oval\">\n    <stroke\n        android:color=\"#FFFF\"\n        android:width=\"5dip\"/>\n    <size android:width=\"100dp\" android:height=\"100dp\"/>\n</shape>"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        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\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/layout/activity_main.xml",
    "content": "<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <FrameLayout\n        android:id=\"@+id/camera_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n</android.support.constraint.ConstraintLayout>"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/layout/camera_connection_fragment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <ai.fritz.camera.AutoFitTextureView\n        android:id=\"@+id/texture\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"/>\n\n    <ai.fritz.camera.OverlayView\n        android:id=\"@+id/debug_overlay\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\"/>\n</RelativeLayout>\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/layout/main_camera.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:id=\"@+id/preview_frame\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n        <ai.fritz.camera.AutoFitTextureView\n            android:id=\"@+id/texture\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\" />\n        <ai.fritz.camera.OverlayView\n            android:id=\"@+id/debug_overlay\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_alignParentTop=\"true\"/>\n    </RelativeLayout>\n\n    <include layout=\"@layout/snapshot_button\" />\n    <include layout=\"@layout/snapshot_overlay_frame\" />\n</RelativeLayout>\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/layout/snapshot_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_alignParentBottom=\"true\"\n    android:layout_marginTop=\"@dimen/margin_sm\"\n    android:layout_marginBottom=\"@dimen/margin_lg\">\n\n    <Button\n        android:id=\"@+id/take_picture_btn\"\n        android:layout_width=\"80dp\"\n        android:layout_height=\"80dp\"\n        android:layout_centerInParent=\"true\"\n        android:background=\"@drawable/round_button\"\n        android:textColor=\"#fff\" />\n\n    <ProgressBar\n        android:id=\"@+id/snapshot_spinner\"\n        style=\"?android:attr/progressBarStyleLarge\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:indeterminateTint=\"#fff\"\n        android:visibility=\"gone\" />\n</RelativeLayout>"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/layout/snapshot_overlay_frame.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/snapshot_frame\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:visibility=\"gone\">\n\n    <ai.fritz.camera.OverlayView\n        android:id=\"@+id/snapshot_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_alignParentTop=\"true\" />\n\n    <ProgressBar\n        android:id=\"@+id/record_spinner\"\n        style=\"?android:attr/progressBarStyleLarge\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:indeterminateTint=\"#fff\"\n        android:visibility=\"gone\" />\n\n    <Button\n        android:id=\"@+id/record_prediction_btn\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentBottom=\"true\"\n        android:background=\"@color/colorPrimary\"\n        android:paddingTop=\"15dp\"\n        android:paddingBottom=\"15dp\"\n        android:text=\"Record Prediction\"\n        android:textAlignment=\"gravity\"\n        android:textColor=\"#fff\"\n        android:textStyle=\"bold\" />\n\n    <Button\n        android:id=\"@+id/close_btn\"\n        android:layout_width=\"50dp\"\n        android:layout_height=\"50dp\"\n        android:layout_alignParentTop=\"true\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_marginTop=\"@dimen/margin_sm\"\n        android:layout_marginRight=\"@dimen/margin_sm\"\n        android:background=\"@drawable/ic_close\" />\n\n</RelativeLayout>"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/values/dimens.xml",
    "content": "<!--\n  Copyright 2013 The Android Open Source Project\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n\n<resources>\n\n    <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->\n\n    <dimen name=\"margin_xs\">4dp</dimen>\n    <dimen name=\"margin_sm\">8dp</dimen>\n    <dimen name=\"margin_md\">16dp</dimen>\n    <dimen name=\"margin_lg\">32dp</dimen>\n    <dimen name=\"margin_xl\">64dp</dimen>\n\n    <!-- Semantic definitions -->\n\n    <dimen name=\"horizontal_page_margin\">@dimen/margin_md</dimen>\n    <dimen name=\"vertical_page_margin\">@dimen/margin_md</dimen>\n\n</resources>"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/values/fritz.xml",
    "content": "<resources>\n    <string name=\"fritz_api_key\">Your API Key</string>\n</resources>\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Pose Estimation App</string>\n    <string name=\"camera_error\">This device doesn\\'t support Camera2 API.</string>\n</resources>\n"
  },
  {
    "path": "Android/PoseEstimationApp/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "Android/PoseEstimationApp/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.6.0'\n\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n\n        // ADD FOR FRITZ DEPENDENCIES\n        maven { url \"https://fritz.mycloudrepo.io/public/repositories/android\" }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "Android/PoseEstimationApp/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n\n"
  },
  {
    "path": "Android/PoseEstimationApp/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/PoseEstimationApp/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "Android/PoseEstimationApp/settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "Android/README.md",
    "content": "# Examples for Android\n\n[ ![Codeship Status for fritzlabs/fritz-sdk-android](https://app.codeship.com/projects/c74152e0-65d1-0136-2d69-32e87736c6c6/status?branch=master)](https://app.codeship.com/projects/297281)\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. [Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to see how you can include machine learning features in your app.\n\n**Vision API: Prebuilt models that you can simply drop into your apps:**\n\n- [Image Segmentation](https://www.fritz.ai/features/image-segmentation.html?utm_source=github&utm_campaign=fritz-examples): Create pixel level masks of different objects in a scene. ([code](HeartbeatDemoApp/app/src/main/java/ai/fritz/aistudio/activities/vision/ImageSegmentationActivity.java))\n- [Image Labeling](https://www.fritz.ai/features/image-labeling.html?utm_source=github&utm_campaign=fritz-examples): Classify different objects in an video or image.([code](HeartbeatDemoApp/app/src/main/java/ai/fritz/aistudio/activities/vision/ImageLabelingActivity.java))\n- [Pose Estimation](https://www.fritz.ai/features/pose-estimation.html?utm_source=github&utm_campaign=fritz-examples): Identify and track a person's body position.([code](HeartbeatDemoApp/app/src/main/java/ai/fritz/aistudio/activities/vision/PoseEstimationActivity.java))\n- [Object Detection](https://www.fritz.ai/features/object-detection.html?utm_source=github&utm_campaign=fritz-examples): Detect multiple objects and track their location.([code](HeartbeatDemoApp/app/src/main/java/ai/fritz/aistudio/activities/vision/ObjectDetectionActivity.java))\n- [Style Transfer](https://www.fritz.ai/features/style-transfer.html?utm_source=github&utm_campaign=fritz-examples): Transform photos and videos into artistic masterpieces.([code](HeartbeatDemoApp/app/src/main/java/ai/fritz/aistudio/activities/vision/StyleTransferActivity.java))\n\n**Custom Models: Deploy, Monitor, and Update your own models:**\n\nWe currently support both TensorFlow Lite ([code](HeartbeatDemoApp/app/src/main/java/ai/fritz/aistudio/activities/custommodel/CustomTFLiteActivity.java)) and TensorFlow Mobile ([code]([HeartbeatDemoApp/app/src/main/java/ai/fritz/aistudio/activities/custommodel/CustomTFMobileActivity.java)) for Android.\n\n- [Analytics and Monitoring](https://www.fritz.ai/features/analytics-monitoring.html?utm_source=github&utm_campaign=fritz-examples): Monitor machine learning models running on-device with Fritz.\n- [Model Management](https://www.fritz.ai/features/model-management.html?utm_source=github&utm_campaign=fritz-examples): Iterate on your ML models over-the-air, without having to release your app.\n- [Model Protection](https://www.fritz.ai/features/model-protection.html?utm_source=github&utm_campaign=fritz-examples): Use model protection to keep models from being tampered-with or stolen.\n\n## Example Apps\n\nIf you are new to Fritz, it's recommended to get started with our Fritz AI Studio app. You can also install the latest version from the [Google Play Store](https://play.google.com/store/apps/details?id=ai.fritz.heartbeat&hl=en_US):\n\n- Fritz AI Studio App - Our kitchen sink project showcases all on-device Vision APIs and Custom Model usage.\n- Camera Boilerplate App - Our lightweight camera app to quickly get started implementing features with the camera.\n- Background Replacement App [People Segmentation] - An example app to replace the background of portraits ([tutorial](https://heartbeat.fritz.ai/image-segmentation-for-android-smart-background-replacement-with-fritz-a09d8b0592a4)).\n- Sky Animation App [Sky Segmentation] - A simple photo app that replaces the sky with an animation. (Tutorial coming soon)\n- Hair Coloring App [Hair Segmentation] - An example app to replace a user's hair color ([tutorial](https://heartbeat.fritz.ai/embrace-your-new-look-with-hair-segmentation-by-fritz-now-available-for-android-developers-f20f5b4e9ae1)).\n- Pet Monitoring App [Object Detection] - An example app to track dogs and cats with the camera ([tutorial](https://medium.freecodecamp.org/a-guide-to-object-detection-with-fritz-build-a-pet-monitoring-app-in-android-with-machine-learning-a8ed500978e5)).\n- Pet Sticker App [Pose Estimation] - Create a sticker from photos of your pets. (Tutorial coming soon)\n- Pose Estimation App [Pose Estimation] - Track body movements and position with Pose Estimation ([tutorial](https://heartbeat.fritz.ai/pose-estimation-on-android-with-fritz-474e646dfede?utm_source=github&utm_campaign=fritz-examples)).\n\n## Latest SDK version\n\n- Fritz Android SDK 3.3.1\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[Android API Docs](https://docs.fritz.ai/android/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 Fritz Labs Incorporated\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Fritz Examples\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Explore our [pre-trained APIs](https://www.fritz.ai/product/pretrained.html?utm_source=github&utm_campaign=fritz-examples) to get started quickly, or check out [Fritz AI Studio](https://www.fritz.ai/product/studio.html?utm_source=github&utm_campaign=fritz-examples) to build and deploy custom models.\n\nIf you're ready to sart building, [sign up](https://fritz.ai/pricing?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to see how you can include machine learning features in your apps.\n\nBelow, you'll find code examples for the different SDKs we offer:\n\n- [iOS](iOS)\n- [Android](Android)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples)\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Visit our [Support Forum](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "SnapLensStudio/README.md",
    "content": "# Snap Lens Studio Examples\nThis repository contains Snap Lens Studio example projects.\n\nTo use a project, download the zip file above, extract the project, and open\nthe project file in Snap Lens Studio."
  },
  {
    "path": "iOS/.gitignore",
    "content": "#### CocoaPods\nPods/\n*.generated.swift\n\n#### macOS\n.DS_Store\n\n#### Xcode\nxcuserdata/\n*.xcworkspace\n*.zip\n*.ipa\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Media/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-20x20@2x-1.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-20x20@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-29x29@2x-1.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-29x29@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-40x40@2x-1.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-40x40@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"60x60\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-60x60@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"60x60\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-60x60@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-20x20@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-20x20@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-29x29@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-29x29@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-40x40@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-40x40@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"76x76\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-76x76@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"76x76\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-76x76@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"83.5x83.5\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-83.5x83.5@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"1024x1024\",\n      \"idiom\" : \"ios-marketing\",\n      \"filename\" : \"iTunesArtwork@2x.png\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  },\n  \"properties\" : {\n    \"pre-rendered\" : true\n  }\n}"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Media/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Media/Assets.xcassets/SettingsIcon.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"settings-48.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"settings-72.png\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Media/Assets.xcassets/fritzLogo.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"fritz_logo_01.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"fritz_logo_01@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"fritz_logo_01@3x.png\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Media/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14868\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <device id=\"retina4_7\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14824\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView userInteractionEnabled=\"NO\" contentMode=\"center\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" image=\"fritzLogo\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"2GP-9i-tWs\">\n                                <rect key=\"frame\" x=\"87.5\" y=\"233.5\" width=\"200\" height=\"200\"/>\n                            </imageView>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <constraints>\n                            <constraint firstItem=\"2GP-9i-tWs\" firstAttribute=\"centerY\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"centerY\" id=\"7t9-FH-GI2\"/>\n                            <constraint firstItem=\"2GP-9i-tWs\" firstAttribute=\"centerX\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"centerX\" id=\"aVU-Q2-7Eo\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"fritzLogo\" width=\"200\" height=\"200\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Delegate/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  Fritz Labs\n//\n//  Created by Andrew Barba on 12/12/17.\n//  Copyright © 2017 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\nimport Crashlytics\nimport Fabric\nimport FritzCore\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n\n    // Configure crash reporting\n    Fabric.with([Crashlytics.self])\n\n    // Configure Fritz models\n    // FritzCore.setLogLevel(.debug)\n    FritzCore.configure()\n\n    return true\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCamera/Delegates/CameraAVCaptureVideoDelegate.swift",
    "content": "//\n//  FritzCamera+AVCaptureVideoDelegate.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/20/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\nimport AVFoundation\n\n\nextension FritzCamera: AVCaptureVideoDataOutputSampleBufferDelegate {\n\n  public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {\n\n    let image = FritzVisionImage(sampleBuffer: sampleBuffer, connection: connection)\n\n    self.delegate?.capture(self, didCaptureFritzImage: image, timestamp: Date())\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCamera/Delegates/CapturePhotoDelgate.swift",
    "content": "//\n//  CapturePhotoDelgate.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/23/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport AVFoundation\nimport Photos\nimport Fritz\n\n\n\nextension FritzCamera: AVCapturePhotoCaptureDelegate {\n\n  func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {\n    guard let pixelBuffer = photo.pixelBuffer else { return }\n\n    // Gets the CGOrientation of the photo\n    let imageOrientation = photo.getImageOrientation(forCamera: position)\n\n    let image = FritzVisionImage(imageBuffer: pixelBuffer)\n    image.metadata = FritzVisionImageMetadata()\n    image.metadata?.orientation = FritzImageOrientation(imageOrientation)\n\n    guard let output = try? delegate?.processPhoto(self, didCaptureFritzImage: image, timestamp: Date()),\n      let jpegData = output.jpegData(compressionQuality: 1.0)\n    else { return }\n\n    // Save JPEG to photo library\n    PHPhotoLibrary.requestAuthorization { status in\n      if status == .authorized {\n        PHPhotoLibrary.shared().performChanges({\n          let creationRequest = PHAssetCreationRequest.forAsset()\n          creationRequest.addResource(with: .photo, data: jpegData, options: nil)\n        }, completionHandler: { _, error in\n          if let error = error {\n            print(\"Error occurred while saving photo to photo library: \\(error)\")\n          }\n        })\n      }\n    }\n  }\n\n\n\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCamera/Extensions/AVPhotoExtension.swift",
    "content": "//\n//  CapturePhotoExtension.swift\n//  Lumina\n//\n//  Created by David Okun on 11/20/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport Foundation\nimport AVFoundation\nimport UIKit\n\n\nextension AVCapturePhoto {\n  func normalizedImage(forCameraPosition position: AVCaptureDevice.Position) -> UIImage? {\n    FritzLogger.notice(message: \"normalizing image from AVCapturePhoto instance\")\n    guard let cgImage = self.cgImageRepresentation() else {\n      return nil\n    }\n    return UIImage(cgImage: cgImage.takeUnretainedValue(), scale: 1.0, orientation: getImageOrientation(forCamera: position))\n  }\n\n  func getImageOrientation(forCamera: AVCaptureDevice.Position) -> UIImage.Orientation {\n    switch UIApplication.shared.statusBarOrientation {\n    case .landscapeLeft:\n      return forCamera == .back ? .down : .upMirrored\n    case .landscapeRight:\n      return forCamera == .back ? .up : .downMirrored\n    case .portraitUpsideDown:\n      return forCamera == .back ? .left : .rightMirrored\n    case .portrait:\n      return forCamera == .back ? .right : .leftMirrored\n    case .unknown:\n      return forCamera == .back ? .right : .leftMirrored\n    @unknown default:\n      return forCamera == .back ? .right : .leftMirrored\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCamera/Extensions/CameraResolutionExtension.swift",
    "content": "//\n//  CameraResolutions.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/20/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\n\nimport CoreMedia\nimport AVFoundation\n\n/// The resolution to set the camera to at any time - refer to AVCaptureSession.Preset definitions for matching, closest as of iOS 11\npublic enum CameraResolution: String {\n  case low352x288 = \"Low 352x288\"\n  case vga640x480 = \"VGA 640x480\"\n  case medium1280x720 = \"Medium 1280x720\"\n  case high1920x1080 = \"HD 1920x1080\"\n  case ultra3840x2160 = \"4K 3840x2160\"\n  case iframe1280x720 = \"iFrame 1280x720\"\n  case iframe960x540 = \"iFrame 960x540\"\n  case photo = \"Photo\"\n  case lowest = \"Lowest\"\n  case medium = \"Medium\"\n  case highest = \"Highest\"\n  case inputPriority = \"Input Priority\"\n\n  public static func all() -> [CameraResolution] {\n    return [CameraResolution.low352x288, CameraResolution.vga640x480, CameraResolution.medium1280x720, CameraResolution.high1920x1080, CameraResolution.ultra3840x2160, CameraResolution.iframe1280x720, CameraResolution.iframe960x540, CameraResolution.photo, CameraResolution.lowest, CameraResolution.medium, CameraResolution.highest, CameraResolution.inputPriority]\n  }\n\n  // swiftlint:disable cyclomatic_complexity\n  func foundationPreset() -> AVCaptureSession.Preset {\n    switch self {\n    case .vga640x480:\n      return AVCaptureSession.Preset.vga640x480\n    case .low352x288:\n      return AVCaptureSession.Preset.cif352x288\n    case .medium1280x720:\n      return AVCaptureSession.Preset.hd1280x720\n    case .high1920x1080:\n      return AVCaptureSession.Preset.hd1920x1080\n    case .ultra3840x2160:\n      return AVCaptureSession.Preset.hd4K3840x2160\n    case .iframe1280x720:\n      return AVCaptureSession.Preset.iFrame1280x720\n    case .iframe960x540:\n      return AVCaptureSession.Preset.iFrame960x540\n    case .photo:\n      return AVCaptureSession.Preset.photo\n    case .lowest:\n      return AVCaptureSession.Preset.low\n    case .medium:\n      return AVCaptureSession.Preset.medium\n    case .highest:\n      return AVCaptureSession.Preset.high\n    case .inputPriority:\n      return AVCaptureSession.Preset.inputPriority\n    }\n  }\n\n  func getDimensions() -> CMVideoDimensions {\n    switch self {\n    case .vga640x480:\n      return CMVideoDimensions(width: 640, height: 480)\n    case .low352x288:\n      return CMVideoDimensions(width: 352, height: 288)\n    case .medium1280x720, .iframe1280x720, .medium:\n      return CMVideoDimensions(width: 1280, height: 720)\n    case .high1920x1080, .highest:\n      return CMVideoDimensions(width: 1920, height: 1080)\n    case .ultra3840x2160:\n      return CMVideoDimensions(width: 3840, height: 2160)\n    case .iframe960x540:\n      return CMVideoDimensions(width: 960, height: 540)\n    case .photo:\n      return CMVideoDimensions(width: INT32_MAX, height: INT32_MAX)\n    case .lowest:\n      return CMVideoDimensions(width: 352, height: 288)\n    case .inputPriority:\n      return CMVideoDimensions(width: INT32_MAX, height: INT32_MAX)\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCamera/Extensions/CameraSessionExtensions.swift",
    "content": "//\n//  FritzCamera+Session.swift\n//\n\nimport Foundation\nimport AVFoundation\n\nextension FritzCamera {\n\n  func requestVideoPermissions() {\n    self.sessionQueue.suspend()\n    AVCaptureDevice.requestAccess(for: .video) { success in\n      if success {\n        FritzLogger.notice(message: \"successfully enabled video permissions\")\n        self.sessionQueue.resume()\n        self.delegate?.cameraSetupCompleted(camera: self, result: .requiresUpdate)\n      } else {\n        self.delegate?.cameraSetupCompleted(camera: self, result: .videoPermissionDenied)\n      }\n    }\n  }\n\n  func updateOutputVideoOrientation(_ orientation: AVCaptureVideoOrientation) {\n    FritzLogger.notice(message: \"Updating output video orientation\")\n    self.sessionQueue.async {\n      for output in self.session.outputs {\n        guard let connection = output.connection(with: AVMediaType.video)\n        else {\n          continue\n        }\n        \n        if connection.isVideoMirroringSupported, self.position == .front {\n          connection.isVideoMirrored = true\n        }\n      }\n    }\n  }\n\n  func restartVideo() {\n    FritzLogger.notice(message: \"restarting video feed\")\n    if self.session.isRunning {\n      self.stop()\n      updateVideo({ result in\n        if result == .videoSuccess {\n          self.start()\n          self.delegate?.cameraRestartCompleted(camera: self, result: result)\n        } else {\n          self.delegate?.cameraSetupCompleted(camera: self, result: result)\n        }\n      })\n    }\n  }\n\n  func updateVideo(_ completion: @escaping (_ result: CameraSetupResult) -> Void) {\n    self.sessionQueue.async {\n      self.purgeVideoDevices()\n      switch AVCaptureDevice.authorizationStatus(for: AVMediaType.video) {\n      case .authorized:\n        return completion(self.videoSetupApproved())\n      case .denied:\n        return completion(CameraSetupResult.videoPermissionDenied)\n      case .notDetermined:\n        return completion(CameraSetupResult.videoRequiresAuthorization)\n      case .restricted:\n        return completion(CameraSetupResult.videoPermissionRestricted)\n      @unknown default:\n        return completion(CameraSetupResult.unknownError)\n      }\n    }\n  }\n\n  private func videoSetupApproved() -> CameraSetupResult {\n    self.session.sessionPreset = .high // set to high here so that device input can be added to session. resolution can be checked for update later\n    guard let videoInput = self.getNewVideoInputDevice() else {\n      return .invalidVideoInput\n    }\n    if let failureResult = checkSessionValidity(for: videoInput) {\n      return failureResult\n    }\n    self.videoInput = videoInput\n    self.session.addInput(videoInput)\n    self.session.addOutput(self.videoDataOutput)\n    self.session.addOutput(self.photoOutput)\n\n    self.session.commitConfiguration()\n\n    if self.session.canSetSessionPreset(self.resolution.foundationPreset()) {\n      FritzLogger.notice(message: \"creating video session with resolution: \\(self.resolution.rawValue)\")\n      self.session.sessionPreset = self.resolution.foundationPreset()\n    }\n\n    configureHiResPhotoOutput(for: self.session)\n    configureFrameRate()\n    return .videoSuccess\n  }\n\n  private func checkSessionValidity(for input: AVCaptureDeviceInput) -> CameraSetupResult? {\n    guard self.session.canAddInput(input) else {\n      FritzLogger.error(message: \"cannot add video input\")\n      return .invalidVideoInput\n    }\n    guard self.session.canAddOutput(self.videoDataOutput) else {\n      FritzLogger.error(message: \"cannot add video data output\")\n      return .invalidVideoDataOutput\n    }\n    guard self.session.canAddOutput(self.photoOutput) else {\n      FritzLogger.error(message: \"cannot add photo output\")\n      return .invalidPhotoOutput\n    }\n\n    return nil\n  }\n\n  private func configureHiResPhotoOutput(for session: AVCaptureSession) {\n    if self.captureHighResolutionImages && !self.photoOutput.isHighResolutionCaptureEnabled {\n      FritzLogger.notice(message: \"enabling high resolution photo capture\")\n      self.photoOutput.isHighResolutionCaptureEnabled = true\n    } else if !self.captureHighResolutionImages {\n      FritzLogger.error(message: \"Disabling High Resolution Camera capture\")\n      self.captureHighResolutionImages = false\n    }\n  }\n\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCamera/Extensions/FritzCamera+CaptureDeviceExtensions.swift",
    "content": "//\n//  CaptureDeviceHandlerExtension.swift\n//  Lumina\n//\n//  Created by David Okun on 11/20/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport Foundation\nimport AVFoundation\n\nextension FritzCamera {\n  func getNewVideoInputDevice() -> AVCaptureDeviceInput? {\n    do {\n      guard let device = getDevice(with: self.position == .front ? AVCaptureDevice.Position.front : AVCaptureDevice.Position.back) else {\n        // LuminaLogger.error(message: \"could not find valid AVCaptureDevice\")\n        return nil\n      }\n      let input = try AVCaptureDeviceInput(device: device)\n      return input\n    } catch {\n      return nil\n    }\n  }\n\n  func purgeVideoDevices() {\n    FritzLogger.notice(message: \"purging old video devices on capture session\")\n    for oldInput in self.session.inputs where oldInput == self.videoInput {\n      self.session.removeInput(oldInput)\n    }\n    for oldOutput in self.session.outputs {\n      if oldOutput == self.videoDataOutput || oldOutput == self.photoOutput  {\n        self.session.removeOutput(oldOutput)\n      }\n      if let dataOutput = oldOutput as? AVCaptureVideoDataOutput {\n        self.session.removeOutput(dataOutput)\n      }\n    }\n  }\n\n  func getDevice(with position: AVCaptureDevice.Position) -> AVCaptureDevice? {\n    if let device = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: position) {\n      self.currentCaptureDevice = device\n      return device\n    } else if let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: position) {\n      self.currentCaptureDevice = device\n      return device\n    }\n    return nil\n  }\n\n  func configureFrameRate() {\n    guard let device = self.currentCaptureDevice else {\n      return\n    }\n    for vFormat in device.formats {\n      let dimensions = CMVideoFormatDescriptionGetDimensions(vFormat.formatDescription)\n      let ranges = vFormat.videoSupportedFrameRateRanges as [AVFrameRateRange]\n      guard let frameRate = ranges.first else {\n        continue\n      }\n      if frameRate.maxFrameRate >= Float64(self.frameRate) &&\n        frameRate.minFrameRate <= Float64(self.frameRate) &&\n        self.resolution.getDimensions().width == dimensions.width &&\n        self.resolution.getDimensions().height == dimensions.height &&\n        CMFormatDescriptionGetMediaSubType(vFormat.formatDescription) == 875704422 { // meant for full range 420f\n        do {\n          try device.lockForConfiguration()\n          device.activeFormat = vFormat as AVCaptureDevice.Format\n          device.activeVideoMinFrameDuration = CMTimeMake(value: 1, timescale: Int32(self.frameRate))\n          device.activeVideoMaxFrameDuration = CMTimeMake(value: 1, timescale: Int32(self.frameRate))\n          device.unlockForConfiguration()\n          break\n        } catch {\n          continue\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCamera/Extensions/FritzCamera+Focus.swift",
    "content": "//\n//  FocusHandlerExtension.swift\n//  Lumina\n//\n//  Created by David Okun on 11/20/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport Foundation\nimport AVFoundation\n\nextension FritzCamera {\n  func handleFocus(at focusPoint: CGPoint) {\n    self.sessionQueue.async {\n      guard let input = self.videoInput else {\n        return\n      }\n      do {\n        if input.device.isFocusModeSupported(.autoFocus) && input.device.isFocusPointOfInterestSupported {\n          try input.device.lockForConfiguration()\n          input.device.focusMode = .autoFocus\n          input.device.focusPointOfInterest = CGPoint(x: focusPoint.x, y: focusPoint.y)\n          if input.device.isExposureModeSupported(.autoExpose) && input.device.isExposurePointOfInterestSupported {\n            input.device.exposureMode = .autoExpose\n            input.device.exposurePointOfInterest = CGPoint(x: focusPoint.x, y: focusPoint.y)\n          }\n          input.device.unlockForConfiguration()\n        } else {\n          self.delegate?.finishedFocus(camera: self)\n        }\n      } catch {\n        self.delegate?.finishedFocus(camera: self)\n      }\n    }\n  }\n\n  func resetCameraToContinuousExposureAndFocus() {\n    do {\n      guard let input = self.videoInput else {\n        FritzLogger.error(message: \"Trying to focus, but cannot detect device input!\")\n        return\n      }\n      if input.device.isFocusModeSupported(.continuousAutoFocus) {\n        try input.device.lockForConfiguration()\n        input.device.focusMode = .autoFocus\n        if input.device.isExposureModeSupported(.continuousAutoExposure) {\n          input.device.exposureMode = .continuousAutoExposure\n        }\n        input.device.unlockForConfiguration()\n      }\n    } catch {\n      FritzLogger.error(message: \"could not reset to continuous auto focus and exposure!!\")\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCamera/Extensions/PhotoCaptureExtensions.swift",
    "content": "//\n//  PhotoCaptureExtensions.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/23/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\n\nimport UIKit\nimport AVFoundation\n\n\n\nextension UIImage.Orientation {\n  func getCGOrientationFromUIImage() -> CGImagePropertyOrientation {\n    // call on top of UIImageOrientation to obtain the corresponding CGImage orientation.\n    // This is required because UIImage.imageOrientation values don't match to CGImagePropertyOrientation values\n    switch self {\n    case UIImageOrientation.down: return CGImagePropertyOrientation.down\n    case UIImageOrientation.left: return CGImagePropertyOrientation.left\n    case UIImageOrientation.right: return CGImagePropertyOrientation.right\n    case UIImageOrientation.up: return CGImagePropertyOrientation.up\n    case UIImageOrientation.downMirrored: return CGImagePropertyOrientation.downMirrored\n    case UIImageOrientation.leftMirrored: return CGImagePropertyOrientation.leftMirrored\n    case UIImageOrientation.rightMirrored: return CGImagePropertyOrientation.rightMirrored\n    case UIImageOrientation.upMirrored: return CGImagePropertyOrientation.upMirrored\n    @unknown default:\n      return CGImagePropertyOrientation.up\n    }\n  }\n}\n\nextension UIDeviceOrientation {\n  func getUIImageOrientationFromDevice() -> UIImage.Orientation {\n    // return CGImagePropertyOrientation based on Device Orientation\n    // This extented function has been determined based on experimentation with how an UIImage gets displayed.\n    switch self {\n    case UIDeviceOrientation.portrait, .faceUp: return UIImage.Orientation.right\n    case UIDeviceOrientation.portraitUpsideDown, .faceDown: return UIImage.Orientation.left\n    case UIDeviceOrientation.landscapeLeft: return UIImage.Orientation.up // this is the base orientation\n    case UIDeviceOrientation.landscapeRight: return UIImage.Orientation.down\n    case UIDeviceOrientation.unknown: return UIImage.Orientation.up\n    @unknown default:\n      return .up\n    }\n  }\n  func getAVCaptureVideoOrientationFromDevice() -> AVCaptureVideoOrientation? {\n    // return AVCaptureVideoOrientation from device\n    switch self {\n    case UIDeviceOrientation.portrait: return AVCaptureVideoOrientation.portrait\n    case UIDeviceOrientation.portraitUpsideDown: return AVCaptureVideoOrientation.portraitUpsideDown\n    case UIDeviceOrientation.landscapeLeft: return AVCaptureVideoOrientation.landscapeLeft\n    case UIDeviceOrientation.landscapeRight: return AVCaptureVideoOrientation.landscapeRight\n    case UIDeviceOrientation.faceDown: return AVCaptureVideoOrientation.portrait // not so sure about this one\n    case UIDeviceOrientation.faceUp: return AVCaptureVideoOrientation.portrait // not so sure about this one\n    case UIDeviceOrientation.unknown: return nil\n    @unknown default:\n      return nil\n    }\n  }\n}\n\n\nextension FritzCamera {\n  func captureStillImage() {\n\n    FritzLogger.info(message: \"Attempting photo capture\")\n\n    let settings = AVCapturePhotoSettings(format: [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)])\n    settings.isAutoStillImageStabilizationEnabled = true\n\n    if self.captureHighResolutionImages {\n      settings.isHighResolutionPhotoEnabled = true\n    }\n    self.photoOutput.capturePhoto(with: settings, delegate: self)\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCamera/FritzCamera.swift",
    "content": "//\n//  FritzCamera.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/20/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\n\nimport UIKit\nimport AVFoundation\nimport Fritz\n\n\nprotocol FritzCameraDelegate: class {\n\n  func capture(_ cameraSession: FritzCamera, didCaptureFritzImage image: FritzVisionImage?, timestamp: Date)\n\n  func processPhoto(_ cameraSession: FritzCamera, didCaptureFritzImage image: FritzVisionImage?, timestamp: Date) throws -> UIImage?\n\n  func cameraSetupCompleted(camera: FritzCamera, result: CameraSetupResult)\n\n  func cameraRestartCompleted(camera: FritzCamera, result: CameraSetupResult)\n\n  func finishedFocus(camera: FritzCamera)\n}\n\n\nenum CameraSetupResult: String {\n  typealias RawValue = String\n  case videoPermissionDenied = \"Video Permissions Denied\"\n  case videoPermissionRestricted = \"Video Permissions Restricted\"\n  case videoRequiresAuthorization = \"Video Permissions Require Authorization\"\n  case unknownError = \"Unknown Error\"\n  case invalidVideoDataOutput = \"Invalid Video Data Output\"\n  case invalidPhotoOutput = \"Invalid Photo Output\"\n  case invalidVideoInput = \"Invalid Video Input\"\n  case requiresUpdate = \"Requires AV Update\"\n  case videoSuccess = \"Video Setup Success\"\n}\n\nfinal class FritzCamera: NSObject {\n\n  weak var delegate: FritzCameraDelegate?\n\n  var captureHighResolutionImages = true {\n    didSet {\n      restartVideo()\n    }\n  }\n\n  var position: AVCaptureDevice.Position = .back {\n    didSet {\n      restartVideo()\n    }\n  }\n\n  var resolution: CameraResolution = .photo {\n    didSet {\n      restartVideo()\n    }\n  }\n\n  var frameRate: Int = 30 {\n    didSet {\n      restartVideo()\n    }\n  }\n\n  var session = AVCaptureSession()\n\n  fileprivate var discoverySession: AVCaptureDevice.DiscoverySession? {\n    var deviceTypes = [AVCaptureDevice.DeviceType]()\n    deviceTypes.append(.builtInWideAngleCamera)\n    deviceTypes.append(.builtInDualCamera)\n    return AVCaptureDevice.DiscoverySession(\n      deviceTypes: deviceTypes,\n      mediaType: AVMediaType.video,\n      position: AVCaptureDevice.Position.unspecified)\n  }\n\n  var videoInput: AVCaptureDeviceInput?\n  var currentCaptureDevice: AVCaptureDevice?\n  var videoBufferQueue = DispatchQueue(label: \"ai.fritz.videoBufferQueue\", attributes: .concurrent)\n  var sessionQueue = DispatchQueue(label: \"ai.fritz.sessionQueue\")\n\n  // private var _videoDataOutput: AVCaptureVideoDataOutput?\n  var videoDataOutput: AVCaptureVideoDataOutput {\n    let output = AVCaptureVideoDataOutput()\n    output.alwaysDiscardsLateVideoFrames = true\n    output.setSampleBufferDelegate(self, queue: videoBufferQueue)\n    // Core ML requires 32BGRA or 32RGBA\n    output.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA as UInt32]\n    return output\n  }\n  \n  var photoOutput = AVCapturePhotoOutput()\n\n  func start() {\n    FritzLogger.notice(message: \"starting capture session\")\n    self.sessionQueue.async {\n      self.session.startRunning()\n    }\n  }\n\n  func stop() {\n    FritzLogger.notice(message: \"stopping capture session\")\n    self.sessionQueue.async {\n      self.session.stopRunning()\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/CameraDelegateImplmentation.swift",
    "content": "//\n//  CameraViewController+CameraDelegate.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/20/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\n\n\nextension FritzCameraViewController: FritzCameraDelegate {\n\n  func capture(_ cameraSession: FritzCamera, didCaptureFritzImage image: FritzVisionImage?, timestamp: Date) {\n    let outputImage = try? delegate?.processImage(image)\n\n    DispatchQueue.main.async {\n      self.cameraView.image = outputImage\n      if self.streamBackgroundImage {\n        self.backgroundView.image = image?.rotated()\n      }\n    }\n  }\n\n  func processPhoto(_ cameraSession: FritzCamera, didCaptureFritzImage image: FritzVisionImage?, timestamp: Date) throws -> UIImage? {\n    return try delegate?.processImage(image)\n  }\n\n  func cameraSetupCompleted(camera: FritzCamera, result: CameraSetupResult) {\n    handleCameraSetupResult(result)\n  }\n\n  func cameraRestartCompleted(camera: FritzCamera, result: CameraSetupResult) {\n    DispatchQueue.main.async {\n      self.updateUI(orientation: UIApplication.shared.statusBarOrientation)\n    }\n  }\n\n  func finishedFocus(camera: FritzCamera) {\n    DispatchQueue.main.async {\n      self.isUpdating = false\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Extensions/ButtonFunctionality.swift",
    "content": "//\n//  ViewControllerButtonFunctions.swift\n//  Lumina\n//\n//  Created by David Okun on 11/20/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\n\nextension FritzCameraViewController {\n  @objc func cancelButtonTapped() {\n    FritzLogger.notice(message: \"cancel button tapped\")\n    dismiss(animated: true)\n  }\n\n  @objc func shutterButtonTapped() {\n    FritzLogger.notice(message: \"shutter button tapped\")\n    shutterButton.takePhoto()\n    cameraView.layer.opacity = 0\n    backgroundView.layer.opacity = 0\n\n    UIView.animate(withDuration: 0.25) {\n      self.cameraView.layer.opacity = 1\n      self.backgroundView.layer.opacity = 1\n    }\n    guard self.camera != nil else {\n      return\n    }\n    self.camera?.captureStillImage()\n  }\n\n\n  @objc func switchButtonTapped() {\n    FritzLogger.notice(message: \"camera switch button tapped\")\n    switch self.position {\n    case .back:\n      self.position = .front\n    default:\n      self.position = .back\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Extensions/CameraInterfaceHandler.swift",
    "content": "//\n//  InterfaceHandlerExtension.swift\n//  Lumina\n//\n//  Created by David Okun on 11/20/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport Foundation\nimport AVFoundation\nimport UIKit\n\nextension FritzCameraViewController {\n\n  @objc func handleTapGestureRecognizer(recognizer: UITapGestureRecognizer) {\n    if position == .back {\n      focusCamera(at: recognizer.location(in: view))\n    }\n  }\n\n  func createUI() {\n    FritzLogger.notice(message: \"Creating UI\")\n    self.view.addSubview(self.backgroundView)\n    self.view.addSubview(self.cameraView)\n    self.view.addSubview(self.cancelButton)\n    self.view.addSubview(self.shutterButton)\n    self.view.addSubview(self.switchButton)\n    self.view.addSubview(self.textPromptView)\n    self.view.addGestureRecognizer(self.focusRecognizer)\n    enableUI(valid: false)\n  }\n\n  func enableUI(valid: Bool) {\n    DispatchQueue.main.async {\n      self.shutterButton.isEnabled = valid\n      self.switchButton.isEnabled = valid\n    }\n  }\n\n  func updateUI(orientation: UIInterfaceOrientation) {\n    self.cameraView.frame = self.view.bounds\n    self.backgroundView.frame = self.view.bounds\n    let actualOrientation = self.necessaryVideoOrientation(for: orientation)\n    self.camera?.updateOutputVideoOrientation(actualOrientation)\n  }\n\n  func updateButtonFrames() {\n    self.cancelButton.center = CGPoint(x: self.view.frame.minX + 55, y: self.view.frame.maxY - 45)\n    var minY = self.view.frame.minY\n    if self.view.frame.width > self.view.frame.height {\n      var maxX = self.view.frame.maxX\n      if #available(iOS 11, *) {\n        maxX = self.view.safeAreaLayoutGuide.layoutFrame.maxX\n      }\n      self.shutterButton.center = CGPoint(x: maxX - 45, y: self.view.frame.midY)\n    } else {\n      var maxY = self.view.frame.maxY\n      if #available(iOS 11, *) {\n        maxY = self.view.safeAreaLayoutGuide.layoutFrame.maxY\n        minY = self.view.safeAreaLayoutGuide.layoutFrame.minY\n      }\n      self.shutterButton.center = CGPoint(x: self.view.frame.midX, y: maxY - 45)\n    }\n    self.switchButton.center = CGPoint(x: self.view.frame.maxX - 55, y: self.view.frame.maxY - 50)\n    /// Use more width, if text has been moved down below the buttons (e.g. notch on iPhone X):\n    let textWidth = self.view.frame.maxX - (minY > 35 ? 20 : 110)\n    self.textPromptView.frame.size = CGSize(width: textWidth - 100 , height: 80)\n    self.textPromptView.layoutSubviews()\n    self.textPromptView.center = CGPoint(x: self.view.frame.midX, y: minY + 45)\n  }\n\n  // swiftlint:disable cyclomatic_complexity\n  func handleCameraSetupResult(_ result: CameraSetupResult) {\n    FritzLogger.notice(message: \"camera set up result: \\(result.rawValue)\")\n    DispatchQueue.main.async {\n    switch result {\n    case .videoSuccess:\n      if let camera = self.camera {\n        self.enableUI(valid: true)\n        self.updateUI(orientation: UIApplication.shared.statusBarOrientation)\n        camera.start()\n      }\n    case .requiresUpdate:\n      self.camera?.updateVideo({ result in\n        self.handleCameraSetupResult(result)\n      })\n    case .videoPermissionDenied:\n      self.textPrompt = \"Camera permissions for Lumina have been previously denied - please access your privacy settings to change this.\"\n    case .videoPermissionRestricted:\n      self.textPrompt = \"Camera permissions for Lumina have been restricted - please access your privacy settings to change this.\"\n    case .videoRequiresAuthorization:\n      self.camera?.requestVideoPermissions()\n    case .invalidVideoDataOutput,\n         .invalidVideoInput,\n         .invalidPhotoOutput:\n      self.textPrompt = \"\\(result.rawValue) - please try again\"\n    case .unknownError:\n      self.textPrompt = \"Unknown error occurred while loading Lumina - please try again\"\n    }\n    }\n  }\n\n  private func necessaryVideoOrientation(for statusBarOrientation: UIInterfaceOrientation) -> AVCaptureVideoOrientation {\n    switch statusBarOrientation {\n    case .portrait:\n      return AVCaptureVideoOrientation.portrait\n    case .landscapeLeft:\n      return AVCaptureVideoOrientation.landscapeLeft\n    case .landscapeRight:\n      return AVCaptureVideoOrientation.landscapeRight\n    case .portraitUpsideDown:\n      return AVCaptureVideoOrientation.portraitUpsideDown\n    default:\n      return AVCaptureVideoOrientation.portrait\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Extensions/DebugImageExtensions.swift",
    "content": "//\n//  DebugImageExtensions.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/26/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\nextension FritzCameraViewController {\n\n  func updateDebugImage() {\n    if debugImageEnabled, let debugImage = debugImage, let camera = camera {\n      let fritzImage = FritzVisionImage(image: debugImage)\n      self.capture(camera, didCaptureFritzImage: fritzImage, timestamp: Date())\n      self.textPrompt = \"\"\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Extensions/FocusExtension.swift",
    "content": "//\n//  ViewControllerFocusHandlerExtension.swift\n//  Lumina\n//\n//  Created by David Okun on 11/20/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\n\n\nextension FritzCameraViewController {\n  func focusCamera(at point: CGPoint) {\n    if self.isUpdating == true {\n      return\n    } else {\n      self.isUpdating = true\n    }\n    let focusX = point.x/UIScreen.main.bounds.size.width\n    let focusY = point.y/UIScreen.main.bounds.size.height\n    guard let camera = self.camera else {\n      return\n    }\n    FritzLogger.notice(message: \"Attempting focus at (\\(focusX), \\(focusY))\")\n    camera.handleFocus(at: CGPoint(x: focusX, y: focusY))\n    showFocusView(at: point)\n    let deadlineTime = DispatchTime.now() + .seconds(1)\n    DispatchQueue.main.asyncAfter(deadline: deadlineTime) {\n      camera.resetCameraToContinuousExposureAndFocus()\n    }\n  }\n\n  private func showFocusView(at point: CGPoint) {\n    let focusView: UIImageView = UIImageView(image: UIImage(named: \"cameraFocus\", in: Bundle(for: FritzCameraViewController.self), compatibleWith: nil))\n    focusView.contentMode = .scaleAspectFit\n    focusView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)\n    focusView.transform = CGAffineTransform(scaleX: 1.7, y: 1.7)\n    focusView.center = point\n    focusView.alpha = 0.0\n    self.view.addSubview(focusView)\n    UIView.animate(withDuration: 0.3, animations: {\n      focusView.alpha = 1.0\n      focusView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)\n    }, completion: { _ in\n      UIView.animate(withDuration: 1.0, animations: {\n        focusView.alpha = 0.0\n      }, completion: { _ in\n        focusView.removeFromSuperview()\n        self.isUpdating = false\n      })\n    })\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Extensions/GestureReconizerDelegateExtension.swift",
    "content": "//\n//  GestureRecognizerDelegateExtension.swift\n//  Lumina\n//\n//  Created by David Okun on 11/20/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\n\nextension FritzCameraViewController: UIGestureRecognizerDelegate {\n  public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {\n    return true\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/FritzCameraButton.swift",
    "content": "//\n//  FritzCameraButton.swift\n//  Lumina\n//\n//  Created by David Okun on 9/11/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport UIKit\n\nenum SystemButtonType {\n  case cameraSwitch\n  case photoCapture\n  case cancel\n  case shutter\n}\n\nfinal class FritzCameraButton: UIButton {\n  private var squareSystemButtonWidth = 50\n  private var squareSystemButtonHeight = 40\n  private var cancelButtonWidth = 70\n  private var cancelButtonHeight = 30\n  private var shutterButtonDimension = 70\n  private var style: SystemButtonType?\n\n  private var border: UIView?\n\n  private var _image: UIImage?\n  var image: UIImage? {\n    get {\n      return _image\n    }\n    set {\n      self.setImage(newValue, for: UIControl.State.normal)\n      _image = newValue\n    }\n  }\n\n  private var _text: String?\n  var text: String? {\n    get {\n      return _text\n    }\n    set {\n      self.setTitle(newValue, for: UIControl.State.normal)\n      _text = newValue\n    }\n  }\n\n  required init() {\n    super.init(frame: CGRect.zero)\n    self.backgroundColor = UIColor.clear\n    if let titleLabel = self.titleLabel {\n      titleLabel.textColor = UIColor.white\n      titleLabel.font = UIFont.systemFont(ofSize: 20)\n      titleLabel.textAlignment = .center\n    }\n  }\n\n  init(with systemStyle: SystemButtonType, origin: CGPoint? = nil) {\n    super.init(frame: CGRect.zero)\n    self.style = systemStyle\n    self.backgroundColor = UIColor.clear\n    if let titleLabel = self.titleLabel {\n      titleLabel.textColor = UIColor.white\n      titleLabel.font = UIFont.systemFont(ofSize: 20)\n    }\n    switch systemStyle {\n    case .cameraSwitch:\n      self.image = UIImage(named: \"cameraSwitch\", in: Bundle(for: FritzCameraViewController.self), compatibleWith: nil)\n      self.frame = CGRect(\n        origin: origin ?? CGPoint(x: UIScreen.main.bounds.maxX - 50, y: UIScreen.main.bounds.maxY - 50),\n        size: CGSize(width: self.squareSystemButtonWidth, height: self.squareSystemButtonHeight)\n      )\n      addButtonShadowEffects()\n    case .cancel:\n      self.text = \"X\"\n      \n      self.frame = CGRect(\n        origin: origin ?? CGPoint(x: 10, y: UIScreen.main.bounds.maxY - 50),\n        size: CGSize(width: self.cancelButtonWidth, height: self.cancelButtonHeight)\n      )\n      self.titleLabel?.font = UIFont.systemFont(ofSize: 40, weight: .light)\n      self.titleLabel?.layer.shadowOffset = CGSize(width: 0, height: 0)\n      self.titleLabel?.layer.shadowOpacity = 1\n      self.titleLabel?.layer.shadowRadius = 6\n    case .shutter:\n      self.backgroundColor = UIColor.normalState\n      var minY = UIScreen.main.bounds.maxY\n      if #available(iOS 11, *) {\n        minY = self.safeAreaLayoutGuide.layoutFrame.maxY\n      }\n      minY -=  80\n      self.frame = CGRect(origin: CGPoint(x: UIScreen.main.bounds.midX - 35, y: minY), size: CGSize(width: self.shutterButtonDimension, height: self.shutterButtonDimension))\n      self.layer.cornerRadius = CGFloat(self.shutterButtonDimension / 2)\n      self.layer.borderWidth = 3\n      self.layer.borderColor = UIColor.borderNormalState\n    default:\n      break\n    }\n  }\n\n  private func addButtonShadowEffects() {\n    self.layer.shadowOffset = CGSize(width: 0, height: 0)\n    self.layer.shadowOpacity = 1\n    self.layer.shadowRadius = 6\n  }\n\n\n  func takePhoto() {\n    if style == .shutter {\n      DispatchQueue.main.async {\n        UIView.animate(withDuration: 0.1, animations: {\n          self.backgroundColor = UIColor.takePhotoState\n          self.layer.borderColor = UIColor.borderTakePhotoState\n        }, completion: { _ in\n          UIView.animate(withDuration: 0.1, animations: {\n            self.backgroundColor = UIColor.normalState\n            self.layer.borderColor = UIColor.borderNormalState\n          })\n        })\n      }\n    }\n  }\n\n  required init?(coder aDecoder: NSCoder) {\n    super.init(coder: aDecoder)\n  }\n}\n\nfileprivate extension UIColor {\n  class var normalState: UIColor {\n    return UIColor(white: 1.0, alpha: 0.65)\n  }\n\n  class var recordingState: UIColor {\n    return UIColor.red.withAlphaComponent(0.65)\n  }\n\n  class var takePhotoState: UIColor {\n    return UIColor.lightGray.withAlphaComponent(0.65)\n  }\n\n  class var borderNormalState: CGColor {\n    return UIColor.gray.cgColor\n  }\n\n  class var borderRecordingState: CGColor {\n    return UIColor.red.cgColor\n  }\n\n  class var borderTakePhotoState: CGColor {\n    return UIColor.darkGray.cgColor\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/FritzCameraControllerDelegate.swift",
    "content": "//\n//  FritzVisionCameraDelegate.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/20/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\n\nprotocol FritzCameraControllerDelegate: class {\n\n  /// Processes image from camera.\n  func processImage(_ image: FritzVisionImage?) throws -> UIImage?\n\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/FritzCameraViewController.swift",
    "content": "//\n//  CameraViewController.swift\n//  CameraFramework\n//\n//  Created by David Okun on 8/29/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport UIKit\nimport AVFoundation\nimport CoreML\nimport Fritz\n\n\n\n/// The main class that developers should interact with and instantiate when using Lumina\nopen class FritzCameraViewController: UIViewController {\n\n  internal var logger = Logger(label: \"ai.fritz.Fritz\")\n\n  var camera: FritzCamera?\n\n  private var _cameraView: UIImageView?\n  var cameraView: UIImageView {\n    if let currentView = _cameraView {\n      return currentView\n    }\n\n    let cameraView = UIImageView()\n    cameraView.contentMode = .scaleAspectFill\n    cameraView.frame = view.bounds\n    _cameraView = cameraView\n\n    return cameraView\n  }\n\n  private var _backgroundView: UIImageView?\n  var backgroundView: UIImageView {\n    if let currentView = _backgroundView {\n      return currentView\n    }\n    let currentView = UIImageView()\n    currentView.frame = view.bounds\n    currentView.contentMode = .scaleAspectFill\n    _backgroundView = currentView\n    return currentView\n  }\n\n  private var _focusRecognizer: UITapGestureRecognizer?\n  var focusRecognizer: UITapGestureRecognizer {\n    if let currentRecognizer = _focusRecognizer {\n      return currentRecognizer\n    }\n    let recognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGestureRecognizer(recognizer:)))\n    recognizer.delegate = self\n    _focusRecognizer = recognizer\n    return recognizer\n  }\n\n  private var _cancelButton: FritzCameraButton?\n  var cancelButton: FritzCameraButton {\n    if let currentButton = _cancelButton {\n      return currentButton\n    }\n    let origin = CGPoint(x: 20 , y: 20)\n    let button = FritzCameraButton(with: SystemButtonType.cancel, origin: origin)\n    button.addTarget(self, action: #selector(cancelButtonTapped), for: .touchUpInside)\n    _cancelButton = button\n    return button\n  }\n\n  private var _shutterButton: FritzCameraButton?\n  var shutterButton: FritzCameraButton {\n    if let currentButton = _shutterButton {\n      return currentButton\n    }\n    let button = FritzCameraButton(with: SystemButtonType.shutter)\n    button.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(shutterButtonTapped)))\n    _shutterButton = button\n    return button\n  }\n\n  private var _switchButton: FritzCameraButton?\n  var switchButton: FritzCameraButton {\n    if let currentButton = _switchButton {\n      return currentButton\n    }\n    let button = FritzCameraButton(with: SystemButtonType.cameraSwitch)\n    button.addTarget(self, action: #selector(switchButtonTapped), for: .touchUpInside)\n    _switchButton = button\n    return button\n  }\n\n  private var _textPromptView: FritzTextPromptView?\n  var textPromptView: FritzTextPromptView {\n    if let existingView = _textPromptView {\n      return existingView\n    }\n    let promptView = FritzTextPromptView()\n    _textPromptView = promptView\n    return promptView\n  }\n\n  var isUpdating = false\n\n  /// The delegate for streaming output from Lumina\n  weak var delegate: FritzCameraControllerDelegate?\n\n  /// The position of the camera\n  ///\n  /// - Note: Responds live to being set at any time, and will update automatically\n  open var position: AVCaptureDevice.Position = .back {\n    didSet {\n      FritzLogger.notice(message: \"Switching camera position to \\(position.rawValue)\")\n      guard let camera = self.camera else {\n        return\n      }\n      \n      camera.position = position\n    }\n  }\n\n  /// The position of the camera\n  ///\n  /// - Note: Responds live to being set at any time, and will update automatically\n  open var streamBackgroundImage: Bool = false {\n    didSet {\n      FritzLogger.notice(message: \"Streaming Background Image set to \\(streamBackgroundImage)\")\n      backgroundView.isHidden = !streamBackgroundImage\n    }\n  }\n\n  /// Set this to choose a resolution for the camera at any time - defaults to highest resolution possible for camera\n  ///\n  /// - Note: Responds live to being set at any time, and will update automatically\n  open var resolution: CameraResolution = .highest {\n    didSet {\n      FritzLogger.notice(message: \"Updating camera resolution to \\(resolution.rawValue)\")\n      self.camera?.resolution = resolution\n    }\n  }\n\n  /// Set this to choose a frame rate for the camera at any time - defaults to 30 if query is not available\n  ///\n  /// - Note: Responds live to being set at any time, and will update automatically\n  open var frameRate: Int = 30 {\n    didSet {\n      FritzLogger.notice(message: \"Attempting to update camera frame rate to \\(frameRate) FPS\")\n      self.camera?.frameRate = frameRate\n    }\n  }\n\n  /// Lumina comes ready with a view for a text prompt to give instructions to the user, and this is where you can set the text of that prompt\n  ///\n  /// - Note: Responds live to being set at any time, and will update automatically\n  ///\n  /// - Warning: If left empty, or unset, no view will be present, but view will be created if changed\n  open var textPrompt = \"\" {\n    didSet {\n      FritzLogger.notice(message: \"Updating text prompt view to: \\(textPrompt)\")\n      self.textPromptView.updateText(to: textPrompt)\n    }\n  }\n\n  /// Image used for debugging.\n  open var debugImage: UIImage? { return nil }\n\n  open var debugImageEnabled: Bool = false\n\n  /// Setting visibility of the buttons (default: all buttons are visible)\n  public func setCancelButton(visible: Bool) {\n    cancelButton.isHidden = !visible\n  }\n\n  public func setShutterButton(visible: Bool) {\n    shutterButton.isHidden = !visible\n  }\n\n  public func setSwitchButton(visible: Bool) {\n    switchButton.isHidden = !visible\n  }\n\n  public func pauseCamera() {\n    self.camera?.stop()\n  }\n\n  public func startCamera() {\n    self.camera?.start()\n  }\n\n  /// Set this to apply a level of logging to Lumina, to track activity within the framework\n  public static var loggingLevel: Logger.Level = .critical {\n    didSet {\n      FritzLogger.level = loggingLevel\n    }\n  }\n\n  /// run this in order to create FritzCamera\n  public init() {\n    super.init(nibName: nil, bundle: nil)\n    let camera = FritzCamera()\n    camera.delegate = self\n    self.camera = camera\n  }\n\n  /// run this in order to create FritzCamera with a storyboard\n  public required init?(coder aDecoder: NSCoder) {\n    super.init(coder: aDecoder)\n    let camera = FritzCamera()\n    camera.delegate = self\n    self.camera = camera\n  }\n\n  /// override with caution\n  open override func didReceiveMemoryWarning() {\n    super.didReceiveMemoryWarning()\n    FritzLogger.error(message: \"Camera framework is overloading on memory\")\n  }\n\n  /// override with caution\n  open override func viewWillAppear(_ animated: Bool) {\n    super.viewWillAppear(animated)\n    createUI()\n    if debugImageEnabled {\n      updateDebugImage()\n      return\n    } \n    self.camera?.updateVideo({ result in\n      self.handleCameraSetupResult(result)\n    })\n\n  }\n\n  /// override with caution\n  open override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n  }\n\n  open override var shouldAutorotate: Bool {\n    guard let _ = self.camera else {\n      return true\n    }\n    return false\n  }\n\n  /// override with caution\n  open override func viewDidDisappear(_ animated: Bool) {\n    super.viewDidDisappear(true)\n    self.camera?.stop()\n  }\n\n  /// override with caution\n  open override func viewWillLayoutSubviews() {\n    super.viewWillLayoutSubviews()\n    updateUI(orientation: UIApplication.shared.statusBarOrientation)\n    updateButtonFrames()\n  }\n\n  /// override with caution\n  open override var prefersStatusBarHidden: Bool {\n    return false\n  }\n\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/FritzTextPromptView.swift",
    "content": "//\n//  LuminaTextPromptView.swift\n//  Lumina\n//\n//  Created by David Okun on 5/7/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport UIKit\n\nenum FritzTextError: Error {\n  case fontError\n}\n\nextension UIFont {\n  static func fontsURLs() -> [URL]? {\n    let bundle = Bundle(identifier: \"com.okun.io.Lumina\")\n    let fileNames = [\"IBMPlexSans-SemiBold\"]\n    let newNames = fileNames.map({ bundle?.url(forResource: $0, withExtension: \"ttf\") })\n    return newNames as? [URL]\n  }\n\n  static func register(from url: URL) throws {\n    guard let fontDataProvider = CGDataProvider(url: url as CFURL) else {\n      throw FritzTextError.fontError\n    }\n    guard let font = CGFont(fontDataProvider) else {\n      throw FritzTextError.fontError\n    }\n    var error: Unmanaged<CFError>?\n    guard CTFontManagerRegisterGraphicsFont(font, &error) else {\n      throw error!.takeUnretainedValue()\n    }\n  }\n}\n\nfinal class FritzTextPromptView: UIView {\n\n  private var textLabel = UILabel()\n  static private let animationDuration = 0.3\n\n  init() {\n    super.init(frame: CGRect.zero)\n    self.textLabel = UILabel()\n    self.textLabel.backgroundColor = UIColor.clear\n    self.textLabel.textColor = UIColor.white\n    self.textLabel.textAlignment = .center\n    do {\n      if let fonts = UIFont.fontsURLs() {\n        try fonts.forEach { try UIFont.register(from: $0) }\n      }\n    } catch {\n      FritzLogger.debug(message: \"Special fonts already registered\")\n    }\n    if let font = UIFont(name: \"IBM Plex Sans\", size: 22) {\n      self.textLabel.font = font\n    } else {\n      self.textLabel.font = UIFont.systemFont(ofSize: 22, weight: .bold)\n    }\n    self.textLabel.numberOfLines = 3\n    self.textLabel.minimumScaleFactor = 10/UIFont.labelFontSize\n    self.textLabel.adjustsFontSizeToFitWidth = true\n    self.textLabel.layer.shadowOffset = CGSize(width: 0, height: 0)\n    self.textLabel.layer.shadowOpacity = 1\n    self.textLabel.layer.shadowRadius = 6\n    self.addSubview(textLabel)\n    self.backgroundColor = UIColor.clear\n    self.alpha = 0.0\n    self.layer.cornerRadius = 5.0\n  }\n\n  func updateText(to text: String) {\n    DispatchQueue.main.async {\n      if text.isEmpty {\n        self.hide(andErase: true)\n      } else {\n        self.textLabel.text = text\n        self.makeAppear()\n      }\n    }\n  }\n\n  func hide(andErase: Bool) {\n    DispatchQueue.main.async {\n      UIView.animate(withDuration: FritzTextPromptView.animationDuration, animations: {\n        self.alpha = 0.0\n      }, completion: { _ in\n        if andErase {\n          self.textLabel.text = \"\"\n        }\n      })\n    }\n  }\n\n  private func makeAppear() {\n    DispatchQueue.main.async {\n      UIView.animate(withDuration: FritzTextPromptView.animationDuration) {\n        self.alpha = 1\n      }\n    }\n  }\n\n  override func layoutSubviews() {\n    self.textLabel.frame = CGRect(origin: CGPoint(x: 5, y: 5), size: CGSize(width: frame.width - 50, height: frame.height - 10))\n  }\n\n  required init?(coder aDecoder: NSCoder) {\n    fatalError(\"init(coder:) has not been implemented\")\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Media.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Media.xcassets/cameraFocus.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"cameraFocus.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Media.xcassets/cameraSwitch.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"flip.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Media.xcassets/cameraTorchAuto.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"cameraTorchAuto.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Media.xcassets/cameraTorchOff.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"cameraTorchOff.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Media.xcassets/cameraTorchOn.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"cameraTorchOn.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Shaders/DepthToGrayscale.metal",
    "content": "/*\nSee LICENSE folder for this sample’s licensing information.\n\nAbstract:\nMetal compute shader that translates depth values to grayscale RGB values.\n*/\n\n#include <metal_stdlib>\nusing namespace metal;\n\nstruct converterParameters {\n\tfloat offset;\n\tfloat range;\n};\n\n// Compute kernel\nkernel void depthToGrayscale(texture2d<float, access::read>  inputTexture      [[ texture(0) ]],\n\t\t\t\t\t\t\t texture2d<float, access::write> outputTexture     [[ texture(1) ]],\n\t\t\t\t\t\t\t constant converterParameters& converterParameters [[ buffer(0) ]],\n\t\t\t\t\t\t\t uint2 gid [[ thread_position_in_grid ]])\n{\n\t// Don't read or write outside of the texture.\n\tif ((gid.x >= inputTexture.get_width()) || (gid.y >= inputTexture.get_height())) {\n\t\treturn;\n\t}\n\t\n\tfloat depth = inputTexture.read(gid).x;\n\t\n\t// Normalize the value between 0 and 1.\n\tdepth = (depth - converterParameters.offset) / (converterParameters.range);\n\t\n\tfloat4 outputColor = float4(float3(depth), 1.0);\n\t\n\toutputTexture.write(outputColor, gid);\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Shaders/Mixer.metal",
    "content": "/*\nSee LICENSE folder for this sample’s licensing information.\n\nAbstract:\nShader that blends two input textures.\n*/\n\n#include <metal_stdlib>\nusing namespace metal;\n\nstruct VertexIO\n{\n\tfloat4 position [[position]];\n\tfloat2 textureCoord [[user(texturecoord)]];\n};\n\nstruct mixerParameters\n{\n\tfloat mixFactor;\n};\n\nvertex VertexIO vertexMixer(device float2 *pPosition [[ buffer(0) ]],\n\t\t\t\t\t\t\tuint index               [[ vertex_id ]])\n{\n\tVertexIO outVertex;\n\t\n\toutVertex.position.xy  = pPosition[index];\n\toutVertex.position.z = 0;\n\toutVertex.position.w = 1.0;\n\t\n\t// Convert texture position to texture coordinates\n\toutVertex.textureCoord.xy = 0.5 + float2(0.5, -0.5) * outVertex.position.xy;\n\t\n\treturn outVertex;\n}\n\nfragment half4 fragmentMixer(VertexIO         inputFragment    [[ stage_in ]],\n\t\t\t\t\t\t\t texture2d<half> mixerInput0      [[ texture(0) ]],\n\t\t\t\t\t\t\t texture2d<half> mixerInput1      [[ texture(1) ]],\n\t\t\t\t\t\t\t const device    mixerParameters& mixerParameters [[ buffer(0) ]],\n\t\t\t\t\t\t\t sampler         samplr           [[ sampler(0) ]])\n{\n\thalf4 input0 = mixerInput0.sample(samplr, inputFragment.textureCoord);\n\thalf4 input1 = mixerInput1.sample(samplr, inputFragment.textureCoord);\n\t\n\thalf4 output = mix(input0, input1, half(mixerParameters.mixFactor));\n\t\n\treturn output;\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Shaders/PassThrough.metal",
    "content": "/*\nSee LICENSE folder for this sample’s licensing information.\n\nAbstract:\nPass-through shader (used for preview).\n*/\n\n#include <metal_stdlib>\nusing namespace metal;\n\n// Vertex input/output structure for passing results from vertex shader to fragment shader\nstruct VertexIO\n{\n\tfloat4 position [[position]];\n\tfloat2 textureCoord [[user(texturecoord)]];\n};\n\n// Vertex shader for a textured quad\nvertex VertexIO vertexPassThrough(device packed_float4 *pPosition  [[ buffer(0) ]],\n\t\t\t\t\t\t\t\t  device packed_float2 *pTexCoords [[ buffer(1) ]],\n\t\t\t\t\t\t\t\t  uint                  vid        [[ vertex_id ]])\n{\n\tVertexIO outVertex;\n\t\n\toutVertex.position = pPosition[vid];\n\toutVertex.textureCoord = pTexCoords[vid];\n\t\n\treturn outVertex;\n}\n\n// Fragment shader for a textured quad\nfragment half4 fragmentPassThrough(VertexIO         inputFragment [[ stage_in ]],\n\t\t\t\t\t\t\t\t\ttexture2d<half> inputTexture  [[ texture(0) ]],\n\t\t\t\t\t\t\t\t\tsampler         samplr        [[ sampler(0) ]])\n{\n\treturn inputTexture.sample(samplr, inputFragment.textureCoord);\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/FritzCamera/FritzCameraUI/Shaders/RosyEffect.metal",
    "content": "/*\nSee LICENSE folder for this sample’s licensing information.\n\nAbstract:\nShader that gives images a pink tint by zero-ing out the green value.\n*/\n\n#include <metal_stdlib>\nusing namespace metal;\n\n// Compute kernel\nkernel void rosyEffect(texture2d<half, access::read>  inputTexture  [[ texture(0) ]],\n\t\t\t\t\t   texture2d<half, access::write> outputTexture [[ texture(1) ]],\n\t\t\t\t\t   uint2 gid [[thread_position_in_grid]])\n{\n\t// Don't read or write outside of the texture.\n\tif ((gid.x >= inputTexture.get_width()) || (gid.y >= inputTexture.get_height())) {\n\t\treturn;\n\t}\n\t\n\thalf4 inputColor = inputTexture.read(gid);\n\t\n\t// Set the output color to the input color, excluding the green component.\n\thalf4 outputColor = half4(inputColor.r, 0.0, inputColor.b, 1.0);\n\t\n\toutputTexture.write(outputColor, gid);\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/AIStudioFeaturePredictors.swift",
    "content": "//\n//  AIStudioFeaturePredictors.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/24/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\n\n\nenum AIStudioFeaturePredictors: String, RawRepresentable {\n\n  case peopleSegmentation = \"people_image_segmentation\"\n  case livingRoomSegmentation = \"living_room_segmentation\"\n  case outdoorSegmentation = \"outdoor_image_segmentation\"\n  case petSegmentation = \"pet_image_segmentation\"\n  case skySegmentation = \"sky_image_segmentation\"\n  case styleTransfer = \"custom_style_transfer\"\n  case hairColor = \"hair_color\"\n  case poseEstimation = \"pose_estimation\"\n  case unknown = \"unknown\"\n\n  var defaultOptions: ConfigurableOptions {\n    switch self {\n    case .peopleSegmentation:\n      return ImageSegmentationViewController.defaultOptions\n    case .livingRoomSegmentation:\n      return ImageSegmentationViewController.defaultOptions\n    case .outdoorSegmentation:\n      return ImageSegmentationViewController.defaultOptions\n    case .petSegmentation:\n      return ImageSegmentationViewController.defaultOptions\n    case .skySegmentation:\n      return ImageSegmentationViewController.defaultOptions\n    case .hairColor:\n      return HairColorViewController.defaultOptions\n    case .styleTransfer:\n      return StyleTransferViewController.defaultOptions\n    case .poseEstimation:\n      return PoseEstimationViewController.defaultOptions\n    case .unknown:\n      return [:]\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/AIStudioImagePredictor.swift",
    "content": "//\n//  AIStudioImagePredictor.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/7/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\n\n\nclass AIStudioImagePredictor {\n\n  let model: ImagePredictor\n\n  let predictorDetails: FritzModelDetails\n\n  init(model: ImagePredictor, predictorDetails: FritzModelDetails) {\n    self.model = model\n    self.predictorDetails = predictorDetails\n  }\n}\n\nextension AIStudioImagePredictor: FritzCameraControllerDelegate {\n\n  public func processImage(_ image: FritzVisionImage?) throws -> UIImage? {\n    guard let image = image else { return nil }\n    return try self.model.predict(image, options: predictorDetails.options)\n  }\n  \n}\n\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/FritzModelDetails.swift",
    "content": "//\n//  FritzModelDetails.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/6/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\n\npublic class FritzModelDetails: Equatable {\n\n  public static func == (lhs: FritzModelDetails, rhs: FritzModelDetails) -> Bool {\n    // This is not the best way to do equality.  It's just checking that it's a\n    // different model on the surface.  would be good to clean this up in the future.\n    return lhs.modelConfig.version == rhs.modelConfig.version && lhs.modelConfig.identifier == rhs.modelConfig.identifier && lhs.featureName == rhs.featureName\n  }\n\n  /// Active Model Configuration for managed model.\n  var modelConfig: FritzModelConfiguration {\n    return managedModel.activeModelConfig\n  }\n\n  /// ManagedModel used to manage interactions with Fritz API.\n  let managedModel: FritzManagedModel\n\n  let featureDescription: AIStudioFeaturePredictors\n\n  var options: ConfigurableOptions\n\n  /// Feature name used to configure which variant of a feature is loaded.\n  /// For example, ImageSegmentation defines three variants: people_segmentation, living_room_segmentation, and outdoor_segementation.\n  private var _featureName: String?\n  public var featureName: String {\n    if let name = _featureName {\n      return name\n    }\n    return modelConfig.metadata?[\"fritz_feature\"] ?? featureDescription.rawValue\n  }\n\n  /// Display name of model.\n  private let _name: String?\n  public var name: String {\n    return managedModel.activeModelConfig.metadata?[\"name\"] ?? _name ?? featureName\n  }\n\n  /// Description of model.\n  public var description: String {\n    return managedModel.activeModelConfig.metadata?[\"description\"] ?? \"\"\n  }\n\n  /// Initialize FritzModel, a wrapper for a FritzManagedModel.\n  ///\n  /// - Parameters:\n  ///   - managedModel: ManagedModel instance.\n  ///   - predefinedFeatureName: Optional feature name that overrides any feature_name metadata property\n  init(\n    with managedModel: FritzManagedModel,\n    featureDescription: AIStudioFeaturePredictors,\n    name: String? = nil\n  ) {\n    self.managedModel = managedModel\n    self.featureDescription = featureDescription\n    self.options = featureDescription.defaultOptions\n    self._name = name\n    self.managedModel.updateModelIfNeeded(skipCache: true) { (result, error) in\n      \n    }\n  }\n\n  public func download() {\n    managedModel.startDownload()\n  }\n\n  public var isDownloaded: Bool {\n    return managedModel.hasDownloadedModel\n  }\n\n  public func isSamePredictor(_ otherDetails: FritzModelDetails) -> Bool {\n    return self.modelConfig.identifier == otherDetails.modelConfig.identifier\n      && self.modelConfig.version == otherDetails.modelConfig.version\n  }\n\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/ImagePredictorProtocol.swift",
    "content": "//\n//  ImagePredictorProtocol.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/24/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\n\nprotocol ImagePredictor {\n\n\n  /// Runs prediction for a FritzVisionImage with user configurable options.\n  ///\n  /// A common use case of this Delegate is to extend an existing FritzVision model\n  /// That just runs the predict method.\n  ///\n  /// - Parameters:\n  ///   - image: FritzVisionImage with camera orientation settings applied.\n  ///   - options: Options that can be be configured for the model.  These commonly can either be used to build the Model's options object or for postprocessing parameters.\n  func predict(_ image: FritzVisionImage, options: ConfigurableOptions) throws -> UIImage?\n\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/Logging/Locks.swift",
    "content": "//===----------------------------------------------------------------------===//\n//\n// This source file is part of the Swift Logging API open source project\n//\n// Copyright (c) 2018-2019 Apple Inc. and the Swift Logging API project authors\n// Licensed under Apache License v2.0\n//\n// See LICENSE.txt for license information\n// See CONTRIBUTORS.txt for the list of Swift Logging API project authors\n//\n// SPDX-License-Identifier: Apache-2.0\n//\n//===----------------------------------------------------------------------===//\n\n//===----------------------------------------------------------------------===//\n//\n// This source file is part of the SwiftNIO open source project\n//\n// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors\n// Licensed under Apache License v2.0\n//\n// See LICENSE.txt for license information\n// See CONTRIBUTORS.txt for the list of SwiftNIO project authors\n//\n// SPDX-License-Identifier: Apache-2.0\n//\n//===----------------------------------------------------------------------===//\n\n#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)\n    import Darwin\n#else\n    import Glibc\n#endif\n\n/// A threading lock based on `libpthread` instead of `libdispatch`.\n///\n/// This object provides a lock on top of a single `pthread_mutex_t`. This kind\n/// of lock is safe to use with `libpthread`-based threading models, such as the\n/// one used by NIO.\ninternal final class Lock {\n    fileprivate let mutex: UnsafeMutablePointer<pthread_mutex_t> = UnsafeMutablePointer.allocate(capacity: 1)\n\n    /// Create a new lock.\n    public init() {\n        let err = pthread_mutex_init(self.mutex, nil)\n        precondition(err == 0)\n    }\n\n    deinit {\n        let err = pthread_mutex_destroy(self.mutex)\n        precondition(err == 0)\n        self.mutex.deallocate()\n    }\n\n    /// Acquire the lock.\n    ///\n    /// Whenever possible, consider using `withLock` instead of this method and\n    /// `unlock`, to simplify lock handling.\n    public func lock() {\n        let err = pthread_mutex_lock(self.mutex)\n        precondition(err == 0)\n    }\n\n    /// Release the lock.\n    ///\n    /// Whenever possible, consider using `withLock` instead of this method and\n    /// `lock`, to simplify lock handling.\n    public func unlock() {\n        let err = pthread_mutex_unlock(self.mutex)\n        precondition(err == 0)\n    }\n}\n\nextension Lock {\n    /// Acquire the lock for the duration of the given block.\n    ///\n    /// This convenience method should be preferred to `lock` and `unlock` in\n    /// most situations, as it ensures that the lock will be released regardless\n    /// of how `body` exits.\n    ///\n    /// - Parameter body: The block to execute while holding the lock.\n    /// - Returns: The value returned by the block.\n    @inlinable\n    internal func withLock<T>(_ body: () throws -> T) rethrows -> T {\n        self.lock()\n        defer {\n            self.unlock()\n        }\n        return try body()\n    }\n\n    // specialise Void return (for performance)\n    @inlinable\n    internal func withLockVoid(_ body: () throws -> Void) rethrows {\n        try self.withLock(body)\n    }\n}\n\n/// A threading lock based on `libpthread` instead of `libdispatch`.\n///\n/// This object provides a lock on top of a single `pthread_mutex_t`. This kind\n/// of lock is safe to use with `libpthread`-based threading models, such as the\n/// one used by NIO.\ninternal final class ReadWriteLock {\n    fileprivate let rwlock: UnsafeMutablePointer<pthread_rwlock_t> = UnsafeMutablePointer.allocate(capacity: 1)\n\n    /// Create a new lock.\n    public init() {\n        let err = pthread_rwlock_init(self.rwlock, nil)\n        precondition(err == 0)\n    }\n\n    deinit {\n        let err = pthread_rwlock_destroy(self.rwlock)\n        precondition(err == 0)\n        self.rwlock.deallocate()\n    }\n\n    /// Acquire a reader lock.\n    ///\n    /// Whenever possible, consider using `withLock` instead of this method and\n    /// `unlock`, to simplify lock handling.\n    public func lockRead() {\n        let err = pthread_rwlock_rdlock(self.rwlock)\n        precondition(err == 0)\n    }\n\n    /// Acquire a writer lock.\n    ///\n    /// Whenever possible, consider using `withLock` instead of this method and\n    /// `unlock`, to simplify lock handling.\n    public func lockWrite() {\n        let err = pthread_rwlock_wrlock(self.rwlock)\n        precondition(err == 0)\n    }\n\n    /// Release the lock.\n    ///\n    /// Whenever possible, consider using `withLock` instead of this method and\n    /// `lock`, to simplify lock handling.\n    public func unlock() {\n        let err = pthread_rwlock_unlock(self.rwlock)\n        precondition(err == 0)\n    }\n}\n\nextension ReadWriteLock {\n    /// Acquire the reader lock for the duration of the given block.\n    ///\n    /// This convenience method should be preferred to `lock` and `unlock` in\n    /// most situations, as it ensures that the lock will be released regardless\n    /// of how `body` exits.\n    ///\n    /// - Parameter body: The block to execute while holding the lock.\n    /// - Returns: The value returned by the block.\n    @inlinable\n    internal func withReaderLock<T>(_ body: () throws -> T) rethrows -> T {\n        self.lockRead()\n        defer {\n            self.unlock()\n        }\n        return try body()\n    }\n\n    /// Acquire the writer lock for the duration of the given block.\n    ///\n    /// This convenience method should be preferred to `lock` and `unlock` in\n    /// most situations, as it ensures that the lock will be released regardless\n    /// of how `body` exits.\n    ///\n    /// - Parameter body: The block to execute while holding the lock.\n    /// - Returns: The value returned by the block.\n    @inlinable\n    internal func withWriterLock<T>(_ body: () throws -> T) rethrows -> T {\n        self.lockWrite()\n        defer {\n            self.unlock()\n        }\n        return try body()\n    }\n\n    // specialise Void return (for performance)\n    @inlinable\n    internal func withReaderLockVoid(_ body: () throws -> Void) rethrows {\n        try self.withReaderLock(body)\n    }\n\n    // specialise Void return (for performance)\n    @inlinable\n    internal func withWriterLockVoid(_ body: () throws -> Void) rethrows {\n        try self.withWriterLock(body)\n    }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/Logging/LogHandler.swift",
    "content": "//===----------------------------------------------------------------------===//\n//\n// This source file is part of the Swift Logging API open source project\n//\n// Copyright (c) 2018-2019 Apple Inc. and the Swift Logging API project authors\n// Licensed under Apache License v2.0\n//\n// See LICENSE.txt for license information\n// See CONTRIBUTORS.txt for the list of Swift Logging API project authors\n//\n// SPDX-License-Identifier: Apache-2.0\n//\n//===----------------------------------------------------------------------===//\n\n/// A `LogHandler` is an implementation of a logging backend.\n///\n/// This type is an implementation detail and should not normally be used, unless implementing your own logging backend.\n/// To use the SwiftLog API, please refer to the documentation of `Logger`.\n///\n/// # Implementation requirements\n///\n/// To implement your own `LogHandler` you should respect a few requirements that are necessary so applications work\n/// as expected regardless of the selected `LogHandler` implementation.\n///\n/// - The `LogHandler` must be a `struct`.\n/// - The metadata and `logLevel` properties must be implemented so that setting them on a `Logger` does not affect\n///   other `Logger`s.\n///\n/// ### Treat log level & metadata as values\n///\n/// When developing your `LogHandler`, please make sure the following test works.\n///\n/// ```swift\n/// LoggingSystem.bootstrap(MyLogHandler.init) // your LogHandler might have a different bootstrapping step\n/// var logger1: Logger(label: \"first logger\")\n/// logger1.logLevel = .debug\n/// logger1[metadataKey: \"only-on\"] = \"first\"\n///\n/// var logger2 = logger1\n/// logger2.logLevel = .error                  // this must not override `logger1`'s log level\n/// logger2[metadataKey: \"only-on\"] = \"second\" // this must not override `logger1`'s metadata\n///\n/// XCTAssertEqual(.debug, logger1.logLevel)\n/// XCTAssertEqual(.error, logger2.logLevel)\n/// XCTAssertEqual(\"first\", logger1[metadataKey: \"only-on\"])\n/// XCTAssertEqual(\"second\", logger2[metadataKey: \"only-on\"])\n/// ```\n///\n/// ### Special cases\n///\n/// In certain special cases, the log level behaving like a value on `Logger` might not be what you want. For example,\n/// you might want to set the log level across _all_ `Logger`s to `.debug` when say a signal (eg. `SIGUSR1`) is received\n/// to be able to debug special failures in production. This special case is acceptable but we urge you to create a\n/// solution specific to your `LogHandler` implementation to achieve that. Please find an example implementation of this\n/// behavior below, on reception of the signal you would call\n/// `LogHandlerWithGlobalLogLevelOverride.overrideGlobalLogLevel = .debug`, for example.\n///\n/// ```swift\n/// public struct LogHandlerWithGlobalLogLevelOverride: LogHandler {\n///     // the static properties hold the globally overridden log level (if overridden)\n///     private static let overrideLock = Lock()\n///     private static var overrideLogLevel: Logger.Level? = nil\n///\n///     // this holds the log level if not overridden\n///     private var _logLevel: Logger.Level = .info\n///\n///     // metadata storage\n///     public var metadata: Logger.Metadata = [:]\n///\n///     public init(label: String) {\n///         // [...]\n///     }\n///\n///     public var logLevel: Logger.Level {\n///         // when we get asked for the log level, we check if it was globally overridden or not\n///         get {\n///             return LogHandlerWithGlobalLogLevelOverride.overrideLock.withLock {\n///                 return LogHandlerWithGlobalLogLevelOverride.overrideLogLevel\n///             } ?? self._logLevel\n///         }\n///         // we set the log level whenever we're asked (note: this might not have an effect if globally\n///         // overridden)\n///         set {\n///             self._logLevel = newValue\n///         }\n///     }\n///\n///     public func log(level: Logger.Level, message: Logger.Message, metadata: Logger.Metadata?,\n///              file: String, function: String, line: UInt) {\n///         // [...]\n///     }\n///\n///     public subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? {\n///         get {\n///             return self.metadata[metadataKey]\n///         }\n///         set(newValue) {\n///             self.metadata[metadataKey] = newValue\n///         }\n///     }\n///\n///     // this is the function to globally override the log level, it is not part of the `LogHandler` protocol\n///     public static func overrideGlobalLogLevel(_ logLevel: Logger.Level) {\n///         LogHandlerWithGlobalLogLevelOverride.overrideLock.withLock {\n///             LogHandlerWithGlobalLogLevelOverride.overrideLogLevel = logLevel\n///         }\n///     }\n/// }\n/// ```\n///\n/// Please note that the above `LogHandler` will still pass the 'log level is a value' test above it iff the global log\n/// level has not been overridden. And most importantly it passes the requirement listed above: A change to the log\n/// level on one `Logger` should not affect the log level of another `Logger` variable.\npublic protocol LogHandler {\n    /// This method is called when a `LogHandler` must emit a log message. There is no need for the `LogHandler` to\n    /// check if the `level` is above or below the configured `logLevel` as `Logger` already performed this check and\n    /// determined that a message should be logged.\n    ///\n    /// - parameters:\n    ///     - level: The log level the message was logged at.\n    ///     - message: The message to log. To obtain a `String` representation call `message.description`.\n    ///     - metadata: The metadata associated to this log message.\n    ///     - file: The file the log message was emitted from.\n    ///     - function: The function the log line was emitted from.\n    ///     - line: The line the log message was emitted from.\n    func log(level: Logger.Level,\n             message: Logger.Message,\n             metadata: Logger.Metadata?,\n             file: String, function: String, line: UInt)\n\n    /// Add, remove, or change the logging metadata.\n    ///\n    /// - note: `LogHandler`s must treat logging metadata as a value type. This means that the change in metadata must\n    ///         only affect this very `LogHandler`.\n    ///\n    /// - parameters:\n    ///    - metadataKey: The key for the metadata item\n    subscript(metadataKey _: String) -> Logger.Metadata.Value? { get set }\n\n    /// Get or set the entire metadata storage as a dictionary.\n    ///\n    /// - note: `LogHandler`s must treat logging metadata as a value type. This means that the change in metadata must\n    ///         only affect this very `LogHandler`.\n    var metadata: Logger.Metadata { get set }\n\n    /// Get or set the configured log level.\n    ///\n    /// - note: `LogHandler`s must treat the log level as a value type. This means that the change in metadata must\n    ///         only affect this very `LogHandler`. It is acceptable to provide some form of global log level override\n    ///         that means a change in log level on a particular `LogHandler` might not be reflected in any\n    ///        `LogHandler`.\n    var logLevel: Logger.Level { get set }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/Logging/Logging.swift",
    "content": "//===----------------------------------------------------------------------===//\n//\n// This source file is part of the Swift Logging API open source project\n//\n// Copyright (c) 2018-2019 Apple Inc. and the Swift Logging API project authors\n// Licensed under Apache License v2.0\n//\n// See LICENSE.txt for license information\n// See CONTRIBUTORS.txt for the list of Swift Logging API project authors\n//\n// SPDX-License-Identifier: Apache-2.0\n//\n//===----------------------------------------------------------------------===//\n\n#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)\n    import Darwin\n#else\n    import Glibc\n#endif\n\n/// A `Logger` is the central type in `SwiftLog`. Its central function is to emit log messages using one of the methods\n/// corresponding to a log level.\n///\n/// The most basic usage of a `Logger` is\n///\n///     logger.info(\"Hello World!\")\n///\npublic struct Logger {\n    @usableFromInline\n    var handler: LogHandler\n    public let label: String\n\n    internal init(label: String, _ handler: LogHandler) {\n        self.label = label\n        self.handler = handler\n    }\n}\n\nextension Logger {\n    /// Log a message passing the log level as a parameter.\n    ///\n    /// If the `logLevel` passed to this method is more severe than the `Logger`'s `logLevel`, it will be logged,\n    /// otherwise nothing will happen.\n    ///\n    /// - parameters:\n    ///    - level: The log level to log `message` at. For the available log levels, see `Logger.Level`.\n    ///    - message: The message to be logged. `message` can be used with any string interpolation literal.\n    ///    - metadata: One-off metadata to attach to this log message\n    ///    - file: The file this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#file`.\n    ///    - function: The function this log message originates from (there's usually no need to pass it explicitly as\n    ///                it defaults to `#file`.\n    ///    - line: The line this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#line`.\n    @inlinable\n    public func log(level: Logger.Level,\n                    _ message: @autoclosure () -> Logger.Message,\n                    metadata: @autoclosure () -> Logger.Metadata? = nil,\n                    file: String = #file, function: String = #function, line: UInt = #line) {\n        if self.logLevel <= level {\n            self.handler.log(level: level,\n                             message: message(),\n                             metadata: metadata(),\n                             file: file, function: function, line: line)\n        }\n    }\n\n    /// Add, change, or remove a logging metadata item.\n    ///\n    /// - note: Logging metadata behaves as a value that means a change to the logging metadata will only affect the\n    ///         very `Logger` it was changed on.\n    @inlinable\n    public subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? {\n        get {\n            return self.handler[metadataKey: metadataKey]\n        }\n        set {\n            self.handler[metadataKey: metadataKey] = newValue\n        }\n    }\n\n    /// Get or set the log level configured for this `Logger`.\n    ///\n    /// - note: `Logger`s treat `logLevel` as a value. This means that a change in `logLevel` will only affect this\n    ///         very `Logger`. It it acceptable for logging backends to have some form of global log level override\n    ///         that affects multiple or even all loggers. This means a change in `logLevel` to one `Logger` might in\n    ///         certain cases have no effect.\n    @inlinable\n    public var logLevel: Logger.Level {\n        get {\n            return self.handler.logLevel\n        }\n        set {\n            self.handler.logLevel = newValue\n        }\n    }\n}\n\nextension Logger {\n    /// Log a message passing with the `Logger.trace` log level.\n    ///\n    /// If `.trace` is at least as severe as the `Logger`'s `logLevel`, it will be logged,\n    /// otherwise nothing will happen.\n    ///\n    /// - parameters:\n    ///    - level: The log level to log `message` at. For the available log levels, see `Logger.Level`.\n    ///    - message: The message to be logged. `message` can be used with any string interpolation literal.\n    ///    - metadata: One-off metadata to attach to this log message\n    ///    - file: The file this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#file`.\n    ///    - function: The function this log message originates from (there's usually no need to pass it explicitly as\n    ///                it defaults to `#file`.\n    ///    - line: The line this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#line`.\n    @inlinable\n    public func trace(_ message: @autoclosure () -> Logger.Message,\n                      metadata: @autoclosure () -> Logger.Metadata? = nil,\n                      file: String = #file, function: String = #function, line: UInt = #line) {\n        self.log(level: .trace, message(), metadata: metadata(), file: file, function: function, line: line)\n    }\n\n    /// Log a message passing with the `Logger.info` log level.\n    ///\n    /// If `.debug` is at least as severe as the `Logger`'s `logLevel`, it will be logged,\n    /// otherwise nothing will happen.\n    ///\n    /// - parameters:\n    ///    - level: The log level to log `message` at. For the available log levels, see `Logger.Level`.\n    ///    - message: The message to be logged. `message` can be used with any string interpolation literal.\n    ///    - metadata: One-off metadata to attach to this log message\n    ///    - file: The file this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#file`.\n    ///    - function: The function this log message originates from (there's usually no need to pass it explicitly as\n    ///                it defaults to `#file`.\n    ///    - line: The line this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#line`.\n    @inlinable\n    public func debug(_ message: @autoclosure () -> Logger.Message,\n                      metadata: @autoclosure () -> Logger.Metadata? = nil,\n                      file: String = #file, function: String = #function, line: UInt = #line) {\n        self.log(level: .debug, message(), metadata: metadata(), file: file, function: function, line: line)\n    }\n\n    /// Log a message passing with the `Logger.Level.info` log level.\n    ///\n    /// If `.info` is at least as severe as the `Logger`'s `logLevel`, it will be logged,\n    /// otherwise nothing will happen.\n    ///\n    /// - parameters:\n    ///    - level: The log level to log `message` at. For the available log levels, see `Logger.Level`.\n    ///    - message: The message to be logged. `message` can be used with any string interpolation literal.\n    ///    - metadata: One-off metadata to attach to this log message\n    ///    - file: The file this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#file`.\n    ///    - function: The function this log message originates from (there's usually no need to pass it explicitly as\n    ///                it defaults to `#file`.\n    ///    - line: The line this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#line`.\n    @inlinable\n    public func info(_ message: @autoclosure () -> Logger.Message,\n                     metadata: @autoclosure () -> Logger.Metadata? = nil,\n                     file: String = #file, function: String = #function, line: UInt = #line) {\n        self.log(level: .info, message(), metadata: metadata(), file: file, function: function, line: line)\n    }\n\n    /// Log a message passing with the `Logger.Level.notice` log level.\n    ///\n    /// If `.notice` is at least as severe as the `Logger`'s `logLevel`, it will be logged,\n    /// otherwise nothing will happen.\n    ///\n    /// - parameters:\n    ///    - level: The log level to log `message` at. For the available log levels, see `Logger.Level`.\n    ///    - message: The message to be logged. `message` can be used with any string interpolation literal.\n    ///    - metadata: One-off metadata to attach to this log message\n    ///    - file: The file this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#file`.\n    ///    - function: The function this log message originates from (there's usually no need to pass it explicitly as\n    ///                it defaults to `#file`.\n    ///    - line: The line this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#line`.\n    @inlinable\n    public func notice(_ message: @autoclosure () -> Logger.Message,\n                       metadata: @autoclosure () -> Logger.Metadata? = nil,\n                       file: String = #file, function: String = #function, line: UInt = #line) {\n        self.log(level: .notice, message(), metadata: metadata(), file: file, function: function, line: line)\n    }\n\n    /// Log a message passing with the `Logger.Level.warning` log level.\n    ///\n    /// If `.warning` is at least as severe as the `Logger`'s `logLevel`, it will be logged,\n    /// otherwise nothing will happen.\n    ///\n    /// - parameters:\n    ///    - level: The log level to log `message` at. For the available log levels, see `Logger.Level`.\n    ///    - message: The message to be logged. `message` can be used with any string interpolation literal.\n    ///    - metadata: One-off metadata to attach to this log message\n    ///    - file: The file this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#file`.\n    ///    - function: The function this log message originates from (there's usually no need to pass it explicitly as\n    ///                it defaults to `#file`.\n    ///    - line: The line this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#line`.\n    @inlinable\n    public func warning(_ message: @autoclosure () -> Logger.Message,\n                        metadata: @autoclosure () -> Logger.Metadata? = nil,\n                        file: String = #file, function: String = #function, line: UInt = #line) {\n        self.log(level: .warning, message(), metadata: metadata(), file: file, function: function, line: line)\n    }\n\n    /// Log a message passing with the `Logger.Level.error` log level.\n    ///\n    /// If `.error` is at least as severe as the `Logger`'s `logLevel`, it will be logged,\n    /// otherwise nothing will happen.\n    ///\n    /// - parameters:\n    ///    - level: The log level to log `message` at. For the available log levels, see `Logger.Level`.\n    ///    - message: The message to be logged. `message` can be used with any string interpolation literal.\n    ///    - metadata: One-off metadata to attach to this log message\n    ///    - file: The file this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#file`.\n    ///    - function: The function this log message originates from (there's usually no need to pass it explicitly as\n    ///                it defaults to `#file`.\n    ///    - line: The line this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#line`.\n    @inlinable\n    public func error(_ message: @autoclosure () -> Logger.Message,\n                      metadata: @autoclosure () -> Logger.Metadata? = nil,\n                      file: String = #file, function: String = #function, line: UInt = #line) {\n        self.log(level: .error, message(), metadata: metadata(), file: file, function: function, line: line)\n    }\n\n    /// Log a message passing with the `Logger.Level.critical` log level.\n    ///\n    /// `.critical` messages will always be logged.\n    ///\n    /// - parameters:\n    ///    - level: The log level to log `message` at. For the available log levels, see `Logger.Level`.\n    ///    - message: The message to be logged. `message` can be used with any string interpolation literal.\n    ///    - metadata: One-off metadata to attach to this log message\n    ///    - file: The file this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#file`.\n    ///    - function: The function this log message originates from (there's usually no need to pass it explicitly as\n    ///                it defaults to `#file`.\n    ///    - line: The line this log message originates from (there's usually no need to pass it explicitly as it\n    ///            defaults to `#line`.\n    @inlinable\n    public func critical(_ message: @autoclosure () -> Logger.Message,\n                         metadata: @autoclosure () -> Logger.Metadata? = nil,\n                         file: String = #file, function: String = #function, line: UInt = #line) {\n        self.log(level: .critical, message(), metadata: metadata(), file: file, function: function, line: line)\n    }\n}\n\n/// The `LoggingSystem` is a global facility where the default logging backend implementation (`LogHandler`) can be\n/// configured. `LoggingSystem` is set up just once in a given program to set up the desired logging backend\n/// implementation.\npublic enum LoggingSystem {\n    fileprivate static let lock = ReadWriteLock()\n    fileprivate static var factory: (String) -> LogHandler = StdoutLogHandler.init\n    fileprivate static var initialized = false\n\n    /// `bootstrap` is a one-time configuration function which globally selects the desired logging backend\n    /// implementation. `bootstrap` can be called at maximum once in any given program, calling it more than once will\n    /// lead to undefined behaviour, most likely a crash.\n    ///\n    /// - parameters:\n    ///     - factory: A closure that given a `Logger` identifier, produces an instance of the `LogHandler`.\n    public static func bootstrap(_ factory: @escaping (String) -> LogHandler) {\n        lock.withWriterLock {\n            precondition(!self.initialized, \"logging system can only be initialized once per process.\")\n            self.factory = factory\n            self.initialized = true\n        }\n    }\n\n    // for our testing we want to allow multiple bootstraping\n    internal static func bootstrapInternal(_ factory: @escaping (String) -> LogHandler) {\n        self.lock.withWriterLock {\n            self.factory = factory\n        }\n    }\n}\n\nextension Logger {\n    /// `Metadata` is a typealias for `[String: Logger.MetadataValue]` the type of the metadata storage.\n    public typealias Metadata = [String: MetadataValue]\n\n    /// A logging metadata value. `Logger.MetadataValue` is string, array, and dictionary literal convertible.\n    public enum MetadataValue {\n        /// A metadata value which is a `String`.\n        case string(String)\n\n        /// A metadata value which is some `CustomStringConvertible`.\n        case stringConvertible(CustomStringConvertible)\n\n        /// A metadata value which is a dictionary from `String` to `Logger.MetadataValue`.\n        case dictionary(Metadata)\n\n        /// A metadata value which is an array of `Logger.MetadataValue`s.\n        case array([Metadata.Value])\n    }\n\n    /// The log level.\n    ///\n    /// Raw values of log levels correspond to their severity, and are ordered by lowest numeric value (0) being\n    /// the most severe. The raw values match the syslog values.\n    public enum Level: CaseIterable {\n        /// Appropriate for messages that contain information only when debugging a program.\n        case trace\n\n        /// Appropriate for messages that contain information normally of use only when\n        /// debugging a program.\n        case debug\n\n        /// Appropriate for informational messages.\n        case info\n\n        /// Appropriate for conditions that are not error conditions, but that may require\n        /// special handling.\n        case notice\n\n        /// Appropriate for messages that are not error conditions, but more severe than\n        /// `.notice`.\n        case warning\n\n        /// Appropriate for error conditions.\n        case error\n\n        /// Appropriate for criticial error conditions that usually require immediate\n        /// attention.\n        ///\n        /// When a `critical` message is logged, the logging backend (`LogHandler`) is free to perform\n        /// more heavy-weight operations to capture system state (such as capturing stack traces) to facilitate\n        /// debugging.\n        case critical\n    }\n\n    /// Construct a `Logger` given a `label` identifying the creator of the `Logger`.\n    ///\n    /// The `label` should identify the creator of the `Logger`. This can be an application, a sub-system, or even\n    /// a datatype.\n    ///\n    /// - parameters:\n    ///     - label: An identifier for the creator of a `Logger`.\n    public init(label: String) {\n        self = LoggingSystem.lock.withReaderLock { Logger(label: label, LoggingSystem.factory(label)) }\n    }\n\n    /// Construct a `Logger` given a `label` identifying the creator of the `Logger` or a non-standard `LogHandler`.\n    ///\n    /// The `label` should identify the creator of the `Logger`. This can be an application, a sub-system, or even\n    /// a datatype.\n    ///\n    /// This initializer provides an escape hatch in case the global default logging backend implementation (set up\n    /// using `LoggingSystem.bootstrap` is not appropriate for this particular logger.\n    ///\n    /// - parameters:\n    ///     - label: An identifier for the creator of a `Logger`.\n    ///     - factory: A closure creating non-standard `LogHandler`s.\n    public init(label: String, factory: (String) -> LogHandler) {\n        self = Logger(label: label, factory(label))\n    }\n}\n\nextension Logger.Level {\n    internal var naturalIntegralValue: Int {\n        switch self {\n        case .trace:\n            return 0\n        case .debug:\n            return 1\n        case .info:\n            return 2\n        case .notice:\n            return 3\n        case .warning:\n            return 4\n        case .error:\n            return 5\n        case .critical:\n            return 6\n        }\n    }\n}\n\nextension Logger.Level: Comparable {\n    public static func < (lhs: Logger.Level, rhs: Logger.Level) -> Bool {\n        return lhs.naturalIntegralValue < rhs.naturalIntegralValue\n    }\n}\n\n// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for\n// https://bugs.swift.org/browse/SR-9687\n// Then we could write it as follows and it would work under Swift 5 and not only 4 as it does currently:\n// extension Logger.Metadata.Value: Equatable {\nextension Logger.MetadataValue: Equatable {\n    public static func == (lhs: Logger.Metadata.Value, rhs: Logger.Metadata.Value) -> Bool {\n        switch (lhs, rhs) {\n        case (.string(let lhs), .string(let rhs)):\n            return lhs == rhs\n        case (.stringConvertible(let lhs), .stringConvertible(let rhs)):\n            return lhs.description == rhs.description\n        case (.array(let lhs), .array(let rhs)):\n            return lhs == rhs\n        case (.dictionary(let lhs), .dictionary(let rhs)):\n            return lhs == rhs\n        default:\n            return false\n        }\n    }\n}\n\nextension Logger {\n    /// `Logger.Message` represents a log message's text. It is usually created using string literals.\n    ///\n    /// Example creating a `Logger.Message`:\n    ///\n    ///     let world: String = \"world\"\n    ///     let myLogMessage: Logger.Message = \"Hello \\(world)\"\n    ///\n    /// Most commonly, `Logger.Message`s appear simply as the parameter to a logging method such as:\n    ///\n    ///     logger.info(\"Hello \\(world)\")\n    ///\n    public struct Message: ExpressibleByStringLiteral,\n                           Equatable,\n                           CustomStringConvertible,\n                           ExpressibleByStringInterpolation {\n        public typealias StringLiteralType = String\n\n        private var value: String\n\n        public init(stringLiteral value: String) {\n            self.value = value\n        }\n\n        public var description: String {\n            return self.value\n        }\n    }\n}\n\n/// A pseudo-`LogHandler` that can be used to send messages to multiple other `LogHandler`s.\n///\n/// The first `LogHandler` passed to the initialisation function of `MultiplexLogHandler` control the `logLevel` as\n/// well as the `metadata` for this `LogHandler`. Any subsequent `LogHandler`s used to initialise a\n/// `MultiplexLogHandler` are merely to emit the log message to another place.\npublic struct MultiplexLogHandler: LogHandler {\n    private var handlers: [LogHandler]\n\n    public init(_ handlers: [LogHandler]) {\n        assert(handlers.count > 0)\n        self.handlers = handlers\n    }\n\n    public var logLevel: Logger.Level {\n        get {\n            return self.handlers[0].logLevel\n        }\n        set {\n            self.mutatingForEachHandler {\n                $0.logLevel = newValue\n            }\n        }\n    }\n\n    public func log(level: Logger.Level,\n                    message: Logger.Message,\n                    metadata: Logger.Metadata?,\n                    file: String, function: String, line: UInt) {\n        self.handlers.forEach { handler in\n            handler.log(level: level, message: message, metadata: metadata, file: file, function: function, line: line)\n        }\n    }\n\n    public var metadata: Logger.Metadata {\n        get {\n            return self.handlers[0].metadata\n        }\n        set {\n            self.mutatingForEachHandler { $0.metadata = newValue }\n        }\n    }\n\n    public subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? {\n        get {\n            return self.handlers[0].metadata[metadataKey]\n        }\n        set {\n            self.mutatingForEachHandler { $0[metadataKey: metadataKey] = newValue }\n        }\n    }\n\n    private mutating func mutatingForEachHandler(_ mutator: (inout LogHandler) -> Void) {\n        for index in self.handlers.indices {\n            mutator(&self.handlers[index])\n        }\n    }\n}\n\n/// Ships with the logging module, really boring just prints something using the `print` function\ninternal struct StdoutLogHandler: LogHandler {\n    private let lock = Lock()\n\n    public init(label: String) {}\n\n    private var _logLevel: Logger.Level = .info\n\n    public var logLevel: Logger.Level {\n        get {\n            return self.lock.withLock { self._logLevel }\n        }\n        set {\n            self.lock.withLock {\n                self._logLevel = newValue\n            }\n        }\n    }\n\n    private var prettyMetadata: String?\n    private var _metadata = Logger.Metadata() {\n        didSet {\n            self.prettyMetadata = self.prettify(self._metadata)\n        }\n    }\n\n    public func log(level: Logger.Level,\n                    message: Logger.Message,\n                    metadata: Logger.Metadata?,\n                    file: String, function: String, line: UInt) {\n        let prettyMetadata = metadata?.isEmpty ?? true\n            ? self.prettyMetadata\n            : self.prettify(self.metadata.merging(metadata!, uniquingKeysWith: { _, new in new }))\n        print(\"\\(self.timestamp()) \\(level):\\(prettyMetadata.map { \" \\($0)\" } ?? \"\") \\(message)\")\n    }\n\n    public var metadata: Logger.Metadata {\n        get {\n            return self.lock.withLock { self._metadata }\n        }\n        set {\n            self.lock.withLock { self._metadata = newValue }\n        }\n    }\n\n    public subscript(metadataKey metadataKey: String) -> Logger.Metadata.Value? {\n        get {\n            return self.lock.withLock { self._metadata[metadataKey] }\n        }\n        set {\n            self.lock.withLock {\n                self._metadata[metadataKey] = newValue\n            }\n        }\n    }\n\n    private func prettify(_ metadata: Logger.Metadata) -> String? {\n        return !metadata.isEmpty ? metadata.map { \"\\($0)=\\($1)\" }.joined(separator: \" \") : nil\n    }\n\n    private func timestamp() -> String {\n        var buffer = [Int8](repeating: 0, count: 255)\n        var timestamp = time(nil)\n        let localTime = localtime(&timestamp)\n        strftime(&buffer, buffer.count, \"%Y-%m-%dT%H:%M:%S%z\", localTime)\n        return buffer.withUnsafeBufferPointer {\n            $0.withMemoryRebound(to: CChar.self) {\n                String(cString: $0.baseAddress!)\n            }\n        }\n    }\n}\n\n// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for\n// https://bugs.swift.org/browse/SR-9687\nextension Logger.MetadataValue: ExpressibleByStringLiteral {\n    public typealias StringLiteralType = String\n\n    public init(stringLiteral value: String) {\n        self = .string(value)\n    }\n}\n\nextension Logger.MetadataValue: CustomStringConvertible {\n    public var description: String {\n        switch self {\n        case .dictionary(let dict):\n            return dict.mapValues { $0.description }.description\n        case .array(let list):\n            return list.map { $0.description }.description\n        case .string(let str):\n            return str\n        case .stringConvertible(let repr):\n            return repr.description\n        }\n    }\n}\n\n// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for\n// https://bugs.swift.org/browse/SR-9687\nextension Logger.MetadataValue: ExpressibleByStringInterpolation {\n}\n\n// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for\n// https://bugs.swift.org/browse/SR-9687\nextension Logger.MetadataValue: ExpressibleByDictionaryLiteral {\n    public typealias Key = String\n    public typealias Value = Logger.Metadata.Value\n\n    public init(dictionaryLiteral elements: (String, Logger.Metadata.Value)...) {\n        self = .dictionary(.init(uniqueKeysWithValues: elements))\n    }\n}\n\n// Extension has to be done on explicit type rather than Logger.Metadata.Value as workaround for\n// https://bugs.swift.org/browse/SR-9687\nextension Logger.MetadataValue: ExpressibleByArrayLiteral {\n    public typealias ArrayLiteralElement = Logger.Metadata.Value\n\n    public init(arrayLiteral elements: Logger.Metadata.Value...) {\n        self = .array(elements)\n    }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/ModelGroupManager.swift",
    "content": "//\n//  ModelGroupManager.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/7/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\n\n/// Manages available models for a AIStudioFeature, including currently selected fetaure.\nclass ModelGroupManager {\n  var models: [FritzModelDetails]\n  var selectedPredictorDetails: FritzModelDetails?\n  let tagName: String?\n\n  init(initialModel model: FritzModelDetails, tagName: String?) {\n    self.models = [model]\n    self.selectedPredictorDetails = model\n    self.tagName = tagName\n  }\n\n  init(with models: [FritzModelDetails], initialModel model: FritzModelDetails?, tagName: String?) {\n    self.models = models\n    self.selectedPredictorDetails = model\n    self.tagName = tagName\n  }\n\n\n  init() {\n    self.models = []\n    self.selectedPredictorDetails = nil\n    self.tagName = nil\n  }\n\n  // Fetch models for tags.\n  func fetchModels() {\n    guard let tagName = tagName else { return }\n    let tags = ModelTagManager(tags: [tagName])\n    tags.fetchManagedModelsForTags { models, error in\n      guard let managedModels = models else { return }\n\n      var newModels: [FritzModelDetails] = []\n\n      // Indices of models in existing models that were also shared by the\n      // tags response.  Helpful if you have models on device that are not tagged.\n      var commonModelIndices: [Int] = []\n\n      for model in managedModels {\n        let featureName = model.activeModelConfig.metadata?[\"fritz_feature\"] ?? \"\"\n        let featureDescription = AIStudioFeaturePredictors.init(rawValue: featureName)\n        let newFritzModel = FritzModelDetails(with: model, featureDescription: featureDescription ?? .unknown)\n\n        if let index = self.models.firstIndex(of: newFritzModel) {\n          commonModelIndices.append(index)\n          newModels.append(self.models[index])\n        } else {\n          newModels.append(newFritzModel)\n        }\n      }\n\n      // add existing models to newModels that were not udpated in tag query.\n      for (i, model) in self.models.enumerated() {\n        if commonModelIndices.contains(i) {\n          continue\n        }\n        newModels.append(model)\n      }\n\n      self.models = newModels\n    }\n  }\n}\n\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/PredictorOptionTypes.swift",
    "content": "//\n//  ConfigurableOptionType.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/24/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\n\n\npublic typealias ConfigurableOptions = [PredictorOptionTypes:PredictorOption]\n\n/// Various Model Configuration parameters.\npublic enum PredictorOptionTypes {\n  // These are global to all models, if you want to add a new one, just add a new case here.\n  case minThreshold\n  case maxThreshold\n  case alpha\n  case modelResolution\n  case numPoses\n  case minPoseThreshold\n  case minPartThreshold\n  case color\n  case interpolationQuality\n  case blendingMode\n  case boundingBoxes\n  case opacity\n\n  func getName() -> String{\n    switch self {\n    case .minThreshold: return \"Min Threshold\"\n    case .maxThreshold: return \"Max Threshold\"\n    case .alpha: return \"Alpha\"\n    case .modelResolution: return \"Model Resolution\"\n    case .numPoses: return \"Number of Poses\"\n    case .minPartThreshold: return \"Min Part Threshold\"\n    case .minPoseThreshold: return \"Min pose Threshold\"\n    case .color: return \"Color\"\n    case .interpolationQuality: return \"Interpolation Quality\"\n    case .blendingMode: return \"Blending Mode\"\n    case .boundingBoxes: return \"Bounding Boxes\"\n    case .opacity: return \"Opacity\"\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/Utils/FritzDeviceUtil.swift",
    "content": "//\n//  LuminaDeviceUtil.swift\n//  Lumina\n//\n//  Created by David Okun on 10/20/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n//  Thank you to Saoud M. Rizwan!\n//  https://medium.com/@sdrzn/make-your-ios-app-feel-better-a-comprehensive-guide-over-taptic-engine-and-haptic-feedback-724dec425f10\n\nimport UIKit\nimport AudioToolbox.AudioServices\n\nfinal class FritzHapticFeedbackGenerator {\n  private let notificationGeneratorSharedInstance = UINotificationFeedbackGenerator()\n\n  func prepare() {\n    notificationGeneratorSharedInstance.prepare()\n  }\n\n  func errorFeedback() {\n    if UIDevice.current.hasHapticFeedback {\n      notificationGeneratorSharedInstance.notificationOccurred(.warning)\n    } else if UIDevice.current.hasTapticEngine {\n      let tryAgain = SystemSoundID(1102)\n      AudioServicesPlaySystemSound(tryAgain)\n    }\n  }\n}\n\ninternal extension UIDevice {\n  enum DevicePlatform {\n    case other\n    case iPhone6S\n    case iPhone6SPlus\n    case iPhone7\n    case iPhone7Plus\n    case iPhone8\n    case iPhone8Plus\n    case iPhoneX\n    case iPhoneXS\n    case iPhoneXSMax\n    case iPhoneXR\n    case simulator\n  }\n\n  static var hasNotch: Bool {\n    return platform == .iPhoneXSMax ||\n      platform == .iPhoneXS ||\n      platform == .iPhoneXR ||\n      platform == .iPhoneX || platform == .simulator\n  }\n\n  static var platform: DevicePlatform {\n    var sysinfo = utsname()\n    uname(&sysinfo)\n    let platform = String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters)\n    switch platform {\n    case \"x86_64\":\n      return .simulator\n    case \"iPhone11,2\":\n      return .iPhoneXS\n    case \"iPhone11,4\", \"iPhone11,6\":\n      return .iPhoneXSMax\n    case \"iPhone11,8\":\n      return .iPhoneXR\n    case \"iPhone10,1\", \"iPhone10,4\":\n      return .iPhone8\n    case \"iPhone10,2\", \"iPhone10,5\":\n      return .iPhone8Plus\n    case \"iPhone10,3\", \"iPhone10,6\":\n      return .iPhoneX\n    case \"iPhone9,2\", \"iPhone9,4\":\n      return .iPhone7Plus\n    case \"iPhone9,1\", \"iPhone9,3\":\n      return .iPhone7\n    case \"iPhone8,2\":\n      return .iPhone6SPlus\n    case \"iPhone8,1\":\n      return .iPhone6S\n    default:\n      return .other\n    }\n  }\n\n  var hasTapticEngine: Bool {\n    let platform = UIDevice.platform\n    return platform == .iPhone6S || platform == .iPhone6SPlus || platform == .iPhone7 || platform == .iPhone7Plus || platform == .iPhone8 || platform == .iPhone8Plus || platform == .iPhoneX\n  }\n\n  var hasHapticFeedback: Bool {\n    let platform = UIDevice.platform\n    return platform == .iPhone7 || platform == .iPhone7Plus || platform == .iPhone8 || platform == .iPhone8Plus || platform == .iPhoneX\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Common/Utils/FritzLogger.swift",
    "content": "//\n//  LuminaLogger.swift\n//  Lumina\n//\n//  Created by David Okun on 4/11/19.\n//  Copyright © 2019 David Okun. All rights reserved.\n//\n\nimport Foundation\n\npublic extension Logger.Level {\n  var uppercasedStringRepresentation: String {\n    switch self {\n    case .trace: return \"TRACE\"\n    case .debug: return \"DEBUG\"\n    case .info: return \"INFO\"\n    case .notice: return \"NOTICE\"\n    case .warning: return \"WARNING\"\n    case .error: return \"ERROR\"\n    case .critical: return \"CRITICAL\"\n    }\n  }\n}\n\ninternal class FritzLogger {\n  private static let logger = Logger(label: \"ai.fritz.aistudio\")\n  internal static var level: Logger.Level = .critical\n\n  static func trace(message: String, metadata: Logger.Metadata? = nil) {\n    if level >= .trace {\n      logger.trace(\"\\(message)\", metadata: metadata)\n    }\n  }\n\n  static func debug(message: String, metadata: Logger.Metadata? = nil) {\n    if level >= .debug {\n      logger.debug(\"\\(message)\", metadata: metadata)\n    }\n  }\n\n  static func info(message: String, metadata: Logger.Metadata? = nil) {\n    if level >= .info {\n      logger.info(\"\\(message)\", metadata: metadata)\n    }\n  }\n\n  static func notice(message: String, metadata: Logger.Metadata? = nil) {\n    if level >= .notice {\n      logger.notice(\"\\(message)\", metadata: metadata)\n    }\n  }\n\n  static func warning(message: String, metadata: Logger.Metadata? = nil) {\n    if level >= .warning {\n      logger.warning(\"\\(message)\", metadata: metadata)\n    }\n  }\n\n  static func error(message: String, metadata: Logger.Metadata? = nil) {\n    if level >= .error {\n      logger.error(\"\\(message)\", metadata: metadata)\n    }\n  }\n\n  static func critical(message: String, metadata: Logger.Metadata? = nil) {\n    if level >= .critical {\n      logger.critical(\"\\(message)\", metadata: metadata)\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Demos/Cells/DemoTableViewCell.swift",
    "content": "//\n//  DemoTableViewCell.swift\n//  FritzAIStudio\n//\n//  Created by Andrew Barba on 12/26/17.\n//  Copyright © 2017 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\n\nclass DemoTableViewCell: UITableViewCell {\n\n    override func awakeFromNib() {\n        super.awakeFromNib()\n\n        let selectionView = UIView()\n        selectionView.backgroundColor = UIColor(red: 0.706, green: 0.133, blue: 0.133, alpha: 1)\n        selectedBackgroundView = selectionView\n    }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Demos/Cells/LinkTableViewCell.swift",
    "content": "//\n//  LinkTableViewCell.swift\n//  FritzAIStudio\n//\n//  Created by Andrew Barba on 12/26/17.\n//  Copyright © 2017 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\n\nclass LinkTableViewCell: UITableViewCell {\n\n    override func awakeFromNib() {\n        super.awakeFromNib()\n\n        let selectionView = UIView()\n        selectionView.backgroundColor = UIColor(red: 0.706, green: 0.133, blue: 0.133, alpha: 1)\n        selectedBackgroundView = selectionView\n    }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Demos/Demos.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15705\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"npk-a6-hdM\">\n    <device id=\"retina4_7\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15706\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Demos View Controller-->\n        <scene sceneID=\"52z-5R-Nve\">\n            <objects>\n                <tableViewController id=\"Cjs-X2-1zP\" customClass=\"DemosViewController\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <tableView key=\"view\" clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" showsHorizontalScrollIndicator=\"NO\" showsVerticalScrollIndicator=\"NO\" dataMode=\"static\" style=\"plain\" separatorStyle=\"default\" rowHeight=\"-1\" estimatedRowHeight=\"-1\" sectionHeaderHeight=\"28\" sectionFooterHeight=\"28\" id=\"ZoN-Fk-Ok9\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <color key=\"separatorColor\" white=\"0.33333333333333331\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <sections>\n                            <tableViewSection id=\"23A-Yv-yEK\">\n                                <cells>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"HairColor\" textLabel=\"lTu-bC-pQm\" detailTextLabel=\"0Fw-CK-INI\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"pUp-vV-F5l\" customClass=\"DemoTableViewCell\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"28\" width=\"375\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"pUp-vV-F5l\" id=\"85h-cn-y1l\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"348\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Hair Color Changer\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"lTu-bC-pQm\" userLabel=\"Hair Color Changer\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"36\" width=\"191.5\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Try on new hair colors on live video.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"0Fw-CK-INI\" userLabel=\"Change the color of your hair\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"66.5\" width=\"207\" height=\"14.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"StyleTransfer\" textLabel=\"Si2-Vg-Bd2\" detailTextLabel=\"IIa-36-1ls\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"hL4-YL-o48\" customClass=\"DemoTableViewCell\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"148\" width=\"375\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"hL4-YL-o48\" id=\"JKc-b2-l1D\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"348\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Style Transfer\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"Si2-Vg-Bd2\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"36\" width=\"138.5\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Apply artistic effects to images and video.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"IIa-36-1ls\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"66.5\" width=\"244.5\" height=\"14.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"PoseEstimation\" textLabel=\"1Ln-SL-nGV\" detailTextLabel=\"C78-aR-I8i\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"WbB-AM-v6l\" customClass=\"DemoTableViewCell\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"268\" width=\"375\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"WbB-AM-v6l\" id=\"Hsy-Mr-xZt\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"348\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Pose Estimation\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"1Ln-SL-nGV\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"29\" width=\"160.5\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Identify and track the body position of a person in real-time.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"C78-aR-I8i\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"59.5\" width=\"291.5\" height=\"29\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"ImageSegmentation\" textLabel=\"PXH-ge-PXM\" detailTextLabel=\"gfc-vs-wq9\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"Ecw-CE-TzD\" customClass=\"DemoTableViewCell\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"388\" width=\"375\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"Ecw-CE-TzD\" id=\"itq-mK-PuL\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"348\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Image Segmentation\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"PXH-ge-PXM\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"29\" width=\"207.5\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Automatically separate people from the background of images and video.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"gfc-vs-wq9\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"59.5\" width=\"318.5\" height=\"29\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"ImageLabeling\" textLabel=\"52B-Dp-Scz\" detailTextLabel=\"V6g-2U-4Wy\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"iMX-bO-lR9\" customClass=\"DemoTableViewCell\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"508\" width=\"375\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"iMX-bO-lR9\" id=\"AHI-PM-OtK\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"348\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Image Labeling\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"52B-Dp-Scz\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"36\" width=\"153\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Label the contents of images in real-time.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"V6g-2U-4Wy\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"66.5\" width=\"241\" height=\"14.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                        <connections>\n                                            <segue destination=\"Qr8-IU-lKA\" kind=\"show\" id=\"QC0-Wb-XkS\"/>\n                                        </connections>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"ObjectDetection\" textLabel=\"yfp-Xy-LzV\" detailTextLabel=\"ZVh-eY-ir5\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"Er5-Ip-S8u\" customClass=\"DemoTableViewCell\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"628\" width=\"375\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"Er5-Ip-S8u\" id=\"v4h-X1-fiq\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"348\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Object Detection\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"yfp-Xy-LzV\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"29\" width=\"170\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Detect objects in a scene and draw bounding boxes around them.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"ZVh-eY-ir5\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"59.5\" width=\"301.5\" height=\"29\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                        <connections>\n                                            <segue destination=\"f9K-kD-QKj\" kind=\"show\" id=\"zmK-qU-nDX\"/>\n                                        </connections>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" textLabel=\"4Rc-Td-Knw\" detailTextLabel=\"UHG-hK-T0P\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"dEF-E8-yAo\" customClass=\"LinkTableViewCell\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"748\" width=\"375\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"dEF-E8-yAo\" id=\"C1e-yy-xk2\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"348\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Learn more about Fritz AI\" textAlignment=\"natural\" lineBreakMode=\"wordWrap\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"4Rc-Td-Knw\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"36\" width=\"250.5\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Teach your mobile app to see, hear, sense, and think.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"UHG-hK-T0P\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"66.5\" width=\"307.5\" height=\"14.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                </cells>\n                            </tableViewSection>\n                        </sections>\n                        <connections>\n                            <outlet property=\"dataSource\" destination=\"Cjs-X2-1zP\" id=\"Jsy-w9-jmc\"/>\n                            <outlet property=\"delegate\" destination=\"Cjs-X2-1zP\" id=\"vXe-2h-7aU\"/>\n                        </connections>\n                    </tableView>\n                    <navigationItem key=\"navigationItem\" id=\"3sy-ld-ocO\"/>\n                </tableViewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"wbQ-fp-TQ8\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"412\" y=\"197.45127436281859\"/>\n        </scene>\n        <!--Navigation Controller-->\n        <scene sceneID=\"RXQ-Fb-gJH\">\n            <objects>\n                <navigationController automaticallyAdjustsScrollViewInsets=\"NO\" modalPresentationStyle=\"fullScreen\" id=\"npk-a6-hdM\" customClass=\"NavigationController\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <toolbarItems/>\n                    <navigationBar key=\"navigationBar\" contentMode=\"scaleToFill\" insetsLayoutMarginsFromSafeArea=\"NO\" id=\"ozK-Nw-7bT\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"44\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </navigationBar>\n                    <nil name=\"viewControllers\"/>\n                    <connections>\n                        <segue destination=\"Cjs-X2-1zP\" kind=\"relationship\" relationship=\"rootViewController\" id=\"h6k-fd-89B\"/>\n                    </connections>\n                </navigationController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"XDu-5k-RaV\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-441\" y=\"197\"/>\n        </scene>\n        <!--DetectObjectsStoryboard-->\n        <scene sceneID=\"L8L-rB-WSc\">\n            <objects>\n                <viewControllerPlaceholder storyboardName=\"DetectObjectsStoryboard\" id=\"f9K-kD-QKj\" sceneMemberID=\"viewController\"/>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"99N-yh-GGM\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"991\" y=\"356\"/>\n        </scene>\n        <!--LabelImages-->\n        <scene sceneID=\"zcB-KE-Ati\">\n            <objects>\n                <viewControllerPlaceholder storyboardName=\"LabelImages\" id=\"Qr8-IU-lKA\" sceneMemberID=\"viewController\"/>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"jff-eE-Bo7\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"991\" y=\"434\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Demos/DemosViewController.swift",
    "content": "//\n//  DemosViewController.swift\n//  FritzAIStudio\n//\n//  Created by Andrew Barba on 12/26/17.\n//  Copyright © 2017 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\nclass DemosViewController: UITableViewController {\n\n  override var preferredStatusBarStyle: UIStatusBarStyle {\n    return .lightContent\n  }\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n    self.view.backgroundColor = .black\n    title = \"Demos\".uppercased()\n    tableView.register(DemoTableViewCell.self, forCellReuseIdentifier: \"DemoTableViewCell\")\n    tableView.register(LinkTableViewCell.self, forCellReuseIdentifier: \"LinkTableViewCell\")\n    clearsSelectionOnViewWillAppear = true\n  }\n\n  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\n    if let _ = tableView.cellForRow(at: indexPath) as? LinkTableViewCell, let url = URL(string: \"https://www.fritz.ai\") {\n      UIApplication.shared.open(url)\n      tableView.deselectRow(at: indexPath, animated: true)\n    }\n\n    if let cell = tableView.cellForRow(at: indexPath) as? DemoTableViewCell {\n      guard let identifier = cell.reuseIdentifier else { return }\n\n      var viewController: UIViewController?\n      switch identifier {\n      case \"ImageSegmentation\":\n        viewController = ImageSegmentationViewController()\n      case \"PoseEstimation\":\n        viewController = PoseEstimationViewController()\n      case \"StyleTransfer\":\n        viewController = StyleTransferViewController()\n      case \"HairColor\":\n        viewController = HairColorViewController()\n      default:\n        return\n      }\n\n      if let currentController = viewController {\n        self.navigationController?.pushViewController(currentController, animated: true)\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Demos/NavigationController.swift",
    "content": "//\n//  NavigationController.swift\n//  FritzAIStudio\n//\n//  Created by Andrew Barba on 12/14/17.\n//  Copyright © 2017 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\n\nclass NavigationController: UINavigationController {\n\n  override var preferredStatusBarStyle: UIStatusBarStyle {\n    return .default\n  }\n\n  override func viewWillAppear(_ animated: Bool) {\n    super.viewWillAppear(animated)\n  }\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    navigationBar.tintColor = .white\n    navigationBar.shadowImage = UIImage()\n    navigationBar.isTranslucent = true\n    navigationBar.setBackgroundImage(UIImage(), for: .default)\n    let blurView = createBlurView()\n    navigationBar.addSubview(blurView)\n\n    let titleFont = UIFont.systemFont(ofSize: 17, weight: .bold)\n    navigationBar.titleTextAttributes = [\n      .font: titleFont,\n      .foregroundColor: UIColor.white\n    ]\n\n    let buttonFont = UIFont.systemFont(ofSize: 14, weight: .semibold)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .normal)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .highlighted)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .disabled)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .selected)\n  }\n\n  private func createBlurView() -> UIVisualEffectView {\n    let visualEffectView   = UIVisualEffectView(effect: UIBlurEffect(style: .dark))\n\n    var bounds = navigationBar.bounds\n    let notchHeight: CGFloat = UIDevice.hasNotch ? 30.0 : 0.0\n    bounds.size.height += 20 + notchHeight\n    bounds.origin.y -= 20 + notchHeight\n\n    visualEffectView.isUserInteractionEnabled = false\n    visualEffectView.frame = bounds\n    visualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]\n    visualEffectView.layer.zPosition = -1\n    return visualEffectView\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ChooseModelController.swift",
    "content": "//\n//  ModelChooserTableViewController.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/5/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\n\nclass ChooseModelTableViewController: UITableViewController {\n  public var models: [FritzModelDetails]!\n\n  private var downloadedModels: [FritzModelDetails] {\n    return models.filter { $0.isDownloaded }\n  }\n  private var notDownloadedModels: [FritzModelDetails] {\n    return models.filter { !$0.isDownloaded }\n  }\n\n  weak var delegate: ChooseFeatureDelegate?\n\n  public var selectedModel: FritzModelDetails? {\n    didSet {\n      if let selectedModel = selectedModel,\n        let index = models.firstIndex(of: selectedModel) {\n        selectedModelIndex = index\n      }\n    }\n  }\n\n  public var selectedModelIndex: Int?\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    if let selectedModel = selectedModel {\n      self.selectedModelIndex = models.firstIndex(of: selectedModel)\n    }\n    self.tableView.delegate = self\n    self.tableView.dataSource = self\n  }\n\n  // MARK: - Table view data source\n\n  override func numberOfSections(in tableView: UITableView) -> Int {\n    return 2\n  }\n\n  override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String {\n\n    if section == 0 {\n      return \"Downloaded models\"\n    }\n    return \"Models available to download\"\n  }\n\n  override func tableView(_ tableView: UITableView,\n                          numberOfRowsInSection section: Int) -> Int {\n    if section == 0 {\n      return downloadedModels.count\n    }\n    return notDownloadedModels.count\n  }\n\n  override func tableView(_ tableView: UITableView,\n                          cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n    if indexPath.section == 0 {\n      let cell = tableView.dequeueReusableCell(withIdentifier: \"ModelCell\", for: indexPath)\n      let model = downloadedModels[indexPath.row]\n      cell.textLabel?.text = model.name\n\n      if model == selectedModel {\n        cell.accessoryType = .checkmark\n      }\n\n      return cell\n    }\n\n    let cell = tableView.dequeueReusableCell(withIdentifier: \"ModelCell\", for: indexPath)\n    cell.textLabel?.text = notDownloadedModels[indexPath.row].name\n\n    return cell\n\n  }\n\n  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\n    if indexPath.section == 0 {\n      let model = downloadedModels[indexPath.row]\n      self.selectedModel = model\n      self.delegate?.choosePredictor(model)\n      self.performSegue(withIdentifier: \"SelectModel\", sender: self)\n    }\n    if indexPath.section == 1 {\n      let cell = tableView.dequeueReusableCell(withIdentifier: \"ModelCell\", for: indexPath)\n      let model = notDownloadedModels[indexPath.row]\n      handleAlert(for: model, cell: cell)\n    }\n  }\n}\n\n\nextension ChooseModelTableViewController {\n\n  func handleAlert(for model: FritzModelDetails, cell: UITableViewCell) {\n    let alertController = UIAlertController(title: model.name, message: model.description, preferredStyle: .actionSheet)\n\n    let downloadAction = UIAlertAction(title: \"Download\", style: .default) { action in\n      let spinner = UIActivityIndicatorView(style: .gray)\n      spinner.startAnimating()\n      DispatchQueue.main.async {\n        cell.accessoryView = spinner\n        self.tableView.reloadData()\n      }\n      model.managedModel.fetchModel { [weak self] downloaded, error in\n        guard let _ = downloaded else { return }\n\n        DispatchQueue.main.async {\n          cell.accessoryView = nil\n          self?.tableView.reloadData()\n        }\n\n      }\n    }\n    alertController.addAction(downloadAction)\n\n    let cancelAction = UIAlertAction(title: \"Cancel\", style: .cancel)\n\n    alertController.addAction(cancelAction)\n\n    //Show alert view\n    present(alertController, animated: true, completion: nil)\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ConfigureModelCells/ChooseColorCell.swift",
    "content": "//\n//  RangeSliderCell.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/7/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\nimport ColorSlider\n\nclass ChooseColorCell: UITableViewCell {\n\n  @IBOutlet weak var sliderView: UIView!\n  \n  @objc func valueChanged(_ sender: UISegmentedControl) {\n    value.color = colorSlider.color\n    delegate?.update(value)\n  }\n\n  var _colorSlider: ColorSlider?\n  var colorSlider: ColorSlider {\n    if let slider = _colorSlider {\n      return slider\n    }\n    let slider = ColorSlider(orientation: .horizontal, previewSide: .top)\n    _colorSlider = slider\n    slider.addTarget(self, action: #selector(valueChanged(_:)), for: .valueChanged)\n\n    return slider\n  }\n\n  weak var delegate: FeatureOptionCellDelegate?\n\n  var name: String!\n\n  var value: ColorSliderValue!\n\n  func initColorSlider(_ colorSliderValue: ColorSliderValue) {\n    self.value = colorSliderValue\n    self.colorSlider.color = colorSliderValue.color\n  }\n\n  override func layoutSubviews() {\n    super.layoutSubviews()\n    colorSlider.frame = bounds\n  }\n\n  override func awakeFromNib() {\n    addSubview(colorSlider)\n  }\n\n  static var identifier: String {\n    return String(describing: self)\n  }\n\n  static var nib: UINib {\n    return UINib(nibName: identifier, bundle: nil)\n  }\n}\n\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ConfigureModelCells/ChooseColorCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"14490.70\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\">\n    <device id=\"retina6_1\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14490.49\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" indentationWidth=\"10\" id=\"wwQ-jE-8Dm\" customClass=\"ChooseColorCell\" customModule=\"Heartbeat\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"44\"/>\n            <autoresizingMask key=\"autoresizingMask\"/>\n            <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"wwQ-jE-8Dm\" id=\"qn5-S4-4GA\" customClass=\"ChooseColorCell\" customModule=\"Heartbeat\" customModuleProvider=\"target\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"43.5\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n            </tableViewCellContentView>\n            <point key=\"canvasLocation\" x=\"-149.27536231884059\" y=\"-60.267857142857139\"/>\n        </tableViewCell>\n    </objects>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ConfigureModelCells/ChooseModelCell.swift",
    "content": "//\n//  ChooseModelCell.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/7/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\n\nimport UIKit\n\nclass ChooseModelCell: UITableViewCell {\n\n    static var identifier: String {\n        return String(describing: self)\n    }\n\n    static var nib:UINib {\n        return UINib(nibName: identifier, bundle: nil)\n    }\n    \n    var name: String?\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ConfigureModelCells/ChooseModelCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\">\n    <device id=\"retina6_1\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14460.20\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\" customClass=\"ChooseModelCell\" customModule=\"Heartbeat\" customModuleProvider=\"target\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" indentationWidth=\"10\" textLabel=\"hkD-tg-TJa\" style=\"IBUITableViewCellStyleDefault\" id=\"hQn-dI-T9f\" customClass=\"ChooseModelCell\" customModule=\"Heartbeat\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"44\"/>\n            <autoresizingMask key=\"autoresizingMask\"/>\n            <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"hQn-dI-T9f\" id=\"YWQ-yJ-khV\" customClass=\"ChooseModelCell\" customModule=\"Heartbeat\" customModuleProvider=\"target\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"43.5\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n                <subviews>\n                    <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Title\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"hkD-tg-TJa\">\n                        <rect key=\"frame\" x=\"20\" y=\"0.0\" width=\"374\" height=\"43.5\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                        <nil key=\"textColor\"/>\n                        <nil key=\"highlightedColor\"/>\n                    </label>\n                </subviews>\n            </tableViewCellContentView>\n            <point key=\"canvasLocation\" x=\"484\" y=\"-202\"/>\n        </tableViewCell>\n    </objects>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ConfigureModelCells/RangeSliderCell.swift",
    "content": "//\n//  RangeSliderCell.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/7/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\n\nclass RangeSliderCell: UITableViewCell {\n\n    @IBOutlet var test: RangeSliderCell!\n    @IBOutlet weak var valueLabel: UILabel!\n    @IBOutlet weak var valueSlider: UISlider!\n\n    weak var delegate: FeatureOptionCellDelegate?\n\n    var name: String!\n    var value: RangeValue!\n\n    @IBAction func valueChanged(_ sender: UISlider) {\n        value.value = sender.value\n        delegate?.update(value)\n        initLabels()\n    }\n\n    func initLabels() {\n        DispatchQueue.main.async {\n            self.valueSlider.minimumValue = self.value.min\n            self.valueSlider.maximumValue = self.value.max\n            self.valueSlider.value = self.value.value\n            self.valueLabel.text = \"\\(self.value.value)\"\n        }\n    }\n\n    static var identifier: String {\n        return String(describing: self)\n    }\n\n    static var nib:UINib {\n        return UINib(nibName: identifier, bundle: nil)\n    }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ConfigureModelCells/RangeSliderCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"14490.70\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\">\n    <device id=\"retina6_1\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14490.49\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\" customClass=\"RangeSliderCell\" customModule=\"Heartbeat\" customModuleProvider=\"target\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" indentationWidth=\"10\" id=\"5pk-1G-6nc\" customClass=\"RangeSliderCell\" customModule=\"Heartbeat\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"44\"/>\n            <autoresizingMask key=\"autoresizingMask\"/>\n            <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"5pk-1G-6nc\" id=\"Yx3-ks-g0Y\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"43.5\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n                <subviews>\n                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"dhj-c9-IIQ\" userLabel=\"Value\">\n                        <rect key=\"frame\" x=\"352\" y=\"11\" width=\"42\" height=\"21\"/>\n                        <constraints>\n                            <constraint firstAttribute=\"width\" constant=\"42\" id=\"fod-OX-PUM\"/>\n                        </constraints>\n                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                        <nil key=\"textColor\"/>\n                        <nil key=\"highlightedColor\"/>\n                    </label>\n                    <slider opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" value=\"0.5\" minValue=\"0.0\" maxValue=\"1\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"f2V-vN-zNW\">\n                        <rect key=\"frame\" x=\"18\" y=\"7\" width=\"286\" height=\"30\"/>\n                        <connections>\n                            <action selector=\"valueChanged:\" destination=\"5pk-1G-6nc\" eventType=\"valueChanged\" id=\"92W-u0-YK7\"/>\n                        </connections>\n                    </slider>\n                </subviews>\n                <constraints>\n                    <constraint firstItem=\"dhj-c9-IIQ\" firstAttribute=\"leading\" secondItem=\"f2V-vN-zNW\" secondAttribute=\"trailing\" constant=\"50\" id=\"BYo-Dj-ut4\"/>\n                    <constraint firstAttribute=\"trailing\" secondItem=\"dhj-c9-IIQ\" secondAttribute=\"trailing\" constant=\"20\" id=\"EzH-LA-Wem\"/>\n                    <constraint firstItem=\"dhj-c9-IIQ\" firstAttribute=\"top\" secondItem=\"Yx3-ks-g0Y\" secondAttribute=\"top\" constant=\"11\" id=\"NdK-d7-4ai\"/>\n                    <constraint firstItem=\"f2V-vN-zNW\" firstAttribute=\"leading\" secondItem=\"Yx3-ks-g0Y\" secondAttribute=\"leading\" constant=\"20\" id=\"Wej-Hg-9f4\"/>\n                    <constraint firstItem=\"f2V-vN-zNW\" firstAttribute=\"top\" secondItem=\"Yx3-ks-g0Y\" secondAttribute=\"top\" constant=\"7\" id=\"k8f-SM-bjc\"/>\n                    <constraint firstAttribute=\"bottom\" secondItem=\"dhj-c9-IIQ\" secondAttribute=\"bottom\" constant=\"11.5\" id=\"w2f-SA-3y1\"/>\n                    <constraint firstAttribute=\"bottom\" secondItem=\"f2V-vN-zNW\" secondAttribute=\"bottom\" constant=\"7.5\" id=\"zGR-IV-XEv\"/>\n                </constraints>\n            </tableViewCellContentView>\n            <connections>\n                <outlet property=\"valueLabel\" destination=\"dhj-c9-IIQ\" id=\"FXh-jk-90u\"/>\n                <outlet property=\"valueSlider\" destination=\"f2V-vN-zNW\" id=\"Gqr-Aq-uqZ\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"479.71014492753625\" y=\"-283.25892857142856\"/>\n        </tableViewCell>\n    </objects>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ConfigureModelCells/SegmentSliderCell.swift",
    "content": "//\n//  RangeSliderCell.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/7/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\n\nclass SegmentSliderCell: UITableViewCell {\n    \n    @IBAction func valueChanged(_ sender: UISegmentedControl) {\n        value.selectedIndex = sender.selectedSegmentIndex\n        delegate?.update(value)\n    }\n    \n    @IBOutlet weak var segmentSlider: UISegmentedControl!\n    weak var delegate: FeatureOptionCellDelegate?\n    \n    var name: String!\n    var value: SegmentValue!\n    \n    func initSegments() {\n        for (i, option) in value.options.enumerated() {\n            segmentSlider.setTitle(option, forSegmentAt: i)\n        }\n        segmentSlider.selectedSegmentIndex = value.selectedIndex\n    }\n    \n    static var identifier: String {\n        return String(describing: self)\n    }\n    \n    static var nib: UINib {\n        return UINib(nibName: identifier, bundle: nil)\n    }\n    \n    \n}\n\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ConfigureModelCells/SegmentSliderCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\">\n    <device id=\"retina6_1\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14460.20\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\" customClass=\"SegmentSliderCell\" customModule=\"Heartbeat\" customModuleProvider=\"target\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" indentationWidth=\"10\" id=\"AoM-pl-b7r\" customClass=\"SegmentSliderCell\" customModule=\"Heartbeat\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"44\"/>\n            <autoresizingMask key=\"autoresizingMask\"/>\n            <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"AoM-pl-b7r\" id=\"6Kd-EI-yWQ\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"43.5\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n                <subviews>\n                    <segmentedControl opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"left\" contentVerticalAlignment=\"top\" segmentControlStyle=\"plain\" selectedSegmentIndex=\"0\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"W9k-AK-W7C\">\n                        <rect key=\"frame\" x=\"20\" y=\"7\" width=\"374\" height=\"29\"/>\n                        <constraints>\n                            <constraint firstAttribute=\"height\" constant=\"28\" id=\"zyK-8c-0XQ\"/>\n                        </constraints>\n                        <segments>\n                            <segment title=\"First\"/>\n                            <segment title=\"Second\"/>\n                            <segment title=\"\"/>\n                            <segment title=\"\"/>\n                        </segments>\n                        <connections>\n                            <action selector=\"valueChanged:\" destination=\"AoM-pl-b7r\" eventType=\"valueChanged\" id=\"y4D-sW-oUJ\"/>\n                        </connections>\n                    </segmentedControl>\n                </subviews>\n                <constraints>\n                    <constraint firstAttribute=\"trailing\" secondItem=\"W9k-AK-W7C\" secondAttribute=\"trailing\" constant=\"20\" id=\"CUE-Qg-2Y4\"/>\n                    <constraint firstItem=\"W9k-AK-W7C\" firstAttribute=\"leading\" secondItem=\"6Kd-EI-yWQ\" secondAttribute=\"leading\" constant=\"20\" id=\"VAD-bx-bw9\"/>\n                    <constraint firstItem=\"W9k-AK-W7C\" firstAttribute=\"top\" secondItem=\"6Kd-EI-yWQ\" secondAttribute=\"top\" constant=\"7\" id=\"mUT-yA-lyM\"/>\n                </constraints>\n            </tableViewCellContentView>\n            <connections>\n                <outlet property=\"segmentSlider\" destination=\"W9k-AK-W7C\" id=\"dDx-wu-zLt\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"-149.27536231884059\" y=\"-60.267857142857139\"/>\n        </tableViewCell>\n    </objects>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ConfigurePopover.swift",
    "content": "//\n//  ConfigureModelPopover.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/6/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\n\n\nprotocol ChooseFeatureDelegate: class {\n\n  func choosePredictor(_ predictor: FritzModelDetails)\n}\n\n\nclass ConfigureFeaturePopoverViewController: UITableViewController {\n\n  @IBAction func unwindWithSelectedRow(segue: UIStoryboardSegue) {\n    tableView.reloadData()\n  }\n\n  public var modelGroup: ModelGroupManager!\n\n  fileprivate var selectedPredictorDetails: FritzModelDetails? {\n    get {\n      return modelGroup.selectedPredictorDetails\n    }\n    set {\n      modelGroup.selectedPredictorDetails = newValue\n    }\n  }\n\n  fileprivate var options: ConfigurableOptions! {\n    set {\n      modelGroup.selectedPredictorDetails!.options = newValue\n    }\n    get {\n      return modelGroup.selectedPredictorDetails!.options\n    }\n  }\n\n  private var optionsList: [PredictorOption]! {\n    return options.values.map { $0 }.sorted { $0.priority < $1.priority }\n  }\n\n  private func getOption(for section: Int) -> PredictorOption {\n    return optionsList[section - 1]\n  }\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    self.tableView.delegate = self\n    self.tableView.dataSource = self\n\n    tableView.register(ChooseModelCell.nib, forCellReuseIdentifier: ChooseModelCell.identifier)\n    tableView.register(RangeSliderCell.nib, forCellReuseIdentifier: RangeSliderCell.identifier)\n    tableView.register(SegmentSliderCell.nib, forCellReuseIdentifier: SegmentSliderCell.identifier)\n    tableView.register(ChooseColorCell.nib, forCellReuseIdentifier: ChooseColorCell.identifier)\n  }\n\n  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {\n    if segue.identifier == \"ChooseModel\" {\n      let modelSelectionViewController = segue.destination as! ChooseModelTableViewController\n      modelSelectionViewController.delegate = self\n      modelSelectionViewController.models = modelGroup.models\n      modelSelectionViewController.selectedModel = selectedPredictorDetails\n      return\n    }\n  }\n\n  override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String {\n    if section == 0 {\n      return \"Model Name\"\n    }\n    return getOption(for: section).optionType.getName()\n  }\n\n  override func numberOfSections(in tableView: UITableView) -> Int {\n    return 1 + optionsList.count\n  }\n\n  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n    if indexPath.section == 0 {\n      let cell = tableView.dequeueReusableCell(withIdentifier: ChooseModelCell.identifier) as! ChooseModelCell\n      if let name = selectedPredictorDetails?.name {\n        cell.textLabel?.text = name\n      } else {\n        cell.textLabel?.text = \"Choose a model\"\n      }\n      cell.accessoryType = .disclosureIndicator\n      return cell\n    }\n\n    let option = getOption(for: indexPath.section)\n\n    switch type(of: option).cellType {\n    case .rangeValue:\n      let cell = tableView.dequeueReusableCell(withIdentifier: RangeSliderCell.identifier) as! RangeSliderCell\n      cell.name = option.optionType.getName()\n      cell.delegate = self\n      cell.value = (option as! RangeValue)\n      cell.initLabels()\n      return cell\n    case .segmentValue:\n      let cell = tableView.dequeueReusableCell(withIdentifier: SegmentSliderCell.identifier) as! SegmentSliderCell\n      cell.name = option.optionType.getName()\n      cell.delegate = self\n      cell.value = (option as! SegmentValue)\n      cell.initSegments()\n      return cell\n    case .colorSlider:\n      let cell = tableView.dequeueReusableCell(withIdentifier: ChooseColorCell.identifier) as! ChooseColorCell\n      cell.name = option.optionType.getName()\n      cell.delegate = self\n      cell.initColorSlider(option as! ColorSliderValue)\n      return cell\n    }\n  }\n\n  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\n    if indexPath.section == 0 {\n      // Segue to the second view controller\n      self.performSegue(withIdentifier: \"ChooseModel\", sender: self)\n    }\n  }\n\n  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n    return 1\n  }\n}\n\nextension ConfigureFeaturePopoverViewController: ChooseFeatureDelegate {\n\n  func choosePredictor(_ predictorDetails: FritzModelDetails) {\n    self.selectedPredictorDetails = predictorDetails\n  }\n}\n\n\nextension ConfigureFeaturePopoverViewController: FeatureOptionCellDelegate {\n\n  func update(_ value: PredictorOption) {\n    options[value.optionType] = value\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/Extensions/NavigationBarCustomization.swift",
    "content": "//\n//  NavigationBarCustomization.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/24/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\n\nextension FeatureViewController {\n\n  func updateNavBar() {\n    let settingsButton = UIImage(named: \"SettingsIcon\")\n    let settingsItem = UIBarButtonItem(\n      image: settingsButton,\n      style: .plain,\n      target: self,\n      action: #selector(settingsButtonTapped(_:)))\n\n    self.navigationItem.rightBarButtonItem = settingsItem\n    self.navigationItem.title = navTitle\n  }\n\n  @objc func settingsButtonTapped(_ button: UIBarButtonItem) {\n    FritzLogger.notice(message: \"Settings button tapped\")\n    let storyboard = UIStoryboard(\n      name: \"ModelOptions\",\n      bundle: Bundle(for: FeatureViewController.self))\n\n    let settingViewController = storyboard.instantiateViewController(\n      withIdentifier: \"ConfigurePredictor\") as! ConfigureFeaturePopoverViewController\n    settingViewController.modelGroup = modelGroup\n\n    let navController =\n      UINavigationController(rootViewController: settingViewController)\n    navController.modalPresentationStyle = .fullScreen\n    let popover = navController.popoverPresentationController\n    popover?.barButtonItem = button\n    \n    present(navController, animated: true)\n  }\n\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/Extensions/SettingsButtonInteractionExtension.swift",
    "content": "//\n//  SettingsButtonInteractionExtension.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/21/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\nimport Fritz\n\nextension FeatureViewController {\n\n  func unwindFromChoosePredictor(segue: UIStoryboardSegue) {\n    if let modelConfigViewController =\n      segue.source as? ConfigureFeaturePopoverViewController {\n      // Add options to feature regardless if it's changed or not.\n      guard let newFeatureDetails =\n        modelConfigViewController.modelGroup.selectedPredictorDetails else { return }\n\n      guard let feature = feature else {\n        self.feature = build(newFeatureDetails)\n        updateDebugImage()\n        return\n      }\n\n      if !feature.predictorDetails.isSamePredictor(newFeatureDetails) {\n        self.feature = build(newFeatureDetails)\n        updateDebugImage()\n        return\n      }\n      feature.predictorDetails.options = newFeatureDetails.options\n      updateDebugImage()\n    }\n  }\n\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/FeatureContainer.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14460.20\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view contentMode=\"scaleToFill\" id=\"iN0-l3-epB\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n            <viewLayoutGuide key=\"safeArea\" id=\"vUN-kp-3ea\"/>\n        </view>\n    </objects>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/FeatureOptions.swift",
    "content": "//\n//  FeatureOptions.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/7/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\n\npublic enum CellType {\n  case rangeValue\n  case segmentValue\n  case colorSlider\n}\n\n\npublic protocol PredictorOption {\n  static var cellType: CellType { get }\n  var priority: Int { get }\n  var optionType: PredictorOptionTypes { get }\n}\n\nprotocol FeatureOptionCellDelegate: class {\n  func update(_ value: PredictorOption)\n}\n\n\n/// Represent a range of values\nstruct RangeValue: PredictorOption {\n  static let cellType: CellType = .rangeValue\n\n  let optionType: PredictorOptionTypes\n  let min: Float\n  let max: Float\n  var value: Float\n  let priority: Int\n}\n\n\n/// Represent distinct values.\nstruct SegmentValue: PredictorOption {\n  static let cellType: CellType = .segmentValue\n\n\n  let optionType: PredictorOptionTypes\n  let options: [String]\n  var selectedIndex: Int\n  let priority: Int\n}\n\n\n/// Represent distinct values.\nstruct ColorSliderValue: PredictorOption {\n  static let cellType: CellType = .colorSlider\n\n  let optionType: PredictorOptionTypes\n  var color: UIColor\n\n  let priority: Int\n}\n\n\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/FeatureViewController.swift",
    "content": "//\n//  FeatureViewController.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 3/7/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\n\nimport UIKit\nimport AVFoundation\nimport Fritz\n\n\nclass FeatureViewController: FritzCameraViewController, FritzCameraControllerDelegate {\n\n  let modelGroup: ModelGroupManager\n\n  var feature: AIStudioImagePredictor?\n\n  let navTitle: String\n\n  public init(modelGroup: ModelGroupManager, title: String) {\n    self.modelGroup = modelGroup\n    self.navTitle = title\n    super.init()\n\n    self.delegate = self\n    self.modelGroup.fetchModels()\n\n    setCancelButton(visible: false)\n\n    if let selectedModel = modelGroup.selectedPredictorDetails {\n      self.feature = build(selectedModel)\n    }\n  }\n\n  required init?(coder aDecoder: NSCoder) {\n    self.modelGroup = ModelGroupManager()\n    self.navTitle = \"\"\n    super.init(coder: aDecoder)\n  }\n\n  open func build(_ predictorDetails: FritzModelDetails) -> AIStudioImagePredictor? {\n    return nil\n  }\n\n  open override func viewWillAppear(_ animated: Bool) {\n    super.viewWillAppear(animated)\n    self.updateNavBar()\n    updateDebugImage()\n  }\n  override func viewDidLoad() {\n    super.viewDidLoad()\n    self.view.backgroundColor = .black\n  }\n\n  override func viewWillLayoutSubviews() {\n    super.viewWillLayoutSubviews()\n  }\n\n\n  @IBAction func unwindWithUpdate(segue: UIStoryboardSegue) {\n    unwindFromChoosePredictor(segue: segue)\n  }\n\n  @IBAction func unwindWithCancel(segue: UIStoryboardSegue) { }\n\n  open func processImage(_ image: FritzVisionImage?) throws -> UIImage? {\n    return try self.feature?.processImage(image)\n  }\n\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/ModelOptions.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<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=\"l86-8w-FuU\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14490.49\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Configure-->\n        <scene sceneID=\"I4y-Lx-iM7\">\n            <objects>\n                <tableViewController storyboardIdentifier=\"ConfigurePredictor\" modalPresentationStyle=\"overCurrentContext\" id=\"l86-8w-FuU\" customClass=\"ConfigureFeaturePopoverViewController\" customModule=\"Heartbeat\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <tableView key=\"view\" clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" dataMode=\"prototypes\" style=\"grouped\" separatorStyle=\"default\" rowHeight=\"-1\" estimatedRowHeight=\"-1\" sectionHeaderHeight=\"1\" sectionFooterHeight=\"5\" id=\"BRh-Bs-cDC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" cocoaTouchSystemColor=\"groupTableViewBackgroundColor\"/>\n                        <prototypes>\n                            <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" textLabel=\"NBU-r6-rRp\" detailTextLabel=\"Up9-Tb-Ao0\" style=\"IBUITableViewCellStyleValue1\" id=\"wod-eK-aWl\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"55.5\" width=\"375\" height=\"44\"/>\n                                <autoresizingMask key=\"autoresizingMask\"/>\n                                <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"wod-eK-aWl\" id=\"I5C-Ov-SQ4\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"341\" height=\"43.5\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                    <subviews>\n                                        <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Model\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"NBU-r6-rRp\">\n                                            <rect key=\"frame\" x=\"16\" y=\"12\" width=\"47.5\" height=\"20.5\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                            <nil key=\"textColor\"/>\n                                            <nil key=\"highlightedColor\"/>\n                                        </label>\n                                        <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"Up9-Tb-Ao0\">\n                                            <rect key=\"frame\" x=\"296\" y=\"12\" width=\"44\" height=\"20.5\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                            <nil key=\"textColor\"/>\n                                            <nil key=\"highlightedColor\"/>\n                                        </label>\n                                    </subviews>\n                                </tableViewCellContentView>\n                            </tableViewCell>\n                        </prototypes>\n                        <sections/>\n                        <connections>\n                            <outlet property=\"dataSource\" destination=\"l86-8w-FuU\" id=\"D78-Lt-eh9\"/>\n                            <outlet property=\"delegate\" destination=\"l86-8w-FuU\" id=\"UG4-T6-PeN\"/>\n                        </connections>\n                    </tableView>\n                    <navigationItem key=\"navigationItem\" title=\"Configure\" id=\"OPx-5O-qNr\">\n                        <barButtonItem key=\"leftBarButtonItem\" title=\"Cancel\" id=\"CTz-Ki-uM6\">\n                            <connections>\n                                <segue destination=\"Ngv-5f-5D6\" kind=\"unwind\" unwindAction=\"unwindWithCancelWithSegue:\" id=\"FQw-Wr-rcd\"/>\n                            </connections>\n                        </barButtonItem>\n                        <barButtonItem key=\"rightBarButtonItem\" title=\"Apply\" id=\"2bx-kt-pAb\">\n                            <connections>\n                                <segue destination=\"Ngv-5f-5D6\" kind=\"unwind\" unwindAction=\"unwindWithUpdateWithSegue:\" id=\"nYW-2l-asU\"/>\n                            </connections>\n                        </barButtonItem>\n                    </navigationItem>\n                    <connections>\n                        <segue destination=\"7a7-gC-daL\" kind=\"show\" identifier=\"ChooseModel\" id=\"ySt-2T-tdJ\"/>\n                    </connections>\n                </tableViewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iD0-2K-RHG\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n                <exit id=\"Ngv-5f-5D6\" userLabel=\"Exit\" sceneMemberID=\"exit\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-4514\" y=\"34\"/>\n        </scene>\n        <!--Choose Model Table View Controller-->\n        <scene sceneID=\"5HM-0p-u0Y\">\n            <objects>\n                <tableViewController id=\"7a7-gC-daL\" customClass=\"ChooseModelTableViewController\" customModule=\"Heartbeat\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <tableView key=\"view\" clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" dataMode=\"prototypes\" style=\"grouped\" separatorStyle=\"default\" rowHeight=\"-1\" estimatedRowHeight=\"-1\" sectionHeaderHeight=\"18\" sectionFooterHeight=\"18\" id=\"cmN-5m-Vm3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" cocoaTouchSystemColor=\"groupTableViewBackgroundColor\"/>\n                        <prototypes>\n                            <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"none\" indentationWidth=\"10\" reuseIdentifier=\"ModelCell\" id=\"VGW-Gb-URc\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"55.5\" width=\"375\" height=\"44\"/>\n                                <autoresizingMask key=\"autoresizingMask\"/>\n                                <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"VGW-Gb-URc\" id=\"2r9-dT-Is9\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"43.5\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                </tableViewCellContentView>\n                            </tableViewCell>\n                        </prototypes>\n                        <connections>\n                            <outlet property=\"dataSource\" destination=\"7a7-gC-daL\" id=\"fZr-v1-bAB\"/>\n                            <outlet property=\"delegate\" destination=\"7a7-gC-daL\" id=\"gBH-Tz-JF0\"/>\n                        </connections>\n                    </tableView>\n                    <connections>\n                        <segue destination=\"bkC-kP-sdR\" kind=\"unwind\" identifier=\"SelectModel\" unwindAction=\"unwindWithSelectedRowWithSegue:\" id=\"Cv0-zb-K6m\"/>\n                    </connections>\n                </tableViewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"Xgv-K7-fYm\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n                <exit id=\"bkC-kP-sdR\" userLabel=\"Exit\" sceneMemberID=\"exit\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-3076\" y=\"214\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/FeatureController/SettingsButton.swift",
    "content": "//\n//  FritzCameraButton.swift\n//  Lumina\n//\n//  Created by David Okun on 9/11/17.\n//  Copyright © 2017 David Okun. All rights reserved.\n//\n\nimport UIKit\n\nfinal class SettingsButton: UIButton {\n  private var buttonWidth = 40\n  private var buttonHeight = 40\n\n  private var border: UIView?\n\n  private var _image: UIImage?\n  var image: UIImage? {\n    get {\n      return _image\n    }\n    set {\n      self.setImage(newValue, for: UIControl.State.normal)\n      _image = newValue\n    }\n  }\n\n  private var _text: String?\n  var text: String? {\n    get {\n      return _text\n    }\n    set {\n      self.setTitle(newValue, for: UIControl.State.normal)\n      _text = newValue\n    }\n  }\n\n  init(origin: CGPoint = CGPoint(x: UIScreen.main.bounds.maxX - 50, y: 10)) {\n    super.init(frame: CGRect.zero)\n    self.backgroundColor = UIColor.clear\n    if let titleLabel = self.titleLabel {\n      titleLabel.textColor = UIColor.white\n      titleLabel.font = UIFont.systemFont(ofSize: 20)\n    }\n      self.image = UIImage(named: \"SettingsIcon\", in: Bundle(for: FritzCameraViewController.self), compatibleWith: nil)\n      self.frame = CGRect(\n        origin: origin,\n        size: CGSize(width: self.buttonWidth, height: self.buttonHeight)\n      )\n      addButtonShadowEffects()\n  }\n\n  private func addButtonShadowEffects() {\n    self.layer.shadowOffset = CGSize(width: 0, height: 0)\n    self.layer.shadowOpacity = 1\n    self.layer.shadowRadius = 6\n  }\n\n  required init?(coder aDecoder: NSCoder) {\n    super.init(coder: aDecoder)\n  }\n}\n\nfileprivate extension UIColor {\n  class var normalState: UIColor {\n    return UIColor(white: 1.0, alpha: 0.65)\n  }\n\n  class var recordingState: UIColor {\n    return UIColor.red.withAlphaComponent(0.65)\n  }\n\n  class var takePhotoState: UIColor {\n    return UIColor.lightGray.withAlphaComponent(0.65)\n  }\n\n  class var borderNormalState: CGColor {\n    return UIColor.gray.cgColor\n  }\n\n  class var borderRecordingState: CGColor {\n    return UIColor.red.cgColor\n  }\n\n  class var borderTakePhotoState: CGColor {\n    return UIColor.darkGray.cgColor\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/ImageSegmentation/ImageSegFeature.swift",
    "content": "//\n//  ImageSegFeature.swift\n//  Heartbeat\n//\n//  Created by Christopher Kelly on 4/22/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/ModelExtensions/ImageSegmentationFeature.swift",
    "content": "//\n//  ImageSegmentationFeature.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/22/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\n\n\nextension FritzVisionSegmentationPredictor: ImagePredictor {\n\n  private func predictSingleClass(_ image: FritzVisionImage, options: ConfigurableOptions) throws -> UIImage? {\n\n    let mask = try self.predict(image)\n\n    let color = (options[.color] as! ColorSliderValue).color\n    let minThreshold = Double((options[.minThreshold] as! RangeValue).value)\n    let maxThreshold = Double((options[.maxThreshold] as! RangeValue).value)\n\n    return mask.buildSingleClassMask(\n      forClass: FritzVisionHairClass.hair,\n      clippingScoresAbove: maxThreshold,\n      zeroingScoresBelow: minThreshold,\n      maxAlpha: 255,\n      resize: false,\n      color: color)\n  }\n\n  func predict(_ image: FritzVisionImage, options: ConfigurableOptions) throws -> UIImage? {\n\n    // color option is only an option in the hair color view for now.\n    if options[PredictorOptionTypes.color] != nil {\n      return try predictSingleClass(image, options: options)\n    }\n\n    let mask = try self.predict(image)\n\n    let minThreshold = Double((options[.minThreshold] as! RangeValue).value)\n    let alpha = UInt8((options[.alpha] as! RangeValue).value)\n\n    return mask.buildMultiClassMask(\n      withMinimumAcceptedScore: minThreshold,\n      maxAlpha: alpha,\n      resize: true)\n  }\n}\n\n\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/ModelExtensions/PoseEstimation+ImagePredictor.swift",
    "content": "//\n//  PoseEstimation+ImagePredictor.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/23/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\nextension FritzVisionHumanPosePredictor: ImagePredictor {\n\n  func predict(_ image: FritzVisionImage, options: ConfigurableOptions) throws -> UIImage? {\n\n    let poseOptions = FritzVisionPoseModelOptions()\n    poseOptions.minPoseThreshold = Double((options[.minPoseThreshold] as! RangeValue).value)\n    poseOptions.minPartThreshold = Double((options[.minPartThreshold] as! RangeValue).value)\n\n    let poseResult = try predict(image, options: poseOptions)\n    let numPoseOption = options[.numPoses] as? RangeValue\n    let poses = poseResult.poses(limit: Int(numPoseOption!.value))\n    return image.draw(poses: poses)\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/PredictorControllers/DetectObjects/DetectObjectsStoryboard.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14113\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"bXN-2g-eap\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14088\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Detect Objects-->\n        <scene sceneID=\"gga-fV-gqh\">\n            <objects>\n                <viewController id=\"bXN-2g-eap\" userLabel=\"Detect Objects\" customClass=\"DetectObjectsViewController\" customModule=\"Heartbeat\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"DTw-l1-0kj\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"2CS-If-s4d\">\n                                <rect key=\"frame\" x=\"171.5\" y=\"643.5\" width=\"32\" height=\"15.5\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <size key=\"shadowOffset\" width=\"1\" height=\"1\"/>\n                            </label>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <constraints>\n                            <constraint firstItem=\"CgA-h6-NiT\" firstAttribute=\"bottom\" secondItem=\"2CS-If-s4d\" secondAttribute=\"bottom\" constant=\"8\" id=\"4Ox-iJ-eF0\"/>\n                            <constraint firstItem=\"2CS-If-s4d\" firstAttribute=\"centerX\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"centerX\" id=\"gmf-iX-8hv\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"CgA-h6-NiT\"/>\n                    </view>\n                    <navigationItem key=\"navigationItem\" title=\"DETECT OBJECTS\" id=\"vW0-XC-6S1\"/>\n                    <simulatedNavigationBarMetrics key=\"simulatedTopBarMetrics\" prompted=\"NO\"/>\n                    <connections>\n                        <outlet property=\"cameraView\" destination=\"DTw-l1-0kj\" id=\"dCi-70-bYu\"/>\n                        <outlet property=\"frameLabel\" destination=\"2CS-If-s4d\" id=\"Kg4-Rc-Ad5\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"pm4-ZZ-n7f\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"18\" y=\"63\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/PredictorControllers/DetectObjects/DetectObjectsViewController.swift",
    "content": "//\n//  DetectObjectsViewController.swift\n//\n\nimport UIKit\nimport CoreML\nimport Vision\nimport AVFoundation\nimport Accelerate\nimport Fritz\n\nextension Double {\n    func format(f: String) -> String {\n        return String(format: \"%\\(f)f\", self)\n    }\n}\n\n\nclass DetectObjectsViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {\n    @IBOutlet weak var cameraView: UIView!\n    @IBOutlet weak var frameLabel: UILabel!\n    var lastExecution = Date()\n    var screenHeight: Double?\n    var screenWidth: Double?\n\n  let visionModel = FritzVisionObjectModelFast()\n\n    private lazy var cameraLayer: AVCaptureVideoPreviewLayer = {\n        let layer = AVCaptureVideoPreviewLayer(session: self.captureSession)\n        layer.videoGravity = .resizeAspectFill\n        return layer\n    }()\n\n    private lazy var captureSession: AVCaptureSession = {\n        let session = AVCaptureSession()\n\n        guard\n            let backCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back),\n            let input = try? AVCaptureDeviceInput(device: backCamera)\n            else { return session }\n        session.addInput(input)\n        return session\n    }()\n\n    let numBoxes = 100\n    var boundingBoxes: [BoundingBoxOutline] = []\n    let multiClass = true\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        self.cameraView?.layer.addSublayer(self.cameraLayer)\n        self.cameraView?.bringSubviewToFront(self.frameLabel)\n        self.frameLabel.textAlignment = .left\n        let videoOutput = AVCaptureVideoDataOutput()\n        videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: \"MyQueue\"))\n        self.captureSession.addOutput(videoOutput)\n        self.captureSession.startRunning()\n        setupBoxes()\n        screenWidth = Double(view.frame.width)\n        screenHeight = Double(view.frame.height)\n    }\n\n    override func viewDidAppear(_ animated: Bool) {\n        super.viewDidAppear(animated)\n        cameraLayer.frame = cameraView.layer.bounds\n    }\n\n    func setupBoxes() {\n        // Create shape layers for the bounding boxes.\n        for _ in 0..<numBoxes {\n            let box = BoundingBoxOutline()\n            box.addToLayer(cameraView.layer)\n            self.boundingBoxes.append(box)\n        }\n    }\n\n    override func viewDidLayoutSubviews() {\n        super.viewDidLayoutSubviews()\n        self.cameraLayer.frame = self.cameraView?.bounds ?? .zero\n    }\n\n    override func didReceiveMemoryWarning() {\n        super.didReceiveMemoryWarning()\n        // Dispose of any resources that can be recreated.\n    }\n\n    func drawBoxes(predictions: [FritzVisionObject], framesPerSecond: Double) {\n        self.frameLabel.text = \"FPS: \\(framesPerSecond.format(f: \".3\"))\"\n\n        for (index, prediction) in predictions.enumerated() {\n            let textLabel = String(format: \"%.2f - %@\", prediction.confidence, prediction.label)\n\n            // Effectively center cropping the bounding box frame.\n            let height = Double(cameraView.frame.height)\n            let width = Double(cameraView.frame.width)\n\n            let box = prediction.boundingBox\n            let rect = box.toCGRect(imgHeight: height, imgWidth: width)\n            self.boundingBoxes[index].show(frame: rect,\n                                           label: textLabel,\n                                           color: UIColor.red,\n                                           textColor: UIColor.black)\n        }\n\n        for index in predictions.count..<self.numBoxes {\n            self.boundingBoxes[index].hide()\n        }\n    }\n\n    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {\n        let options = FritzVisionObjectModelOptions()\n        options.threshold = 0.5\n\n        let image = FritzVisionImage(buffer: sampleBuffer)\n        image.metadata = FritzVisionImageMetadata()\n        image.metadata?.orientation = FritzImageOrientation(from: connection)\n\n        visionModel.predict(image, options: options) { objects, error in\n            if let objects = objects, objects.count > 0 {\n                let thisExecution = Date()\n                let executionTime = thisExecution.timeIntervalSince(self.lastExecution)\n                let framesPerSecond:Double = 1 / executionTime\n                self.lastExecution = thisExecution\n\n                DispatchQueue.main.async {\n                    self.drawBoxes(predictions: objects, framesPerSecond: framesPerSecond)\n\n                }\n            }\n        }\n\n    }\n}\n\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/PredictorControllers/HairColor+ColorSlider.swift",
    "content": "//\n//  HairColor+ColorSlider.swift\n//  FritzAIStudio\n//\n//  Created by Christopher Kelly on 4/25/19.\n//  Copyright © 2019 Fritz Labs, Inc. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\nimport ColorSlider\n\n\nextension HairColorViewController {\n\n  @objc func updateColor(_ slider: ColorSlider) {\n    let color = slider.color\n    guard let feature = feature else { return }\n    var sliderValue = feature.predictorDetails.options[.color] as! ColorSliderValue\n    sliderValue.color = color\n    feature.predictorDetails.options[.color] = sliderValue\n  }\n\n  func addColorSlider() {\n    colorSlider.translatesAutoresizingMaskIntoConstraints = false\n    view.addSubview(colorSlider)\n    let rightEdgeConstraint = NSLayoutConstraint(\n      item: colorSlider,\n      attribute: .trailing,\n      relatedBy: .equal,\n      toItem: view,\n      attribute: .trailingMargin,\n      multiplier: 1.0,\n      constant: 0.0)\n    let centerVerticalConstraint = NSLayoutConstraint(\n      item: colorSlider,\n      attribute: .centerY,\n      relatedBy: .equal,\n      toItem: view,\n      attribute: .centerY,\n      multiplier: 1.0,\n      constant: 0)\n    let widthConstraint = NSLayoutConstraint(\n      item: colorSlider,\n      attribute: .width,\n      relatedBy: .equal,\n      toItem: nil,\n      attribute: .notAnAttribute,\n      multiplier: 1,\n      constant: 30)\n    let heightConstraint = NSLayoutConstraint(\n      item: colorSlider,\n      attribute: .height,\n      relatedBy: .equal,\n      toItem: nil,\n      attribute: .notAnAttribute,\n      multiplier: 1,\n      constant: 250)\n\n    widthConstraint.isActive = true\n    heightConstraint.isActive = true\n    rightEdgeConstraint.isActive = true\n    centerVerticalConstraint.isActive = true\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/PredictorControllers/HairColorViewController.swift",
    "content": "//\n//  ImageSegmentationViewController\n//  FritzAIStudio\n//\n//  Created by Chris Kelly on 9/12/2018.\n//  Copyright © 2018 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\nimport AVFoundation\nimport Vision\nimport Fritz\nimport VideoToolbox\nimport ColorSlider\n\nclass HairColorViewController: FeatureViewController {\n\n  /// Default options.  These are options that users can change on the feature page.\n  /// When a predictor is build, it is instantiated with this option set.\n  static let defaultOptions: [PredictorOptionTypes:PredictorOption] = [\n    .color: ColorSliderValue(optionType: .color, color: .red, priority: 0),\n    .blendingMode: SegmentValue(\n      optionType: .blendingMode,\n      options: [\"Soft light\", \"Hue\", \"Color\", \"Plus Lighter\"],\n      selectedIndex: 0,\n      priority: 1\n    ),\n    .alpha: RangeValue(optionType: .alpha, min: 0.0, max: 1.0, value: 0.75, priority: 2),\n    .maxThreshold: RangeValue(optionType: .maxThreshold, min: 0.0, max: 1.0, value: 0.7, priority: 3),\n    .minThreshold: RangeValue(optionType: .minThreshold, min: 0.0, max: 1.0, value: 0.3, priority: 4),\n    .interpolationQuality: SegmentValue(\n      optionType: .interpolationQuality,\n      options: [\"Low\", \"Medium\", \"High\", \"None\"],\n      selectedIndex: 0,\n      priority: 5\n    )\n  ]\n\n  var _colorSlider: ColorSlider?\n  var colorSlider: ColorSlider {\n    if let slider = _colorSlider {\n      return slider\n    }\n\n    let slider = ColorSlider(orientation: .vertical, previewSide: .left)\n    _colorSlider = slider\n    slider.addTarget(self, action: #selector(updateColor(_:)), for: .valueChanged)\n    return slider\n  }\n\n  override var debugImage: UIImage? { return UIImage(named: \"hair1.jpg\") }\n\n  convenience init() {\n\n    let managedModel = FritzVisionHairSegmentationModelFast().managedModel\n    let hairSeg = FritzModelDetails(\n      with: managedModel,\n      featureDescription: .hairColor\n    )\n    let group = ModelGroupManager(initialModel: hairSeg, tagName: nil)\n\n    self.init(modelGroup: group, title: \"Hair Segmentation\")\n\n    // Configure camera options for this class.\n    self.position = .front\n    self.streamBackgroundImage = false\n  }\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n    addColorSlider()\n  }\n\n  override func viewWillAppear(_ animated: Bool) {\n    super.viewWillAppear(animated)\n    if let feature = feature {\n      let colorOption = feature.predictorDetails.options[.color] as! ColorSliderValue\n      colorSlider.color = colorOption.color\n    }\n  }\n\n  override func viewWillLayoutSubviews() {\n    super.viewWillLayoutSubviews()\n    view.bringSubviewToFront(colorSlider)\n  }\n\n  /// Build a new instance of the image predictor.\n  /// This is called when the view controller is initialized and when a new model is chosed\n  /// from the settings popover.\n  override func build(_ predictorDetails: FritzModelDetails) -> AIStudioImagePredictor? {\n    guard let mlmodel = predictorDetails.managedModel.loadModel() else { return nil }\n\n    switch predictorDetails.featureDescription {\n    case .hairColor:\n      let model = FritzVisionHairSegmentationPredictor(model: mlmodel)\n      return AIStudioImagePredictor(model: model, predictorDetails: predictorDetails)\n    default:\n      return nil\n    }\n  }\n\n  override func processImage(_ image: FritzVisionImage?) throws -> UIImage? {\n\n    guard let fritzImage = image else { return nil }\n    let options = feature?.predictorDetails.options ?? type(of: self).defaultOptions\n\n    let alpha = (options[.alpha] as! RangeValue).value\n\n    // Change blend mode\n    let blend = (options[.blendingMode] as! SegmentValue).selectedIndex\n    var blendingMode: CIBlendKernel\n    switch blend {\n    case 0: blendingMode = .softLight\n    case 1: blendingMode = .hue\n    case 2: blendingMode = .color\n    case 3: blendingMode = .componentAdd\n    default: blendingMode = .softLight\n    }\n\n    guard let mask = try? feature?.model.predict(fritzImage, options: options) else { return nil }\n    guard let blended = fritzImage.blend(withMask: mask, blendKernel: blendingMode, opacity: CGFloat(alpha))\n      else { return nil }\n\n    return blended\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/PredictorControllers/ImageSegmentationViewController.swift",
    "content": "//\n//  ImageSegmentationViewController\n//  FritzAIStudio\n//\n//  Created by Chris Kelly on 9/12/2018.\n//  Copyright © 2018 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\nimport AVFoundation\nimport Vision\nimport Fritz\nimport VideoToolbox\n\n\n\nclass ImageSegmentationViewController: FeatureViewController {\n\n  static let defaultOptions: ConfigurableOptions = [\n    .minThreshold: RangeValue(optionType: .minThreshold, min: 0.0, max: 1.0, value: 0.5, priority: 0),\n    .alpha: RangeValue(optionType: .alpha, min: 0.0, max: 255.0, value: 190.0, priority: 1)\n  ]\n\n  override var debugImage: UIImage? { return UIImage(named: \"eric.jpg\") }\n\n  convenience init() {\n    let peopleSeg = FritzModelDetails(\n      with: FritzVisionPeopleSegmentationModelFast().managedModel,\n      featureDescription: .peopleSegmentation\n    )\n\n    let modelGroup = ModelGroupManager(\n      initialModel: peopleSeg,\n      tagName: \"aistudio-ios-image-segmentation\"\n    )\n\n    self.init(modelGroup: modelGroup, title: \"Image Segmentation\")\n    streamBackgroundImage = true\n  }\n\n  /// Image Segmentation feature. Segments images into different classes.  For more information, see https://docs.fritz.ai/develop/vision/image-segmentation/about.html.\n  override func build(_ predictorDetails: FritzModelDetails) -> AIStudioImagePredictor? {\n    guard let model = predictorDetails.managedModel.loadModel()\n      else { return nil }\n\n    let modelType = predictorDetails.featureDescription\n    var segmentationPredictor: FritzVisionSegmentationPredictor? = nil\n    \n    switch modelType {\n    case .peopleSegmentation:\n      segmentationPredictor = FritzVisionPeopleSegmentationPredictor(model: model)\n    case .livingRoomSegmentation:\n      segmentationPredictor = FritzVisionLivingRoomSegmentationPredictor(model: model)\n    case .outdoorSegmentation:\n      segmentationPredictor = FritzVisionOutdoorSegmentationPredictor(model: model)\n    case .petSegmentation:\n      segmentationPredictor = FritzVisionPetSegmentationPredictor(model: model)\n    case .skySegmentation:\n      segmentationPredictor = FritzVisionSkySegmentationPredictor(model: model)\n    default:\n      return nil\n    }\n    if let segmentationPredictor = segmentationPredictor {\n      return AIStudioImagePredictor(model: segmentationPredictor, predictorDetails: predictorDetails)\n    }\n    return nil\n  }\n}\n\n\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/PredictorControllers/LabelImages/FritzVisionLabelViewController.swift",
    "content": "//\n//  MobileNetViewController.swift\n//  FritzAIStudio\n//\n//  Created by Andrew Barba on 1/3/18.\n//  Copyright © 2018 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\nimport AVFoundation\nimport Fritz\nimport Vision\n\nclass FritzVisionLabelViewController: UIViewController {\n\n    @IBOutlet weak var resultView: UIView! {\n        didSet { resultView.layer.cornerRadius = 4 }\n    }\n\n    @IBOutlet weak var predictionLabel: UILabel! {\n        didSet { predictionLabel.text = \"Loading... 🚀\" }\n    }\n\n    @IBOutlet weak var confidenceLabel: UILabel! {\n        didSet { confidenceLabel.text = nil }\n    }\n\n    private lazy var cameraSession = AVCaptureSession()\n\n    private lazy var previewLayer: AVCaptureVideoPreviewLayer = {\n        let preview =  AVCaptureVideoPreviewLayer(session: cameraSession)\n        preview.videoGravity = .resizeAspectFill\n        return preview\n    }()\n\n    private let visionModel = FritzVisionLabelModelFast()\n\n    private let sessionQueue = DispatchQueue(label: \"ai.fritz.aistudio.mobilenet.session\")\n\n    private let captureQueue = DispatchQueue(label: \"ai.fritz.aistudio.mobilenet.capture\")\n\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        guard let device = AVCaptureDevice.default(for: .video), let input = try? AVCaptureDeviceInput(device: device) else { return }\n\n        let output = AVCaptureVideoDataOutput()\n        output.alwaysDiscardsLateVideoFrames = true\n        output.setSampleBufferDelegate(self, queue: captureQueue)\n\n        sessionQueue.async {\n            self.cameraSession.beginConfiguration()\n            self.cameraSession.addInput(input)\n            self.cameraSession.addOutput(output)\n            self.cameraSession.commitConfiguration()\n        }\n    }\n\n    override func viewDidAppear(_ animated: Bool) {\n        super.viewDidAppear(animated)\n\n        previewLayer.frame = view.layer.bounds\n        view.layer.insertSublayer(previewLayer, at: 0)\n\n        sessionQueue.async {\n            self.cameraSession.startRunning()\n        }\n    }\n\n    override func viewWillLayoutSubviews() {\n        super.viewWillLayoutSubviews()\n\n        previewLayer.frame = view.layer.bounds\n    }\n\n    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {\n        super.viewWillTransition(to: size, with: coordinator)\n\n        coordinator.animate(\n            alongsideTransition: { _ in\n                self.previewLayer.frame = CGRect(origin: .zero, size: size)\n        },\n            completion: nil\n        )\n    }\n}\n\nextension FritzVisionLabelViewController: AVCaptureVideoDataOutputSampleBufferDelegate {\n\n    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {\n        let image = FritzVisionImage(buffer: sampleBuffer)\n        image.metadata = FritzVisionImageMetadata()\n        let options = FritzVisionLabelModelOptions()\n        options.threshold = 0.1\n\n        visionModel.predict(image, options: options) { labels, error in\n            if let labels = labels, labels.count > 0 {\n                let observation = labels[0]\n                let confidence = Int(observation.confidence * 100)\n                self.setResult(text: observation.label, confidence: confidence)\n            } else {\n                self.setNoResult()\n            }\n        }\n    }\n\n    private func setResult(text: String, confidence: Int) {\n        DispatchQueue.main.async {\n            self.predictionLabel.text = text.capitalized\n            self.confidenceLabel.text = self.confidenceString(confidence)\n            self.confidenceLabel.textColor = self.confidenceColor(confidence)\n        }\n    }\n\n    private func setNoResult() {\n        DispatchQueue.main.async {\n            self.predictionLabel.text = \"?????\"\n            self.confidenceLabel.text = \"\"\n        }\n    }\n\n    private func confidenceString(_ value: Int) -> String {\n        return \"\\(value)%\"\n    }\n\n    private func confidenceColor(_ value: Int) -> UIColor {\n        switch value {\n        case ...33: return .red\n        case 34...66: return .orange\n        default: return .green\n        }\n    }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/PredictorControllers/LabelImages/LabelImages.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14113\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"GhT-AM-2Xp\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14088\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--MOBILENET-->\n        <scene sceneID=\"Olm-CA-aK0\">\n            <objects>\n                <viewController id=\"GhT-AM-2Xp\" customClass=\"FritzVisionLabelViewController\" customModule=\"Heartbeat\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"VCH-bE-Orv\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <view contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Xl3-VW-CRJ\">\n                                <rect key=\"frame\" x=\"20\" y=\"579\" width=\"335\" height=\"54\"/>\n                                <subviews>\n                                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" minimumScaleFactor=\"0.5\" adjustsLetterSpacingToFitWidth=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"cvG-AU-vgE\">\n                                        <rect key=\"frame\" x=\"12\" y=\"14\" width=\"311\" height=\"26.5\"/>\n                                        <fontDescription key=\"fontDescription\" type=\"boldSystem\" pointSize=\"22\"/>\n                                        <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                        <nil key=\"highlightedColor\"/>\n                                    </label>\n                                </subviews>\n                                <color key=\"backgroundColor\" red=\"0.1215697452\" green=\"0.1215666011\" blue=\"0.12156876179999999\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                                <constraints>\n                                    <constraint firstItem=\"cvG-AU-vgE\" firstAttribute=\"leading\" secondItem=\"Xl3-VW-CRJ\" secondAttribute=\"leading\" constant=\"12\" id=\"1ex-nn-afo\"/>\n                                    <constraint firstItem=\"cvG-AU-vgE\" firstAttribute=\"centerY\" secondItem=\"Xl3-VW-CRJ\" secondAttribute=\"centerY\" id=\"4zj-td-gyr\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"54\" id=\"Li1-Em-QmS\"/>\n                                    <constraint firstAttribute=\"trailing\" secondItem=\"cvG-AU-vgE\" secondAttribute=\"trailing\" constant=\"12\" id=\"jLO-OM-UFD\"/>\n                                </constraints>\n                            </view>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ZIZ-Al-HBK\">\n                                <rect key=\"frame\" x=\"171.5\" y=\"643.5\" width=\"32\" height=\"15.5\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <size key=\"shadowOffset\" width=\"1\" height=\"1\"/>\n                            </label>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <constraints>\n                            <constraint firstItem=\"Vzw-Am-OMq\" firstAttribute=\"bottom\" secondItem=\"Xl3-VW-CRJ\" secondAttribute=\"bottom\" constant=\"34\" id=\"CTY-lO-EzI\"/>\n                            <constraint firstItem=\"Vzw-Am-OMq\" firstAttribute=\"trailing\" secondItem=\"Xl3-VW-CRJ\" secondAttribute=\"trailing\" constant=\"20\" id=\"DVX-Hi-CoU\"/>\n                            <constraint firstItem=\"Xl3-VW-CRJ\" firstAttribute=\"leading\" secondItem=\"Vzw-Am-OMq\" secondAttribute=\"leading\" constant=\"20\" id=\"KRT-Wr-BDZ\"/>\n                            <constraint firstItem=\"Vzw-Am-OMq\" firstAttribute=\"bottom\" secondItem=\"ZIZ-Al-HBK\" secondAttribute=\"bottom\" constant=\"8\" id=\"fZK-R1-A1b\"/>\n                            <constraint firstItem=\"ZIZ-Al-HBK\" firstAttribute=\"centerX\" secondItem=\"Vzw-Am-OMq\" secondAttribute=\"centerX\" id=\"qBq-1E-htl\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"Vzw-Am-OMq\"/>\n                    </view>\n                    <navigationItem key=\"navigationItem\" title=\"MOBILENET\" id=\"aSF-jE-iSZ\"/>\n                    <simulatedNavigationBarMetrics key=\"simulatedTopBarMetrics\" prompted=\"NO\"/>\n                    <connections>\n                        <outlet property=\"confidenceLabel\" destination=\"ZIZ-Al-HBK\" id=\"tet-3j-52Y\"/>\n                        <outlet property=\"predictionLabel\" destination=\"cvG-AU-vgE\" id=\"jbU-BK-BE3\"/>\n                        <outlet property=\"resultView\" destination=\"Xl3-VW-CRJ\" id=\"tA7-DN-1zL\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"6tT-Vu-ky2\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"96.799999999999997\" y=\"196.55172413793105\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/PredictorControllers/PoseEstimationViewController.swift",
    "content": "//\n//  ImageSegmentationViewController\n//  FritzAIStudio\n//\n//  Created by Chris Kelly on 9/12/2018.\n//  Copyright © 2018 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\nimport AVFoundation\nimport Vision\nimport Fritz\nimport VideoToolbox\n\n\n\nclass PoseEstimationViewController: FeatureViewController {\n\n  static let defaultOptions: ConfigurableOptions = [\n    .minPoseThreshold: RangeValue(optionType: .minPoseThreshold, min: 0.0, max: 1.0, value: 0.4, priority: 0),\n    .minPartThreshold: RangeValue(optionType: .minPartThreshold, min: 0.0, max: 1.0, value: 0.4, priority: 1),\n    .numPoses: RangeValue(optionType: .numPoses, min: 1.0, max: 20.0, value: 7.0, priority: 2)\n  ]\n\n  override var debugImage: UIImage? {\n    return UIImage(named: \"pose.jpg\")\n  }\n\n  override func build(_ predictorDetails: FritzModelDetails) -> AIStudioImagePredictor? {\n    guard let mlmodel = predictorDetails.managedModel.loadModel()\n      else { return nil }\n    let poseModel = FritzVisionHumanPosePredictor(model: mlmodel)\n\n    switch predictorDetails.featureDescription {\n    case .poseEstimation:\n      return AIStudioImagePredictor(model: poseModel, predictorDetails: predictorDetails)\n    default: return nil\n    }\n  }\n\n  convenience init() {\n    let managedModel = FritzVisionHumanPoseModelFast().managedModel\n    let poseModel = FritzModelDetails(\n      with: managedModel,\n      featureDescription: .poseEstimation)\n\n    let group = ModelGroupManager(initialModel: poseModel, tagName: \"aistudio-ios-pose-estimation\")\n    self.init(modelGroup: group, title: \"Pose Estimation\")\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/PredictorControllers/StyleTransferViewController.swift",
    "content": "//\n//  StyleTransferViewController.swift\n//  FritzAIStudio\n//\n//  Created by Jameson Toole on 6/8/18.\n//  Copyright © 2018 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\nimport AVFoundation\nimport Photos\nimport Vision\nimport CoreML\nimport Fritz\n\n\nextension FritzVisionStylePredictor: ImagePredictor {\n  func predict(_ image: FritzVisionImage, options: ConfigurableOptions) throws -> UIImage? {\n\n    let styleOptions = FritzVisionStyleModelOptions()\n    \n    let value = options[.modelResolution] as! SegmentValue\n    // This is a bit hacky, but we can change it if it becomes a problem\n    let index = value.selectedIndex\n    if index == 0 {\n      styleOptions.flexibleModelDimensions = .lowResolution\n    } else if index == 1 {\n      styleOptions.flexibleModelDimensions = .mediumResolution\n    } else if index == 2 {\n      styleOptions.flexibleModelDimensions = .highResolution\n    } else if index == 3 {\n      styleOptions.flexibleModelDimensions = .original\n    }\n    \n    // Resize the final image to match the input\n    styleOptions.resizeOutputToInputDimensions = true\n    \n    // Stylize the image\n    let stylizedBuffer = try predict(image, options: styleOptions)\n\n    return UIImage(pixelBuffer: stylizedBuffer)\n  }\n}\n\n\nclass StyleTransferViewController: FeatureViewController {\n\n  override var debugImage: UIImage? { return UIImage(named: \"styleTransferBoston.jpg\") }\n  \n  static let defaultOptions: ConfigurableOptions = [\n    .modelResolution: SegmentValue(\n      optionType: .modelResolution,\n      options: [\"Low\", \"Medium\", \"High\", \"original\"],\n      selectedIndex: 0, priority: 0\n    )\n  ]\n  \n  class func buildModelGroup() -> ModelGroupManager {\n    var models: [FritzModelDetails] = []\n    for paintingStyle in PaintingStyleModel.Style.allCases {\n      let styleModel = paintingStyle.build()\n      let fritzModel = FritzModelDetails(\n        with: styleModel.managedModel,\n        featureDescription: .styleTransfer,\n        name: paintingStyle.name\n      )\n      models.append(fritzModel)\n    }\n    \n    for patternStyle in PatternStyleModel.Style.allCases {\n      let styleModel = patternStyle.build()\n      let fritzModel = FritzModelDetails(\n        with: styleModel.managedModel,\n        featureDescription: .styleTransfer,\n        name: patternStyle.name\n      )\n      models.append(fritzModel)\n    }\n\n    return ModelGroupManager(with: models, initialModel: models[0], tagName: nil)\n  }\n\n  convenience init() {\n    let group = StyleTransferViewController.buildModelGroup()\n    self.init(modelGroup: group, title: \"Style Transfer\")\n    self.position = .front\n    self.resolution = .high1920x1080\n  }\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(doubleTapped))\n    gestureRecognizer.numberOfTapsRequired = 2\n    view.addGestureRecognizer(gestureRecognizer)\n  }\n\n  override func build(_ predictorDetails: FritzModelDetails) -> AIStudioImagePredictor? {\n    guard let model = predictorDetails.managedModel.loadModel(),\n      let predictor = try? FritzVisionStylePredictor(model: model) else { return nil }\n    \n    return AIStudioImagePredictor(model: predictor, predictorDetails: predictorDetails)\n  }\n}\n\nextension StyleTransferViewController {\n\n  @objc func doubleTapped() {\n    activateNextStyle()\n  }\n\n  func updateFeature(_ fritzModel: FritzModelDetails) {\n    if let feature = build(fritzModel) {\n      self.feature = feature\n      self.streamBackgroundImage = false\n    }\n  }\n\n  func activateNextStyle() {\n    let allModels = modelGroup.models\n\n    // No index, choose first one,\n    guard let selectedModel = modelGroup.selectedPredictorDetails,\n      let index = allModels.firstIndex(of: selectedModel),\n      index != allModels.count - 1 else {\n        // If there is not a selected model, or the model is the last\n        // model, start at the beginining. Ideally, we would show the plain\n        // image, but there is a small still untraced bug in the FritzCameraViewController blocking that.\n        let newModel = modelGroup.models[0]\n        // Model is the same model that is already loaded.\n        if newModel == modelGroup.selectedPredictorDetails {\n          return\n        }\n        modelGroup.selectedPredictorDetails = newModel\n        updateFeature(newModel)\n        return\n    }\n\n    // Normal model, just take the next one\n    let nextModel = allModels[index + 1]\n    modelGroup.selectedPredictorDetails = nextModel\n    updateFeature(nextModel)\n  }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Root/Root.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14868\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BRy-bl-cgV\">\n    <device id=\"retina4_7\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14824\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Root View Controller-->\n        <scene sceneID=\"cK8-AA-1nR\">\n            <objects>\n                <viewController id=\"hqM-8d-JS0\" customClass=\"RootViewController\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"91w-7J-Ucv\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView userInteractionEnabled=\"NO\" contentMode=\"scaleToFill\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" image=\"fritzLogo\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"hpv-Gw-uNe\">\n                                <rect key=\"frame\" x=\"87.5\" y=\"233.5\" width=\"200\" height=\"200\"/>\n                            </imageView>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <constraints>\n                            <constraint firstItem=\"hpv-Gw-uNe\" firstAttribute=\"centerX\" secondItem=\"ZjF-g5-A5N\" secondAttribute=\"centerX\" id=\"NGZ-4c-XTj\"/>\n                            <constraint firstItem=\"hpv-Gw-uNe\" firstAttribute=\"centerY\" secondItem=\"ZjF-g5-A5N\" secondAttribute=\"centerY\" id=\"ajo-Zl-aPb\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"ZjF-g5-A5N\"/>\n                    </view>\n                    <navigationItem key=\"navigationItem\" id=\"SNA-rg-QyG\"/>\n                    <connections>\n                        <segue destination=\"bx1-wx-3nn\" kind=\"showDetail\" identifier=\"toDemos\" id=\"VDI-iX-0i8\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"mKr-hU-NY3\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"537\" y=\"175\"/>\n        </scene>\n        <!--Demos-->\n        <scene sceneID=\"bdq-fH-3sV\">\n            <objects>\n                <viewControllerPlaceholder storyboardName=\"Demos\" id=\"bx1-wx-3nn\" sceneMemberID=\"viewController\"/>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"CsO-Fa-xJP\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"1255\" y=\"220\"/>\n        </scene>\n        <!--Navigation Controller-->\n        <scene sceneID=\"Rw4-vI-zmy\">\n            <objects>\n                <navigationController automaticallyAdjustsScrollViewInsets=\"NO\" navigationBarHidden=\"YES\" id=\"BRy-bl-cgV\" customClass=\"NavigationController\" customModule=\"FritzAIStudio\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <toolbarItems/>\n                    <navigationBar key=\"navigationBar\" contentMode=\"scaleToFill\" insetsLayoutMarginsFromSafeArea=\"NO\" id=\"dLo-IE-qPP\">\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </navigationBar>\n                    <nil name=\"viewControllers\"/>\n                    <connections>\n                        <segue destination=\"hqM-8d-JS0\" kind=\"relationship\" relationship=\"rootViewController\" id=\"5TQ-mG-Pqu\"/>\n                    </connections>\n                </navigationController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"GFX-uP-uYO\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-300\" y=\"175\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"fritzLogo\" width=\"200\" height=\"200\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Source/Modules/Root/RootViewController.swift",
    "content": "//\n//  RootViewController.swift\n//  FritzAIStudio\n//\n//  Created by Andrew Barba on 12/14/17.\n//  Copyright © 2017 Fritz Labs, Inc. All rights reserved.\n//\n\nimport UIKit\n\nclass RootViewController: UIViewController {\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        // Do any additional setup after loading the view.\n    }\n\n    override func viewDidAppear(_ animated: Bool) {\n        super.viewDidAppear(animated)\n\n        performSegue(withIdentifier: R.segue.rootViewController.toDemos, sender: self)\n    }\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio/Supporting Files/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>Fritz AI Studio</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>4.0.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>370</string>\n\t<key>Fabric</key>\n\t<dict>\n\t\t<key>APIKey</key>\n\t\t<string>3ab14d933cbf3577dd7434aa17e1171fdd726172</string>\n\t\t<key>Kits</key>\n\t\t<array>\n\t\t\t<dict>\n\t\t\t\t<key>KitInfo</key>\n\t\t\t\t<dict/>\n\t\t\t\t<key>KitName</key>\n\t\t\t\t<string>Crashlytics</string>\n\t\t\t</dict>\n\t\t</array>\n\t</dict>\n\t<key>ITSAppUsesNonExemptEncryption</key>\n\t<false/>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSBluetoothPeripheralUsageDescription</key>\n\t<string>For processing images from your devices camera</string>\n\t<key>NSCameraUsageDescription</key>\n\t<string>For processing images from your devices camera</string>\n\t<key>NSMicrophoneUsageDescription</key>\n\t<string>For processing images from your devices camera</string>\n\t<key>NSPhotoLibraryAddUsageDescription</key>\n\t<string>For processing images from your devices camera</string>\n\t<key>NSPhotoLibraryUsageDescription</key>\n\t<string>For processing images from your devices camera</string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Root</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UIStatusBarStyle</key>\n\t<string>UIStatusBarStyleLightContent</string>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 48;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t05EF5E33F1BB897F7E2DA89C /* Pods_FritzAIStudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 987A4D76A43F0D9DAAA2EEA0 /* Pods_FritzAIStudio.framework */; };\n\t\t381817E31FE2DADD00050FF6 /* RootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 381817E21FE2DADD00050FF6 /* RootViewController.swift */; };\n\t\t381817E51FE2DAE400050FF6 /* Root.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 381817E41FE2DAE400050FF6 /* Root.storyboard */; };\n\t\t383D40CB1FE18FAC00438A9B /* R.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 383D40CA1FE18FAC00438A9B /* R.generated.swift */; };\n\t\t385CF1B31FF2EAA200F1BFF0 /* DemosViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 385CF1B21FF2EAA200F1BFF0 /* DemosViewController.swift */; };\n\t\t385CF1B51FF2EAAA00F1BFF0 /* Demos.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 385CF1B41FF2EAAA00F1BFF0 /* Demos.storyboard */; };\n\t\t385CF1B81FF2F14700F1BFF0 /* DemoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 385CF1B71FF2F14700F1BFF0 /* DemoTableViewCell.swift */; };\n\t\t3890742A1FFDE6A000DFF7F9 /* FritzVisionLabelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 389074291FFDE6A000DFF7F9 /* FritzVisionLabelViewController.swift */; };\n\t\t3890742C1FFDE6A900DFF7F9 /* LabelImages.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3890742B1FFDE6A900DFF7F9 /* LabelImages.storyboard */; };\n\t\t38E96C042001310000683571 /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38E96C032001310000683571 /* NavigationController.swift */; };\n\t\t38F2E23A1FE0D0B6007241CB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38F2E2391FE0D0B6007241CB /* AppDelegate.swift */; };\n\t\t38F2E2411FE0D0B6007241CB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 38F2E2401FE0D0B6007241CB /* Assets.xcassets */; };\n\t\t38F2E2441FE0D0B6007241CB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 38F2E2421FE0D0B6007241CB /* LaunchScreen.storyboard */; };\n\t\t3B5631AD233A7A3200B2D289 /* FritzLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B5631AC233A7A3200B2D289 /* FritzLogger.swift */; };\n\t\t8325F7E922323110007C1D38 /* StyleTransferViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8325F7E822323110007C1D38 /* StyleTransferViewController.swift */; };\n\t\t8325F7F1223238DC007C1D38 /* SegmentSliderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8325F7F0223238DC007C1D38 /* SegmentSliderCell.swift */; };\n\t\t8325F7F3223243FB007C1D38 /* SegmentSliderCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8325F7F2223243FB007C1D38 /* SegmentSliderCell.xib */; };\n\t\t8325F7F522325A29007C1D38 /* LinkTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8325F7F422325A29007C1D38 /* LinkTableViewCell.swift */; };\n\t\t8375F0262271313B0048B9D8 /* AIStudioFeaturePredictors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8375F0252271313B0048B9D8 /* AIStudioFeaturePredictors.swift */; };\n\t\t8375F028227134780048B9D8 /* PredictorOptionTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8375F027227134780048B9D8 /* PredictorOptionTypes.swift */; };\n\t\t8375F02B227135F80048B9D8 /* ImagePredictorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8375F02A227135F80048B9D8 /* ImagePredictorProtocol.swift */; };\n\t\t8375F02F22714D4E0048B9D8 /* NavigationBarCustomization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8375F02E22714D4E0048B9D8 /* NavigationBarCustomization.swift */; };\n\t\t8375F03522721CE00048B9D8 /* HairColor+ColorSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8375F03422721CE00048B9D8 /* HairColor+ColorSlider.swift */; };\n\t\t8379BD3E22725B72008E041D /* styleTransferBoston.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8379BD3D22725B71008E041D /* styleTransferBoston.jpg */; };\n\t\t8379BD4022725CF9008E041D /* eric.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8379BD3F22725CF9008E041D /* eric.jpg */; };\n\t\t8379BD462272604A008E041D /* hair1.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8379BD452272604A008E041D /* hair1.jpg */; };\n\t\t8379BD4A2272664D008E041D /* pose.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8379BD492272664D008E041D /* pose.jpg */; };\n\t\t8379BD4F22739102008E041D /* DebugImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8379BD4E22739102008E041D /* DebugImageExtensions.swift */; };\n\t\t837B6EEC226A6C9300158698 /* ChooseColorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 837B6EEB226A6C9300158698 /* ChooseColorCell.swift */; };\n\t\t837B6EEE226A6CDF00158698 /* ChooseColorCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 837B6EED226A6CDF00158698 /* ChooseColorCell.xib */; };\n\t\t838B528B2102432700E0D50A /* DetectObjectsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 838B528A2102432700E0D50A /* DetectObjectsViewController.swift */; };\n\t\t838B528D210243CF00E0D50A /* DetectObjectsStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 838B528C210243CF00E0D50A /* DetectObjectsStoryboard.storyboard */; };\n\t\t839231F2222F76F1001182EB /* ChooseModelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839231F1222F76F1001182EB /* ChooseModelController.swift */; };\n\t\t839231F4222F8DF9001182EB /* ConfigurePopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839231F3222F8DF9001182EB /* ConfigurePopover.swift */; };\n\t\t839231F6222F9282001182EB /* FritzModelDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839231F5222F9282001182EB /* FritzModelDetails.swift */; };\n\t\t8392321B2230673D001182EB /* ModelOptions.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8392321A2230673D001182EB /* ModelOptions.storyboard */; };\n\t\t8396CA2D220A9FDC00742120 /* PoseEstimationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8396CA2C220A9FDC00742120 /* PoseEstimationViewController.swift */; };\n\t\t83AC97D72149CB8600E86B44 /* ImageSegmentationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83AC97D62149CB8600E86B44 /* ImageSegmentationViewController.swift */; };\n\t\t83E704B9226A4D4B00FF678D /* HairColorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E704B8226A4D4B00FF678D /* HairColorViewController.swift */; };\n\t\t83F8B4962231932C00686149 /* FeatureViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83F8B4952231932C00686149 /* FeatureViewController.swift */; };\n\t\t83F8B4982231934F00686149 /* ModelGroupManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83F8B4972231934F00686149 /* ModelGroupManager.swift */; };\n\t\t83F8B49A2231A65C00686149 /* AIStudioImagePredictor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83F8B4992231A65C00686149 /* AIStudioImagePredictor.swift */; };\n\t\t83F8B49F2231C4DB00686149 /* ChooseModelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83F8B49E2231C4DB00686149 /* ChooseModelCell.swift */; };\n\t\t83F8B4A12231CAB400686149 /* ChooseModelCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 83F8B4A02231CAB300686149 /* ChooseModelCell.xib */; };\n\t\t83F8B4A32231E25800686149 /* RangeSliderCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 83F8B4A22231E25800686149 /* RangeSliderCell.xib */; };\n\t\t83F8B4A522320AD200686149 /* RangeSliderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83F8B4A422320AD200686149 /* RangeSliderCell.swift */; };\n\t\t83F8B4A722320AF700686149 /* FeatureOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83F8B4A622320AF700686149 /* FeatureOptions.swift */; };\n\t\t83FFFA7E226BB09B0038EEE2 /* FritzCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA7D226BB09B0038EEE2 /* FritzCamera.swift */; };\n\t\t83FFFA80226BB4E60038EEE2 /* CameraSessionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA7F226BB4E60038EEE2 /* CameraSessionExtensions.swift */; };\n\t\t83FFFA82226BB6B90038EEE2 /* FritzCamera+CaptureDeviceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA81226BB6B90038EEE2 /* FritzCamera+CaptureDeviceExtensions.swift */; };\n\t\t83FFFA84226BB7620038EEE2 /* CameraResolutionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA83226BB7620038EEE2 /* CameraResolutionExtension.swift */; };\n\t\t83FFFA86226BB9360038EEE2 /* FritzCamera+Focus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA85226BB9360038EEE2 /* FritzCamera+Focus.swift */; };\n\t\t83FFFA88226BBA5E0038EEE2 /* CameraAVCaptureVideoDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA87226BBA5E0038EEE2 /* CameraAVCaptureVideoDelegate.swift */; };\n\t\t83FFFA8B226BBCDF0038EEE2 /* FritzCameraButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA8A226BBCDF0038EEE2 /* FritzCameraButton.swift */; };\n\t\t83FFFA8D226BBD6E0038EEE2 /* FritzCameraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA8C226BBD6E0038EEE2 /* FritzCameraViewController.swift */; };\n\t\t83FFFA92226BBDD80038EEE2 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA8F226BBDD80038EEE2 /* Logging.swift */; };\n\t\t83FFFA93226BBDD80038EEE2 /* LogHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA90226BBDD80038EEE2 /* LogHandler.swift */; };\n\t\t83FFFA94226BBDD80038EEE2 /* Locks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA91226BBDD80038EEE2 /* Locks.swift */; };\n\t\t83FFFA96226BBE660038EEE2 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83FFFA95226BBE650038EEE2 /* Media.xcassets */; };\n\t\t83FFFA9A226BC13F0038EEE2 /* FocusExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA99226BC13F0038EEE2 /* FocusExtension.swift */; };\n\t\t83FFFA9C226BC2640038EEE2 /* CameraInterfaceHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA9B226BC2640038EEE2 /* CameraInterfaceHandler.swift */; };\n\t\t83FFFA9E226BC2BC0038EEE2 /* FritzTextPromptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA9D226BC2BC0038EEE2 /* FritzTextPromptView.swift */; };\n\t\t83FFFAA0226BC5980038EEE2 /* ButtonFunctionality.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFA9F226BC5980038EEE2 /* ButtonFunctionality.swift */; };\n\t\t83FFFAA2226BC8F60038EEE2 /* CameraDelegateImplmentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFAA1226BC8F60038EEE2 /* CameraDelegateImplmentation.swift */; };\n\t\t83FFFAA4226BC9C00038EEE2 /* FritzCameraControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFAA3226BC9C00038EEE2 /* FritzCameraControllerDelegate.swift */; };\n\t\t83FFFAA6226BCAD30038EEE2 /* GestureReconizerDelegateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFAA5226BCAD30038EEE2 /* GestureReconizerDelegateExtension.swift */; };\n\t\t83FFFAA8226BCB3F0038EEE2 /* FritzDeviceUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFAA7226BCB3F0038EEE2 /* FritzDeviceUtil.swift */; };\n\t\t83FFFAAF226C1D020038EEE2 /* SettingsButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFAAE226C1D020038EEE2 /* SettingsButton.swift */; };\n\t\t83FFFAB2226C2F6F0038EEE2 /* SettingsButtonInteractionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFAB1226C2F6F0038EEE2 /* SettingsButtonInteractionExtension.swift */; };\n\t\t83FFFAD8226E5C1E0038EEE2 /* ImageSegmentationFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFAD7226E5C1E0038EEE2 /* ImageSegmentationFeature.swift */; };\n\t\t83FFFADA226ED1400038EEE2 /* CapturePhotoDelgate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFAD9226ED1400038EEE2 /* CapturePhotoDelgate.swift */; };\n\t\t83FFFADC226ED4460038EEE2 /* PhotoCaptureExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFADB226ED4460038EEE2 /* PhotoCaptureExtensions.swift */; };\n\t\t83FFFADE226ED66C0038EEE2 /* AVPhotoExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFADD226ED66C0038EEE2 /* AVPhotoExtension.swift */; };\n\t\t83FFFAE2226EF2760038EEE2 /* PoseEstimation+ImagePredictor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FFFAE1226EF2760038EEE2 /* PoseEstimation+ImagePredictor.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t381817E21FE2DADD00050FF6 /* RootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewController.swift; sourceTree = \"<group>\"; };\n\t\t381817E41FE2DAE400050FF6 /* Root.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Root.storyboard; sourceTree = \"<group>\"; };\n\t\t383D40CA1FE18FAC00438A9B /* R.generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = R.generated.swift; path = FritzAIStudio/R.generated.swift; sourceTree = SOURCE_ROOT; };\n\t\t385CF1B21FF2EAA200F1BFF0 /* DemosViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemosViewController.swift; sourceTree = \"<group>\"; };\n\t\t385CF1B41FF2EAAA00F1BFF0 /* Demos.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Demos.storyboard; sourceTree = \"<group>\"; };\n\t\t385CF1B71FF2F14700F1BFF0 /* DemoTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoTableViewCell.swift; sourceTree = \"<group>\"; };\n\t\t389074291FFDE6A000DFF7F9 /* FritzVisionLabelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FritzVisionLabelViewController.swift; sourceTree = \"<group>\"; };\n\t\t3890742B1FFDE6A900DFF7F9 /* LabelImages.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LabelImages.storyboard; sourceTree = \"<group>\"; };\n\t\t38E96C032001310000683571 /* NavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = \"<group>\"; };\n\t\t38F2E2361FE0D0B6007241CB /* FritzAIStudio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzAIStudio.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t38F2E2391FE0D0B6007241CB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t38F2E2401FE0D0B6007241CB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t38F2E2431FE0D0B6007241CB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t38F2E2451FE0D0B6007241CB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t3B5631AC233A7A3200B2D289 /* FritzLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FritzLogger.swift; sourceTree = \"<group>\"; };\n\t\t8325F7E822323110007C1D38 /* StyleTransferViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyleTransferViewController.swift; sourceTree = \"<group>\"; };\n\t\t8325F7F0223238DC007C1D38 /* SegmentSliderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentSliderCell.swift; sourceTree = \"<group>\"; };\n\t\t8325F7F2223243FB007C1D38 /* SegmentSliderCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SegmentSliderCell.xib; sourceTree = \"<group>\"; };\n\t\t8325F7F422325A29007C1D38 /* LinkTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkTableViewCell.swift; sourceTree = \"<group>\"; };\n\t\t8375F0252271313B0048B9D8 /* AIStudioFeaturePredictors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIStudioFeaturePredictors.swift; sourceTree = \"<group>\"; };\n\t\t8375F027227134780048B9D8 /* PredictorOptionTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PredictorOptionTypes.swift; sourceTree = \"<group>\"; };\n\t\t8375F02A227135F80048B9D8 /* ImagePredictorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePredictorProtocol.swift; sourceTree = \"<group>\"; };\n\t\t8375F02E22714D4E0048B9D8 /* NavigationBarCustomization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarCustomization.swift; sourceTree = \"<group>\"; };\n\t\t8375F03422721CE00048B9D8 /* HairColor+ColorSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"HairColor+ColorSlider.swift\"; sourceTree = \"<group>\"; };\n\t\t8379BD3D22725B71008E041D /* styleTransferBoston.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = styleTransferBoston.jpg; sourceTree = \"<group>\"; };\n\t\t8379BD3F22725CF9008E041D /* eric.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = eric.jpg; sourceTree = \"<group>\"; };\n\t\t8379BD452272604A008E041D /* hair1.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = hair1.jpg; sourceTree = \"<group>\"; };\n\t\t8379BD492272664D008E041D /* pose.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = pose.jpg; sourceTree = \"<group>\"; };\n\t\t8379BD4E22739102008E041D /* DebugImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugImageExtensions.swift; sourceTree = \"<group>\"; };\n\t\t837B6EEB226A6C9300158698 /* ChooseColorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChooseColorCell.swift; sourceTree = \"<group>\"; };\n\t\t837B6EED226A6CDF00158698 /* ChooseColorCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ChooseColorCell.xib; sourceTree = \"<group>\"; };\n\t\t838B528A2102432700E0D50A /* DetectObjectsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetectObjectsViewController.swift; sourceTree = \"<group>\"; };\n\t\t838B528C210243CF00E0D50A /* DetectObjectsStoryboard.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = DetectObjectsStoryboard.storyboard; sourceTree = \"<group>\"; };\n\t\t839231F1222F76F1001182EB /* ChooseModelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChooseModelController.swift; sourceTree = \"<group>\"; };\n\t\t839231F3222F8DF9001182EB /* ConfigurePopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurePopover.swift; sourceTree = \"<group>\"; };\n\t\t839231F5222F9282001182EB /* FritzModelDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FritzModelDetails.swift; sourceTree = \"<group>\"; };\n\t\t8392321A2230673D001182EB /* ModelOptions.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ModelOptions.storyboard; sourceTree = \"<group>\"; };\n\t\t8396CA2C220A9FDC00742120 /* PoseEstimationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoseEstimationViewController.swift; sourceTree = \"<group>\"; };\n\t\t83AC97D62149CB8600E86B44 /* ImageSegmentationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageSegmentationViewController.swift; sourceTree = \"<group>\"; };\n\t\t83E704B8226A4D4B00FF678D /* HairColorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HairColorViewController.swift; sourceTree = \"<group>\"; };\n\t\t83F8B4952231932C00686149 /* FeatureViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureViewController.swift; sourceTree = \"<group>\"; };\n\t\t83F8B4972231934F00686149 /* ModelGroupManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelGroupManager.swift; sourceTree = \"<group>\"; };\n\t\t83F8B4992231A65C00686149 /* AIStudioImagePredictor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIStudioImagePredictor.swift; sourceTree = \"<group>\"; };\n\t\t83F8B49E2231C4DB00686149 /* ChooseModelCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChooseModelCell.swift; sourceTree = \"<group>\"; };\n\t\t83F8B4A02231CAB300686149 /* ChooseModelCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ChooseModelCell.xib; sourceTree = \"<group>\"; };\n\t\t83F8B4A22231E25800686149 /* RangeSliderCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RangeSliderCell.xib; sourceTree = \"<group>\"; };\n\t\t83F8B4A422320AD200686149 /* RangeSliderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RangeSliderCell.swift; sourceTree = \"<group>\"; };\n\t\t83F8B4A622320AF700686149 /* FeatureOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureOptions.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA7D226BB09B0038EEE2 /* FritzCamera.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FritzCamera.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA7F226BB4E60038EEE2 /* CameraSessionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraSessionExtensions.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA81226BB6B90038EEE2 /* FritzCamera+CaptureDeviceExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"FritzCamera+CaptureDeviceExtensions.swift\"; sourceTree = \"<group>\"; };\n\t\t83FFFA83226BB7620038EEE2 /* CameraResolutionExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraResolutionExtension.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA85226BB9360038EEE2 /* FritzCamera+Focus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"FritzCamera+Focus.swift\"; sourceTree = \"<group>\"; };\n\t\t83FFFA87226BBA5E0038EEE2 /* CameraAVCaptureVideoDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraAVCaptureVideoDelegate.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA8A226BBCDF0038EEE2 /* FritzCameraButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FritzCameraButton.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA8C226BBD6E0038EEE2 /* FritzCameraViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FritzCameraViewController.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA8F226BBDD80038EEE2 /* Logging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logging.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA90226BBDD80038EEE2 /* LogHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogHandler.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA91226BBDD80038EEE2 /* Locks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Locks.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA95226BBE650038EEE2 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = \"<group>\"; };\n\t\t83FFFA99226BC13F0038EEE2 /* FocusExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FocusExtension.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA9B226BC2640038EEE2 /* CameraInterfaceHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraInterfaceHandler.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA9D226BC2BC0038EEE2 /* FritzTextPromptView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FritzTextPromptView.swift; sourceTree = \"<group>\"; };\n\t\t83FFFA9F226BC5980038EEE2 /* ButtonFunctionality.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonFunctionality.swift; sourceTree = \"<group>\"; };\n\t\t83FFFAA1226BC8F60038EEE2 /* CameraDelegateImplmentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraDelegateImplmentation.swift; sourceTree = \"<group>\"; };\n\t\t83FFFAA3226BC9C00038EEE2 /* FritzCameraControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FritzCameraControllerDelegate.swift; sourceTree = \"<group>\"; };\n\t\t83FFFAA5226BCAD30038EEE2 /* GestureReconizerDelegateExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GestureReconizerDelegateExtension.swift; sourceTree = \"<group>\"; };\n\t\t83FFFAA7226BCB3F0038EEE2 /* FritzDeviceUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FritzDeviceUtil.swift; sourceTree = \"<group>\"; };\n\t\t83FFFAAE226C1D020038EEE2 /* SettingsButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsButton.swift; sourceTree = \"<group>\"; };\n\t\t83FFFAB1226C2F6F0038EEE2 /* SettingsButtonInteractionExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsButtonInteractionExtension.swift; sourceTree = \"<group>\"; };\n\t\t83FFFAD7226E5C1E0038EEE2 /* ImageSegmentationFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageSegmentationFeature.swift; sourceTree = \"<group>\"; };\n\t\t83FFFAD9226ED1400038EEE2 /* CapturePhotoDelgate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapturePhotoDelgate.swift; sourceTree = \"<group>\"; };\n\t\t83FFFADB226ED4460038EEE2 /* PhotoCaptureExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoCaptureExtensions.swift; sourceTree = \"<group>\"; };\n\t\t83FFFADD226ED66C0038EEE2 /* AVPhotoExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPhotoExtension.swift; sourceTree = \"<group>\"; };\n\t\t83FFFAE1226EF2760038EEE2 /* PoseEstimation+ImagePredictor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"PoseEstimation+ImagePredictor.swift\"; sourceTree = \"<group>\"; };\n\t\t987A4D76A43F0D9DAAA2EEA0 /* Pods_FritzAIStudio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzAIStudio.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tB5A0312806F40AF1D5063CC7 /* Pods-FritzAIStudio.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzAIStudio.release.xcconfig\"; path = \"Target Support Files/Pods-FritzAIStudio/Pods-FritzAIStudio.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tD6D64EB84C51E54A675D10D5 /* Pods-FritzAIStudio.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzAIStudio.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzAIStudio/Pods-FritzAIStudio.debug.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t38F2E2331FE0D0B6007241CB /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t05EF5E33F1BB897F7E2DA89C /* Pods_FritzAIStudio.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t381817D91FE2D93F00050FF6 /* Root */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t381817E21FE2DADD00050FF6 /* RootViewController.swift */,\n\t\t\t\t381817E41FE2DAE400050FF6 /* Root.storyboard */,\n\t\t\t);\n\t\t\tpath = Root;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t381817DA1FE2D94600050FF6 /* Common */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8379BD4B22727E01008E041D /* DebuggingImages */,\n\t\t\t\t8375F029227134CC0048B9D8 /* Utils */,\n\t\t\t\t83FFFA8E226BBDD80038EEE2 /* Logging */,\n\t\t\t\t8375F0252271313B0048B9D8 /* AIStudioFeaturePredictors.swift */,\n\t\t\t\t8375F02A227135F80048B9D8 /* ImagePredictorProtocol.swift */,\n\t\t\t\t83F8B4972231934F00686149 /* ModelGroupManager.swift */,\n\t\t\t\t8375F027227134780048B9D8 /* PredictorOptionTypes.swift */,\n\t\t\t\t83F8B4992231A65C00686149 /* AIStudioImagePredictor.swift */,\n\t\t\t\t839231F5222F9282001182EB /* FritzModelDetails.swift */,\n\t\t\t);\n\t\t\tpath = Common;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t383D40C41FE18EEC00438A9B /* Source */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8379BD3922724097008E041D /* FritzCamera */,\n\t\t\t\t383D40C51FE18EF300438A9B /* Delegate */,\n\t\t\t\t383D40C61FE18EFA00438A9B /* Modules */,\n\t\t\t);\n\t\t\tpath = Source;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t383D40C51FE18EF300438A9B /* Delegate */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t38F2E2391FE0D0B6007241CB /* AppDelegate.swift */,\n\t\t\t);\n\t\t\tpath = Delegate;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t383D40C61FE18EFA00438A9B /* Modules */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83FFFAAD226C1CC80038EEE2 /* FeatureController */,\n\t\t\t\t385CF1B11FF2EA8600F1BFF0 /* Demos */,\n\t\t\t\t83FFFADF226EF20B0038EEE2 /* PredictorControllers */,\n\t\t\t\t83FFFAE0226EF2270038EEE2 /* ModelExtensions */,\n\t\t\t\t381817DA1FE2D94600050FF6 /* Common */,\n\t\t\t\t381817D91FE2D93F00050FF6 /* Root */,\n\t\t\t);\n\t\t\tpath = Modules;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t383D40C71FE18F0400438A9B /* Media */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t38F2E2401FE0D0B6007241CB /* Assets.xcassets */,\n\t\t\t\t38F2E2421FE0D0B6007241CB /* LaunchScreen.storyboard */,\n\t\t\t);\n\t\t\tpath = Media;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t383D40C81FE18F0D00438A9B /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t383D40CA1FE18FAC00438A9B /* R.generated.swift */,\n\t\t\t\t38F2E2451FE0D0B6007241CB /* Info.plist */,\n\t\t\t);\n\t\t\tpath = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t385CF1B11FF2EA8600F1BFF0 /* Demos */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t385CF1B61FF2F13400F1BFF0 /* Cells */,\n\t\t\t\t38E96C032001310000683571 /* NavigationController.swift */,\n\t\t\t\t385CF1B21FF2EAA200F1BFF0 /* DemosViewController.swift */,\n\t\t\t\t385CF1B41FF2EAAA00F1BFF0 /* Demos.storyboard */,\n\t\t\t);\n\t\t\tpath = Demos;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t385CF1B61FF2F13400F1BFF0 /* Cells */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t385CF1B71FF2F14700F1BFF0 /* DemoTableViewCell.swift */,\n\t\t\t\t8325F7F422325A29007C1D38 /* LinkTableViewCell.swift */,\n\t\t\t);\n\t\t\tpath = Cells;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t389074281FFDE68900DFF7F9 /* LabelImages */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t389074291FFDE6A000DFF7F9 /* FritzVisionLabelViewController.swift */,\n\t\t\t\t3890742B1FFDE6A900DFF7F9 /* LabelImages.storyboard */,\n\t\t\t);\n\t\t\tpath = LabelImages;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t38F2E22D1FE0D0B6007241CB = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t38F2E2381FE0D0B6007241CB /* FritzAIStudio */,\n\t\t\t\t38F2E2371FE0D0B6007241CB /* Products */,\n\t\t\t\tBB7C1803FE2702C0510B0BC9 /* Pods */,\n\t\t\t\tA2FA376779F0F93A7EBAFE6F /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t38F2E2371FE0D0B6007241CB /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t38F2E2361FE0D0B6007241CB /* FritzAIStudio.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t38F2E2381FE0D0B6007241CB /* FritzAIStudio */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t383D40C41FE18EEC00438A9B /* Source */,\n\t\t\t\t383D40C71FE18F0400438A9B /* Media */,\n\t\t\t\t383D40C81FE18F0D00438A9B /* Supporting Files */,\n\t\t\t);\n\t\t\tpath = FritzAIStudio;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8375F029227134CC0048B9D8 /* Utils */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B5631AC233A7A3200B2D289 /* FritzLogger.swift */,\n\t\t\t\t83FFFAA7226BCB3F0038EEE2 /* FritzDeviceUtil.swift */,\n\t\t\t);\n\t\t\tpath = Utils;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8379BD3922724097008E041D /* FritzCamera */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83FFFA7C226BAF880038EEE2 /* FritzCamera */,\n\t\t\t\t83FFFA89226BBCB40038EEE2 /* FritzCameraUI */,\n\t\t\t);\n\t\t\tpath = FritzCamera;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8379BD4B22727E01008E041D /* DebuggingImages */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8379BD3D22725B71008E041D /* styleTransferBoston.jpg */,\n\t\t\t\t8379BD3F22725CF9008E041D /* eric.jpg */,\n\t\t\t\t8379BD452272604A008E041D /* hair1.jpg */,\n\t\t\t\t8379BD492272664D008E041D /* pose.jpg */,\n\t\t\t);\n\t\t\tpath = DebuggingImages;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t838B5289210242DD00E0D50A /* DetectObjects */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t838B528A2102432700E0D50A /* DetectObjectsViewController.swift */,\n\t\t\t\t838B528C210243CF00E0D50A /* DetectObjectsStoryboard.storyboard */,\n\t\t\t);\n\t\t\tpath = DetectObjects;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83F8B49D2231C4C200686149 /* ConfigureModelCells */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83F8B4A02231CAB300686149 /* ChooseModelCell.xib */,\n\t\t\t\t83F8B49E2231C4DB00686149 /* ChooseModelCell.swift */,\n\t\t\t\t8325F7F0223238DC007C1D38 /* SegmentSliderCell.swift */,\n\t\t\t\t8325F7F2223243FB007C1D38 /* SegmentSliderCell.xib */,\n\t\t\t\t83F8B4A422320AD200686149 /* RangeSliderCell.swift */,\n\t\t\t\t83F8B4A22231E25800686149 /* RangeSliderCell.xib */,\n\t\t\t\t837B6EEB226A6C9300158698 /* ChooseColorCell.swift */,\n\t\t\t\t837B6EED226A6CDF00158698 /* ChooseColorCell.xib */,\n\t\t\t);\n\t\t\tpath = ConfigureModelCells;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83FFFA7C226BAF880038EEE2 /* FritzCamera */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83FFFA7D226BB09B0038EEE2 /* FritzCamera.swift */,\n\t\t\t\t83FFFAD0226E51E60038EEE2 /* Extensions */,\n\t\t\t\t83FFFACF226E51D50038EEE2 /* Delegates */,\n\t\t\t);\n\t\t\tpath = FritzCamera;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83FFFA89226BBCB40038EEE2 /* FritzCameraUI */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83FFFAB3226E19970038EEE2 /* Extensions */,\n\t\t\t\t83FFFA8C226BBD6E0038EEE2 /* FritzCameraViewController.swift */,\n\t\t\t\t83FFFAA1226BC8F60038EEE2 /* CameraDelegateImplmentation.swift */,\n\t\t\t\t83FFFA8A226BBCDF0038EEE2 /* FritzCameraButton.swift */,\n\t\t\t\t83FFFA9D226BC2BC0038EEE2 /* FritzTextPromptView.swift */,\n\t\t\t\t83FFFAA3226BC9C00038EEE2 /* FritzCameraControllerDelegate.swift */,\n\t\t\t\t83FFFA95226BBE650038EEE2 /* Media.xcassets */,\n\t\t\t);\n\t\t\tpath = FritzCameraUI;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83FFFA8E226BBDD80038EEE2 /* Logging */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83FFFA8F226BBDD80038EEE2 /* Logging.swift */,\n\t\t\t\t83FFFA90226BBDD80038EEE2 /* LogHandler.swift */,\n\t\t\t\t83FFFA91226BBDD80038EEE2 /* Locks.swift */,\n\t\t\t);\n\t\t\tpath = Logging;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83FFFAAD226C1CC80038EEE2 /* FeatureController */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8392321A2230673D001182EB /* ModelOptions.storyboard */,\n\t\t\t\t83F8B4952231932C00686149 /* FeatureViewController.swift */,\n\t\t\t\t83F8B4A622320AF700686149 /* FeatureOptions.swift */,\n\t\t\t\t83FFFAAE226C1D020038EEE2 /* SettingsButton.swift */,\n\t\t\t\t839231F3222F8DF9001182EB /* ConfigurePopover.swift */,\n\t\t\t\t839231F1222F76F1001182EB /* ChooseModelController.swift */,\n\t\t\t\t83F8B49D2231C4C200686149 /* ConfigureModelCells */,\n\t\t\t\t83FFFAB0226C2F510038EEE2 /* Extensions */,\n\t\t\t);\n\t\t\tpath = FeatureController;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83FFFAB0226C2F510038EEE2 /* Extensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83FFFAB1226C2F6F0038EEE2 /* SettingsButtonInteractionExtension.swift */,\n\t\t\t\t8375F02E22714D4E0048B9D8 /* NavigationBarCustomization.swift */,\n\t\t\t);\n\t\t\tpath = Extensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83FFFAB3226E19970038EEE2 /* Extensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83FFFAA5226BCAD30038EEE2 /* GestureReconizerDelegateExtension.swift */,\n\t\t\t\t83FFFA9B226BC2640038EEE2 /* CameraInterfaceHandler.swift */,\n\t\t\t\t83FFFA9F226BC5980038EEE2 /* ButtonFunctionality.swift */,\n\t\t\t\t83FFFA99226BC13F0038EEE2 /* FocusExtension.swift */,\n\t\t\t\t8379BD4E22739102008E041D /* DebugImageExtensions.swift */,\n\t\t\t);\n\t\t\tpath = Extensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83FFFACF226E51D50038EEE2 /* Delegates */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83FFFA87226BBA5E0038EEE2 /* CameraAVCaptureVideoDelegate.swift */,\n\t\t\t\t83FFFAD9226ED1400038EEE2 /* CapturePhotoDelgate.swift */,\n\t\t\t);\n\t\t\tpath = Delegates;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83FFFAD0226E51E60038EEE2 /* Extensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83FFFADB226ED4460038EEE2 /* PhotoCaptureExtensions.swift */,\n\t\t\t\t83FFFA7F226BB4E60038EEE2 /* CameraSessionExtensions.swift */,\n\t\t\t\t83FFFA85226BB9360038EEE2 /* FritzCamera+Focus.swift */,\n\t\t\t\t83FFFA83226BB7620038EEE2 /* CameraResolutionExtension.swift */,\n\t\t\t\t83FFFA81226BB6B90038EEE2 /* FritzCamera+CaptureDeviceExtensions.swift */,\n\t\t\t\t83FFFADD226ED66C0038EEE2 /* AVPhotoExtension.swift */,\n\t\t\t);\n\t\t\tpath = Extensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83FFFADF226EF20B0038EEE2 /* PredictorControllers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t389074281FFDE68900DFF7F9 /* LabelImages */,\n\t\t\t\t838B5289210242DD00E0D50A /* DetectObjects */,\n\t\t\t\t83E704B8226A4D4B00FF678D /* HairColorViewController.swift */,\n\t\t\t\t8375F03422721CE00048B9D8 /* HairColor+ColorSlider.swift */,\n\t\t\t\t8396CA2C220A9FDC00742120 /* PoseEstimationViewController.swift */,\n\t\t\t\t83AC97D62149CB8600E86B44 /* ImageSegmentationViewController.swift */,\n\t\t\t\t8325F7E822323110007C1D38 /* StyleTransferViewController.swift */,\n\t\t\t);\n\t\t\tpath = PredictorControllers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83FFFAE0226EF2270038EEE2 /* ModelExtensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83FFFAD7226E5C1E0038EEE2 /* ImageSegmentationFeature.swift */,\n\t\t\t\t83FFFAE1226EF2760038EEE2 /* PoseEstimation+ImagePredictor.swift */,\n\t\t\t);\n\t\t\tpath = ModelExtensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA2FA376779F0F93A7EBAFE6F /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t987A4D76A43F0D9DAAA2EEA0 /* Pods_FritzAIStudio.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tBB7C1803FE2702C0510B0BC9 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tD6D64EB84C51E54A675D10D5 /* Pods-FritzAIStudio.debug.xcconfig */,\n\t\t\t\tB5A0312806F40AF1D5063CC7 /* Pods-FritzAIStudio.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t38F2E2351FE0D0B6007241CB /* FritzAIStudio */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 38F2E2481FE0D0B6007241CB /* Build configuration list for PBXNativeTarget \"FritzAIStudio\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t2C1AC0BE073F2B5C7B449D97 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t383D40CC1FE1901700438A9B /* Swift Lint */,\n\t\t\t\t383D40C31FE18EA000438A9B /* R.swift */,\n\t\t\t\t38F2E2321FE0D0B6007241CB /* Sources */,\n\t\t\t\t38F2E2331FE0D0B6007241CB /* Frameworks */,\n\t\t\t\t38F2E2341FE0D0B6007241CB /* Resources */,\n\t\t\t\t38B18CC31FE22C91005AA896 /* Fabric */,\n\t\t\t\tEA18C4F1306D7737BA6172C8 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzAIStudio;\n\t\t\tproductName = \"Fritz Labs\";\n\t\t\tproductReference = 38F2E2361FE0D0B6007241CB /* FritzAIStudio.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t38F2E22E1FE0D0B6007241CB /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 0920;\n\t\t\t\tLastUpgradeCheck = 0930;\n\t\t\t\tORGANIZATIONNAME = \"Fritz Labs, Inc.\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t38F2E2351FE0D0B6007241CB = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 9.2;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 38F2E2311FE0D0B6007241CB /* Build configuration list for PBXProject \"Fritz Labs\" */;\n\t\t\tcompatibilityVersion = \"Xcode 8.0\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 38F2E22D1FE0D0B6007241CB;\n\t\t\tproductRefGroup = 38F2E2371FE0D0B6007241CB /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t38F2E2351FE0D0B6007241CB /* FritzAIStudio */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t38F2E2341FE0D0B6007241CB /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8392321B2230673D001182EB /* ModelOptions.storyboard in Resources */,\n\t\t\t\t83F8B4A12231CAB400686149 /* ChooseModelCell.xib in Resources */,\n\t\t\t\t3890742C1FFDE6A900DFF7F9 /* LabelImages.storyboard in Resources */,\n\t\t\t\t381817E51FE2DAE400050FF6 /* Root.storyboard in Resources */,\n\t\t\t\t83FFFA96226BBE660038EEE2 /* Media.xcassets in Resources */,\n\t\t\t\t8379BD3E22725B72008E041D /* styleTransferBoston.jpg in Resources */,\n\t\t\t\t8379BD462272604A008E041D /* hair1.jpg in Resources */,\n\t\t\t\t38F2E2441FE0D0B6007241CB /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t83F8B4A32231E25800686149 /* RangeSliderCell.xib in Resources */,\n\t\t\t\t8379BD4A2272664D008E041D /* pose.jpg in Resources */,\n\t\t\t\t38F2E2411FE0D0B6007241CB /* Assets.xcassets in Resources */,\n\t\t\t\t838B528D210243CF00E0D50A /* DetectObjectsStoryboard.storyboard in Resources */,\n\t\t\t\t8325F7F3223243FB007C1D38 /* SegmentSliderCell.xib in Resources */,\n\t\t\t\t8379BD4022725CF9008E041D /* eric.jpg in Resources */,\n\t\t\t\t837B6EEE226A6CDF00158698 /* ChooseColorCell.xib in Resources */,\n\t\t\t\t385CF1B51FF2EAAA00F1BFF0 /* Demos.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t2C1AC0BE073F2B5C7B449D97 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzAIStudio-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t383D40C31FE18EA000438A9B /* R.swift */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"$(SRCROOT)/FritzAIStudio/rswift.workaround.file\",\n\t\t\t);\n\t\t\tname = R.swift;\n\t\t\toutputPaths = (\n\t\t\t\t\"$(SRCROOT)/FritzAIStudio/R.generated.swift\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"$PODS_ROOT/R.swift/rswift\\\" generate \\\"$SRCROOT/FritzAIStudio\\\"\\n# Solution as per https://github.com/mac-cain13/R.swift/issues/456#issuecomment-426344064\\ndate > \\\"$SRCROOT/FritzAIStudio/rswift.workaround.file\\\"\\n\";\n\t\t};\n\t\t383D40CC1FE1901700438A9B /* Swift Lint */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Swift Lint\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"#if which swiftlint >/dev/null; then\\n#    swiftlint\\n#else\\n#    echo \\\"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\\\"\\n#fi\";\n\t\t};\n\t\t38B18CC31FE22C91005AA896 /* Fabric */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = Fabric;\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Fabric/run\\\" 3ab14d933cbf3577dd7434aa17e1171fdd726172 a7e273788cbf79557095d9bd720a5d71abef69142d7a82ef17e9d88751ee49d8\\n\";\n\t\t};\n\t\tEA18C4F1306D7737BA6172C8 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzAIStudio/Pods-FritzAIStudio-frameworks.sh\",\n\t\t\t\t\"${BUILT_PRODUCTS_DIR}/ColorSlider/ColorSlider.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzBase/Frameworks/FritzCore.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzBase/Frameworks/Fritz.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzBase/Frameworks/CoreMLHelpers.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzBase/Frameworks/FritzManagedModel.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzBase/Frameworks/FritzVision.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzVisionHairSegmentationModelFast/Frameworks/FritzVisionHairSegmentationModelFast.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzVisionHumanPoseModelFast/Frameworks/FritzVisionHumanPoseModelFast.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzVisionLabelModelFast/Frameworks/FritzVisionLabelModelFast.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzVisionObjectModelFast/Frameworks/FritzVisionObjectModelFast.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzVisionPeopleSegmentationModelFast/Frameworks/FritzVisionPeopleSegmentationModelFast.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzVisionStyleModelPaintings/Frameworks/FritzVisionStyleModelPaintings.framework\",\n\t\t\t\t\"${PODS_ROOT}/FritzVisionStyleModelPatterns/Frameworks/FritzVisionStyleModelPatterns.framework\",\n\t\t\t\t\"${BUILT_PRODUCTS_DIR}/R.swift.Library/Rswift.framework\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputPaths = (\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ColorSlider.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FritzCore.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Fritz.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CoreMLHelpers.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FritzManagedModel.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FritzVision.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FritzVisionHairSegmentationModelFast.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FritzVisionHumanPoseModelFast.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FritzVisionLabelModelFast.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FritzVisionObjectModelFast.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FritzVisionPeopleSegmentationModelFast.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FritzVisionStyleModelPaintings.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FritzVisionStyleModelPatterns.framework\",\n\t\t\t\t\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Rswift.framework\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzAIStudio/Pods-FritzAIStudio-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t38F2E2321FE0D0B6007241CB /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t385CF1B31FF2EAA200F1BFF0 /* DemosViewController.swift in Sources */,\n\t\t\t\t83FFFA94226BBDD80038EEE2 /* Locks.swift in Sources */,\n\t\t\t\t83FFFA84226BB7620038EEE2 /* CameraResolutionExtension.swift in Sources */,\n\t\t\t\t8375F03522721CE00048B9D8 /* HairColor+ColorSlider.swift in Sources */,\n\t\t\t\t83FFFA92226BBDD80038EEE2 /* Logging.swift in Sources */,\n\t\t\t\t83FFFAA6226BCAD30038EEE2 /* GestureReconizerDelegateExtension.swift in Sources */,\n\t\t\t\t839231F4222F8DF9001182EB /* ConfigurePopover.swift in Sources */,\n\t\t\t\t839231F6222F9282001182EB /* FritzModelDetails.swift in Sources */,\n\t\t\t\t8379BD4F22739102008E041D /* DebugImageExtensions.swift in Sources */,\n\t\t\t\t83E704B9226A4D4B00FF678D /* HairColorViewController.swift in Sources */,\n\t\t\t\t385CF1B81FF2F14700F1BFF0 /* DemoTableViewCell.swift in Sources */,\n\t\t\t\t8325F7F522325A29007C1D38 /* LinkTableViewCell.swift in Sources */,\n\t\t\t\t381817E31FE2DADD00050FF6 /* RootViewController.swift in Sources */,\n\t\t\t\t83FFFADE226ED66C0038EEE2 /* AVPhotoExtension.swift in Sources */,\n\t\t\t\t83F8B4962231932C00686149 /* FeatureViewController.swift in Sources */,\n\t\t\t\t83FFFAA8226BCB3F0038EEE2 /* FritzDeviceUtil.swift in Sources */,\n\t\t\t\t8375F0262271313B0048B9D8 /* AIStudioFeaturePredictors.swift in Sources */,\n\t\t\t\t8375F02F22714D4E0048B9D8 /* NavigationBarCustomization.swift in Sources */,\n\t\t\t\t83FFFA8B226BBCDF0038EEE2 /* FritzCameraButton.swift in Sources */,\n\t\t\t\t83FFFAAF226C1D020038EEE2 /* SettingsButton.swift in Sources */,\n\t\t\t\t83FFFA80226BB4E60038EEE2 /* CameraSessionExtensions.swift in Sources */,\n\t\t\t\t8375F02B227135F80048B9D8 /* ImagePredictorProtocol.swift in Sources */,\n\t\t\t\t83FFFA9E226BC2BC0038EEE2 /* FritzTextPromptView.swift in Sources */,\n\t\t\t\t83FFFA9A226BC13F0038EEE2 /* FocusExtension.swift in Sources */,\n\t\t\t\t83FFFA7E226BB09B0038EEE2 /* FritzCamera.swift in Sources */,\n\t\t\t\t3890742A1FFDE6A000DFF7F9 /* FritzVisionLabelViewController.swift in Sources */,\n\t\t\t\t8325F7F1223238DC007C1D38 /* SegmentSliderCell.swift in Sources */,\n\t\t\t\t3B5631AD233A7A3200B2D289 /* FritzLogger.swift in Sources */,\n\t\t\t\t83AC97D72149CB8600E86B44 /* ImageSegmentationViewController.swift in Sources */,\n\t\t\t\t83F8B4A722320AF700686149 /* FeatureOptions.swift in Sources */,\n\t\t\t\t8325F7E922323110007C1D38 /* StyleTransferViewController.swift in Sources */,\n\t\t\t\t83FFFAA4226BC9C00038EEE2 /* FritzCameraControllerDelegate.swift in Sources */,\n\t\t\t\t83FFFAB2226C2F6F0038EEE2 /* SettingsButtonInteractionExtension.swift in Sources */,\n\t\t\t\t83F8B49A2231A65C00686149 /* AIStudioImagePredictor.swift in Sources */,\n\t\t\t\t38F2E23A1FE0D0B6007241CB /* AppDelegate.swift in Sources */,\n\t\t\t\t83FFFA88226BBA5E0038EEE2 /* CameraAVCaptureVideoDelegate.swift in Sources */,\n\t\t\t\t83FFFAA2226BC8F60038EEE2 /* CameraDelegateImplmentation.swift in Sources */,\n\t\t\t\t83FFFADC226ED4460038EEE2 /* PhotoCaptureExtensions.swift in Sources */,\n\t\t\t\t83F8B4982231934F00686149 /* ModelGroupManager.swift in Sources */,\n\t\t\t\t383D40CB1FE18FAC00438A9B /* R.generated.swift in Sources */,\n\t\t\t\t83FFFAD8226E5C1E0038EEE2 /* ImageSegmentationFeature.swift in Sources */,\n\t\t\t\t83FFFA82226BB6B90038EEE2 /* FritzCamera+CaptureDeviceExtensions.swift in Sources */,\n\t\t\t\t83FFFADA226ED1400038EEE2 /* CapturePhotoDelgate.swift in Sources */,\n\t\t\t\t8375F028227134780048B9D8 /* PredictorOptionTypes.swift in Sources */,\n\t\t\t\t83F8B49F2231C4DB00686149 /* ChooseModelCell.swift in Sources */,\n\t\t\t\t838B528B2102432700E0D50A /* DetectObjectsViewController.swift in Sources */,\n\t\t\t\t83FFFA93226BBDD80038EEE2 /* LogHandler.swift in Sources */,\n\t\t\t\t83FFFA8D226BBD6E0038EEE2 /* FritzCameraViewController.swift in Sources */,\n\t\t\t\t83FFFAA0226BC5980038EEE2 /* ButtonFunctionality.swift in Sources */,\n\t\t\t\t83F8B4A522320AD200686149 /* RangeSliderCell.swift in Sources */,\n\t\t\t\t83FFFA9C226BC2640038EEE2 /* CameraInterfaceHandler.swift in Sources */,\n\t\t\t\t837B6EEC226A6C9300158698 /* ChooseColorCell.swift in Sources */,\n\t\t\t\t38E96C042001310000683571 /* NavigationController.swift in Sources */,\n\t\t\t\t83FFFA86226BB9360038EEE2 /* FritzCamera+Focus.swift in Sources */,\n\t\t\t\t839231F2222F76F1001182EB /* ChooseModelController.swift in Sources */,\n\t\t\t\t8396CA2D220A9FDC00742120 /* PoseEstimationViewController.swift in Sources */,\n\t\t\t\t83FFFAE2226EF2760038EEE2 /* PoseEstimation+ImagePredictor.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t38F2E2421FE0D0B6007241CB /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t38F2E2431FE0D0B6007241CB /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t38F2E2461FE0D0B6007241CB /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 11.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t38F2E2471FE0D0B6007241CB /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 11.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Owholemodule\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t38F2E2491FE0D0B6007241CB /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = D6D64EB84C51E54A675D10D5 /* Pods-FritzAIStudio.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/FritzAIStudio/Supporting Files/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.fritz.Heartbeat;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t38F2E24A1FE0D0B6007241CB /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = B5A0312806F40AF1D5063CC7 /* Pods-FritzAIStudio.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/FritzAIStudio/Supporting Files/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.fritz.Heartbeat;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t38F2E2311FE0D0B6007241CB /* Build configuration list for PBXProject \"Fritz Labs\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t38F2E2461FE0D0B6007241CB /* Debug */,\n\t\t\t\t38F2E2471FE0D0B6007241CB /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t38F2E2481FE0D0B6007241CB /* Build configuration list for PBXNativeTarget \"FritzAIStudio\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t38F2E2491FE0D0B6007241CB /* Debug */,\n\t\t\t\t38F2E24A1FE0D0B6007241CB /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 38F2E22E1FE0D0B6007241CB /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzAIStudio/FritzAIStudio.xcodeproj/xcshareddata/xcschemes/FritzAIStudio.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1100\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"38F2E2351FE0D0B6007241CB\"\n               BuildableName = \"FritzAIStudio.app\"\n               BlueprintName = \"FritzAIStudio\"\n               ReferencedContainer = \"container:FritzAIStudio.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"38F2E2351FE0D0B6007241CB\"\n            BuildableName = \"FritzAIStudio.app\"\n            BlueprintName = \"FritzAIStudio\"\n            ReferencedContainer = \"container:FritzAIStudio.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"38F2E2351FE0D0B6007241CB\"\n            BuildableName = \"FritzAIStudio.app\"\n            BlueprintName = \"FritzAIStudio\"\n            ReferencedContainer = \"container:FritzAIStudio.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"38F2E2351FE0D0B6007241CB\"\n            BuildableName = \"FritzAIStudio.app\"\n            BlueprintName = \"FritzAIStudio\"\n            ReferencedContainer = \"container:FritzAIStudio.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "iOS/FritzAIStudio/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 Fritz Labs Incorporated\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "iOS/FritzAIStudio/Podfile",
    "content": "\nplatform :ios, '12.0'\n\nuse_frameworks!\ninhibit_all_warnings!\n\nproject 'FritzAIStudio.xcodeproj'\n\ntarget 'FritzAIStudio' do\n  pod 'Crashlytics', '~> 3.9'\n  pod 'Fabric', '~> 1.7'\n  pod 'ColorSlider', '~> 4.4'\n  pod 'Fritz', '6.1.2'\n  pod 'Fritz/VisionObjectModel/Fast'\n  pod 'Fritz/VisionStyleModel/Paintings'\n  pod 'Fritz/VisionStyleModel/Patterns'\n  pod 'Fritz/VisionLabelModel/Fast'\n  pod 'Fritz/VisionSegmentationModel/People/Fast'\n  pod 'Fritz/VisionSegmentationModel/Hair/Fast'\n  pod 'Fritz/VisionPoseModel/Human/Fast'\n\n  pod 'R.swift', '5.0.0.alpha.2'\nend\n"
  },
  {
    "path": "iOS/FritzAIStudio/README.md",
    "content": "# Fritz AI Studio\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nFritz AI Studio is a collection of unique experiences built with machine learning models. Explore the code for our demos, or fork the repo and build your own app. It's also available from the [App Store](https://apps.apple.com/us/app/fritz-ai-studio/id1325206416).\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started with machine learning in your apps.\n\n## Getting Started\n\nThe steps below will guide you through downloading this project, getting it up, and running in a simulator or on device.\n\n### Requirements\n\nIn order to run this project you need:\n\n- Swift 5.1, Xcode 11.2 or later\n- Git Large File Storage (LFS) - [available here](https://git-lfs.github.com)\n- Cocoapods - [available here](https://cocoapods.org)\n\n### Step 1 - Clone Project\n\nIn order to clone the project, you must first install Git Large File Storage (LFS), [available here](https://git-lfs.github.com). The `MLModel` files are checked into the repo using LFS and will not clone properly otherwise.\n\nAfter installing LFS, [clone](https://github.com/fritzlabs/fritz-examples/tree/master/iOS/FritzAIStudio) the project to your Mac.\n\n### Step 2 - Install Dependencies\n\nOpen a terminal and `cd` to the project directory, then run:\n\n```bash\npod install\n```\n\n### Step 3 - Open Workspace\n\nStart Xcode and open the project from the workspace `FritzAIStudio.xcworkspace`.\n\n### Step 4 - Build & Run\n\nBuild and run the project through the Xcode simulator, using any iOS device.\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzAIStudio/fastlane/Appfile",
    "content": "app_identifier \"com.fritz.Heartbeat\"\napple_id \"andrew@fritz.ai\"\nteam_id \"T3RGJF7P9D\"\n"
  },
  {
    "path": "iOS/FritzAIStudio/fastlane/Deliverfile",
    "content": "app_identifier \"com.fritz.Heartbeat\"\nusername \"andrew@fritz.ai\"\n"
  },
  {
    "path": "iOS/FritzAIStudio/fastlane/Fastfile",
    "content": "lane :dist do\n  gym(\n    workspace: 'FritzAIStudio.xcworkspace',\n    scheme: 'FritzAIStudio',\n    include_symbols: true,\n    include_bitcode: true,\n    export_xcargs: \"-allowProvisioningUpdates\"\n  )\n\n  deliver(\n    team_id: 'T3RGJF7P9D',\n    skip_metadata: true,\n    skip_screenshots: true,\n    force: true,\n    edit_live: get_version_number(target: 'FritzAIStudio')\n  )\n\n  clean_build_artifacts\nend\n"
  },
  {
    "path": "iOS/FritzARKitDemo/ARKIt+Utilities.swift",
    "content": "//\n//  ARKit+Utilities.swift\n//  ARKitCoreML\n//\n//  Created by Jason Clark on 10/11/18.\n//  Copyright © 2018 Raizlabs. All rights reserved.\n//\n\nimport ARKit\n\nimport CoreImage\n\nimport UIKit\nimport VideoToolbox\n\nextension ARSCNView {\n\n  /**\n   Functionally equivalent to `SCNView`'s `snapshot()`, except only including the raw camera image, not any virtual geometry that may be in the scene.\n   */\n  public func capturedImage() -> UIImage? {\n    guard let frame = session.currentFrame else { return nil }\n    return frame.getCapturedImage(inSceneView: self)\n  }\n\n  /**\n   Returns a cropped and deskewed image of the raw camera image of a given `ARImageAnchor`, not including any virtual geometry that may be in the scene.\n   */\n  public func capturedImage(from anchor: ARImageAnchor) -> UIImage? {\n    guard\n      let frame = session.currentFrame,\n      let node = node(for: anchor),\n      let pov = pointOfView,\n      isNode(node, insideFrustumOf: pov),\n      let snapshot = frame.getCapturedImage(inSceneView: self),\n      let coreImage = CIImage(image: snapshot),\n      let featureCorners = projectCorners(of: anchor)\n      else {\n        return nil\n    }\n    // CoreImage uses cartesian coordinates\n    func cartesianForPoint(point: CGPoint, extent: CGRect) -> CGPoint {\n      return CGPoint(x: point.x, y: extent.height - point.y)\n    }\n    let deskewed = coreImage.perspectiveCorrected(\n      topLeft: cartesianForPoint(point: featureCorners.topLeft, extent: coreImage.extent),\n      topRight: cartesianForPoint(point: featureCorners.topRight, extent: coreImage.extent),\n      bottomLeft: cartesianForPoint(point: featureCorners.bottomLeft, extent: coreImage.extent),\n      bottomRight: cartesianForPoint(point: featureCorners.bottomRight, extent: coreImage.extent)\n    )\n    return UIImage(ciImage: deskewed)\n  }\n\n}\n\nextension ARFrame {\n  /**\n   Gives the camera data in the given frame after scaling and cropping it\n   in the same way Apple does it for constructing the backing image you\n   can retrieve via `sceneView.snapshot()`.\n   */\n  func getCapturedImage(inSceneView sceneView: ARSCNView) -> UIImage? {\n    let rawImage = getOrientationCorrectedCameraImage(forOrientation: UIApplication.shared.statusBarOrientation)\n    let viewportSize = sceneView.frame.size\n\n    switch UIApplication.shared.statusBarOrientation {\n\n    case .portrait, .portraitUpsideDown:\n      guard let resized = rawImage?.resize(toHeight: viewportSize.height) else {\n        return nil\n      }\n      return resized.crop(rect: CGRect(\n        x: (resized.size.width - viewportSize.width) / 2,\n        y: 0,\n        width: viewportSize.width,\n        height: viewportSize.height)\n      )\n\n    case .landscapeLeft, .landscapeRight:\n      guard let resized = rawImage?.resize(toWidth: viewportSize.width) else {\n        return nil\n      }\n      return resized.crop(rect: CGRect(\n        x: 0,\n        y: (resized.size.height - viewportSize.height) / 2,\n        width: viewportSize.width,\n        height: viewportSize.height)\n      )\n\n    case .unknown:\n      return nil\n    }\n  }\n\n}\n\nprivate extension ARSCNView {\n\n  private func projectCorners(of imageAnchor: ARImageAnchor) -> (topRight: CGPoint, bottomRight: CGPoint, bottomLeft: CGPoint, topLeft: CGPoint)? {\n    guard\n      let camera = session.currentFrame?.camera,\n      let corners = CornerTrackingNode.tracking(anchor: imageAnchor, inScene: self)\n      else { return nil }\n\n    defer {\n      corners.removeFromParentNode()\n    }\n\n    let pointsWorldSpace = [\n      corners.topRight.simdWorldPosition,\n      corners.bottomRight.simdWorldPosition,\n      corners.bottomLeft.simdWorldPosition,\n      corners.topLeft.simdWorldPosition,\n    ]\n\n    let pointsImageSpace: [CGPoint] = pointsWorldSpace.map {\n      var point = camera.projectPoint($0,\n                                      orientation: UIApplication.shared.statusBarOrientation,\n                                      viewportSize: bounds.size)\n      point.x *= UIScreen.main.scale\n      point.y *= UIScreen.main.scale\n      return point\n    }\n\n    return (\n      topRight: pointsImageSpace[0],\n      bottomRight: pointsImageSpace[1],\n      bottomLeft: pointsImageSpace[2],\n      topLeft: pointsImageSpace[3]\n    )\n  }\n\n}\n\nprivate extension ARFrame {\n  /**\n   Rotates the image from the camera to match the orientation of the device.\n   */\n  private func getOrientationCorrectedCameraImage(forOrientation orientation: UIInterfaceOrientation) -> UIImage? {\n    var rotationRadians: Float = 0\n    switch orientation {\n    case .portrait:\n      rotationRadians = .pi / 2\n    case .portraitUpsideDown:\n      rotationRadians = -.pi / 2\n    case .landscapeLeft:\n      rotationRadians = .pi\n    case .landscapeRight:\n      break\n    case .unknown:\n      return nil\n    }\n    return UIImage(pixelBuffer: capturedImage)?.rotate(radians: rotationRadians)\n  }\n\n}\n\n\nprivate class CornerTrackingNode: SCNNode {\n\n  let topLeft = SCNNode()\n  let topRight = SCNNode()\n  let bottomLeft = SCNNode()\n  let bottomRight = SCNNode()\n\n  init(anchor: ARImageAnchor) {\n    super.init()\n\n    let physicalSize = anchor.referenceImage.physicalSize\n    let halfWidth = Float(physicalSize.width / 2)\n    let halfHeight = Float(physicalSize.height / 2)\n\n    addChildNode(topLeft)\n    topLeft.position = position\n    topLeft.localTranslate(by: SCNVector3(-halfWidth, 0, halfHeight))\n\n    addChildNode(topRight)\n    topRight.position = position\n    topRight.localTranslate(by: SCNVector3(halfWidth, 0, halfHeight))\n\n    addChildNode(bottomLeft)\n    bottomLeft.position = position\n    bottomLeft.localTranslate(by: SCNVector3(-halfWidth, 0, -halfHeight))\n\n    addChildNode(bottomRight)\n    bottomRight.position = position\n    bottomRight.localTranslate(by: SCNVector3(halfWidth, 0, -halfHeight))\n  }\n\n  required init?(coder aDecoder: NSCoder) {\n    fatalError(\"init(coder:) has not been implemented\")\n  }\n\n  static func tracking(anchor: ARImageAnchor, inScene scene: ARSCNView) -> CornerTrackingNode? {\n    guard let node = scene.node(for: anchor) else { return nil }\n    let tracker = CornerTrackingNode(anchor: anchor)\n    node.addChildNode(tracker)\n    return tracker\n  }\n\n}\n\nextension CIImage {\n\n  func perspectiveCorrected(topLeft: CGPoint, topRight: CGPoint, bottomLeft: CGPoint, bottomRight: CGPoint) -> CIImage {\n    return self.applyingFilter(\"CIPerspectiveCorrection\", parameters: [\n      \"inputTopLeft\": CIVector(cgPoint: topLeft),\n      \"inputTopRight\": CIVector(cgPoint: topRight),\n      \"inputBottomLeft\": CIVector(cgPoint: bottomLeft),\n      \"inputBottomRight\": CIVector(cgPoint: bottomRight),\n      ])\n  }\n\n}\n\n\nextension UIImage {\n\n  public convenience init?(pixelBuffer: CVPixelBuffer) {\n    var cgImage: CGImage?\n    VTCreateCGImageFromCVPixelBuffer(pixelBuffer, options: nil, imageOut: &cgImage)\n    guard let image = cgImage else { return nil }\n    self.init(cgImage: image)\n  }\n\n  public func crop(rect: CGRect) -> UIImage? {\n    var rect = rect\n    rect.origin.x *= scale\n    rect.origin.y *= scale\n    rect.size.width *= scale\n    rect.size.height *= scale\n\n    if let imageRef = cgImage?.cropping(to: rect) {\n      return UIImage(cgImage: imageRef, scale: scale, orientation: imageOrientation)\n    }\n    return nil\n  }\n\n  public func rotate(radians: Float) -> UIImage? {\n    var newSize = CGRect(origin: .zero, size: size)\n      .applying(CGAffineTransform(rotationAngle: CGFloat(radians))).size\n\n    newSize.width = floor(newSize.width)\n    newSize.height = floor(newSize.height)\n\n    UIGraphicsBeginImageContextWithOptions(newSize, true, scale)\n    guard let context = UIGraphicsGetCurrentContext() else { return nil }\n\n    // Move origin to middle\n    context.translateBy(x: newSize.width / 2, y: newSize.height / 2)\n    // Rotate around middle\n    context.rotate(by: CGFloat(radians))\n\n    self.draw(in: CGRect(\n      x: -size.width / 2,\n      y: -size.height / 2,\n      width: size.width, height: size.height\n    ))\n\n    let newImage = UIGraphicsGetImageFromCurrentImageContext()\n    UIGraphicsEndImageContext()\n\n    return newImage\n  }\n\n  public func getOrCreateCGImage() -> CGImage? {\n    return cgImage ?? ciImage.flatMap {\n      let context = CIContext()\n      return context.createCGImage($0, from: $0.extent)\n    }\n  }\n\n  /**\n   Scales the image to the given height while preserving its aspect ratio.\n   */\n  public func resize(toHeight newHeight: CGFloat) -> UIImage? {\n    guard self.size.height != newHeight else { return self }\n    let ratio = newHeight / size.height\n    let newSize = CGSize(width: size.width * ratio, height: newHeight)\n    return resize(to: newSize)\n  }\n\n  /**\n   Scales the image to the given width while preserving its aspect ratio.\n   */\n  public func resize(toWidth newWidth: CGFloat) -> UIImage? {\n    guard self.size.width != newWidth else { return self }\n    let ratio = newWidth / size.width\n    let newSize = CGSize(width: newWidth, height: size.height * ratio)\n    return resize(to: newSize)\n  }\n\n  private func resize(to newSize: CGSize) -> UIImage? {\n    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)\n    self.draw(in: CGRect(origin: .zero, size: newSize))\n    let scaledImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()\n    UIGraphicsEndImageContext()\n    return scaledImage\n  }\n\n}\n"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  ARPoseDemo\n//\n//  Created by Christopher Kelly on 5/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n    // Override point for customization after application launch.\n      // Automatically added FritzCore configure.\n      FritzCore.configure()\n    return true\n  }\n\n  func applicationWillResignActive(_ application: UIApplication) {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n  }\n\n  func applicationDidEnterBackground(_ application: UIApplication) {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n  }\n\n  func applicationWillEnterForeground(_ application: UIApplication) {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n  }\n\n  func applicationDidBecomeActive(_ application: UIApplication) {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n  }\n\n  func applicationWillTerminate(_ application: UIApplication) {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<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=\"gEv-jC-I5c\">\n    <device id=\"retina6_1\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14490.49\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Tab Bar Controller-->\n        <scene sceneID=\"Vzw-un-9WO\">\n            <objects>\n                <tabBarController id=\"gEv-jC-I5c\" sceneMemberID=\"viewController\">\n                    <tabBar key=\"tabBar\" contentMode=\"scaleToFill\" insetsLayoutMarginsFromSafeArea=\"NO\" id=\"KWi-PD-Fwt\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"49\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                    </tabBar>\n                    <connections>\n                        <segue destination=\"BV1-FR-VrT\" kind=\"relationship\" relationship=\"viewControllers\" id=\"FJs-P6-JBX\"/>\n                        <segue destination=\"PxD-0M-vmm\" kind=\"relationship\" relationship=\"viewControllers\" id=\"ABU-c0-bMu\"/>\n                    </connections>\n                </tabBarController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"pnp-A5-X8i\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-2094\" y=\"28\"/>\n        </scene>\n        <!--Pose Estimation-->\n        <scene sceneID=\"tXr-a1-R10\">\n            <objects>\n                <viewController id=\"BV1-FR-VrT\" customClass=\"ViewController\" customModule=\"ARPoseDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"U0K-SW-4ec\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"896\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                        <subviews>\n                            <arscnView clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"BrB-h1-WRS\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"813\"/>\n                            </arscnView>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <constraints>\n                            <constraint firstItem=\"BrB-h1-WRS\" firstAttribute=\"leading\" secondItem=\"fQZ-KI-GVf\" secondAttribute=\"leading\" id=\"GsS-dJ-CKf\"/>\n                            <constraint firstItem=\"BrB-h1-WRS\" firstAttribute=\"bottom\" secondItem=\"fQZ-KI-GVf\" secondAttribute=\"bottom\" id=\"VpT-BR-CcM\"/>\n                            <constraint firstItem=\"BrB-h1-WRS\" firstAttribute=\"trailing\" secondItem=\"fQZ-KI-GVf\" secondAttribute=\"trailing\" id=\"XyZ-9z-H8e\"/>\n                            <constraint firstItem=\"BrB-h1-WRS\" firstAttribute=\"top\" secondItem=\"U0K-SW-4ec\" secondAttribute=\"top\" id=\"rJc-2c-zQA\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"fQZ-KI-GVf\"/>\n                    </view>\n                    <tabBarItem key=\"tabBarItem\" title=\"Pose Estimation\" id=\"NGG-Ld-dEf\"/>\n                    <connections>\n                        <outlet property=\"sceneView\" destination=\"BrB-h1-WRS\" id=\"5nT-qQ-ynl\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"SZV-WD-TEh\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-338\" y=\"-297\"/>\n        </scene>\n        <!--Object Detection-->\n        <scene sceneID=\"hux-mV-GMi\">\n            <objects>\n                <viewController id=\"PxD-0M-vmm\" userLabel=\"Object Detection\" customClass=\"ObjectDetectionViewController\" customModule=\"ARPoseDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"AES-8a-yBc\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"896\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                        <subviews>\n                            <arscnView clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"P5f-9l-fO2\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"813\"/>\n                            </arscnView>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <constraints>\n                            <constraint firstItem=\"P5f-9l-fO2\" firstAttribute=\"top\" secondItem=\"AES-8a-yBc\" secondAttribute=\"top\" id=\"BGL-Of-AGU\"/>\n                            <constraint firstItem=\"P5f-9l-fO2\" firstAttribute=\"bottom\" secondItem=\"ZAF-rf-jxn\" secondAttribute=\"bottom\" id=\"bRl-oe-38R\"/>\n                            <constraint firstItem=\"P5f-9l-fO2\" firstAttribute=\"trailing\" secondItem=\"ZAF-rf-jxn\" secondAttribute=\"trailing\" id=\"e6G-Md-k5S\"/>\n                            <constraint firstItem=\"P5f-9l-fO2\" firstAttribute=\"leading\" secondItem=\"ZAF-rf-jxn\" secondAttribute=\"leading\" id=\"vQM-vs-3oE\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"ZAF-rf-jxn\"/>\n                    </view>\n                    <tabBarItem key=\"tabBarItem\" title=\"Object Detection\" id=\"uYw-YN-pGQ\"/>\n                    <connections>\n                        <outlet property=\"sceneView\" destination=\"P5f-9l-fO2\" id=\"Wqf-mw-zct\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"Uzz-YY-oOk\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-339\" y=\"400\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string></string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t\t<string>arkit</string>\n\t</array>\n\t<key>UIStatusBarHidden</key>\n\t<true/>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo/ObjectDetectionViewController.swift",
    "content": "//\n//  ObjectDetectionViewController.swift\n//  ARPoseDemo\n//\n//  Created by Christopher Kelly on 5/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport SceneKit\nimport ARKit\nimport Fritz\nimport AVFoundation\n\n\nclass ObjectDetectionViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate {\n\n  @IBOutlet var sceneView: ARSCNView!\n\n\n  lazy var objectModel = FritzVisionObjectModelFast()\n\n  var detectorQueue = DispatchQueue(label: \"ai.arpose.fritz.detectorQueue\")\n\n  let labelName = \"cup\"\n\n  var detectedObjects: [(SCNNode, CGRect)] = []\n\n  var viewBounds: CGSize!\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    // Set the view's delegate\n    sceneView.delegate = self\n    sceneView.session.delegate = self\n\n    // Show statistics such as fps and timing information\n    sceneView.showsStatistics = true\n    viewBounds = sceneView.bounds.size\n  }\n\n  override var supportedInterfaceOrientations: UIInterfaceOrientationMask {\n    return .landscapeRight\n  }\n\n  override func viewWillAppear(_ animated: Bool) {\n    super.viewWillAppear(animated)\n\n    // Create a session configuration\n    let configuration = ARWorldTrackingConfiguration()\n\n    // Run the view's session\n    sceneView.session.run(configuration)\n  }\n\n  override func viewWillDisappear(_ animated: Bool) {\n    super.viewWillDisappear(animated)\n\n    // Pause the view's session\n    sceneView.session.pause()\n  }\n\n  // MARK: - ARSCNViewDelegate\n  /// Update detected objects.\n  ///\n  /// - Parameters:\n  ///   - objects: Objects detected from most recent object detection run.\n  ///   - image: Image.\n  func update(newObjects objects: [CGRect], forImage image: FritzVisionImage) {\n\n    let size = image.size\n\n    // remove objects that are not still in there and save those that are.\n    var toInclude: [(SCNNode, CGRect)] = []\n    for (node, rect) in detectedObjects {\n      var found: CGRect?\n      for other in objects {\n        if IOU(rect, other) > 0 {\n          found = rect\n        }\n      }\n\n      if let found = found {\n        // Update position of that node\n        toInclude.append((node, found))\n      } else {\n        node.removeFromParentNode()\n      }\n    }\n\n    // Go through and add objects that are not already included\n    for object in objects {\n      var overlaps = false\n      for (_, other) in toInclude {\n\n        if IOU(object, other) > 0 {\n          overlaps = true\n        }\n      }\n      if !overlaps {\n        guard let node = buildNode(size, object) else { continue }\n        sceneView.scene.rootNode.addChildNode(node)\n        toInclude.append((node, object))\n      }\n    }\n    detectedObjects = toInclude\n  }\n\n  var predicting = false\n\n  func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {\n    guard let frame = self.sceneView.session.currentFrame else { return }\n\n    if predicting { return }\n\n    detectorQueue.async {\n      self.predicting = true\n      self.runPrediction(on: frame)\n      self.predicting = false\n    }\n  }\n\n  func runPrediction(on frame: ARFrame) {\n\n    let orientation = CGImagePropertyOrientation(UIDevice.current.orientation)\n    let image = FritzVisionImage(imageBuffer: frame.capturedImage)\n    image.metadata = FritzVisionImageMetadata()\n    image.metadata?.orientation = FritzImageOrientation(UIImage.Orientation(orientation))\n\n    let options = FritzVisionObjectModelOptions()\n    options.forceVisionPrediction = true\n\n    guard let objects = try? self.objectModel.predict(image, options: options) else { return }\n\n    let selected = objects.filter { $0.label == self.labelName }\n    let scaledObjects = selected.map { $0.boundingBox.scaledBy(image.size) }\n    self.update(newObjects: scaledObjects, forImage: image)\n  }\n\n\n  /// Build Node when found object.\n  ///\n  /// - Parameters:\n  ///   - size: Image size\n  ///   - rect: Bounding box of object\n  /// - Returns: Node in 3D space.\n  func buildNode(_ size: CGSize, _ rect: CGRect) -> SCNNode? {\n\n    // Find center of object and translate to current camera view\n    let center = rect.center\n    let deltaY = (size.height - viewBounds.height) / 2\n    let deltaX = (size.width - viewBounds.width) / 2\n    let point = CGPoint(x: center.x - deltaX, y: center.y - deltaY)\n\n\n    // Build node and add to view\n    let hitTestResults = sceneView.hitTest(point, types: [.featurePoint, .estimatedHorizontalPlane])\n    guard let result = hitTestResults.first else { return nil }\n\n    let hitPosition = SCNVector3.positionFromTransform(result.worldTransform)\n    // Add a new anchor at the tap location.\n\n    let node: SCNNode = {\n      let sphere = SCNSphere(radius: 0.005)\n      sphere.firstMaterial?.diffuse.contents = UIColor.red\n      sphere.firstMaterial?.lightingModel = .constant\n      sphere.firstMaterial?.isDoubleSided = true\n\n      let node = SCNNode(geometry: sphere)\n      node.position = hitPosition\n      return node\n    }()\n\n    return node\n\n  }\n\n  func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {\n    DispatchQueue.main.async {\n      self.viewBounds = self.sceneView.bounds.size\n    }\n  }\n\n  func session(_ session: ARSession, didFailWithError error: Error) {\n    // Present an error message to the user\n\n  }\n\n  func sessionWasInterrupted(_ session: ARSession) {\n    // Inform the user that the session has been interrupted, for example, by presenting an overlay\n\n  }\n\n  func sessionInterruptionEnded(_ session: ARSession) {\n    // Reset tracking and/or remove existing anchors if consistent tracking is required\n\n  }\n}\n"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo/SCNVector+Extensions.swift",
    "content": "/*\n * Copyright (c) 2013-2014 Kim Pedersen\n * http://47.110.91.75/devindazzle/SCNVector3Extensions\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nimport Foundation\nimport SceneKit \n\nextension SCNVector3\n{\n  /**\n   * Negates the vector described by SCNVector3 and returns\n   * the result as a new SCNVector3.\n   */\n  func negate() -> SCNVector3 {\n    return self * -1\n  }\n\n  /**\n   * Negates the vector described by SCNVector3\n   */\n  mutating func negated() -> SCNVector3 {\n    self = negate()\n    return self\n  }\n\n  /**\n   * Returns the length (magnitude) of the vector described by the SCNVector3\n   */\n  func length() -> Float {\n    return sqrtf(x*x + y*y + z*z)\n  }\n\n  /**\n   * Normalizes the vector described by the SCNVector3 to length 1.0 and returns\n   * the result as a new SCNVector3.\n   */\n  func normalized() -> SCNVector3 {\n    return self / length()\n  }\n\n  /**\n   * Normalizes the vector described by the SCNVector3 to length 1.0.\n   */\n  mutating func normalize() -> SCNVector3 {\n    self = normalized()\n    return self\n  }\n\n  /**\n   * Calculates the distance between two SCNVector3. Pythagoras!\n   */\n  func distance(_ vector: SCNVector3) -> Float {\n    return (self - vector).length()\n  }\n\n  func angle(between vector: SCNVector3) -> Float {\n\n    let len = self.length() * vector.length()\n    if len == 0 { return 0.0 }\n\n    return acos( min(1.0, max(-1.0, self.dot(vector) / len)) )\n\n  }\n\n}\n\n/**\n * Adds two SCNVector3 vectors and returns the result as a new SCNVector3.\n */\nfunc + (left: SCNVector3, right: SCNVector3) -> SCNVector3 {\n  return SCNVector3Make(left.x + right.x, left.y + right.y, left.z + right.z)\n}\n\n/**\n * Increments a SCNVector3 with the value of another.\n */\nfunc += (left: inout SCNVector3, right: SCNVector3) {\n  left = left + right\n}\n\n/**\n * Subtracts two SCNVector3 vectors and returns the result as a new SCNVector3.\n */\nfunc - (left: SCNVector3, right: SCNVector3) -> SCNVector3 {\n  return SCNVector3Make(left.x - right.x, left.y - right.y, left.z - right.z)\n}\n\n/**\n * Decrements a SCNVector3 with the value of another.\n */\nfunc -= (left: inout  SCNVector3, right: SCNVector3) {\n  left = left - right\n}\n\n/**\n * Multiplies two SCNVector3 vectors and returns the result as a new SCNVector3.\n */\nfunc * (left: SCNVector3, right: SCNVector3) -> SCNVector3 {\n  return SCNVector3Make(left.x * right.x, left.y * right.y, left.z * right.z)\n}\n\n/**\n * Multiplies a SCNVector3 with another.\n */\nfunc *= (left: inout  SCNVector3, right: SCNVector3) {\n  left = left * right\n}\n\n/**\n * Multiplies the x, y and z fields of a SCNVector3 with the same scalar value and\n * returns the result as a new SCNVector3.\n */\nfunc * (vector: SCNVector3, scalar: Float) -> SCNVector3 {\n  return SCNVector3Make(vector.x * scalar, vector.y * scalar, vector.z * scalar)\n}\n\n/**\n * Multiplies the x and y fields of a SCNVector3 with the same scalar value.\n */\nfunc *= (vector: inout  SCNVector3, scalar: Float) {\n  vector = vector * scalar\n}\n\n/**\n * Divides two SCNVector3 vectors abd returns the result as a new SCNVector3\n */\nfunc / (left: SCNVector3, right: SCNVector3) -> SCNVector3 {\n  return SCNVector3Make(left.x / right.x, left.y / right.y, left.z / right.z)\n}\n\n/**\n * Divides a SCNVector3 by another.\n */\nfunc /= (left: inout  SCNVector3, right: SCNVector3) {\n  left = left / right\n}\n\n/**\n * Divides the x, y and z fields of a SCNVector3 by the same scalar value and\n * returns the result as a new SCNVector3.\n */\nfunc / (vector: SCNVector3, scalar: Float) -> SCNVector3 {\n  return SCNVector3Make(vector.x / scalar, vector.y / scalar, vector.z / scalar)\n}\n\n/**\n * Divides the x, y and z of a SCNVector3 by the same scalar value.\n */\nfunc /= (vector: inout  SCNVector3, scalar: Float) {\n  vector = vector / scalar\n}\n\n/**\n * Negate a vector\n */\nfunc SCNVector3Negate(vector: SCNVector3) -> SCNVector3 {\n  return vector * -1\n}\n\n/**\n * Returns the length (magnitude) of the vector described by the SCNVector3\n */\nfunc SCNVector3Length(_ vector: SCNVector3) -> Float\n{\n  return sqrtf(vector.x*vector.x + vector.y*vector.y + vector.z*vector.z)\n}\n\n/**\n * Returns the distance between two SCNVector3 vectors\n */\nfunc SCNVector3Distance(vectorStart: SCNVector3, vectorEnd: SCNVector3) -> Float {\n  return SCNVector3Length(vectorEnd - vectorStart)\n}\n\n/**\n * Returns the distance between two SCNVector3 vectors\n */\nfunc SCNVector3Normalize(vector: SCNVector3) -> SCNVector3 {\n  return vector / SCNVector3Length(vector)\n}\n\n/**\n * Calculates the dot product between two SCNVector3 vectors\n */\nfunc SCNVector3DotProduct(_ left: SCNVector3, right: SCNVector3) -> Float {\n  return left.x * right.x + left.y * right.y + left.z * right.z\n}\n\n/**\n * Calculates the cross product between two SCNVector3 vectors\n */\nfunc SCNVector3CrossProduct(left: SCNVector3, right: SCNVector3) -> SCNVector3 {\n  return SCNVector3Make(left.y * right.z - left.z * right.y, left.z * right.x - left.x * right.z, left.x * right.y - left.y * right.x)\n}\n\n/**\n * Calculates the SCNVector from lerping between two SCNVector3 vectors\n */\nfunc SCNVector3Lerp(vectorStart: SCNVector3, vectorEnd: SCNVector3, t: Float) -> SCNVector3 {\n  return SCNVector3Make(vectorStart.x + ((vectorEnd.x - vectorStart.x) * t), vectorStart.y + ((vectorEnd.y - vectorStart.y) * t), vectorStart.z + ((vectorEnd.z - vectorStart.z) * t))\n}\n\n/*\n angle in radians\n */\nfunc SCNVector3Rotate(vector: SCNVector3, around: SCNVector3, radians : Float ) -> SCNVector3 {\n\n  let rm = GLKMatrix3MakeRotation(radians, around.x, around.y, around.z);\n  let v = GLKMatrix3MultiplyVector3(rm, SCNVector3ToGLKVector3(vector))\n  return SCNVector3FromGLKVector3(v)\n\n}\n\n/**\n * Project the vector, vectorToProject, onto the vector, projectionVector.\n */\nfunc SCNVector3Project(vectorToProject: SCNVector3, projectionVector: SCNVector3) -> SCNVector3 {\n  let scale: Float = SCNVector3DotProduct(projectionVector, right: vectorToProject) / SCNVector3DotProduct(projectionVector, right: projectionVector)\n  let v: SCNVector3 = projectionVector * scale\n  return v\n}\n\n\nfunc SCNVector3ProjectPlane(vector: SCNVector3, planeNormal: SCNVector3 ) -> SCNVector3 {\n\n  let projection = SCNVector3Project(vectorToProject: vector, projectionVector: planeNormal)\n  return ( vector - projection )\n\n}\n\nfunc * (left: SCNMatrix4, right: Float) -> SCNMatrix4 {\n  return SCNMatrix4.init(m11: left.m11 * right, m12: left.m12 * right, m13: left.m13 * right, m14: left.m14 * right,\n                         m21: left.m21 * right, m22: left.m22 * right, m23: left.m23 * right, m24: left.m24 * right,\n                         m31: left.m31 * right, m32: left.m32 * right, m33: left.m33 * right, m34: left.m34 * right,\n                         m41: left.m41 * right, m42: left.m42 * right, m43: left.m43 * right, m44: left.m44 * right)\n}\n\nfunc SCNMatrix4Add( _ m1 : SCNMatrix4 , _ m2 : SCNMatrix4 ) -> SCNMatrix4 {\n\n  return SCNMatrix4.init(m11: m1.m11 + m2.m11, m12: m1.m12 + m2.m12, m13: m1.m13 + m2.m13, m14: m1.m14 + m2.m14,\n                         m21: m1.m21 + m2.m21, m22: m1.m22 + m2.m22, m23: m1.m23 + m2.m23, m24: m1.m24 + m2.m24,\n                         m31: m1.m31 + m2.m31, m32: m1.m32 + m2.m32, m33: m1.m33 + m2.m33, m34: m1.m34 + m2.m34,\n                         m41: m1.m41 + m2.m41, m42: m1.m42 + m2.m42, m43: m1.m43 + m2.m43, m44: m1.m44 + m2.m44)\n\n}\n\nfunc SCNMatrix4Lerp( _ m1 : SCNMatrix4 , _ m2 : SCNMatrix4, _ v : Float ) -> SCNMatrix4 {\n\n  return SCNMatrix4.init(m11: m1.m11 + (m2.m11-m1.m11)*v, m12: m1.m12 + (m2.m12-m1.m12)*v, m13: m1.m13 + (m2.m13-m1.m13)*v, m14: m1.m14 + (m2.m14-m1.m14)*v,\n                         m21: m1.m21 + (m2.m21-m1.m21)*v, m22: m1.m22 + (m2.m22-m1.m22)*v, m23: m1.m23 + (m2.m23-m1.m23)*v, m24: m1.m24 + (m2.m24-m1.m24)*v,\n                         m31: m1.m31 + (m2.m31-m1.m31)*v, m32: m1.m32 + (m2.m32-m1.m32)*v, m33: m1.m33 + (m2.m33-m1.m33)*v, m34: m1.m34 + (m2.m34-m1.m34)*v,\n                         m41: m1.m41 + (m2.m41-m1.m41)*v, m42: m1.m42 + (m2.m42-m1.m42)*v, m43: m1.m43 + (m2.m43-m1.m43)*v, m44: m1.m44 + (m2.m44-m1.m44)*v)\n\n}\n\nfunc SCNMatrix4GetAxesTransform( newX : SCNVector3 ,\n                                 newY : SCNVector3 ,\n                                 newZ : SCNVector3 ,\n                                 position : SCNVector3 = .zero ) -> SCNMatrix4 {\n\n  let transform = SCNMatrix4.init(m11: newX.x, m12: newX.y, m13: newX.z, m14: 0,\n                                  m21: newY.x, m22: newY.y, m23: newY.z, m24: 0,\n                                  m31: newZ.x, m32: newZ.y, m33: newZ.z, m34: 0,\n                                  m41: position.x, m42: position.y, m43: position.z, m44: 1.0)\n  return transform\n\n}\n\n// MARK: Axis aliases\n\nextension SCNVector3 {\n  enum Axis {\n    case x, y, z\n  }\n\n  static let zero = SCNVector3Zero\n  static let one = SCNVector3(x: 1, y: 1, z: 1)\n\n  static let axisX = SCNVector3(x: 1, y: 0, z: 0)\n  static let axisY = SCNVector3(x: 0, y: 1, z: 0)\n  static let axisZ = SCNVector3(x: 0, y: 0, z: 1)\n}\n\n\n// MARK: - Debugging\n\n// numpy formatting\nextension SCNVector3 {\n  var np: String {\n    get {\n      let f: (Float) -> String = { num in\n        return String(format: \"%.4f\", num)\n      }\n      return \"array([\\(f(x)), \\(f(y)), \\(f(z))])\"\n    }\n  }\n\n  func withX(x : Float) -> SCNVector3 {\n    return SCNVector3(x, self.y, self.z)\n  }\n  func withY(y : Float) -> SCNVector3 {\n    return SCNVector3(self.x, y, self.z)\n  }\n  func withZ(z : Float) -> SCNVector3 {\n    return SCNVector3(self.x, self.y, z)\n  }\n\n\n}\n\nextension SCNMatrix4 {\n  // format matrix for numpy (printed in row-major form)\n  var np: String {\n    get {\n      let f: (Float) -> String = { num in\n        return String(format: \"%.4f\", num)\n      }\n      let row1 = \"[\\(f(m11)), \\(f(m21)), \\(f(m31)), \\(f(m41))]\"\n      let row2 = \"[\\(f(m12)), \\(f(m22)), \\(f(m32)), \\(f(m42))]\"\n      let row3 = \"[\\(f(m13)), \\(f(m23)), \\(f(m33)), \\(f(m43))]\"\n      let row4 = \"[\\(f(m14)), \\(f(m24)), \\(f(m34)), \\(f(m44))]\"\n      return \"\\narray([\\n  \\(row1),\\n  \\(row2),\\n  \\(row3),\\n  \\(row4)\\n])\"\n    }\n  }\n\n  var rowMajorArray : [Float] {\n    get {\n      let mat : [Float] = [m11, m21, m31, m41,\n                           m12, m22, m32, m42,\n                           m13, m23, m33, m43,\n                           m14, m24, m34, m44]\n      return mat\n    }\n  }\n\n  var rowArrays : [[Float]] {\n    get {\n      return [[m11, m21, m31, m41],\n              [m12, m22, m32, m42],\n              [m13, m23, m33, m43],\n              [m14, m24, m34, m44]]\n\n    }\n  }\n\n  var xAxis: SCNVector3 {\n    get {\n      return SCNVector3(self.m11, self.m12, self.m13)\n    }\n    set {\n      self.m11 = newValue.x\n      self.m12 = newValue.y\n      self.m13 = newValue.z\n    }\n  }\n  var yAxis: SCNVector3 {\n    get {\n      return SCNVector3(self.m21, self.m22, self.m23)\n    }\n    set {\n      self.m21 = newValue.x\n      self.m22 = newValue.y\n      self.m23 = newValue.z\n    }\n  }\n  var zAxis: SCNVector3 {\n    get {\n      return SCNVector3(self.m31, self.m32, self.m33)\n    }\n    set {\n      self.m31 = newValue.x\n      self.m32 = newValue.y\n      self.m33 = newValue.z\n    }\n  }\n  var translation: SCNVector3 {\n    get {\n      return SCNVector3(self.m41, self.m42, self.m43)\n    }\n  }\n  var sceneKitCameraDirection : SCNVector3 {\n    return self.zAxis * -1.0\n  }\n}\n\nextension matrix_float4x4 {\n  // format matrix for numpy\n  var np: String {\n    get {\n      return SCNMatrix4.init(self).np\n    }\n  }\n\n  var rowMajorArray : [Float] {\n    get {\n      return SCNMatrix4.init(self).rowMajorArray\n    }\n  }\n  var rowArrays : [[Float]] {\n    get {\n      return SCNMatrix4.init(self).rowArrays\n    }\n  }\n\n}\n\nextension matrix_float3x3 {\n  var rowMajorArray : [Float] {\n    get {\n\n      let mat : [Float] = [columns.0.x, columns.1.x, columns.2.x,\n                           columns.0.y, columns.1.y, columns.2.y,\n                           columns.0.z, columns.1.z, columns.2.z ]\n      return mat\n    }\n  }\n\n  var rowArrays : [[Float]] {\n    get {\n\n      return [[columns.0.x, columns.1.x, columns.2.x],\n              [columns.0.y, columns.1.y, columns.2.y],\n              [columns.0.z, columns.1.z, columns.2.z] ]\n\n    }\n  }\n\n}\n"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo/Utils.swift",
    "content": "//\n//  Utils.swift\n//  ARPoseDemo\n//\n//  Created by Christopher Kelly on 5/9/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport ARKit\n// MARK: - SCNVector3 extensions\n\nextension SCNVector3 {\n\n\n  static func positionFromTransform(_ transform: matrix_float4x4) -> SCNVector3 {\n    return SCNVector3Make(transform.columns.3.x, transform.columns.3.y, transform.columns.3.z)\n  }\n\n  func friendlyString() -> String {\n    return \"(\\(String(format: \"%.2f\", x)), \\(String(format: \"%.2f\", y)), \\(String(format: \"%.2f\", z)))\"\n  }\n\n  func dot(_ vec: SCNVector3) -> Float {\n    return (self.x * vec.x) + (self.y * vec.y) + (self.z * vec.z)\n  }\n\n  func cross(_ vec: SCNVector3) -> SCNVector3 {\n    return SCNVector3(self.y * vec.z - self.z * vec.y, self.z * vec.x - self.x * vec.z, self.x * vec.y - self.y * vec.x)\n  }\n}\n"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  ARPoseDemo\n//\n//  Created by Christopher Kelly on 5/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport SceneKit\nimport ARKit\nimport Fritz\nimport AVFoundation\n\ntypealias HumanPose = Pose<HumanSkeleton>\nextension CGRect {\n\n  var center: CGPoint {\n    return CGPoint(\n      x: (self.minX + self.maxX) / 2,\n      y: (self.minY + self.maxY) / 2\n    )\n  }\n}\n\nextension Pose {\n\n  func boundingBox() -> CGRect {\n    var (minX, minY, maxX, maxY) = (CGFloat(0.0), CGFloat(0.0), CGFloat(0.0), CGFloat(0.0))\n\n    for keypoint in keypoints {\n      let x = keypoint.position.x\n      let y = keypoint.position.y\n\n      if x < minX {\n        minX = x\n      }\n      if x > maxX {\n        maxX = x\n      }\n      if y < minY {\n        minY = y\n      }\n      if y > maxY {\n        maxY = y\n      }\n    }\n\n    return CGRect(x: minX, y: minY, width: maxX - minX, height: maxY - minY)\n  }\n\n}\n\n\nextension float4x4 {\n  var translation: float3 {\n    let translation = self.columns.3\n    return float3(translation.x, translation.y, translation.z)\n  }\n}\n\nclass ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate {\n\n  @IBOutlet var sceneView: ARSCNView!\n\n  lazy var poseModel = FritzVisionHumanPoseModelFast()\n\n  private var anchorPoints = [UUID: HumanSkeleton]()\n\n  var detectorQueue = DispatchQueue(label: \"ai.arpose.fritz.detectorQueue\")\n\n  let labelName = \"cup\"\n\n  // List of nodes associated with a pose and rect of bounding box for pose.\n  var detectedPoses: [([SCNNode], CGRect)] = []\n\n  var viewBounds: CGSize!\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    // Set the view's delegate\n    sceneView.delegate = self\n    sceneView.session.delegate = self\n\n    // Show statistics such as fps and timing information\n    sceneView.showsStatistics = true\n    viewBounds = sceneView.bounds.size\n  }\n\n  override var supportedInterfaceOrientations: UIInterfaceOrientationMask {\n    return .landscapeRight\n  }\n\n  override func viewWillAppear(_ animated: Bool) {\n    super.viewWillAppear(animated)\n\n    // Create a session configuration\n    let configuration = ARWorldTrackingConfiguration()\n\n    // Run the view's session\n    sceneView.session.run(configuration)\n  }\n\n  override func viewWillDisappear(_ animated: Bool) {\n    super.viewWillDisappear(animated)\n\n    // Pause the view's session\n    sceneView.session.pause()\n  }\n\n  // MARK: - ARSCNViewDelegate\n  /// Update detected objects.\n  ///\n  /// - Parameters:\n  ///   - objects: Objects detected from most recent object detection run.\n  ///   - image: Image.\n  func update(newPoses poses: [HumanPose], forImage image: FritzVisionImage) {\n\n    let size = image.size\n    // Find center of object and translate to current camera view\n    let deltaY = (size.height - viewBounds.height) / 2\n    let deltaX = (size.width - viewBounds.width) / 2\n\n    // remove objects that are not still in there and save those that are.\n    var toInclude: [([SCNNode], CGRect)] = []\n    for (nodes, rect) in detectedPoses {\n\n      var found: CGRect?\n      for pose in poses {\n        if IOU(rect, pose.boundingBox()) > 0 {\n          found = rect\n          for node in nodes {\n            node.removeFromParentNode()\n          }\n          // Update position of that node\n          var newNodes: [SCNNode] = []\n          for keypoint in pose.keypoints {\n            let point = CGPoint(\n              x: CGFloat(keypoint.position.x) - deltaX,\n              y: CGFloat(keypoint.position.y) - deltaY\n            )\n\n            guard let node = buildNode(point) else { continue }\n            sceneView.scene.rootNode.addChildNode(node)\n            newNodes.append(node)\n          }\n          toInclude.append((newNodes, rect))\n        }\n      }\n\n\n      if let found = found {\n      } else {\n        toInclude.append((nodes, rect))\n\n      }\n    }\n\n    // Go through and add objects that are not already included\n    for pose in poses {\n      var overlaps = false\n      for (_, other) in toInclude {\n\n        if IOU(other, pose.boundingBox()) > 0 {\n          overlaps = true\n        }\n      }\n\n      if !overlaps {\n        var nodes: [SCNNode] = []\n        for keypoint in pose.keypoints {\n          let point = CGPoint(\n            x: CGFloat(keypoint.position.x) - deltaX,\n            y: CGFloat(keypoint.position.y) - deltaY\n          )\n\n          guard let node = buildNode(point) else { continue }\n          sceneView.scene.rootNode.addChildNode(node)\n          nodes.append(node)\n        }\n\n        if nodes.count > 5 {\n          toInclude.append((nodes, pose.boundingBox()))\n        }\n      }\n    }\n    detectedPoses = toInclude\n  }\n\n  var predicting = false\n\n  func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {\n    guard let frame = self.sceneView.session.currentFrame else { return }\n\n    if predicting { return }\n\n    detectorQueue.async {\n      self.predicting = true\n      self.runPrediction(on: frame)\n      self.predicting = false\n    }\n  }\n\n  func runPrediction(on frame: ARFrame) {\n\n    let orientation = CGImagePropertyOrientation(UIDevice.current.orientation)\n    let image = FritzVisionImage(imageBuffer: frame.capturedImage)\n    image.metadata = FritzVisionImageMetadata()\n    image.metadata?.orientation = FritzImageOrientation(UIImage.Orientation(orientation))\n\n    let options = FritzVisionPoseModelOptions()\n    options.minPartThreshold = 0.3\n    options.minPoseThreshold = 0.1\n    options.forceVisionPrediction = true\n    guard let poseResults = try? self.poseModel.predict(image, options: options),\n      let pose = poseResults.pose()\n      else { return }\n\n    self.update(newPoses: [pose], forImage: image)\n  }\n\n\n  /// Build Node when found object.\n  ///\n  /// - Parameters:\n  ///   - size: Image size\n  ///   - rect: Bounding box of object\n  /// - Returns: Node in 3D space.\n  func buildNode(_ point: CGPoint) -> SCNNode? {\n    // Build node and add to view\n    let hitTestResults = sceneView.hitTest(point, types: [.featurePoint, .estimatedHorizontalPlane])\n    guard let result = hitTestResults.first else { return nil }\n\n    let hitPosition = SCNVector3.positionFromTransform(result.worldTransform)\n    // Add a new anchor at the tap location.\n\n    let node: SCNNode = {\n      let sphere = SCNSphere(radius: 0.005)\n      sphere.firstMaterial?.diffuse.contents = UIColor.red\n      sphere.firstMaterial?.lightingModel = .constant\n      sphere.firstMaterial?.isDoubleSided = true\n\n      let node = SCNNode(geometry: sphere)\n      node.position = hitPosition\n      return node\n    }()\n\n    return node\n\n  }\n\n  func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {\n    DispatchQueue.main.async {\n      self.viewBounds = self.sceneView.bounds.size\n    }\n  }\n\n  func session(_ session: ARSession, didFailWithError error: Error) {\n    // Present an error message to the user\n\n  }\n\n  func sessionWasInterrupted(_ session: ARSession) {\n    // Inform the user that the session has been interrupted, for example, by presenting an overlay\n\n  }\n\n  func sessionInterruptionEnded(_ session: ARSession) {\n    // Reset tracking and/or remove existing anchors if consistent tracking is required\n\n  }\n}\n"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t28417A9083D2916A461EE350 /* Pods_FritzARKitDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC268F42EA9A09AA734F4AB4 /* Pods_FritzARKitDemo.framework */; };\n\t\t83305C75228399E500F93F6B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83305C74228399E500F93F6B /* AppDelegate.swift */; };\n\t\t83305C77228399E500F93F6B /* art.scnassets in Resources */ = {isa = PBXBuildFile; fileRef = 83305C76228399E500F93F6B /* art.scnassets */; };\n\t\t83305C79228399E500F93F6B /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83305C78228399E500F93F6B /* ViewController.swift */; };\n\t\t83305C7C228399E500F93F6B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83305C7A228399E500F93F6B /* Main.storyboard */; };\n\t\t83305C7E228399E600F93F6B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83305C7D228399E600F93F6B /* Assets.xcassets */; };\n\t\t83305C81228399E600F93F6B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83305C7F228399E600F93F6B /* LaunchScreen.storyboard */; };\n\t\t83305CBC2284E20500F93F6B /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83305CBB2284E20500F93F6B /* Utils.swift */; };\n\t\t83305CBE2284EE5000F93F6B /* ARKIt+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83305CBD2284EE5000F93F6B /* ARKIt+Utilities.swift */; };\n\t\t83305CC02285094800F93F6B /* ObjectDetectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83305CBF2285094800F93F6B /* ObjectDetectionViewController.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t3BC704DD15BD47860F72D7F8 /* Pods-FritzARKitDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzARKitDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzARKitDemo/Pods-FritzARKitDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t83305C71228399E500F93F6B /* FritzARKitDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzARKitDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t83305C74228399E500F93F6B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t83305C76228399E500F93F6B /* art.scnassets */ = {isa = PBXFileReference; lastKnownFileType = wrapper.scnassets; path = art.scnassets; sourceTree = \"<group>\"; };\n\t\t83305C78228399E500F93F6B /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t83305C7B228399E500F93F6B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t83305C7D228399E600F93F6B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t83305C80228399E600F93F6B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t83305C82228399E600F93F6B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t83305CBB2284E20500F93F6B /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = \"<group>\"; };\n\t\t83305CBD2284EE5000F93F6B /* ARKIt+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"ARKIt+Utilities.swift\"; sourceTree = \"<group>\"; };\n\t\t83305CBF2285094800F93F6B /* ObjectDetectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectDetectionViewController.swift; sourceTree = \"<group>\"; };\n\t\tBDCEB3DB110FDD4D69EDF9F6 /* Pods-FritzARKitDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzARKitDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzARKitDemo/Pods-FritzARKitDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tCC268F42EA9A09AA734F4AB4 /* Pods_FritzARKitDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzARKitDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t83305C6E228399E500F93F6B /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t28417A9083D2916A461EE350 /* Pods_FritzARKitDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t6AAD0B742F5315E0A15ECA94 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3BC704DD15BD47860F72D7F8 /* Pods-FritzARKitDemo.debug.xcconfig */,\n\t\t\t\tBDCEB3DB110FDD4D69EDF9F6 /* Pods-FritzARKitDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83305C68228399E500F93F6B = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83305CBD2284EE5000F93F6B /* ARKIt+Utilities.swift */,\n\t\t\t\t83305C73228399E500F93F6B /* FritzARKitDemo */,\n\t\t\t\t83305C72228399E500F93F6B /* Products */,\n\t\t\t\t6AAD0B742F5315E0A15ECA94 /* Pods */,\n\t\t\t\tE6859B0F91049BBFA96AB957 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83305C72228399E500F93F6B /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83305C71228399E500F93F6B /* FritzARKitDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83305C73228399E500F93F6B /* FritzARKitDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83305C74228399E500F93F6B /* AppDelegate.swift */,\n\t\t\t\t83305C76228399E500F93F6B /* art.scnassets */,\n\t\t\t\t83305C78228399E500F93F6B /* ViewController.swift */,\n\t\t\t\t83305CBF2285094800F93F6B /* ObjectDetectionViewController.swift */,\n\t\t\t\t83305CBB2284E20500F93F6B /* Utils.swift */,\n\t\t\t\t83305C7A228399E500F93F6B /* Main.storyboard */,\n\t\t\t\t83305C7D228399E600F93F6B /* Assets.xcassets */,\n\t\t\t\t83305C7F228399E600F93F6B /* LaunchScreen.storyboard */,\n\t\t\t\t83305C82228399E600F93F6B /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzARKitDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tE6859B0F91049BBFA96AB957 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tCC268F42EA9A09AA734F4AB4 /* Pods_FritzARKitDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t83305C70228399E500F93F6B /* FritzARKitDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 83305C85228399E600F93F6B /* Build configuration list for PBXNativeTarget \"FritzARKitDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tCEF2B1E578DE1A338462465F /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t83305C6D228399E500F93F6B /* Sources */,\n\t\t\t\t83305C6E228399E500F93F6B /* Frameworks */,\n\t\t\t\t83305C6F228399E500F93F6B /* Resources */,\n\t\t\t\t2FCD9D984A4D0A8021B0A733 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzARKitDemo;\n\t\t\tproductName = ARPoseDemo;\n\t\t\tproductReference = 83305C71228399E500F93F6B /* FritzARKitDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t83305C69228399E500F93F6B /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1020;\n\t\t\t\tLastUpgradeCheck = 1020;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t83305C70228399E500F93F6B = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 10.2.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 83305C6C228399E500F93F6B /* Build configuration list for PBXProject \"ARPoseDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 83305C68228399E500F93F6B;\n\t\t\tproductRefGroup = 83305C72228399E500F93F6B /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t83305C70228399E500F93F6B /* FritzARKitDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t83305C6F228399E500F93F6B /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83305C77228399E500F93F6B /* art.scnassets in Resources */,\n\t\t\t\t83305C81228399E600F93F6B /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t83305C7E228399E600F93F6B /* Assets.xcassets in Resources */,\n\t\t\t\t83305C7C228399E500F93F6B /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t2FCD9D984A4D0A8021B0A733 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzARKitDemo/Pods-FritzARKitDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzARKitDemo/Pods-FritzARKitDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzARKitDemo/Pods-FritzARKitDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tCEF2B1E578DE1A338462465F /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzARKitDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t83305C6D228399E500F93F6B /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83305C79228399E500F93F6B /* ViewController.swift in Sources */,\n\t\t\t\t83305C75228399E500F93F6B /* AppDelegate.swift in Sources */,\n\t\t\t\t83305CBE2284EE5000F93F6B /* ARKIt+Utilities.swift in Sources */,\n\t\t\t\t83305CC02285094800F93F6B /* ObjectDetectionViewController.swift in Sources */,\n\t\t\t\t83305CBC2284E20500F93F6B /* Utils.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t83305C7A228399E500F93F6B /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83305C7B228399E500F93F6B /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83305C7F228399E600F93F6B /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83305C80228399E600F93F6B /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t83305C83228399E600F93F6B /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83305C84228399E600F93F6B /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t83305C86228399E600F93F6B /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 3BC704DD15BD47860F72D7F8 /* Pods-FritzARKitDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzARKitDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMTLLINKER_FLAGS = \"-cikernel\";\n\t\t\t\tMTL_COMPILER_FLAGS = \"-fcikernel\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.ARKitFritzPoseExample;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83305C87228399E600F93F6B /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = BDCEB3DB110FDD4D69EDF9F6 /* Pods-FritzARKitDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzARKitDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMTLLINKER_FLAGS = \"-cikernel\";\n\t\t\t\tMTL_COMPILER_FLAGS = \"-fcikernel\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.ARKitFritzPoseExample;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t83305C6C228399E500F93F6B /* Build configuration list for PBXProject \"ARPoseDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83305C83228399E600F93F6B /* Debug */,\n\t\t\t\t83305C84228399E600F93F6B /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t83305C85228399E600F93F6B /* Build configuration list for PBXNativeTarget \"FritzARKitDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83305C86228399E600F93F6B /* Debug */,\n\t\t\t\t83305C87228399E600F93F6B /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 83305C69228399E500F93F6B /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzARKitDemo/FritzARKitDemo.xcodeproj/xcshareddata/xcschemes/FritzARKitDemo.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1020\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"83305C70228399E500F93F6B\"\n               BuildableName = \"FritzARKitDemo.app\"\n               BlueprintName = \"FritzARKitDemo\"\n               ReferencedContainer = \"container:FritzARKitDemo.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"83305C70228399E500F93F6B\"\n            BuildableName = \"FritzARKitDemo.app\"\n            BlueprintName = \"FritzARKitDemo\"\n            ReferencedContainer = \"container:FritzARKitDemo.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      disableMainThreadChecker = \"YES\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"83305C70228399E500F93F6B\"\n            BuildableName = \"FritzARKitDemo.app\"\n            BlueprintName = \"FritzARKitDemo\"\n            ReferencedContainer = \"container:FritzARKitDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"83305C70228399E500F93F6B\"\n            BuildableName = \"FritzARKitDemo.app\"\n            BlueprintName = \"FritzARKitDemo\"\n            ReferencedContainer = \"container:FritzARKitDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "iOS/FritzARKitDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzARKitDemo' do\n  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks\n  use_frameworks!\n\n  # Pods for ARPoseDemo\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionPoseModel/Human/Fast'\n  pod 'Fritz/VisionObjectModel/Fast'\n\nend\n"
  },
  {
    "path": "iOS/FritzARKitDemo/README.md",
    "content": "# Fritz ARKit Examples\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use [Object Detection API by Fritz](https://www.fritz.ai/features/object-detection.html) and [Pose Estimation API by Fritz](https://www.fritz.ai/features/pose-estimation.html) in order to build different ARKit experiences.\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.6.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\nMake sure that you have added the `Fritz-Info.plist` file to the app.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzStyleTransferDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzARKitDemo`\n\n```\ncd fritz-examples/iOS/FritzARKitDemo\npod repo update\npod install\n```\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzARKitDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## For questions on how to use the demos, contact us:\n\n- [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n- [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzHairColorDemo\n//\n//  Created by Christopher Kelly on 4/19/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n    // Override point for customization after application launch.\n      // Automatically added FritzCore configure.\n    FritzCore.configure()\n    return true\n  }\n\n  func applicationWillResignActive(_ application: UIApplication) {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n  }\n\n  func applicationDidEnterBackground(_ application: UIApplication) {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n  }\n\n  func applicationWillEnterForeground(_ application: UIApplication) {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n  }\n\n  func applicationDidBecomeActive(_ application: UIApplication) {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n  }\n\n  func applicationWillTerminate(_ application: UIApplication) {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Controllers/HairPredictor.swift",
    "content": "import Foundation\nimport UIKit\nimport Fritz\nimport ColorSlider\n\nprotocol HairPredictor: UIViewController {\n\n  var visionModel: FritzVisionHairSegmentationModelFast { get }\n  var colorSlider: ColorSlider { get }\n}\n\nextension HairPredictor {\n  \n  func addColorSlider() {\n    colorSlider.translatesAutoresizingMaskIntoConstraints = false\n    view.addSubview(colorSlider)\n    let rightEdgeConstraint = NSLayoutConstraint(\n      item: colorSlider,\n      attribute: .trailing,\n      relatedBy: .equal,\n      toItem: view,\n      attribute: .trailingMargin,\n      multiplier: 1.0,\n      constant: 0.0)\n    let centerVerticalConstraint = NSLayoutConstraint(\n      item: colorSlider,\n      attribute: .centerY,\n      relatedBy: .equal,\n      toItem: view,\n      attribute: .centerY,\n      multiplier: 1.0,\n      constant: 0)\n    let widthConstraint = NSLayoutConstraint(\n      item: colorSlider,\n      attribute: .width,\n      relatedBy: .equal,\n      toItem: nil,\n      attribute: .notAnAttribute,\n      multiplier: 1,\n      constant: 30)\n    let heightConstraint = NSLayoutConstraint(\n      item: colorSlider,\n      attribute: .height,\n      relatedBy: .equal,\n      toItem: nil,\n      attribute: .notAnAttribute,\n      multiplier: 1,\n      constant: 250)\n\n    widthConstraint.isActive = true\n    heightConstraint.isActive = true\n    rightEdgeConstraint.isActive = true\n    centerVerticalConstraint.isActive = true\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Controllers/LiveHairViewController.swift",
    "content": "import UIKit\nimport AVFoundation\nimport Fritz\nimport ColorSlider\n\nclass LiveHairViewController: UIViewController, HairPredictor {\n\n  var cameraView: UIImageView!\n  lazy var visionModel = FritzVisionHairSegmentationModelFast()\n  var colorSlider = ColorSlider(orientation: .vertical, previewSide: .left)\n\n  private lazy var cameraSession = AVCaptureSession()\n  private let sessionQueue = DispatchQueue(label: \"com.fritzdemo.imagesegmentation.session\")\n  private let captureQueue = DispatchQueue(\n    label: \"com.fritzdemo.imagesegmentation.capture\",\n    qos: DispatchQoS.userInitiated\n  )\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    cameraView = UIImageView(frame: view.bounds)\n    cameraView.contentMode = .scaleAspectFill\n    view.addSubview(cameraView)\n    addColorSlider()\n\n    // Setup camera\n    guard let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front),\n      let input = try? AVCaptureDeviceInput(device: device)\n      else { return }\n\n    let output = AVCaptureVideoDataOutput()\n\n    // Configure pixelBuffer format for use in model\n    output.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA as UInt32]\n    output.alwaysDiscardsLateVideoFrames = true\n    output.setSampleBufferDelegate(self, queue: captureQueue)\n\n    sessionQueue.async {\n      self.cameraSession.beginConfiguration()\n      self.cameraSession.addInput(input)\n      self.cameraSession.addOutput(output)\n      self.cameraSession.commitConfiguration()\n      self.cameraSession.sessionPreset = .photo\n\n      // Front camera images are mirrored.\n      output.connection(with: .video)?.isVideoMirrored = true\n    }\n  }\n\n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n\n    sessionQueue.async {\n      self.cameraSession.startRunning()\n    }\n  }\n\n  override func viewWillLayoutSubviews() {\n    super.viewWillLayoutSubviews()\n    view.bringSubviewToFront(colorSlider)\n  }\n}\n\nextension LiveHairViewController: AVCaptureVideoDataOutputSampleBufferDelegate {\n\n  /// Scores output from model greater than this value will be set as 1.\n  /// Lowering this value will make the mask more intense for lower confidence values.\n  var clippingScoresAbove: Double { return 0.7 }\n\n  /// Values lower than this value will not appear in the mask.\n  var zeroingScoresBelow: Double { return 0.3 }\n\n  /// Controls the opacity the mask is applied to the base image.\n  var opacity: CGFloat { return 0.7 }\n\n  /// The method used to blend the hair mask with the underlying image.\n  /// Soft light produces the best results in our tests, but check out\n  /// .hue and .color for different effects.\n  var blendKernel: CIBlendKernel { return .softLight }\n\n  /// Color of the mask.\n  var maskColor: UIColor { return colorSlider.color }\n\n  func captureOutput(\n    _ output: AVCaptureOutput,\n    didOutput sampleBuffer: CMSampleBuffer,\n    from connection: AVCaptureConnection\n  ) {\n    let image = FritzVisionImage(sampleBuffer: sampleBuffer, connection: connection)\n\n    guard let result = try? visionModel.predict(image),\n      let mask = result.buildSingleClassMask(\n        forClass: FritzVisionHairClass.hair,\n        clippingScoresAbove: clippingScoresAbove,\n        zeroingScoresBelow: zeroingScoresBelow,\n        resize: false,\n        color: maskColor)\n      else { return }\n\n    let blended = image.blend(\n      withMask: mask,\n      blendKernel: blendKernel,\n      opacity: opacity\n    )\n\n    DispatchQueue.main.async {\n      self.cameraView.image = blended\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Controllers/NavigationController.swift",
    "content": "import UIKit\n\nclass NavigationController: UINavigationController {\n\n  override var preferredStatusBarStyle: UIStatusBarStyle {\n    return .default\n  }\n\n  override func viewWillAppear(_ animated: Bool) {\n    super.viewWillAppear(animated)\n  }\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    navigationBar.tintColor = .white\n    navigationBar.shadowImage = UIImage()\n    navigationBar.isTranslucent = true\n    navigationBar.setBackgroundImage(UIImage(), for: .default)\n\n    let titleFont = UIFont.systemFont(ofSize: 17, weight: .bold)\n    navigationBar.titleTextAttributes = [\n      .font: titleFont,\n      .foregroundColor: UIColor.white\n    ]\n\n    let buttonFont = UIFont.systemFont(ofSize: 14, weight: .semibold)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .normal)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .highlighted)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .disabled)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .selected)\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Controllers/VideoHairViewController.swift",
    "content": "import UIKit\nimport AVKit\nimport AVFoundation\nimport Fritz\nimport ColorSlider\n\nclass VideoHairViewController: UIViewController, HairPredictor {\n\n  var videoPicker: VideoPicker!\n  var videoPlayer: FritzVisionVideo!\n  var filterOptions = FritzVisionSegmentationMaskOptions()\n\n  lazy var visionModel = FritzVisionHairSegmentationModelFast()\n  var colorSlider = ColorSlider(orientation: .vertical, previewSide: .left)\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n    colorSlider.addTarget(self, action: #selector(updateColor), for: .valueChanged)\n    filterOptions.maskColor = colorSlider.color\n  }\n\n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n\n    // Show video picker\n    self.videoPicker = VideoPicker(controller: self, delegate: self)\n    self.videoPicker.present(from: view)\n  }\n}\n\nextension VideoHairViewController: VideoPickerDelegate {\n\n  func didSelect(url: URL?) {\n    guard let url = url else { return }\n\n    // Setting the options for the video\n    let filter = FritzVisionBlendHairCompoundFilter(model: visionModel, options: filterOptions)\n    videoPlayer = FritzVisionVideo(url: url, withFilter: filter)\n\n    // Setup the view\n    let fritzView = FritzVideoView()\n    fritzView.frame = view.bounds\n    fritzView.fritzVideo = videoPlayer\n\n    // Add components to the view and start the video\n    addColorSlider()\n    view.addSubview(fritzView)\n    view.bringSubviewToFront(fritzView)\n    view.bringSubviewToFront(colorSlider)\n    fritzView.play()\n  }\n}\n\nextension VideoHairViewController {\n  \n  @objc func updateColor(_ slider: ColorSlider) {\n    filterOptions.maskColor = slider.color\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Controllers/ViewController.swift",
    "content": "import UIKit\nimport Fritz\n\nclass ViewController: UITableViewController {\n\n  override var preferredStatusBarStyle: UIStatusBarStyle {\n    return .lightContent\n  }\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n    self.view.backgroundColor = .black\n    title = \"Hair Coloring\".uppercased()\n    tableView.register(DemoTableViewCell.self, forCellReuseIdentifier: \"DemoTableViewCell\")\n    tableView.register(LinkTableViewCell.self, forCellReuseIdentifier: \"LinkTableViewCell\")\n    clearsSelectionOnViewWillAppear = true\n  }\n\n  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\n    if let _ = tableView.cellForRow(at: indexPath) as? LinkTableViewCell,\n      let url = URL(string: \"https://www.fritz.ai/pricing\") {\n      UIApplication.shared.open(url)\n      tableView.deselectRow(at: indexPath, animated: true)\n    }\n\n    if let cell = tableView.cellForRow(at: indexPath) as? DemoTableViewCell {\n      guard let identifier = cell.reuseIdentifier else { return }\n\n      var viewController: UIViewController?\n      switch identifier {\n      case \"LiveHairColor\":\n        viewController = LiveHairViewController()\n      case \"VideoHairColor\":\n        viewController = VideoHairViewController()\n      default:\n        return\n      }\n\n      if let currentController = viewController {\n        self.navigationController?.pushViewController(currentController, animated: true)\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string>Uses Camera for Image processing</string>\n  <key>NSPhotoLibraryUsageDescription</key>\n  <string>Uses video library for post-processing</string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Storyboards/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Storyboards/Base.lproj/LiveHairColorStoryboard.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15400\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <device id=\"retina6_1\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15404\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Live Hair View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"LiveHairViewController\" customModule=\"FritzHairColorDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"896\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"132\" y=\"129\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Storyboards/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15400\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"SsJ-BJ-qTj\">\n    <device id=\"retina4_7\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15404\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"52z-5R-Nve\">\n            <objects>\n                <tableViewController id=\"Cjs-X2-1zP\" customClass=\"ViewController\" customModule=\"FritzHairColorDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <tableView key=\"view\" clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" showsHorizontalScrollIndicator=\"NO\" showsVerticalScrollIndicator=\"NO\" dataMode=\"static\" style=\"plain\" separatorStyle=\"default\" rowHeight=\"-1\" estimatedRowHeight=\"-1\" sectionHeaderHeight=\"28\" sectionFooterHeight=\"28\" id=\"ZoN-Fk-Ok9\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <color key=\"separatorColor\" white=\"0.33333333333333331\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <sections>\n                            <tableViewSection id=\"23A-Yv-yEK\">\n                                <cells>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"LiveHairColor\" textLabel=\"lTu-bC-pQm\" detailTextLabel=\"0Fw-CK-INI\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"pUp-vV-F5l\" customClass=\"DemoTableViewCell\" customModule=\"FritzHairColorDemo\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"28\" width=\"375\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"pUp-vV-F5l\" id=\"85h-cn-y1l\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"348\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Run in Real-Time\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"lTu-bC-pQm\" userLabel=\"Hair Color Changer\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"36\" width=\"169\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Try on new hair colors on live video.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"0Fw-CK-INI\" userLabel=\"Change the color of your hair\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"66.5\" width=\"207\" height=\"14.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"VideoHairColor\" textLabel=\"9JU-mk-wuE\" detailTextLabel=\"sN4-oT-Ygr\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"axi-Pb-Hs0\" customClass=\"DemoTableViewCell\" customModule=\"FritzHairColorDemo\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"148\" width=\"375\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"axi-Pb-Hs0\" id=\"iDH-co-T30\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"348\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Run on a Saved Video\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"9JU-mk-wuE\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"29\" width=\"216.5\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Choose a video you've already recorded and run hair coloring on each frame.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"2\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"sN4-oT-Ygr\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"59.5\" width=\"307\" height=\"29\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                </cells>\n                            </tableViewSection>\n                        </sections>\n                        <connections>\n                            <outlet property=\"dataSource\" destination=\"Cjs-X2-1zP\" id=\"Jsy-w9-jmc\"/>\n                            <outlet property=\"delegate\" destination=\"Cjs-X2-1zP\" id=\"vXe-2h-7aU\"/>\n                        </connections>\n                    </tableView>\n                    <navigationItem key=\"navigationItem\" id=\"3sy-ld-ocO\"/>\n                </tableViewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"wbQ-fp-TQ8\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"1917.5999999999999\" y=\"170.46476761619192\"/>\n        </scene>\n        <!--Navigation Controller-->\n        <scene sceneID=\"wqO-nk-NYO\">\n            <objects>\n                <navigationController id=\"SsJ-BJ-qTj\" customClass=\"NavigationController\" customModule=\"FritzHairColorDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <navigationBar key=\"navigationBar\" contentMode=\"scaleToFill\" insetsLayoutMarginsFromSafeArea=\"NO\" id=\"VFV-IY-Ee9\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"44\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </navigationBar>\n                    <connections>\n                        <segue destination=\"Cjs-X2-1zP\" kind=\"relationship\" relationship=\"rootViewController\" id=\"zWD-QK-1UO\"/>\n                    </connections>\n                </navigationController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"eZ9-sb-vjd\" userLabel=\"First Responder\" customClass=\"UIResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"1078\" y=\"172\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/Storyboards/VideoHairViewStoryboard.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15400\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"WXX-D2-m06\">\n    <device id=\"retina6_1\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15404\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Video Hair View Controller-->\n        <scene sceneID=\"YMA-Bt-Ajh\">\n            <objects>\n                <viewController id=\"WXX-D2-m06\" customClass=\"VideoHairViewController\" customModule=\"FritzHairColorDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"4YX-Yp-28u\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"896\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" systemColor=\"systemBackgroundColor\" cocoaTouchSystemColor=\"whiteColor\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"jD1-4u-wX6\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"pqh-NI-shg\" userLabel=\"First Responder\" customClass=\"UIResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"138\" y=\"133\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/UI/DemoTableViewCell.swift",
    "content": "//\n//  StylizeHairMaskFilter.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\n\nclass DemoTableViewCell: UITableViewCell {\n\n  override func awakeFromNib() {\n    super.awakeFromNib()\n\n    let selectionView = UIView()\n    selectionView.backgroundColor = UIColor(red: 0.706, green: 0.133, blue: 0.133, alpha: 1)\n    selectedBackgroundView = selectionView\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/UI/LinkTableViewCell.swift",
    "content": "//\n//  StylizeHairMaskFilter.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\n\nclass LinkTableViewCell: UITableViewCell {\n\n  override func awakeFromNib() {\n    super.awakeFromNib()\n\n    let selectionView = UIView()\n    selectionView.backgroundColor = UIColor(red: 0.706, green: 0.133, blue: 0.133, alpha: 1)\n    selectedBackgroundView = selectionView\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo/UI/VideoPicker.swift",
    "content": "//\n//  VideoPicker.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\n\npublic protocol VideoPickerDelegate: class {\n  func didSelect(url: URL?)\n}\n\npublic class VideoPicker: NSObject {\n\n  private let pickerController = UIImagePickerController()\n  private weak var viewController: UIViewController?\n  private weak var delegate: VideoPickerDelegate?\n\n  public init(controller: UIViewController, delegate: VideoPickerDelegate) {\n    super.init()\n\n    self.viewController = controller\n    self.delegate = delegate\n    self.pickerController.delegate = self\n    self.pickerController.allowsEditing = true\n    self.pickerController.mediaTypes = [\"public.movie\"]\n    self.pickerController.videoQuality = .typeHigh\n  }\n\n  private func action(\n    for type: UIImagePickerController.SourceType,\n    title: String\n  ) -> UIAlertAction? {\n    guard UIImagePickerController.isSourceTypeAvailable(type) else {\n      return nil\n    }\n\n    return UIAlertAction(title: title, style: .default) { [unowned self] _ in\n      self.pickerController.sourceType = type\n      self.viewController?.present(self.pickerController, animated: true)\n    }\n  }\n\n  /// Show the action sheet.\n  ///\n  /// - Parameters:\n  ///   - sourceView: the view to show the action sheet on\n  public func present(from sourceView: UIView) {\n    let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)\n\n    if let action = self.action(for: .photoLibrary, title: \"Video library\") {\n      alertController.addAction(action)\n    }\n\n    alertController.addAction(UIAlertAction(title: \"Cancel\", style: .cancel) { _ in\n      self.popToRoot()\n    })\n\n    if UIDevice.current.userInterfaceIdiom == .pad {\n      alertController.popoverPresentationController?.sourceView = sourceView\n      alertController.popoverPresentationController?.sourceRect = sourceView.bounds\n      alertController.popoverPresentationController?.permittedArrowDirections = [.down, .up]\n    }\n\n    self.viewController?.present(alertController, animated: true)\n  }\n\n  /// Dismisses the menu and calls the delegate.\n  ///\n  /// - Parameters:\n  ///  - controller: the picker controller\n  ///  - url: the url of the selected item\n  private func pickerController(_ controller: UIImagePickerController, didSelect url: URL?) {\n    if let _ = url {\n      controller.dismiss(animated: true)\n    }\n    else {\n      controller.dismiss(animated: false) { self.popToRoot() }\n    }\n    self.delegate?.didSelect(url: url)\n  }\n\n  /// Go back to the main page\n  private func popToRoot() {\n    self.viewController?.navigationController?.popToRootViewController(animated: true)\n  }\n}\n\nextension VideoPicker: UIImagePickerControllerDelegate {\n\n  public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {\n    self.pickerController(picker, didSelect: nil)\n  }\n\n  public func imagePickerController(\n    _ picker: UIImagePickerController,\n    didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]\n  ) {\n    guard let url = info[.mediaURL] as? URL else {\n      return self.pickerController(picker, didSelect: nil)\n    }\n\n    self.pickerController(picker, didSelect: url)\n  }\n}\n\nextension VideoPicker: UINavigationControllerDelegate {}\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/FritzHairColorDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t3B1828952356E01000A238F7 /* VideoHairViewStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3B1828942356E01000A238F7 /* VideoHairViewStoryboard.storyboard */; };\n\t\t3B18289723575CAA00A238F7 /* HairPredictor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B18289623575CAA00A238F7 /* HairPredictor.swift */; };\n\t\t3B78A37223569AFD0025AD73 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B78A37123569AFD0025AD73 /* ViewController.swift */; };\n\t\t3B78A37423569B0D0025AD73 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3B78A37323569B0D0025AD73 /* Main.storyboard */; };\n\t\t3B78A37B2356AB9C0025AD73 /* DemoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B78A37A2356AB9C0025AD73 /* DemoTableViewCell.swift */; };\n\t\t3B78A37D2356ABB40025AD73 /* LinkTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B78A37C2356ABB40025AD73 /* LinkTableViewCell.swift */; };\n\t\t3B78A37F2356AD420025AD73 /* VideoHairViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B78A37E2356AD420025AD73 /* VideoHairViewController.swift */; };\n\t\t3B78A3812356B2F40025AD73 /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B78A3802356B2F40025AD73 /* NavigationController.swift */; };\n\t\t3B78A3872356C4A40025AD73 /* VideoPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B78A3862356C4A40025AD73 /* VideoPicker.swift */; };\n\t\t83E704A6226A4B6200FF678D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E704A5226A4B6200FF678D /* AppDelegate.swift */; };\n\t\t83E704A8226A4B6200FF678D /* LiveHairViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E704A7226A4B6200FF678D /* LiveHairViewController.swift */; };\n\t\t83E704AB226A4B6200FF678D /* LiveHairColorStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83E704A9226A4B6200FF678D /* LiveHairColorStoryboard.storyboard */; };\n\t\t83E704AD226A4B6200FF678D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83E704AC226A4B6200FF678D /* Assets.xcassets */; };\n\t\t83E704B0226A4B6200FF678D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83E704AE226A4B6200FF678D /* LaunchScreen.storyboard */; };\n\t\tA3089B330C5471177D90773A /* Pods_FritzHairColorDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05803C4F467E2627EC32D3A7 /* Pods_FritzHairColorDemo.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t05803C4F467E2627EC32D3A7 /* Pods_FritzHairColorDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzHairColorDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t3B1828942356E01000A238F7 /* VideoHairViewStoryboard.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = VideoHairViewStoryboard.storyboard; sourceTree = \"<group>\"; };\n\t\t3B18289623575CAA00A238F7 /* HairPredictor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HairPredictor.swift; sourceTree = \"<group>\"; };\n\t\t3B78A37123569AFD0025AD73 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t3B78A37323569B0D0025AD73 /* Main.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = \"<group>\"; };\n\t\t3B78A37A2356AB9C0025AD73 /* DemoTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoTableViewCell.swift; sourceTree = \"<group>\"; };\n\t\t3B78A37C2356ABB40025AD73 /* LinkTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkTableViewCell.swift; sourceTree = \"<group>\"; };\n\t\t3B78A37E2356AD420025AD73 /* VideoHairViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoHairViewController.swift; sourceTree = \"<group>\"; };\n\t\t3B78A3802356B2F40025AD73 /* NavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = \"<group>\"; };\n\t\t3B78A3862356C4A40025AD73 /* VideoPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPicker.swift; sourceTree = \"<group>\"; };\n\t\t83E704A2226A4B6200FF678D /* FritzHairColorDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzHairColorDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t83E704A5226A4B6200FF678D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t83E704A7226A4B6200FF678D /* LiveHairViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveHairViewController.swift; sourceTree = \"<group>\"; };\n\t\t83E704AA226A4B6200FF678D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LiveHairColorStoryboard.storyboard; sourceTree = \"<group>\"; };\n\t\t83E704AC226A4B6200FF678D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t83E704AF226A4B6200FF678D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t83E704B1226A4B6200FF678D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tA26562A73DD601DCB1888B65 /* Pods-FritzHairColorDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzHairColorDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzHairColorDemo/Pods-FritzHairColorDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tDCA977652A98D87A8EB5BE5A /* Pods-FritzHairColorDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzHairColorDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzHairColorDemo/Pods-FritzHairColorDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t83E7049F226A4B6200FF678D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tA3089B330C5471177D90773A /* Pods_FritzHairColorDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t3416539E3282F0B389088B90 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tDCA977652A98D87A8EB5BE5A /* Pods-FritzHairColorDemo.debug.xcconfig */,\n\t\t\t\tA26562A73DD601DCB1888B65 /* Pods-FritzHairColorDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B78A3772356AB2F0025AD73 /* UI */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B78A37A2356AB9C0025AD73 /* DemoTableViewCell.swift */,\n\t\t\t\t3B78A37C2356ABB40025AD73 /* LinkTableViewCell.swift */,\n\t\t\t\t3B78A3862356C4A40025AD73 /* VideoPicker.swift */,\n\t\t\t);\n\t\t\tpath = UI;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B78A3822356B40A0025AD73 /* Storyboards */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704A9226A4B6200FF678D /* LiveHairColorStoryboard.storyboard */,\n\t\t\t\t83E704AE226A4B6200FF678D /* LaunchScreen.storyboard */,\n\t\t\t\t3B78A37323569B0D0025AD73 /* Main.storyboard */,\n\t\t\t\t3B1828942356E01000A238F7 /* VideoHairViewStoryboard.storyboard */,\n\t\t\t);\n\t\t\tpath = Storyboards;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B78A3832356B4270025AD73 /* Controllers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704A7226A4B6200FF678D /* LiveHairViewController.swift */,\n\t\t\t\t3B78A37123569AFD0025AD73 /* ViewController.swift */,\n\t\t\t\t3B78A37E2356AD420025AD73 /* VideoHairViewController.swift */,\n\t\t\t\t3B78A3802356B2F40025AD73 /* NavigationController.swift */,\n\t\t\t\t3B18289623575CAA00A238F7 /* HairPredictor.swift */,\n\t\t\t);\n\t\t\tpath = Controllers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83E70499226A4B6200FF678D = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704A4226A4B6200FF678D /* FritzHairColorDemo */,\n\t\t\t\t83E704A3226A4B6200FF678D /* Products */,\n\t\t\t\t3416539E3282F0B389088B90 /* Pods */,\n\t\t\t\t84BEB48CA4AE3E92296CE6BD /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83E704A3226A4B6200FF678D /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704A2226A4B6200FF678D /* FritzHairColorDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83E704A4226A4B6200FF678D /* FritzHairColorDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B78A3832356B4270025AD73 /* Controllers */,\n\t\t\t\t3B78A3822356B40A0025AD73 /* Storyboards */,\n\t\t\t\t3B78A3772356AB2F0025AD73 /* UI */,\n\t\t\t\t83E704A5226A4B6200FF678D /* AppDelegate.swift */,\n\t\t\t\t83E704AC226A4B6200FF678D /* Assets.xcassets */,\n\t\t\t\t83E704B1226A4B6200FF678D /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzHairColorDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t84BEB48CA4AE3E92296CE6BD /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t05803C4F467E2627EC32D3A7 /* Pods_FritzHairColorDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t83E704A1226A4B6200FF678D /* FritzHairColorDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 83E704B4226A4B6200FF678D /* Build configuration list for PBXNativeTarget \"FritzHairColorDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tA87BA6BF21E7427A83460FB4 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t83E7049E226A4B6200FF678D /* Sources */,\n\t\t\t\t83E7049F226A4B6200FF678D /* Frameworks */,\n\t\t\t\t83E704A0226A4B6200FF678D /* Resources */,\n\t\t\t\t75EBBA0EAF846061FEE1D29C /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzHairColorDemo;\n\t\t\tproductName = FritzHairColorDemo;\n\t\t\tproductReference = 83E704A2226A4B6200FF678D /* FritzHairColorDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t83E7049A226A4B6200FF678D /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1020;\n\t\t\t\tLastUpgradeCheck = 1020;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t83E704A1226A4B6200FF678D = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 10.2.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 83E7049D226A4B6200FF678D /* Build configuration list for PBXProject \"FritzHairColorDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 83E70499226A4B6200FF678D;\n\t\t\tproductRefGroup = 83E704A3226A4B6200FF678D /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t83E704A1226A4B6200FF678D /* FritzHairColorDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t83E704A0226A4B6200FF678D /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t3B1828952356E01000A238F7 /* VideoHairViewStoryboard.storyboard in Resources */,\n\t\t\t\t83E704B0226A4B6200FF678D /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t3B78A37423569B0D0025AD73 /* Main.storyboard in Resources */,\n\t\t\t\t83E704AD226A4B6200FF678D /* Assets.xcassets in Resources */,\n\t\t\t\t83E704AB226A4B6200FF678D /* LiveHairColorStoryboard.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t75EBBA0EAF846061FEE1D29C /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzHairColorDemo/Pods-FritzHairColorDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzHairColorDemo/Pods-FritzHairColorDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzHairColorDemo/Pods-FritzHairColorDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tA87BA6BF21E7427A83460FB4 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzHairColorDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t83E7049E226A4B6200FF678D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t3B78A37F2356AD420025AD73 /* VideoHairViewController.swift in Sources */,\n\t\t\t\t3B78A37223569AFD0025AD73 /* ViewController.swift in Sources */,\n\t\t\t\t83E704A8226A4B6200FF678D /* LiveHairViewController.swift in Sources */,\n\t\t\t\t3B78A3872356C4A40025AD73 /* VideoPicker.swift in Sources */,\n\t\t\t\t83E704A6226A4B6200FF678D /* AppDelegate.swift in Sources */,\n\t\t\t\t3B18289723575CAA00A238F7 /* HairPredictor.swift in Sources */,\n\t\t\t\t3B78A37B2356AB9C0025AD73 /* DemoTableViewCell.swift in Sources */,\n\t\t\t\t3B78A3812356B2F40025AD73 /* NavigationController.swift in Sources */,\n\t\t\t\t3B78A37D2356ABB40025AD73 /* LinkTableViewCell.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t83E704A9226A4B6200FF678D /* LiveHairColorStoryboard.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704AA226A4B6200FF678D /* Base */,\n\t\t\t);\n\t\t\tname = LiveHairColorStoryboard.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83E704AE226A4B6200FF678D /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704AF226A4B6200FF678D /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t83E704B2226A4B6200FF678D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83E704B3226A4B6200FF678D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t83E704B5226A4B6200FF678D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = DCA977652A98D87A8EB5BE5A /* Pods-FritzHairColorDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzHairColorDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.HairColorDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83E704B6226A4B6200FF678D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = A26562A73DD601DCB1888B65 /* Pods-FritzHairColorDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzHairColorDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.HairColorDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t83E7049D226A4B6200FF678D /* Build configuration list for PBXProject \"FritzHairColorDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83E704B2226A4B6200FF678D /* Debug */,\n\t\t\t\t83E704B3226A4B6200FF678D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t83E704B4226A4B6200FF678D /* Build configuration list for PBXNativeTarget \"FritzHairColorDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83E704B5226A4B6200FF678D /* Debug */,\n\t\t\t\t83E704B6226A4B6200FF678D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 83E7049A226A4B6200FF678D /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzHairColorDemo' do\n  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks\n  use_frameworks!\n\n  # Pods for FritzHairColorDemo\n  pod 'ColorSlider', '~> 4.4'\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionSegmentationModel/Hair/Fast'\n\nend\n"
  },
  {
    "path": "iOS/FritzHairColorDemo/README.md",
    "content": "# Hair Coloring with Hair Segmentation\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use the Hair Segmentation model by Fritz in order to allow users to try out different hair colors.\n\nFor the full tutorial, visit [our post on Heartbeat](https://heartbeat.fritz.ai/try-on-a-new-style-build-an-ios-app-to-change-your-hair-color-with-fritz-hair-segmentation-177324b077b3).\n\n<img src=\"images/hair_seg_ios.jpg\" width=\"250\" />\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzHairColorDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzHairColorDemo`\n\n```\ncd fritz-examples/iOS/FritzHairColorDemo\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzHairColorDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzPoseEstimationDemo\n//\n//  Created by Christopher Kelly on 4/17/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n    // Override point for customization after application launch.\n    FritzCore.configure()\n    return true\n  }\n\n  func applicationWillResignActive(_ application: UIApplication) {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n  }\n\n  func applicationDidEnterBackground(_ application: UIApplication) {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n  }\n\n  func applicationWillEnterForeground(_ application: UIApplication) {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n  }\n\n  func applicationDidBecomeActive(_ application: UIApplication) {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n  }\n\n  func applicationWillTerminate(_ application: UIApplication) {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15705\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <device id=\"retina6_1\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15706\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModule=\"FritzHandPoseEstimationDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"896\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <toolbar hidden=\"YES\" opaque=\"NO\" clearsContextBeforeDrawing=\"NO\" contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"6c2-xc-ipM\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"813\" width=\"414\" height=\"49\"/>\n                                <items>\n                                    <barButtonItem title=\"Item\" image=\"checkmark\" catalog=\"system\" id=\"mz3-tY-cQb\">\n                                        <color key=\"tintColor\" systemColor=\"systemGreenColor\" red=\"0.20392156859999999\" green=\"0.78039215689999997\" blue=\"0.34901960780000002\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                        <connections>\n                                            <action selector=\"keepButtonAction:\" destination=\"BYZ-38-t0r\" id=\"ICc-0i-2X9\"/>\n                                        </connections>\n                                    </barButtonItem>\n                                    <barButtonItem style=\"plain\" systemItem=\"flexibleSpace\" id=\"wnW-dp-eJO\"/>\n                                    <barButtonItem title=\"Item\" image=\"pencil\" catalog=\"system\" width=\"40\" id=\"h5c-9k-Qrc\">\n                                        <color key=\"tintColor\" systemColor=\"linkColor\" red=\"0.0\" green=\"0.47843137250000001\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                        <connections>\n                                            <action selector=\"editButtonAction:\" destination=\"BYZ-38-t0r\" id=\"jMy-dm-yiE\"/>\n                                        </connections>\n                                    </barButtonItem>\n                                    <barButtonItem style=\"plain\" systemItem=\"flexibleSpace\" id=\"g8Y-nr-bUE\"/>\n                                    <barButtonItem title=\"Item\" image=\"trash\" catalog=\"system\" width=\"40\" id=\"SSV-re-cfl\">\n                                        <color key=\"tintColor\" systemColor=\"systemRedColor\" red=\"1\" green=\"0.23137254900000001\" blue=\"0.18823529410000001\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                        <connections>\n                                            <action selector=\"discardButtonAction:\" destination=\"BYZ-38-t0r\" id=\"CqX-tr-wVC\"/>\n                                        </connections>\n                                    </barButtonItem>\n                                </items>\n                            </toolbar>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"tA9-xk-pw6\" userLabel=\"Model Version\">\n                                <rect key=\"frame\" x=\"20\" y=\"84\" width=\"32\" height=\"15\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"tcN-OU-RUb\" userLabel=\"Model ID\">\n                                <rect key=\"frame\" x=\"20\" y=\"113\" width=\"32\" height=\"15\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"pcs-CX-y3h\" userLabel=\"FPS\">\n                                <rect key=\"frame\" x=\"20\" y=\"142\" width=\"32\" height=\"15\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstItem=\"tcN-OU-RUb\" firstAttribute=\"top\" secondItem=\"tA9-xk-pw6\" secondAttribute=\"bottom\" constant=\"14\" id=\"CjB-GV-mKq\"/>\n                            <constraint firstItem=\"tcN-OU-RUb\" firstAttribute=\"leading\" secondItem=\"pcs-CX-y3h\" secondAttribute=\"leading\" id=\"E7s-Sh-1m7\"/>\n                            <constraint firstItem=\"pcs-CX-y3h\" firstAttribute=\"top\" secondItem=\"tcN-OU-RUb\" secondAttribute=\"bottom\" constant=\"14\" id=\"Lw0-Wc-qEd\"/>\n                            <constraint firstItem=\"tA9-xk-pw6\" firstAttribute=\"leading\" secondItem=\"8bC-Xf-vdC\" secondAttribute=\"leadingMargin\" id=\"Mgt-Mx-zcG\"/>\n                            <constraint firstItem=\"tA9-xk-pw6\" firstAttribute=\"leading\" secondItem=\"tcN-OU-RUb\" secondAttribute=\"leading\" id=\"T4b-zT-oLP\"/>\n                            <constraint firstItem=\"6c2-xc-ipM\" firstAttribute=\"centerX\" secondItem=\"8bC-Xf-vdC\" secondAttribute=\"centerX\" id=\"UoU-aN-Bbk\"/>\n                            <constraint firstItem=\"6c2-xc-ipM\" firstAttribute=\"bottom\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"bottom\" id=\"cjk-Hi-xPX\"/>\n                            <constraint firstItem=\"6c2-xc-ipM\" firstAttribute=\"leading\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"leading\" id=\"dk7-bX-5sA\"/>\n                            <constraint firstItem=\"tA9-xk-pw6\" firstAttribute=\"top\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"top\" constant=\"40\" id=\"q2v-OH-svK\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                    <connections>\n                        <outlet property=\"buttonBar\" destination=\"6c2-xc-ipM\" id=\"7a5-HP-xnv\"/>\n                        <outlet property=\"editButton\" destination=\"h5c-9k-Qrc\" id=\"cPK-yI-WvB\"/>\n                        <outlet property=\"fpsLabel\" destination=\"pcs-CX-y3h\" id=\"k8d-MP-JKf\"/>\n                        <outlet property=\"modelIdLabel\" destination=\"tcN-OU-RUb\" id=\"7EZ-hY-HUw\"/>\n                        <outlet property=\"modelVersionLabel\" destination=\"tA9-xk-pw6\" id=\"NTi-gp-kge\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"137.68115942028987\" y=\"138.61607142857142\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"checkmark\" catalog=\"system\" width=\"64\" height=\"56\"/>\n        <image name=\"pencil\" catalog=\"system\" width=\"64\" height=\"56\"/>\n        <image name=\"trash\" catalog=\"system\" width=\"60\" height=\"64\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/CameraButton.swift",
    "content": "//\n//  CameraButton.swift\n//  FritzHandPoseEstimationDemo\n//\n//  Created by Steven Yeung on 11/14/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\n\nfinal class CameraButton: UIButton {\n  private var buttonDimension = 70\n  private var buttonOffsetX: CGFloat = 35\n  private var buttonOffsetY: CGFloat = 80\n\n  public init() {\n    super.init(frame: CGRect.zero)\n    self.backgroundColor = UIColor.clear\n    if let titleLabel = self.titleLabel {\n      titleLabel.textColor = UIColor.white\n      titleLabel.font = UIFont.systemFont(ofSize: 20)\n    }\n\n    self.backgroundColor = UIColor(white: 1.0, alpha: 0.65)\n    let minY = self.safeAreaLayoutGuide.layoutFrame.maxY - buttonOffsetY\n    self.frame = CGRect(\n      origin: CGPoint(x: UIScreen.main.bounds.midX - buttonOffsetX, y: minY),\n      size: CGSize(width: buttonDimension, height: buttonDimension)\n    )\n    self.layer.cornerRadius = CGFloat(buttonDimension / 2)\n    self.layer.borderColor = UIColor.gray.cgColor\n    self.layer.borderWidth = 3\n  }\n\n  required init?(coder aDecoder: NSCoder) {\n    super.init(coder: aDecoder)\n  }\n\n  /// Centers the button.\n  ///\n  /// - Parameters:\n  ///   - x: Location on the x-axis.\n  ///   - y: Location on the y-axis.\n  func center(_ x: CGFloat, _ y: CGFloat) {\n    self.center = CGPoint(x: x, y: y - (buttonOffsetY / 2))\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/DraggableKeypoint.swift",
    "content": "//\n//  DraggableKeypoint.swift\n//  FritzHandPoseEstimationDemo\n//\n//  Created by Steven Yeung on 11/20/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\n\nprotocol DragDelegate: class {\n\n  /// Triggers an action after dragging a keypoint.\n  ///\n  /// - Parameters:\n  ///   - posePart: The part of the keypoint dragged.\n  ///   - position: Where the keypoint was dragged to.\n  func didDrag(_ posePart: HandSkeleton, to position: CGPoint)\n}\n\nclass DraggableKeypoint: UIView {\n  let pointRadius: CGFloat = 40\n  let posePart: HandSkeleton!\n  weak var delegate: DragDelegate?\n\n  public init(\n    position: CGPoint,\n    posePart: HandSkeleton\n  ) {\n    self.posePart = posePart\n    super.init(frame: .zero)\n\n    self.frame = CGRect(\n      origin: CGPoint(x: position.x - (pointRadius / 2), y: position.y - (pointRadius / 2)),\n      size: CGSize(width: pointRadius, height: pointRadius)\n    )\n\n    // Make the view draggable\n    let dragRecognizer = UIPanGestureRecognizer(target:self, action:#selector(dragRecognized))\n    self.isUserInteractionEnabled = true\n    self.addGestureRecognizer(dragRecognizer)\n    self.layer.cornerRadius = CGFloat(pointRadius / 2)\n    self.backgroundColor = .red\n  }\n\n  required init?(coder aDecoder: NSCoder) {\n    self.posePart = nil\n    super.init(coder: aDecoder)\n  }\n\n  @objc func dragRecognized(_ recognizer: UIPanGestureRecognizer) {\n    let translation = recognizer.translation(in: superview)\n\n    // Move the keypoint to the new position\n    let newPositionX = center.x + translation.x\n    let newPositionY = center.y + translation.y\n    self.center = CGPoint(x: newPositionX, y: newPositionY)\n    recognizer.setTranslation(.zero, in: superview)\n    delegate?.didDrag(posePart, to: center)\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/HandPoseModel.swift",
    "content": "//\n//  HandPoseModel.swift\n//  FritzHandPoseEstimationDemo\n//\n//  Created by Jameson Toole on 12/13/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\n// Extend the model class for use with Fritz.\nextension HandPose: SwiftIdentifiedModel {\n  static let modelIdentifier = HandPoseModel.modelConfig.identifier\n  static let packagedModelVersion = HandPoseModel.modelConfig.version\n}\n\n// Define a custom hand pose skeleton. This must match the keypoint configuration you entered in the Dataset Generator.\npublic enum HandSkeleton: Int, SkeletonType {\n  case thumb\n  case index\n  case middle\n  case ring\n  case pinky\n\n  public static let objectName = \"hand\"\n}\n\n@available(iOS 11.0, *)\npublic final class HandPoseModel: FritzVisionPosePredictor<HandSkeleton>, DownloadableModel {\n\n  @objc public static let modelConfig = FritzModelConfiguration(\n    identifier: \"4845423b36014942b9fb274fe751e8da\",\n    version: 6\n  )\n\n  @objc public static var managedModel: FritzManagedModel {\n    return modelConfig.buildManagedModel()\n  }\n\n  @objc public static var wifiRequiredForModelDownload: Bool = _wifiRequiredForModelDownload\n\n  public static func fetchModel(completionHandler: @escaping (HandPoseModel?, Error?) -> Void) {\n    _fetchModel(completionHandler: completionHandler)\n  }\n\n  public convenience init() {\n    let model = HandPose().fritzModel()\n    self.init(model: model)\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string>For processing camera inputs</string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/UIImageView+Transformations.swift",
    "content": "//\n//  UIImageView+Transformations.swift\n//  FritzHandPoseEstimationDemo\n//\n//  Created by Christopher Kelly on 6/11/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n//\n//  The MIT License (MIT)\n//\n//  Copyright (c) 2012 Dominique d'Argent\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in all\n//  copies or substantial portions of the Software.\n//\n//  Adapted from https://github.com/nubbel/UIImageView-GeometryConversion\n\nimport UIKit\n\n\nextension UIImageView {\n\n  func convertPoint(fromImagePoint imagePoint: CGPoint) -> CGPoint {\n    guard let imageSize = image?.size else { return CGPoint.zero }\n\n    var viewPoint = imagePoint\n    let viewSize = bounds.size\n\n    let ratioX = viewSize.width / imageSize.width\n    let ratioY = viewSize.height / imageSize.height\n\n    switch contentMode {\n    case .scaleAspectFit: fallthrough\n    case .scaleAspectFill:\n      var scale : CGFloat = 0\n\n      if contentMode == .scaleAspectFit {\n        scale = min(ratioX, ratioY)\n      }\n      else {\n        scale = max(ratioX, ratioY)\n      }\n\n      viewPoint.x *= scale\n      viewPoint.y *= scale\n\n      viewPoint.x += (viewSize.width  - imageSize.width  * scale) / 2.0\n      viewPoint.y += (viewSize.height - imageSize.height * scale) / 2.0\n\n    case .scaleToFill: fallthrough\n    case .redraw:\n      viewPoint.x *= ratioX\n      viewPoint.y *= ratioY\n    case .center:\n      viewPoint.x += viewSize.width / 2.0  - imageSize.width  / 2.0\n      viewPoint.y += viewSize.height / 2.0 - imageSize.height / 2.0\n    case .top:\n      viewPoint.x += viewSize.width / 2.0 - imageSize.width / 2.0\n    case .bottom:\n      viewPoint.x += viewSize.width / 2.0 - imageSize.width / 2.0\n      viewPoint.y += viewSize.height - imageSize.height\n    case .left:\n      viewPoint.y += viewSize.height / 2.0 - imageSize.height / 2.0\n    case .right:\n      viewPoint.x += viewSize.width - imageSize.width\n      viewPoint.y += viewSize.height / 2.0 - imageSize.height / 2.0\n    case .topRight:\n      viewPoint.x += viewSize.width - imageSize.width\n    case .bottomLeft:\n      viewPoint.y += viewSize.height - imageSize.height\n    case .bottomRight:\n      viewPoint.x += viewSize.width  - imageSize.width\n      viewPoint.y += viewSize.height - imageSize.height\n    case.topLeft: fallthrough\n    default:\n      break\n    }\n\n    return viewPoint\n  }\n\n  func convertRect(fromImageRect imageRect: CGRect) -> CGRect {\n    let imageTopLeft = imageRect.origin\n    let imageBottomRight = CGPoint(x: imageRect.maxX, y: imageRect.maxY)\n\n    let viewTopLeft = convertPoint(fromImagePoint: imageTopLeft)\n    let viewBottomRight = convertPoint(fromImagePoint: imageBottomRight)\n\n    var viewRect : CGRect = .zero\n    viewRect.origin = viewTopLeft\n    viewRect.size = CGSize(width: abs(viewBottomRight.x - viewTopLeft.x), height: abs(viewBottomRight.y - viewTopLeft.y))\n    return viewRect\n  }\n\n  func convertPoint(fromViewPoint viewPoint: CGPoint) -> CGPoint {\n    guard let imageSize = image?.size else { return CGPoint.zero }\n\n    var imagePoint = viewPoint\n    let viewSize = bounds.size\n\n    let ratioX = viewSize.width / imageSize.width\n    let ratioY = viewSize.height / imageSize.height\n\n    switch contentMode {\n    case .scaleAspectFit: fallthrough\n    case .scaleAspectFill:\n      var scale : CGFloat = 0\n\n      if contentMode == .scaleAspectFit {\n        scale = min(ratioX, ratioY)\n      }\n      else {\n        scale = max(ratioX, ratioY)\n      }\n\n      // Remove the x or y margin added in FitMode\n      imagePoint.x -= (viewSize.width  - imageSize.width  * scale) / 2.0\n      imagePoint.y -= (viewSize.height - imageSize.height * scale) / 2.0\n\n      imagePoint.x /= scale;\n      imagePoint.y /= scale;\n\n    case .scaleToFill: fallthrough\n    case .redraw:\n      imagePoint.x /= ratioX\n      imagePoint.y /= ratioY\n    case .center:\n      imagePoint.x -= (viewSize.width - imageSize.width)  / 2.0\n      imagePoint.y -= (viewSize.height - imageSize.height) / 2.0\n    case .top:\n      imagePoint.x -= (viewSize.width - imageSize.width)  / 2.0\n    case .bottom:\n      imagePoint.x -= (viewSize.width - imageSize.width)  / 2.0\n      imagePoint.y -= (viewSize.height - imageSize.height);\n    case .left:\n      imagePoint.y -= (viewSize.height - imageSize.height) / 2.0\n    case .right:\n      imagePoint.x -= (viewSize.width - imageSize.width);\n      imagePoint.y -= (viewSize.height - imageSize.height) / 2.0\n    case .topRight:\n      imagePoint.x -= (viewSize.width - imageSize.width);\n    case .bottomLeft:\n      imagePoint.y -= (viewSize.height - imageSize.height);\n    case .bottomRight:\n      imagePoint.x -= (viewSize.width - imageSize.width)\n      imagePoint.y -= (viewSize.height - imageSize.height)\n    case.topLeft: fallthrough\n    default:\n      break\n    }\n\n    return imagePoint\n  }\n\n  func convertRect(fromViewRect viewRect : CGRect) -> CGRect {\n    let viewTopLeft = viewRect.origin\n    let viewBottomRight = CGPoint(x: viewRect.maxX, y: viewRect.maxY)\n\n    let imageTopLeft = convertPoint(fromImagePoint: viewTopLeft)\n    let imageBottomRight = convertPoint(fromImagePoint: viewBottomRight)\n\n    var imageRect : CGRect = .zero\n    imageRect.origin = imageTopLeft\n    imageRect.size = CGSize(width: abs(imageBottomRight.x - imageTopLeft.x), height: abs(imageBottomRight.y - imageTopLeft.y))\n    return imageRect\n  }\n\n}\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  FritzStyleTransferDemo\n//\n//  Created by Christopher Kelly on 9/12/18.\n//  Copyright © 2018 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Photos\nimport Fritz\n\n\nextension Double {\n  func format(f: String) -> String {\n    return String(format: \"%\\(f)f\", self)\n  }\n}\n\n\nclass ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {\n  \n  // Buttons for editing keypoints and submitting predictions\n  @IBOutlet weak var buttonBar: UIToolbar!\n  @IBOutlet weak var editButton: UIBarButtonItem!\n  \n  @IBOutlet weak var fpsLabel: UILabel!\n  @IBOutlet weak var modelIdLabel: UILabel!\n  @IBOutlet weak var modelVersionLabel: UILabel!\n\n  /// Transmits a captured photo to Fritz.\n  @IBAction func keepButtonAction(_ sender: UIBarButtonItem) {\n    if let lastPrediction = lastPrediction {\n      var poses: [Pose<HandSkeleton>] = []\n      var modifiedPoses: [Pose<HandSkeleton>]?\n      if let pose = lastPrediction.pose {\n        poses.append(pose)\n      }\n      if let modifiedPose = lastPrediction.modifiedPose,\n        lastPrediction.pose != modifiedPose {\n        modifiedPoses = [modifiedPose]\n      }\n      poseModel.record(lastPrediction.image, predicted: poses, modified: modifiedPoses)\n    }\n    restartCamera()\n  }\n\n  /// Edit the keypoints on a captured photo.\n  @IBAction func editButtonAction(_ sender: UIBarButtonItem) {\n    guard let modifiedPose = lastPrediction?.modifiedPose else { return }\n    editButton.isEnabled = false\n\n    // Draw a draggable keypoint at each keypoint position, regardless of confidence\n    for keypoint in modifiedPose.keypoints {\n      let draggable = DraggableKeypoint(\n        position: previewView.convertPoint(fromImagePoint: keypoint.position),\n        posePart: keypoint.part\n      )\n      draggable.delegate = self\n      previewView.addSubview(draggable)\n      previewView.bringSubviewToFront(draggable)\n    }\n  }\n\n  /// Discard a captured photo and restart the camera.\n  @IBAction func discardButtonAction(_ sender: UIBarButtonItem) {\n    restartCamera()\n  }\n\n  var previewView: UIImageView!\n  \n  /// The keypoint and rectangle overlay.\n  var shapeLayer: CAShapeLayer!\n  \n  /// The button used to capture the current frame.\n  var captureButton = CameraButton()\n\n  // Model and Predictions\n  lazy var poseModel = HandPoseModel()\n  \n  var minPoseThreshold: Double { return 0.6 }\n  var keypointThrehold: Double { return 0.5 }\n  \n  var lastExecution = Date()\n  \n  /// The most recent frame and the its associated pose.\n  var lastPrediction: (\n    image: FritzVisionImage,\n    pose: Pose<HandSkeleton>?,\n    modifiedPose: Pose<HandSkeleton>?\n  )?\n\n  private lazy var captureSession: AVCaptureSession = {\n    let session = AVCaptureSession()\n\n    guard\n      let backCamera = AVCaptureDevice.default(\n          .builtInWideAngleCamera,\n        for: .video,\n        position: .back),\n      let input = try? AVCaptureDeviceInput(device: backCamera)\n      else { return session }\n    session.addInput(input)\n\n    session.sessionPreset = .photo\n    return session\n  }()\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    // Add preview View as a subview\n    previewView = UIImageView(frame: view.bounds)\n    previewView.contentMode = .scaleAspectFill\n    previewView.isUserInteractionEnabled = true\n    view.addSubview(previewView)\n    \n    // Setup the capture button\n    captureButton.addGestureRecognizer(\n      UITapGestureRecognizer(target: self, action: #selector(cameraButtonTapped))\n    )\n    view.addSubview(captureButton)\n\n    // Setup the layer to plot the keypoints and rectangles.\n    shapeLayer = buildRectangleLayer()\n    previewView.layer.addSublayer(shapeLayer)\n    let videoOutput = AVCaptureVideoDataOutput()\n    videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA as UInt32]\n    videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: \"MyQueue\"))\n    self.captureSession.addOutput(videoOutput)\n    self.captureSession.startRunning()\n    \n    view.bringSubviewToFront(captureButton)\n    view.layer.addSublayer(shapeLayer)\n    view.bringSubviewToFront(captureButton)\n    view.bringSubviewToFront(buttonBar)\n    view.bringSubviewToFront(modelVersionLabel)\n    view.bringSubviewToFront(modelIdLabel)\n    view.bringSubviewToFront(fpsLabel)\n    previewView.contentMode = .scaleAspectFill\n  }\n  \n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n    captureButton.center(view.frame.midX, view.safeAreaLayoutGuide.layoutFrame.maxY)\n  }\n\n  override func viewWillLayoutSubviews() {\n    super.viewWillLayoutSubviews()\n\n    previewView.frame = view.bounds\n  }\n\n  override func didReceiveMemoryWarning() {\n    super.didReceiveMemoryWarning()\n    // Dispose of any resources that can be recreated.\n  }\n  \n  func buildRectangleLayer() -> CAShapeLayer {\n    let shape = CAShapeLayer()\n    shape.opacity = 0.5\n    shape.lineWidth = 2\n    shape.lineJoin = .miter\n    shape.strokeColor =  UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).cgColor\n    return shape\n  }\n\n  func displayInputImage(_ image: FritzVisionImage) {\n    guard let image = image.rotated() else { return }\n\n    DispatchQueue.main.async {\n      self.previewView.image = image\n    }\n  }\n  \n  func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {\n    let image = FritzVisionImage(sampleBuffer: sampleBuffer, connection: connection)\n    predict(image)\n  }\n}\n\n/// Methods for handling model predictions\nextension ViewController {\n  \n  func predict(_ image: FritzVisionImage) {\n    let options = FritzVisionPoseModelOptions()\n    options.minPoseThreshold = minPoseThreshold\n    options.minPartThreshold = keypointThrehold\n\n    guard let result = try? poseModel.predict(image, options: options),\n      let pose = result.pose() else {\n      // No pose was found, but store the the input image.\n      lastPrediction = (image: image, pose: nil, modifiedPose: nil)\n      // If there was no pose, display original image\n      displayInputImage(image)\n      return\n    }\n    \n    updateLabels()\n    \n    // A pose was found, store it. There are no modifications yet so store\n    // the predicted pose as the modified pose as well.\n    lastPrediction = (image: image, pose: pose, modifiedPose: pose.scaled(to: image.size))\n\n    guard let poseResult = image.draw(pose: pose) else {\n      displayInputImage(image)\n      return\n    }\n\n    DispatchQueue.main.async {\n      self.previewView.image = poseResult\n    }\n  }\n  \n  func updateLayer(pose: Pose<HandSkeleton>) {\n    DispatchQueue.main.async {\n      let path = UIBezierPath()\n      for keypoint in pose.keypoints {\n        path.move(to: self.previewView.convertPoint(fromImagePoint: keypoint.position))\n      }\n      path.close()\n\n      self.shapeLayer.path = path.cgPath\n    }\n  }\n  \n  func updateLabels() {\n    let thisExecution = Date()\n    let executionTime = thisExecution.timeIntervalSince(self.lastExecution)\n    let framesPerSecond: Double = 1 / executionTime\n    self.lastExecution = thisExecution\n    \n    DispatchQueue.main.async {\n      self.fpsLabel.text = \"FPS: \\(framesPerSecond.format(f: \".3\"))\"\n      self.modelIdLabel.text = \"Model ID: \\(self.poseModel.managedModel.activeModelConfig.identifier)\"\n      self.modelVersionLabel.text = \"Active Version: \\(self.poseModel.managedModel.activeModelConfig.version)\"\n    }\n  }\n}\n\n\n/// Methods for changing capture state\nextension ViewController {\n  \n  @objc func cameraButtonTapped() {\n    captureSession.stopRunning()\n    DispatchQueue.main.async {\n      self.editButton.isEnabled = true\n      self.toggleCaptureUI()\n    }\n  }\n  \n  /// Restarts the capturing state.\n  func restartCamera() {\n    DispatchQueue.main.async {\n      self.previewView.subviews.forEach { $0.removeFromSuperview() }\n      self.shapeLayer.path = nil\n      self.captureSession.startRunning()\n      self.toggleCaptureUI()\n    }\n  }\n  \n  /// Swaps visibility of UI elements\n  func toggleCaptureUI() {\n    buttonBar.isHidden = !buttonBar.isHidden\n    captureButton.isHidden = !captureButton.isHidden\n    fpsLabel.isHidden = !fpsLabel.isHidden\n    modelVersionLabel.isHidden = !modelVersionLabel.isHidden\n    modelIdLabel.isHidden = !modelIdLabel.isHidden\n  }\n}\n\n\n/// For updating keypoint locations.\nextension ViewController: DragDelegate {\n\n  func didDrag(_ posePart: HandSkeleton, to position: CGPoint) {\n    guard let prediction = lastPrediction,\n      let modifiedPose = prediction.modifiedPose,\n      let startingPoint = modifiedPose.getKeypoint(for: posePart)\n      else { return }\n\n    // Create a new keypoint at the new position\n    let movedPoint = Keypoint<HandSkeleton>(\n      index: startingPoint.index,\n      position: previewView.convertPoint(fromViewPoint: position),\n      score: startingPoint.score,\n      part: posePart\n    )\n\n    // Replace the matching keypoint with the new keypoint\n    var updatedPoints: [Keypoint<HandSkeleton>] = []\n    for keypoint in modifiedPose.keypoints {\n      if keypoint.part ~= posePart {\n        updatedPoints.append(movedPoint)\n      }\n      else {\n        updatedPoints.append(keypoint)\n      }\n    }\n\n    // Store the new pose and redraw the view\n    let updatedPose = Pose(\n      keypoints: updatedPoints,\n      score: modifiedPose.score,\n      bounds: modifiedPose.bounds\n    )\n    let drawnImage = prediction.image.draw(pose: updatedPose, keypointsMeeting: keypointThrehold)\n    previewView.image = drawnImage\n    updateLayer(pose: updatedPose)\n    lastPrediction = (image: prediction.image, pose: prediction.pose, modifiedPose: updatedPose)\n  }\n}\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t452D8EEC24049CA500E5B147 /* HandPose.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 452D8EEB24049CA500E5B147 /* HandPose.mlmodel */; };\n\t\t45BB898E23E4996300A793CA /* CameraButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BB898D23E4996300A793CA /* CameraButton.swift */; };\n\t\t45BB899023E4A39B00A793CA /* DraggableKeypoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BB898F23E4A39B00A793CA /* DraggableKeypoint.swift */; };\n\t\t45BB899223E4A43200A793CA /* UIImageView+Transformations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BB899123E4A43200A793CA /* UIImageView+Transformations.swift */; };\n\t\t45D66EC223A3F7860036D5D0 /* HandPoseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45D66EC123A3F7860036D5D0 /* HandPoseModel.swift */; };\n\t\t835093982266E79700A81041 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835093972266E79700A81041 /* AppDelegate.swift */; };\n\t\t8350939A2266E79700A81041 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835093992266E79700A81041 /* ViewController.swift */; };\n\t\t8350939D2266E79700A81041 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8350939B2266E79700A81041 /* Main.storyboard */; };\n\t\t8350939F2266E79A00A81041 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8350939E2266E79A00A81041 /* Assets.xcassets */; };\n\t\t835093A22266E79A00A81041 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 835093A02266E79A00A81041 /* LaunchScreen.storyboard */; };\n\t\tC2489EC6276C923D2C20E64B /* Pods_FritzHandPoseEstimationDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C9146E99F3F7FBDC6854F7D /* Pods_FritzHandPoseEstimationDemo.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t0406162FD9C0E9753BC72215 /* Pods-FritzHandPoseEstimationDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzHandPoseEstimationDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzHandPoseEstimationDemo/Pods-FritzHandPoseEstimationDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t04412028C23E81BD0E2D9B82 /* Pods-FritzHandPoseEstimationDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzHandPoseEstimationDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzHandPoseEstimationDemo/Pods-FritzHandPoseEstimationDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t452D8EEB24049CA500E5B147 /* HandPose.mlmodel */ = {isa = PBXFileReference; lastKnownFileType = file.mlmodel; path = HandPose.mlmodel; sourceTree = \"<group>\"; };\n\t\t45BB898D23E4996300A793CA /* CameraButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraButton.swift; sourceTree = \"<group>\"; };\n\t\t45BB898F23E4A39B00A793CA /* DraggableKeypoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggableKeypoint.swift; sourceTree = \"<group>\"; };\n\t\t45BB899123E4A43200A793CA /* UIImageView+Transformations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIImageView+Transformations.swift\"; sourceTree = \"<group>\"; };\n\t\t45D66EC123A3F7860036D5D0 /* HandPoseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HandPoseModel.swift; sourceTree = \"<group>\"; };\n\t\t4C9146E99F3F7FBDC6854F7D /* Pods_FritzHandPoseEstimationDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzHandPoseEstimationDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t5A8D7CE66F17A61DA977138B /* Pods-FritzPoseEstimationDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzPoseEstimationDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzPoseEstimationDemo/Pods-FritzPoseEstimationDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t6A08DD3E86E2A713EEF67E48 /* Pods-FritzPoseEstimationDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzPoseEstimationDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzPoseEstimationDemo/Pods-FritzPoseEstimationDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t835093942266E79700A81041 /* FritzHandPoseEstimationDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzHandPoseEstimationDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t835093972266E79700A81041 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t835093992266E79700A81041 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t8350939C2266E79700A81041 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t8350939E2266E79A00A81041 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t835093A12266E79A00A81041 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t835093A32266E79A00A81041 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t835093912266E79700A81041 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC2489EC6276C923D2C20E64B /* Pods_FritzHandPoseEstimationDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t6B6A0C1CDEA2CB519307802D /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6A08DD3E86E2A713EEF67E48 /* Pods-FritzPoseEstimationDemo.debug.xcconfig */,\n\t\t\t\t5A8D7CE66F17A61DA977138B /* Pods-FritzPoseEstimationDemo.release.xcconfig */,\n\t\t\t\t0406162FD9C0E9753BC72215 /* Pods-FritzHandPoseEstimationDemo.debug.xcconfig */,\n\t\t\t\t04412028C23E81BD0E2D9B82 /* Pods-FritzHandPoseEstimationDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t80F091B9BB57DECF95370E3C /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4C9146E99F3F7FBDC6854F7D /* Pods_FritzHandPoseEstimationDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8350938B2266E79700A81041 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t835093962266E79700A81041 /* FritzHandPoseEstimationDemo */,\n\t\t\t\t835093952266E79700A81041 /* Products */,\n\t\t\t\t6B6A0C1CDEA2CB519307802D /* Pods */,\n\t\t\t\t80F091B9BB57DECF95370E3C /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t\ttabWidth = 2;\n\t\t};\n\t\t835093952266E79700A81041 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t835093942266E79700A81041 /* FritzHandPoseEstimationDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t835093962266E79700A81041 /* FritzHandPoseEstimationDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t835093972266E79700A81041 /* AppDelegate.swift */,\n\t\t\t\t835093992266E79700A81041 /* ViewController.swift */,\n\t\t\t\t8350939B2266E79700A81041 /* Main.storyboard */,\n\t\t\t\t8350939E2266E79A00A81041 /* Assets.xcassets */,\n\t\t\t\t835093A02266E79A00A81041 /* LaunchScreen.storyboard */,\n\t\t\t\t452D8EEB24049CA500E5B147 /* HandPose.mlmodel */,\n\t\t\t\t835093A32266E79A00A81041 /* Info.plist */,\n\t\t\t\t45D66EC123A3F7860036D5D0 /* HandPoseModel.swift */,\n\t\t\t\t45BB898D23E4996300A793CA /* CameraButton.swift */,\n\t\t\t\t45BB898F23E4A39B00A793CA /* DraggableKeypoint.swift */,\n\t\t\t\t45BB899123E4A43200A793CA /* UIImageView+Transformations.swift */,\n\t\t\t);\n\t\t\tpath = FritzHandPoseEstimationDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t835093932266E79700A81041 /* FritzHandPoseEstimationDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 835093A62266E79A00A81041 /* Build configuration list for PBXNativeTarget \"FritzHandPoseEstimationDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tAB259BB30D8015E9D7B7AB83 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t835093902266E79700A81041 /* Sources */,\n\t\t\t\t835093912266E79700A81041 /* Frameworks */,\n\t\t\t\t835093922266E79700A81041 /* Resources */,\n\t\t\t\tF52AF00E29834A62B877F6DC /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzHandPoseEstimationDemo;\n\t\t\tproductName = FritzPoseEstimationDemo;\n\t\t\tproductReference = 835093942266E79700A81041 /* FritzHandPoseEstimationDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t8350938C2266E79700A81041 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1020;\n\t\t\t\tLastUpgradeCheck = 1020;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t835093932266E79700A81041 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 10.2;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 8350938F2266E79700A81041 /* Build configuration list for PBXProject \"FritzPoseEstimationDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 8350938B2266E79700A81041;\n\t\t\tproductRefGroup = 835093952266E79700A81041 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t835093932266E79700A81041 /* FritzHandPoseEstimationDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t835093922266E79700A81041 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t835093A22266E79A00A81041 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t8350939F2266E79A00A81041 /* Assets.xcassets in Resources */,\n\t\t\t\t8350939D2266E79700A81041 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\tAB259BB30D8015E9D7B7AB83 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzHandPoseEstimationDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tF52AF00E29834A62B877F6DC /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzHandPoseEstimationDemo/Pods-FritzHandPoseEstimationDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzHandPoseEstimationDemo/Pods-FritzHandPoseEstimationDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzHandPoseEstimationDemo/Pods-FritzHandPoseEstimationDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t835093902266E79700A81041 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t452D8EEC24049CA500E5B147 /* HandPose.mlmodel in Sources */,\n\t\t\t\t45BB899223E4A43200A793CA /* UIImageView+Transformations.swift in Sources */,\n\t\t\t\t45D66EC223A3F7860036D5D0 /* HandPoseModel.swift in Sources */,\n\t\t\t\t45BB898E23E4996300A793CA /* CameraButton.swift in Sources */,\n\t\t\t\t8350939A2266E79700A81041 /* ViewController.swift in Sources */,\n\t\t\t\t45BB899023E4A39B00A793CA /* DraggableKeypoint.swift in Sources */,\n\t\t\t\t835093982266E79700A81041 /* AppDelegate.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t8350939B2266E79700A81041 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t8350939C2266E79700A81041 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t835093A02266E79A00A81041 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t835093A12266E79A00A81041 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t835093A42266E79A00A81041 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t835093A52266E79A00A81041 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t835093A72266E79A00A81041 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 0406162FD9C0E9753BC72215 /* Pods-FritzHandPoseEstimationDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzHandPoseEstimationDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzHandPoseEstimationDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t835093A82266E79A00A81041 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 04412028C23E81BD0E2D9B82 /* Pods-FritzHandPoseEstimationDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzHandPoseEstimationDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzHandPoseEstimationDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t8350938F2266E79700A81041 /* Build configuration list for PBXProject \"FritzPoseEstimationDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t835093A42266E79A00A81041 /* Debug */,\n\t\t\t\t835093A52266E79A00A81041 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t835093A62266E79A00A81041 /* Build configuration list for PBXNativeTarget \"FritzHandPoseEstimationDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t835093A72266E79A00A81041 /* Debug */,\n\t\t\t\t835093A82266E79A00A81041 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 8350938C2266E79700A81041 /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/FritzHandPoseEstimationDemo.xcodeproj/xcshareddata/xcschemes/FritzHandPoseEstimationDemo.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1130\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"835093932266E79700A81041\"\n               BuildableName = \"FritzHandPoseEstimationDemo.app\"\n               BlueprintName = \"FritzHandPoseEstimationDemo\"\n               ReferencedContainer = \"container:FritzHandPoseEstimationDemo.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"835093932266E79700A81041\"\n            BuildableName = \"FritzHandPoseEstimationDemo.app\"\n            BlueprintName = \"FritzHandPoseEstimationDemo\"\n            ReferencedContainer = \"container:FritzHandPoseEstimationDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"835093932266E79700A81041\"\n            BuildableName = \"FritzHandPoseEstimationDemo.app\"\n            BlueprintName = \"FritzHandPoseEstimationDemo\"\n            ReferencedContainer = \"container:FritzHandPoseEstimationDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzHandPoseEstimationDemo' do\n  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks\n  use_frameworks!\n\n  pod 'Fritz', '6.1.1'\nend\n"
  },
  {
    "path": "iOS/FritzHandPoseEstimationDemo/README.md",
    "content": "# Pose Estimation\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use the Pose Estimation API by Fritz in order to identify and track the movement of different human poses.\n\nFor the full tutorial, visit [our post on Heartbeat](https://heartbeat.fritz.ai/pose-estimation-on-ios-with-fritz-60c8e5f7d195).\n\n<img src=\"images/pose_estimation_ios.jpg\" width=\"250\" />\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzPoseEstimationDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzPoseEstimationDemo`\n\n```\ncd fritz-examples/iOS/FritzPoseEstimationDemo\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzPoseEstimationDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/FritzImageLabelingDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzImageLabelingDemo\n//\n//  Created by Steven Yeung on 10/23/19.\n//  Copyright © 2019 Fritz AI. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        // Override point for customization after application launch.\n        FritzCore.configure()\n        return true\n    }\n\n    func applicationWillResignActive(_ application: UIApplication) {\n        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n    }\n\n    func applicationDidEnterBackground(_ application: UIApplication) {\n        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n    }\n\n    func applicationWillEnterForeground(_ application: UIApplication) {\n        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n    }\n\n    func applicationDidBecomeActive(_ application: UIApplication) {\n        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n    }\n\n    func applicationWillTerminate(_ application: UIApplication) {\n        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n    }\n\n\n}\n"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/FritzImageLabelingDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/FritzImageLabelingDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/FritzImageLabelingDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" xcode11CocoaTouchSystemColor=\"systemBackgroundColor\" cocoaTouchSystemColor=\"whiteColor\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/FritzImageLabelingDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"16096\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"bXN-2g-eap\">\n    <device id=\"retina4_7\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"16086\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Image Labeling-->\n        <scene sceneID=\"gga-fV-gqh\">\n            <objects>\n                <viewController id=\"bXN-2g-eap\" userLabel=\"Image Labeling\" customClass=\"ViewController\" customModule=\"FritzImageLabelingDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"DTw-l1-0kj\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"XOI-62-OJZ\" userLabel=\"Model Version Label\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"595\" width=\"377\" height=\"15\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"7ym-Xz-hjF\" userLabel=\"Model ID Label\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"618\" width=\"377\" height=\"15\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"2CS-If-s4d\" userLabel=\"FPS Label\">\n                                <rect key=\"frame\" x=\"88\" y=\"641\" width=\"200\" height=\"15.5\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <size key=\"shadowOffset\" width=\"1\" height=\"1\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"onp-ok-7O5\">\n                                <rect key=\"frame\" x=\"47\" y=\"86\" width=\"280\" height=\"33\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"26\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.33333333329999998\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"rNJ-ef-VJT\" userLabel=\"Confidence\">\n                                <rect key=\"frame\" x=\"169.5\" y=\"127\" width=\"33\" height=\"16\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"13\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                            </label>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <constraints>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"leading\" secondItem=\"2CS-If-s4d\" secondAttribute=\"leading\" id=\"2jA-7n-H7f\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"centerX\" secondItem=\"7ym-Xz-hjF\" secondAttribute=\"centerX\" id=\"7PA-r8-ubr\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"centerX\" secondItem=\"DTw-l1-0kj\" secondAttribute=\"centerX\" id=\"96p-ZT-MSS\"/>\n                            <constraint firstItem=\"rNJ-ef-VJT\" firstAttribute=\"top\" secondItem=\"onp-ok-7O5\" secondAttribute=\"bottom\" constant=\"8\" id=\"HK8-yQ-AGD\"/>\n                            <constraint firstItem=\"onp-ok-7O5\" firstAttribute=\"centerX\" secondItem=\"XOI-62-OJZ\" secondAttribute=\"centerX\" constant=\"-1.5\" id=\"Lhz-xE-Kzu\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"top\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"top\" constant=\"551\" id=\"OLh-lr-EBf\"/>\n                            <constraint firstItem=\"onp-ok-7O5\" firstAttribute=\"leading\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"leading\" constant=\"47\" id=\"V8S-RG-YXR\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"leading\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"leading\" id=\"ayJ-DJ-ZIk\"/>\n                            <constraint firstItem=\"onp-ok-7O5\" firstAttribute=\"top\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"top\" constant=\"42\" id=\"d8k-vq-ibk\"/>\n                            <constraint firstItem=\"2CS-If-s4d\" firstAttribute=\"top\" secondItem=\"7ym-Xz-hjF\" secondAttribute=\"bottom\" constant=\"8\" id=\"hzG-gT-3qI\"/>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"top\" secondItem=\"XOI-62-OJZ\" secondAttribute=\"bottom\" constant=\"8\" id=\"j0W-WU-A8M\"/>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"trailing\" secondItem=\"2CS-If-s4d\" secondAttribute=\"trailing\" id=\"m1R-Jm-BoQ\"/>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"leading\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"leading\" id=\"t9z-e3-fYl\"/>\n                            <constraint firstItem=\"onp-ok-7O5\" firstAttribute=\"centerX\" secondItem=\"rNJ-ef-VJT\" secondAttribute=\"centerX\" id=\"u6t-jQ-W9U\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"CgA-h6-NiT\"/>\n                    </view>\n                    <navigationItem key=\"navigationItem\" title=\"LABEL IMAGES\" id=\"vW0-XC-6S1\" userLabel=\"LABEL IMAGES\"/>\n                    <simulatedNavigationBarMetrics key=\"simulatedTopBarMetrics\" prompted=\"NO\"/>\n                    <connections>\n                        <outlet property=\"cameraView\" destination=\"DTw-l1-0kj\" id=\"dCi-70-bYu\"/>\n                        <outlet property=\"confidenceLabel\" destination=\"rNJ-ef-VJT\" id=\"LeE-HY-2xj\"/>\n                        <outlet property=\"fpsLabel\" destination=\"2CS-If-s4d\" id=\"LIz-l8-ftX\"/>\n                        <outlet property=\"modelIdLabel\" destination=\"7ym-Xz-hjF\" id=\"Lya-8E-cgA\"/>\n                        <outlet property=\"modelVersionLabel\" destination=\"XOI-62-OJZ\" id=\"vID-DU-bFc\"/>\n                        <outlet property=\"predictionLabel\" destination=\"onp-ok-7O5\" id=\"82f-GN-LO1\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"pm4-ZZ-n7f\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"16.800000000000001\" y=\"62.518740629685162\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/FritzImageLabelingDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string>For inference</string>\n\t<key>UIApplicationSceneManifest</key>\n\t<dict>\n\t\t<key>UIApplicationSupportsMultipleScenes</key>\n\t\t<false/>\n\t\t<key>UISceneConfigurations</key>\n\t\t<dict>\n\t\t\t<key>UIWindowSceneSessionRoleApplication</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>UISceneConfigurationName</key>\n\t\t\t\t\t<string>Default Configuration</string>\n\t\t\t\t\t<key>UISceneDelegateClassName</key>\n\t\t\t\t\t<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>\n\t\t\t\t\t<key>UISceneStoryboardFile</key>\n\t\t\t\t\t<string>Main</string>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t</dict>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/FritzImageLabelingDemo/SceneDelegate.swift",
    "content": "//\n//  SceneDelegate.swift\n//  FritzImageLabelingDemo\n//\n//  Created by Steven Yeung on 10/23/19.\n//  Copyright © 2019 Fritz AI. All rights reserved.\n//\n\nimport UIKit\n\nclass SceneDelegate: UIResponder, UIWindowSceneDelegate {\n\n  var window: UIWindow?\n\n\n  func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {\n    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.\n    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.\n    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).\n    guard let _ = (scene as? UIWindowScene) else { return }\n  }\n\n  func sceneDidDisconnect(_ scene: UIScene) {\n    // Called as the scene is being released by the system.\n    // This occurs shortly after the scene enters the background, or when its session is discarded.\n    // Release any resources associated with this scene that can be re-created the next time the scene connects.\n    // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).\n  }\n\n  func sceneDidBecomeActive(_ scene: UIScene) {\n    // Called when the scene has moved from an inactive state to an active state.\n    // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.\n  }\n\n  func sceneWillResignActive(_ scene: UIScene) {\n    // Called when the scene will move from an active state to an inactive state.\n    // This may occur due to temporary interruptions (ex. an incoming phone call).\n  }\n\n  func sceneWillEnterForeground(_ scene: UIScene) {\n    // Called as the scene transitions from the background to the foreground.\n    // Use this method to undo the changes made on entering the background.\n  }\n\n  func sceneDidEnterBackground(_ scene: UIScene) {\n    // Called as the scene transitions from the foreground to the background.\n    // Use this method to save data, release shared resources, and store enough scene-specific state information\n    // to restore the scene back to its current state.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/FritzImageLabelingDemo/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  FritzImageLabelingDemo\n//\n//  Created by Steven Yeung on 10/23/19.\n//  Copyright © 2019 Steven Yeung. All rights reserved.\n//\n\nimport UIKit\nimport CoreML\nimport Vision\nimport AVFoundation\nimport Accelerate\nimport Fritz\n\nextension Double {\n  func format(f: String) -> String {\n    return String(format: \"%\\(f)f\", self)\n  }\n}\n\n\nclass ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {\n  @IBOutlet weak var cameraView: UIView!\n  @IBOutlet weak var fpsLabel: UILabel!\n  @IBOutlet weak var modelIdLabel: UILabel!\n  @IBOutlet weak var modelVersionLabel: UILabel!\n\n  @IBOutlet weak var predictionLabel: UILabel! {\n      didSet { predictionLabel.text = \"Loading... 🚀\" }\n  }\n\n  @IBOutlet weak var confidenceLabel: UILabel! {\n      didSet { confidenceLabel.text = nil }\n  }\n\n  var lastExecution = Date()\n  var screenHeight: Double?\n  var screenWidth: Double?\n\n  // Use a pre-trained image labeling model from Fritz AI.\n  lazy var visionModel = FritzVisionLabelModelFast()\n\n  // To use your own custom image labeling model, follow the instructions here:\n  // https://docs.fritz.ai/develop/vision/image-labeling/ios.html\n  // lazy var visionModel = FritzVisionLabelPredictor(model: YourModelName().fritzModel())\n\n  // Only show labels above a certain confidence threshold. For new models in development,\n  // you may need to lower this to see predictions. As you improve your model, you can\n  // increase this reduce false positives.\n  let confidenceThreshold = 0.1\n\n  private lazy var cameraLayer: AVCaptureVideoPreviewLayer = {\n    let layer = AVCaptureVideoPreviewLayer(session: self.captureSession)\n    layer.videoGravity = .resizeAspectFill\n    return layer\n  }()\n\n  private lazy var captureSession: AVCaptureSession = {\n    let session = AVCaptureSession()\n\n    guard\n      let backCamera = AVCaptureDevice.default(\n        .builtInWideAngleCamera,\n        for: .video,\n        position: .back\n      ),\n      let input = try? AVCaptureDeviceInput(device: backCamera)\n      else { return session }\n    session.addInput(input)\n    return session\n  }()\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n    self.cameraView?.layer.addSublayer(self.cameraLayer)\n    // Setup model labels\n    self.cameraView?.bringSubviewToFront(self.fpsLabel)\n    self.fpsLabel.textAlignment = .center\n    self.cameraView?.bringSubviewToFront(self.modelIdLabel)\n    self.modelIdLabel.textAlignment = .center\n    self.cameraView?.bringSubviewToFront(self.modelVersionLabel)\n    self.modelVersionLabel.textAlignment = .center\n\n    // Setup prediction labels\n    self.cameraView?.bringSubviewToFront(self.predictionLabel)\n    self.predictionLabel.textAlignment = .center\n    self.cameraView?.bringSubviewToFront(self.confidenceLabel)\n    self.confidenceLabel.textAlignment = .center\n\n    // Setup video capture.\n    let videoOutput = AVCaptureVideoDataOutput()\n    videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: \"MyQueue\"))\n    self.captureSession.addOutput(videoOutput)\n    self.captureSession.startRunning()\n\n    screenWidth = Double(view.frame.width)\n    screenHeight = Double(view.frame.height)\n  }\n\n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n    cameraLayer.frame = cameraView.layer.bounds\n  }\n\n  override func viewDidLayoutSubviews() {\n    super.viewDidLayoutSubviews()\n    self.cameraLayer.frame = self.cameraView?.bounds ?? .zero\n  }\n\n  override func didReceiveMemoryWarning() {\n    super.didReceiveMemoryWarning()\n    // Dispose of any resources that can be recreated.\n  }\n\n  func updateLabels() {\n    let thisExecution = Date()\n    let executionTime = thisExecution.timeIntervalSince(self.lastExecution)\n    let framesPerSecond: Double = 1 / executionTime\n    self.lastExecution = thisExecution\n\n    DispatchQueue.main.async {\n      self.fpsLabel.text = \"FPS: \\(framesPerSecond.format(f: \".3\"))\"\n      self.modelIdLabel.text = \"Model ID: \\(self.visionModel.managedModel.activeModelConfig.identifier)\"\n      self.modelVersionLabel.text = \"Active Version: \\(self.visionModel.managedModel.activeModelConfig.version)\"\n    }\n  }\n\n  func captureOutput(\n    _ output: AVCaptureOutput,\n    didOutput sampleBuffer: CMSampleBuffer,\n    from connection: AVCaptureConnection) {\n    let image = FritzVisionImage(sampleBuffer: sampleBuffer, connection: connection)\n    let options = FritzVisionLabelModelOptions()\n    options.threshold = confidenceThreshold\n\n\n    guard let results = try? visionModel.predict(image, options: options) else { return }\n\n    // Display results\n    if results.count > 0 {\n      let observation = results[0]\n      let confidence = Int(observation.confidence * 100)\n      self.setResult(text: observation.label, confidence: confidence)\n    } else {\n      self.setNoResult()\n    }\n\n    // To record predictions and send data back to Fritz AI via the Data Collection System, use the predictors's record method.\n    // In addition to the input image, predicted model results can be collected as well as user-modified annotations.\n    // This allows developers to both gather data on model performance and have users collect additional ground truth data for future model retraining.\n    // Note, the Data Collection System is only available on paid plans.\n    // visionModel.record(image, predicted: results, modified: nil)\n\n    updateLabels()\n  }\n\n  private func setResult(text: String, confidence: Int) {\n      DispatchQueue.main.async {\n          self.predictionLabel.text = text.capitalized\n          self.confidenceLabel.text = self.confidenceString(confidence)\n          self.confidenceLabel.textColor = self.confidenceColor(confidence)\n      }\n  }\n\n  private func setNoResult() {\n      DispatchQueue.main.async {\n          self.predictionLabel.text = \"?????\"\n          self.confidenceLabel.text = \"\"\n      }\n  }\n\n  private func confidenceString(_ value: Int) -> String {\n      return \"\\(value)%\"\n  }\n\n  private func confidenceColor(_ value: Int) -> UIColor {\n      switch value {\n      case ...33: return .red\n      case 34...66: return .orange\n      default: return .green\n      }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/FritzImageLabelingDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t457E45E52447915E001FE3E2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457E45DB2447915E001FE3E2 /* ViewController.swift */; };\n\t\t457E45E72447915E001FE3E2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 457E45DD2447915E001FE3E2 /* Assets.xcassets */; };\n\t\t457E45E82447915E001FE3E2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 457E45DE2447915E001FE3E2 /* LaunchScreen.storyboard */; };\n\t\t457E45E92447915E001FE3E2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 457E45E02447915E001FE3E2 /* Main.storyboard */; };\n\t\t457E45EA2447915E001FE3E2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457E45E22447915E001FE3E2 /* AppDelegate.swift */; };\n\t\t457E45EF24479B7B001FE3E2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457E45E42447915E001FE3E2 /* SceneDelegate.swift */; };\n\t\t8BE269F8148FB99D872C5EA4 /* Pods_FritzImageLabelingDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F381606B319F0DEC8876A40 /* Pods_FritzImageLabelingDemo.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t0F381606B319F0DEC8876A40 /* Pods_FritzImageLabelingDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzImageLabelingDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t3B3BCBFA2360AE3600898CF5 /* FritzImageLabelingDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzImageLabelingDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t42618F0E7610810E0D5B537C /* Pods-FritzImageLabelingDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzImageLabelingDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzImageLabelingDemo/Pods-FritzImageLabelingDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t457E45DB2447915E001FE3E2 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t457E45DD2447915E001FE3E2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t457E45DF2447915E001FE3E2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t457E45E12447915E001FE3E2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t457E45E22447915E001FE3E2 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t457E45E32447915E001FE3E2 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t457E45E42447915E001FE3E2 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = \"<group>\"; };\n\t\tD05A08F5B7DDA21E19CCCFBE /* Pods-FritzImageLabelingDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzImageLabelingDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzImageLabelingDemo/Pods-FritzImageLabelingDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t3B3BCBF72360AE3600898CF5 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8BE269F8148FB99D872C5EA4 /* Pods_FritzImageLabelingDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t3B3BCBF12360AE3600898CF5 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t457E45DA2447915E001FE3E2 /* FritzImageLabelingDemo */,\n\t\t\t\t3B3BCBFB2360AE3600898CF5 /* Products */,\n\t\t\t\tC4BF6B27527268175F03B925 /* Pods */,\n\t\t\t\tD9D25D5E90756A46542316FD /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B3BCBFB2360AE3600898CF5 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B3BCBFA2360AE3600898CF5 /* FritzImageLabelingDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t457E45DA2447915E001FE3E2 /* FritzImageLabelingDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t457E45DB2447915E001FE3E2 /* ViewController.swift */,\n\t\t\t\t457E45DD2447915E001FE3E2 /* Assets.xcassets */,\n\t\t\t\t457E45DE2447915E001FE3E2 /* LaunchScreen.storyboard */,\n\t\t\t\t457E45E02447915E001FE3E2 /* Main.storyboard */,\n\t\t\t\t457E45E22447915E001FE3E2 /* AppDelegate.swift */,\n\t\t\t\t457E45E32447915E001FE3E2 /* Info.plist */,\n\t\t\t\t457E45E42447915E001FE3E2 /* SceneDelegate.swift */,\n\t\t\t);\n\t\t\tpath = FritzImageLabelingDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC4BF6B27527268175F03B925 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tD05A08F5B7DDA21E19CCCFBE /* Pods-FritzImageLabelingDemo.debug.xcconfig */,\n\t\t\t\t42618F0E7610810E0D5B537C /* Pods-FritzImageLabelingDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tD9D25D5E90756A46542316FD /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t0F381606B319F0DEC8876A40 /* Pods_FritzImageLabelingDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t3B3BCBF92360AE3600898CF5 /* FritzImageLabelingDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 3B3BCC0E2360AE3700898CF5 /* Build configuration list for PBXNativeTarget \"FritzImageLabelingDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t41EDD3C7B775CAB36AA94CCD /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t3B3BCBF62360AE3600898CF5 /* Sources */,\n\t\t\t\t3B3BCBF72360AE3600898CF5 /* Frameworks */,\n\t\t\t\t3B3BCBF82360AE3600898CF5 /* Resources */,\n\t\t\t\t94092D4CF10BB59E813F65F1 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzImageLabelingDemo;\n\t\t\tproductName = FritzObjectDetectionDemo;\n\t\t\tproductReference = 3B3BCBFA2360AE3600898CF5 /* FritzImageLabelingDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t3B3BCBF22360AE3600898CF5 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1110;\n\t\t\t\tLastUpgradeCheck = 1110;\n\t\t\t\tORGANIZATIONNAME = \"Fritz AI\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t3B3BCBF92360AE3600898CF5 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 11.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 3B3BCBF52360AE3600898CF5 /* Build configuration list for PBXProject \"FritzObjectDetectionDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 3B3BCBF12360AE3600898CF5;\n\t\t\tproductRefGroup = 3B3BCBFB2360AE3600898CF5 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t3B3BCBF92360AE3600898CF5 /* FritzImageLabelingDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t3B3BCBF82360AE3600898CF5 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t457E45E82447915E001FE3E2 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t457E45E72447915E001FE3E2 /* Assets.xcassets in Resources */,\n\t\t\t\t457E45E92447915E001FE3E2 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t41EDD3C7B775CAB36AA94CCD /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzImageLabelingDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t94092D4CF10BB59E813F65F1 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzImageLabelingDemo/Pods-FritzImageLabelingDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzImageLabelingDemo/Pods-FritzImageLabelingDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzImageLabelingDemo/Pods-FritzImageLabelingDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t3B3BCBF62360AE3600898CF5 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t457E45EF24479B7B001FE3E2 /* SceneDelegate.swift in Sources */,\n\t\t\t\t457E45EA2447915E001FE3E2 /* AppDelegate.swift in Sources */,\n\t\t\t\t457E45E52447915E001FE3E2 /* ViewController.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t457E45DE2447915E001FE3E2 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t457E45DF2447915E001FE3E2 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t457E45E02447915E001FE3E2 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t457E45E12447915E001FE3E2 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t3B3BCC0C2360AE3700898CF5 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 13.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t3B3BCC0D2360AE3700898CF5 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 13.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t3B3BCC0F2360AE3700898CF5 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = D05A08F5B7DDA21E19CCCFBE /* Pods-FritzImageLabelingDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/FritzImageLabelingDemo/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzImageLabelingDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t3B3BCC102360AE3700898CF5 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 42618F0E7610810E0D5B537C /* Pods-FritzImageLabelingDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/FritzImageLabelingDemo/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzImageLabelingDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t3B3BCBF52360AE3600898CF5 /* Build configuration list for PBXProject \"FritzObjectDetectionDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t3B3BCC0C2360AE3700898CF5 /* Debug */,\n\t\t\t\t3B3BCC0D2360AE3700898CF5 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t3B3BCC0E2360AE3700898CF5 /* Build configuration list for PBXNativeTarget \"FritzImageLabelingDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t3B3BCC0F2360AE3700898CF5 /* Debug */,\n\t\t\t\t3B3BCC102360AE3700898CF5 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 3B3BCBF22360AE3600898CF5 /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/FritzImageLabelingDemo.xcodeproj/xcshareddata/xcschemes/FritzImageLabelingDemo.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1140\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"3B3BCBF92360AE3600898CF5\"\n               BuildableName = \"FritzImageLabelingDemo.app\"\n               BlueprintName = \"FritzImageLabelingDemo\"\n               ReferencedContainer = \"container:FritzImageLabelingDemo.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"3B3BCBF92360AE3600898CF5\"\n            BuildableName = \"FritzImageLabelingDemo.app\"\n            BlueprintName = \"FritzImageLabelingDemo\"\n            ReferencedContainer = \"container:FritzImageLabelingDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"3B3BCBF92360AE3600898CF5\"\n            BuildableName = \"FritzImageLabelingDemo.app\"\n            BlueprintName = \"FritzImageLabelingDemo\"\n            ReferencedContainer = \"container:FritzImageLabelingDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzImageLabelingDemo' do\n  use_frameworks!\n\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionLabelModel/Fast'\n\nend\n"
  },
  {
    "path": "iOS/FritzImageLabelingDemo/README.md",
    "content": "# Image Labeling\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use the Image Labeling API by Fritz in order to assign labels to images based on their content.\n\nFor the full tutorial, visit [our post on Heartbeat](https://heartbeat.fritz.ai/pose-estimation-on-ios-with-fritz-60c8e5f7d195).\n\n<img src=\"images/image_labeling_ios.jpg\" width=\"250\" />\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzImageLabelingDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzImageLabelingDemo`\n\n```\ncd fritz-examples/iOS/FritzImageLabelingDemo\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzImageLabelingDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to our [Help Center](https://docs.fritz.ai/help-center/index.html?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/FritzImageSegmentationDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzImageSegmentationDemo\n//\n//  Created by Christopher Kelly on 10/9/18.\n//  Copyright © 2018 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        // Override point for customization after application launch.\n        FritzCore.configure()\n        return true\n    }\n\n    func applicationWillResignActive(_ application: UIApplication) {\n        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n    }\n\n    func applicationDidEnterBackground(_ application: UIApplication) {\n        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n    }\n\n    func applicationWillEnterForeground(_ application: UIApplication) {\n        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n    }\n\n    func applicationDidBecomeActive(_ application: UIApplication) {\n        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n    }\n\n    func applicationWillTerminate(_ application: UIApplication) {\n        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n    }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/FritzImageSegmentationDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/FritzImageSegmentationDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/FritzImageSegmentationDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/FritzImageSegmentationDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/FritzImageSegmentationDemo/CustomBlurView.swift",
    "content": "//\n//  CustomBlurView.swift\n//  FritzImageSegmentationDemo\n//\n//  Created by Collin Hundley on 1/15/16.\n//  https://gist.github.com/afshin-hoseini/9c370268ffa4c43b0696\n//\nimport UIKit\n\npublic class CustomBlurView: UIVisualEffectView {\n\n    private let blurEffect: UIBlurEffect\n    public var blurRadius: CGFloat {\n        return blurEffect.value(forKeyPath: \"blurRadius\") as! CGFloat\n    }\n\n    public convenience init() {\n        self.init(withRadius: 0)\n    }\n\n    public init(withRadius radius: CGFloat) {\n        let customBlurClass: AnyObject.Type = NSClassFromString(\"_UICustomBlurEffect\")!\n        let customBlurObject: NSObject.Type = customBlurClass as! NSObject.Type\n        self.blurEffect = customBlurObject.init() as! UIBlurEffect\n        self.blurEffect.setValue(1.0, forKeyPath: \"scale\")\n        self.blurEffect.setValue(radius, forKeyPath: \"blurRadius\")\n        super.init(effect: radius == 0 ? nil : self.blurEffect)\n    }\n\n    required public init?(coder aDecoder: NSCoder) {\n        fatalError(\"init(coder:) has not been implemented\")\n    }\n\n    public func setBlurRadius(radius: CGFloat) {\n        guard radius != blurRadius else {\n            return\n        }\n        blurEffect.setValue(radius, forKeyPath: \"blurRadius\")\n        self.effect = blurEffect\n    }\n}\n"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/FritzImageSegmentationDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string>For processing images from the device camera</string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/FritzImageSegmentationDemo/ViewController.swift",
    "content": "import UIKit\nimport AVFoundation\nimport Fritz\n\nclass ViewController: UIViewController {\n\n  var cameraView: UIImageView!\n  var maskView: UIImageView!\n  var backgroundView: UIImageView!\n\n  private lazy var visionModel = FritzVisionPeopleSegmentationModelFast()\n\n  private lazy var cameraSession = AVCaptureSession()\n  private let sessionQueue = DispatchQueue(label: \"com.fritzdemo.imagesegmentation.session\")\n  private let captureQueue = DispatchQueue(label: \"com.fritzdemo.imagesegmentation.capture\", qos: DispatchQoS.userInitiated)\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    cameraView = UIImageView(frame: view.bounds)\n    cameraView.contentMode = .scaleAspectFill\n\n    maskView = UIImageView(frame: view.bounds)\n    maskView.contentMode = .scaleAspectFill\n\n    cameraView.mask = maskView\n\n    backgroundView = UIImageView(frame: view.bounds)\n    backgroundView.contentMode = .scaleAspectFill\n\n    let blurView = CustomBlurView(withRadius: 6.0)\n    blurView.frame = self.cameraView.bounds\n\n    backgroundView.addSubview(blurView)\n\n    view.addSubview(backgroundView)\n    view.addSubview(cameraView)\n\n    // Setup camera\n    guard let device = AVCaptureDevice.default(for: .video),\n      let input = try? AVCaptureDeviceInput(device: device) else { return }\n\n    let output = AVCaptureVideoDataOutput()\n\n    // Configure pixelBuffer format for use in model\n    output.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA as UInt32]\n    output.alwaysDiscardsLateVideoFrames = true\n    output.setSampleBufferDelegate(self, queue: captureQueue)\n\n    sessionQueue.async {\n      self.cameraSession.beginConfiguration()\n      self.cameraSession.addInput(input)\n      self.cameraSession.addOutput(output)\n      self.cameraSession.commitConfiguration()\n    }\n  }\n\n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n\n    sessionQueue.async {\n      self.cameraSession.startRunning()\n    }\n  }\n}\n\nextension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate {\n\n  /// Scores output from model greater than this value will be set as 1.\n  /// Lowering this value will make the mask more intense for lower confidence values.\n  var clippingScoresAbove: Double { return 0.7 }\n\n  /// Values lower than this value will not appear in the mask.\n  var zeroingScoresBelow: Double { return 0.25 }\n\n  func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {\n    let image = FritzVisionImage(sampleBuffer: sampleBuffer, connection: connection)\n\n    guard let result = try? visionModel.predict(image),\n      let rotatedImage = image.rotate()\n      else { return }\n\n    let background = UIImage(pixelBuffer: rotatedImage)\n\n    let mask = result.buildSingleClassMask(\n      forClass: FritzVisionPeopleClass.person,\n      clippingScoresAbove: clippingScoresAbove,\n      zeroingScoresBelow: zeroingScoresBelow\n    )\n\n    DispatchQueue.main.async {\n      self.cameraView.image = background\n      self.maskView.image = mask\n      self.backgroundView.image = background\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/FritzImageSegmentationDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t33D68F0AA3D533CA117ABA11 /* Pods_FritzImageSegmentationDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CDDD5B65086AE2C6FCA1D47 /* Pods_FritzImageSegmentationDemo.framework */; };\n\t\t830D47BD216CF3530003DE84 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 830D47BC216CF3530003DE84 /* AppDelegate.swift */; };\n\t\t830D47BF216CF3530003DE84 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 830D47BE216CF3530003DE84 /* ViewController.swift */; };\n\t\t830D47C2216CF3530003DE84 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 830D47C0216CF3530003DE84 /* Main.storyboard */; };\n\t\t830D47C4216CF3530003DE84 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 830D47C3216CF3530003DE84 /* Assets.xcassets */; };\n\t\t830D47C7216CF3530003DE84 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 830D47C5216CF3530003DE84 /* LaunchScreen.storyboard */; };\n\t\t83446F40216D727600B87ED3 /* CustomBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83446F3F216D727600B87ED3 /* CustomBlurView.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t830D47B9216CF3530003DE84 /* FritzImageSegmentationDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzImageSegmentationDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t830D47BC216CF3530003DE84 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t830D47BE216CF3530003DE84 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t830D47C1216CF3530003DE84 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t830D47C3216CF3530003DE84 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t830D47C6216CF3530003DE84 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t830D47C8216CF3530003DE84 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t83446F3F216D727600B87ED3 /* CustomBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomBlurView.swift; sourceTree = \"<group>\"; };\n\t\t8CDDD5B65086AE2C6FCA1D47 /* Pods_FritzImageSegmentationDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzImageSegmentationDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tE7EF8C04E604E27DBB0B8572 /* Pods-FritzImageSegmentationDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzImageSegmentationDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzImageSegmentationDemo/Pods-FritzImageSegmentationDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tED261265C7C0872D6EDDE954 /* Pods-FritzImageSegmentationDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzImageSegmentationDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzImageSegmentationDemo/Pods-FritzImageSegmentationDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t830D47B6216CF3530003DE84 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t33D68F0AA3D533CA117ABA11 /* Pods_FritzImageSegmentationDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t830D47B0216CF3530003DE84 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t830D47BB216CF3530003DE84 /* FritzImageSegmentationDemo */,\n\t\t\t\t830D47BA216CF3530003DE84 /* Products */,\n\t\t\t\tE80DAFCE9CAD317B0AADF19B /* Pods */,\n\t\t\t\tB96B639D589745193082A0A7 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t830D47BA216CF3530003DE84 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t830D47B9216CF3530003DE84 /* FritzImageSegmentationDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t830D47BB216CF3530003DE84 /* FritzImageSegmentationDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t830D47BC216CF3530003DE84 /* AppDelegate.swift */,\n\t\t\t\t830D47BE216CF3530003DE84 /* ViewController.swift */,\n\t\t\t\t83446F3F216D727600B87ED3 /* CustomBlurView.swift */,\n\t\t\t\t830D47C0216CF3530003DE84 /* Main.storyboard */,\n\t\t\t\t830D47C3216CF3530003DE84 /* Assets.xcassets */,\n\t\t\t\t830D47C5216CF3530003DE84 /* LaunchScreen.storyboard */,\n\t\t\t\t830D47C8216CF3530003DE84 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzImageSegmentationDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tB96B639D589745193082A0A7 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t8CDDD5B65086AE2C6FCA1D47 /* Pods_FritzImageSegmentationDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tE80DAFCE9CAD317B0AADF19B /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tED261265C7C0872D6EDDE954 /* Pods-FritzImageSegmentationDemo.debug.xcconfig */,\n\t\t\t\tE7EF8C04E604E27DBB0B8572 /* Pods-FritzImageSegmentationDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t830D47B8216CF3530003DE84 /* FritzImageSegmentationDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 830D47D6216CF3530003DE84 /* Build configuration list for PBXNativeTarget \"FritzImageSegmentationDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tC9497E339FE0479F9C03BBC9 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t830D47B5216CF3530003DE84 /* Sources */,\n\t\t\t\t830D47B6216CF3530003DE84 /* Frameworks */,\n\t\t\t\t830D47B7216CF3530003DE84 /* Resources */,\n\t\t\t\tF799D23F61F3FAECCF8959DB /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzImageSegmentationDemo;\n\t\t\tproductName = FritzImageSegmentationDemo;\n\t\t\tproductReference = 830D47B9216CF3530003DE84 /* FritzImageSegmentationDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t830D47B1216CF3530003DE84 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1000;\n\t\t\t\tLastUpgradeCheck = 1210;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t830D47B8216CF3530003DE84 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 10.0;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 830D47B4216CF3530003DE84 /* Build configuration list for PBXProject \"FritzImageSegmentationDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 830D47B0216CF3530003DE84;\n\t\t\tproductRefGroup = 830D47BA216CF3530003DE84 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t830D47B8216CF3530003DE84 /* FritzImageSegmentationDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t830D47B7216CF3530003DE84 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t830D47C7216CF3530003DE84 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t830D47C4216CF3530003DE84 /* Assets.xcassets in Resources */,\n\t\t\t\t830D47C2216CF3530003DE84 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\tC9497E339FE0479F9C03BBC9 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzImageSegmentationDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tF799D23F61F3FAECCF8959DB /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzImageSegmentationDemo/Pods-FritzImageSegmentationDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzImageSegmentationDemo/Pods-FritzImageSegmentationDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzImageSegmentationDemo/Pods-FritzImageSegmentationDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t830D47B5216CF3530003DE84 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t830D47BF216CF3530003DE84 /* ViewController.swift in Sources */,\n\t\t\t\t83446F40216D727600B87ED3 /* CustomBlurView.swift in Sources */,\n\t\t\t\t830D47BD216CF3530003DE84 /* AppDelegate.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t830D47C0216CF3530003DE84 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t830D47C1216CF3530003DE84 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t830D47C5216CF3530003DE84 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t830D47C6216CF3530003DE84 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t830D47D4216CF3530003DE84 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t830D47D5216CF3530003DE84 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t830D47D7216CF3530003DE84 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = ED261265C7C0872D6EDDE954 /* Pods-FritzImageSegmentationDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzImageSegmentationDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzImageSegmentationDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t830D47D8216CF3530003DE84 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = E7EF8C04E604E27DBB0B8572 /* Pods-FritzImageSegmentationDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzImageSegmentationDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzImageSegmentationDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t830D47B4216CF3530003DE84 /* Build configuration list for PBXProject \"FritzImageSegmentationDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t830D47D4216CF3530003DE84 /* Debug */,\n\t\t\t\t830D47D5216CF3530003DE84 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t830D47D6216CF3530003DE84 /* Build configuration list for PBXNativeTarget \"FritzImageSegmentationDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t830D47D7216CF3530003DE84 /* Debug */,\n\t\t\t\t830D47D8216CF3530003DE84 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 830D47B1216CF3530003DE84 /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzImageSegmentationDemo' do\n  use_frameworks!\n\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionSegmentationModel/People/Fast'\nend\n"
  },
  {
    "path": "iOS/FritzImageSegmentationDemo/README.md",
    "content": "# Portrait Mode with People Segmentation\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use the People Segmentation API by Fritz in order to build a portrait mode feature that blurs out the background and focuses on the people in each frame.\n\nFor the full tutorial, visit [our post on Heartbeat](https://heartbeat.fritz.ai/building-an-image-segmentation-app-in-ios-3377eb4a3e7c).\n\n<img src=\"images/image_segmentation_ios.jpg\" width=\"250\" />\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzImageSegmentationDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzImageSegmentationDemo`\n\n```\ncd fritz-examples/iOS/FritzImageSegmentationDemo\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzImageSegmentationDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/FritzMaskRecognitionDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzImageLabelingDemo\n//\n//  Created by Steven Yeung on 10/23/19.\n//  Copyright © 2019 Fritz AI. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        // Override point for customization after application launch.\n        FritzCore.configure()\n        return true\n    }\n\n    func applicationWillResignActive(_ application: UIApplication) {\n        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n    }\n\n    func applicationDidEnterBackground(_ application: UIApplication) {\n        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n    }\n\n    func applicationWillEnterForeground(_ application: UIApplication) {\n        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n    }\n\n    func applicationDidBecomeActive(_ application: UIApplication) {\n        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n    }\n\n    func applicationWillTerminate(_ application: UIApplication) {\n        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n    }\n\n\n}\n"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/FritzMaskRecognitionDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/FritzMaskRecognitionDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/FritzMaskRecognitionDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" xcode11CocoaTouchSystemColor=\"systemBackgroundColor\" cocoaTouchSystemColor=\"whiteColor\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/FritzMaskRecognitionDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"16096\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"bXN-2g-eap\">\n    <device id=\"retina4_7\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"16086\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Image Labeling-->\n        <scene sceneID=\"gga-fV-gqh\">\n            <objects>\n                <viewController id=\"bXN-2g-eap\" userLabel=\"Image Labeling\" customClass=\"ViewController\" customModule=\"FritzImageLabelingDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"DTw-l1-0kj\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"XOI-62-OJZ\" userLabel=\"Model Version Label\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"595\" width=\"377\" height=\"15\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"7ym-Xz-hjF\" userLabel=\"Model ID Label\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"618\" width=\"377\" height=\"15\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"2CS-If-s4d\" userLabel=\"FPS Label\">\n                                <rect key=\"frame\" x=\"88\" y=\"641\" width=\"200\" height=\"15.5\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <size key=\"shadowOffset\" width=\"1\" height=\"1\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"onp-ok-7O5\">\n                                <rect key=\"frame\" x=\"47\" y=\"86\" width=\"280\" height=\"33\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"26\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.33333333329999998\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"rNJ-ef-VJT\" userLabel=\"Confidence\">\n                                <rect key=\"frame\" x=\"169.5\" y=\"127\" width=\"33\" height=\"16\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"13\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                            </label>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <constraints>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"leading\" secondItem=\"2CS-If-s4d\" secondAttribute=\"leading\" id=\"2jA-7n-H7f\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"centerX\" secondItem=\"7ym-Xz-hjF\" secondAttribute=\"centerX\" id=\"7PA-r8-ubr\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"centerX\" secondItem=\"DTw-l1-0kj\" secondAttribute=\"centerX\" id=\"96p-ZT-MSS\"/>\n                            <constraint firstItem=\"rNJ-ef-VJT\" firstAttribute=\"top\" secondItem=\"onp-ok-7O5\" secondAttribute=\"bottom\" constant=\"8\" id=\"HK8-yQ-AGD\"/>\n                            <constraint firstItem=\"onp-ok-7O5\" firstAttribute=\"centerX\" secondItem=\"XOI-62-OJZ\" secondAttribute=\"centerX\" constant=\"-1.5\" id=\"Lhz-xE-Kzu\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"top\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"top\" constant=\"551\" id=\"OLh-lr-EBf\"/>\n                            <constraint firstItem=\"onp-ok-7O5\" firstAttribute=\"leading\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"leading\" constant=\"47\" id=\"V8S-RG-YXR\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"leading\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"leading\" id=\"ayJ-DJ-ZIk\"/>\n                            <constraint firstItem=\"onp-ok-7O5\" firstAttribute=\"top\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"top\" constant=\"42\" id=\"d8k-vq-ibk\"/>\n                            <constraint firstItem=\"2CS-If-s4d\" firstAttribute=\"top\" secondItem=\"7ym-Xz-hjF\" secondAttribute=\"bottom\" constant=\"8\" id=\"hzG-gT-3qI\"/>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"top\" secondItem=\"XOI-62-OJZ\" secondAttribute=\"bottom\" constant=\"8\" id=\"j0W-WU-A8M\"/>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"trailing\" secondItem=\"2CS-If-s4d\" secondAttribute=\"trailing\" id=\"m1R-Jm-BoQ\"/>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"leading\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"leading\" id=\"t9z-e3-fYl\"/>\n                            <constraint firstItem=\"onp-ok-7O5\" firstAttribute=\"centerX\" secondItem=\"rNJ-ef-VJT\" secondAttribute=\"centerX\" id=\"u6t-jQ-W9U\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"CgA-h6-NiT\"/>\n                    </view>\n                    <navigationItem key=\"navigationItem\" title=\"LABEL IMAGES\" id=\"vW0-XC-6S1\" userLabel=\"LABEL IMAGES\"/>\n                    <simulatedNavigationBarMetrics key=\"simulatedTopBarMetrics\" prompted=\"NO\"/>\n                    <connections>\n                        <outlet property=\"cameraView\" destination=\"DTw-l1-0kj\" id=\"dCi-70-bYu\"/>\n                        <outlet property=\"confidenceLabel\" destination=\"rNJ-ef-VJT\" id=\"LeE-HY-2xj\"/>\n                        <outlet property=\"fpsLabel\" destination=\"2CS-If-s4d\" id=\"LIz-l8-ftX\"/>\n                        <outlet property=\"modelIdLabel\" destination=\"7ym-Xz-hjF\" id=\"Lya-8E-cgA\"/>\n                        <outlet property=\"modelVersionLabel\" destination=\"XOI-62-OJZ\" id=\"vID-DU-bFc\"/>\n                        <outlet property=\"predictionLabel\" destination=\"onp-ok-7O5\" id=\"82f-GN-LO1\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"pm4-ZZ-n7f\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"16.800000000000001\" y=\"62.518740629685162\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/FritzMaskRecognitionDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string>For inference</string>\n\t<key>UIApplicationSceneManifest</key>\n\t<dict>\n\t\t<key>UIApplicationSupportsMultipleScenes</key>\n\t\t<false/>\n\t\t<key>UISceneConfigurations</key>\n\t\t<dict>\n\t\t\t<key>UIWindowSceneSessionRoleApplication</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>UISceneConfigurationName</key>\n\t\t\t\t\t<string>Default Configuration</string>\n\t\t\t\t\t<key>UISceneDelegateClassName</key>\n\t\t\t\t\t<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>\n\t\t\t\t\t<key>UISceneStoryboardFile</key>\n\t\t\t\t\t<string>Main</string>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t</dict>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/FritzMaskRecognitionDemo/SceneDelegate.swift",
    "content": "//\n//  SceneDelegate.swift\n//  FritzImageLabelingDemo\n//\n//  Created by Steven Yeung on 10/23/19.\n//  Copyright © 2019 Fritz AI. All rights reserved.\n//\n\nimport UIKit\n\nclass SceneDelegate: UIResponder, UIWindowSceneDelegate {\n\n  var window: UIWindow?\n\n\n  func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {\n    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.\n    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.\n    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).\n    guard let _ = (scene as? UIWindowScene) else { return }\n  }\n\n  func sceneDidDisconnect(_ scene: UIScene) {\n    // Called as the scene is being released by the system.\n    // This occurs shortly after the scene enters the background, or when its session is discarded.\n    // Release any resources associated with this scene that can be re-created the next time the scene connects.\n    // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).\n  }\n\n  func sceneDidBecomeActive(_ scene: UIScene) {\n    // Called when the scene has moved from an inactive state to an active state.\n    // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.\n  }\n\n  func sceneWillResignActive(_ scene: UIScene) {\n    // Called when the scene will move from an active state to an inactive state.\n    // This may occur due to temporary interruptions (ex. an incoming phone call).\n  }\n\n  func sceneWillEnterForeground(_ scene: UIScene) {\n    // Called as the scene transitions from the background to the foreground.\n    // Use this method to undo the changes made on entering the background.\n  }\n\n  func sceneDidEnterBackground(_ scene: UIScene) {\n    // Called as the scene transitions from the foreground to the background.\n    // Use this method to save data, release shared resources, and store enough scene-specific state information\n    // to restore the scene back to its current state.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/FritzMaskRecognitionDemo/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  FritzImageLabelingDemo\n//\n//  Created by Steven Yeung on 10/23/19.\n//  Copyright © 2019 Steven Yeung. All rights reserved.\n//\n\nimport UIKit\nimport CoreML\nimport Vision\nimport AVFoundation\nimport Accelerate\nimport Fritz\n\nextension Double {\n  func format(f: String) -> String {\n    return String(format: \"%\\(f)f\", self)\n  }\n}\n\nimport Fritz\n\nextension MaskRecognition: SwiftIdentifiedModel {\n   static let modelIdentifier = \"f361a07db99e480198621240a8e5ecd1\"\n   static let packagedModelVersion = 2\n}\n\n\nclass ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {\n  @IBOutlet weak var cameraView: UIView!\n  @IBOutlet weak var fpsLabel: UILabel!\n  @IBOutlet weak var modelIdLabel: UILabel!\n  @IBOutlet weak var modelVersionLabel: UILabel!\n\n  @IBOutlet weak var predictionLabel: UILabel! {\n      didSet { predictionLabel.text = \"Loading... 🚀\" }\n  }\n\n  @IBOutlet weak var confidenceLabel: UILabel! {\n      didSet { confidenceLabel.text = nil }\n  }\n\n  var lastExecution = Date()\n  var screenHeight: Double?\n  var screenWidth: Double?\n\n  // Use a pre-trained image labeling model from Fritz AI.\n  lazy var visionModel = FritzVisionLabelPredictor(model: MaskRecognition())\n\n  // To use your own custom image labeling model, follow the instructions here:\n  // https://docs.fritz.ai/develop/vision/image-labeling/ios.html\n  // lazy var visionModel = FritzVisionLabelPredictor(model: YourModelName())\n\n  // Only show labels above a certain confidence threshold. For new models in development,\n  // you may need to lower this to see predictions. As you improve your model, you can\n  // increase this reduce false positives.\n  let confidenceThreshold = 0.1\n\n  private lazy var cameraLayer: AVCaptureVideoPreviewLayer = {\n    let layer = AVCaptureVideoPreviewLayer(session: self.captureSession)\n    layer.videoGravity = .resizeAspectFill\n    return layer\n  }()\n\n  private lazy var captureSession: AVCaptureSession = {\n    let session = AVCaptureSession()\n\n    guard\n      let backCamera = AVCaptureDevice.default(\n        .builtInWideAngleCamera,\n        for: .video,\n        position: .front\n      ),\n      let input = try? AVCaptureDeviceInput(device: backCamera)\n      else { return session }\n    session.addInput(input)\n    return session\n  }()\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n    self.cameraView?.layer.addSublayer(self.cameraLayer)\n    // Setup model labels\n    self.cameraView?.bringSubviewToFront(self.fpsLabel)\n    self.fpsLabel.textAlignment = .center\n    self.cameraView?.bringSubviewToFront(self.modelIdLabel)\n    self.modelIdLabel.textAlignment = .center\n    self.cameraView?.bringSubviewToFront(self.modelVersionLabel)\n    self.modelVersionLabel.textAlignment = .center\n\n    // Setup prediction labels\n    self.cameraView?.bringSubviewToFront(self.predictionLabel)\n    self.predictionLabel.textAlignment = .center\n    self.cameraView?.bringSubviewToFront(self.confidenceLabel)\n    self.confidenceLabel.textAlignment = .center\n\n    // Setup video capture.\n    let videoOutput = AVCaptureVideoDataOutput()\n    videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: \"MyQueue\"))\n    self.captureSession.addOutput(videoOutput)\n    self.captureSession.startRunning()\n\n    screenWidth = Double(view.frame.width)\n    screenHeight = Double(view.frame.height)\n  }\n\n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n    cameraLayer.frame = cameraView.layer.bounds\n  }\n\n  override func viewDidLayoutSubviews() {\n    super.viewDidLayoutSubviews()\n    self.cameraLayer.frame = self.cameraView?.bounds ?? .zero\n  }\n\n  override func didReceiveMemoryWarning() {\n    super.didReceiveMemoryWarning()\n    // Dispose of any resources that can be recreated.\n  }\n\n  func updateLabels() {\n    let thisExecution = Date()\n    let executionTime = thisExecution.timeIntervalSince(self.lastExecution)\n    let framesPerSecond: Double = 1 / executionTime\n    self.lastExecution = thisExecution\n\n    DispatchQueue.main.async {\n      self.fpsLabel.text = \"FPS: \\(framesPerSecond.format(f: \".3\"))\"\n      self.modelIdLabel.text = \"Model ID: \\(self.visionModel.managedModel.activeModelConfig.identifier)\"\n      self.modelVersionLabel.text = \"Active Version: \\(self.visionModel.managedModel.activeModelConfig.version)\"\n    }\n  }\n\n  func captureOutput(\n    _ output: AVCaptureOutput,\n    didOutput sampleBuffer: CMSampleBuffer,\n    from connection: AVCaptureConnection) {\n    let image = FritzVisionImage(sampleBuffer: sampleBuffer, connection: connection)\n    let options = FritzVisionLabelModelOptions()\n    options.threshold = confidenceThreshold\n\n\n    guard let results = try? visionModel.predict(image, options: options) else { return }\n\n    // Display results\n    if results.count > 0 {\n      let observation = results[0]\n      let confidence = Int(observation.confidence * 100)\n      self.setResult(text: observation.label, confidence: confidence)\n    } else {\n      self.setNoResult()\n    }\n\n    // To record predictions and send data back to Fritz AI via the Data Collection System, use the predictors's record method.\n    // In addition to the input image, predicted model results can be collected as well as user-modified annotations.\n    // This allows developers to both gather data on model performance and have users collect additional ground truth data for future model retraining.\n    // Note, the Data Collection System is only available on paid plans.\n    // visionModel.record(image, predicted: results, modified: nil)\n\n    updateLabels()\n  }\n\n  private func setResult(text: String, confidence: Int) {\n      DispatchQueue.main.async {\n          self.predictionLabel.text = text.capitalized\n          self.confidenceLabel.text = self.confidenceString(confidence)\n          self.confidenceLabel.textColor = self.confidenceColor(confidence)\n      }\n  }\n\n  private func setNoResult() {\n      DispatchQueue.main.async {\n          self.predictionLabel.text = \"?????\"\n          self.confidenceLabel.text = \"\"\n      }\n  }\n\n  private func confidenceString(_ value: Int) -> String {\n      return \"\\(value)%\"\n  }\n\n  private func confidenceColor(_ value: Int) -> UIColor {\n      switch value {\n      case ...33: return .red\n      case 34...66: return .orange\n      default: return .green\n      }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/FritzMaskRecognitionDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t457E45E52447915E001FE3E2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457E45DB2447915E001FE3E2 /* ViewController.swift */; };\n\t\t457E45E72447915E001FE3E2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 457E45DD2447915E001FE3E2 /* Assets.xcassets */; };\n\t\t457E45E82447915E001FE3E2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 457E45DE2447915E001FE3E2 /* LaunchScreen.storyboard */; };\n\t\t457E45E92447915E001FE3E2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 457E45E02447915E001FE3E2 /* Main.storyboard */; };\n\t\t457E45EA2447915E001FE3E2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457E45E22447915E001FE3E2 /* AppDelegate.swift */; };\n\t\t457E45EF24479B7B001FE3E2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 457E45E42447915E001FE3E2 /* SceneDelegate.swift */; };\n\t\t45F2C724247D6C8A00D96754 /* MaskRecognition.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 45F2C723247D6C8A00D96754 /* MaskRecognition.mlmodel */; };\n\t\t69156451740E575356F8C91A /* Pods_FritzMaskRecognitionDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EFD1FBA3EA00ADFDF4A88554 /* Pods_FritzMaskRecognitionDemo.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t3B3BCBFA2360AE3600898CF5 /* FritzMaskRecognitionDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzMaskRecognitionDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t457E45DB2447915E001FE3E2 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t457E45DD2447915E001FE3E2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t457E45DF2447915E001FE3E2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t457E45E12447915E001FE3E2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t457E45E22447915E001FE3E2 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t457E45E32447915E001FE3E2 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t457E45E42447915E001FE3E2 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = \"<group>\"; };\n\t\t45F2C723247D6C8A00D96754 /* MaskRecognition.mlmodel */ = {isa = PBXFileReference; lastKnownFileType = file.mlmodel; path = MaskRecognition.mlmodel; sourceTree = \"<group>\"; };\n\t\t74684289D7E74482826FF46C /* Pods-FritzMaskRecognitionDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzMaskRecognitionDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzMaskRecognitionDemo/Pods-FritzMaskRecognitionDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t9CAF5A0FC63D224A299B03EB /* Pods-FritzMaskRecognitionDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzMaskRecognitionDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzMaskRecognitionDemo/Pods-FritzMaskRecognitionDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tEFD1FBA3EA00ADFDF4A88554 /* Pods_FritzMaskRecognitionDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzMaskRecognitionDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t3B3BCBF72360AE3600898CF5 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t69156451740E575356F8C91A /* Pods_FritzMaskRecognitionDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t3B3BCBF12360AE3600898CF5 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t457E45DA2447915E001FE3E2 /* FritzMaskRecognitionDemo */,\n\t\t\t\t3B3BCBFB2360AE3600898CF5 /* Products */,\n\t\t\t\tC4BF6B27527268175F03B925 /* Pods */,\n\t\t\t\tACF443D621D08CB260B4484B /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B3BCBFB2360AE3600898CF5 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B3BCBFA2360AE3600898CF5 /* FritzMaskRecognitionDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t457E45DA2447915E001FE3E2 /* FritzMaskRecognitionDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t457E45DB2447915E001FE3E2 /* ViewController.swift */,\n\t\t\t\t457E45DD2447915E001FE3E2 /* Assets.xcassets */,\n\t\t\t\t45F2C723247D6C8A00D96754 /* MaskRecognition.mlmodel */,\n\t\t\t\t457E45DE2447915E001FE3E2 /* LaunchScreen.storyboard */,\n\t\t\t\t457E45E02447915E001FE3E2 /* Main.storyboard */,\n\t\t\t\t457E45E22447915E001FE3E2 /* AppDelegate.swift */,\n\t\t\t\t457E45E32447915E001FE3E2 /* Info.plist */,\n\t\t\t\t457E45E42447915E001FE3E2 /* SceneDelegate.swift */,\n\t\t\t);\n\t\t\tpath = FritzMaskRecognitionDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tACF443D621D08CB260B4484B /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEFD1FBA3EA00ADFDF4A88554 /* Pods_FritzMaskRecognitionDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC4BF6B27527268175F03B925 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CAF5A0FC63D224A299B03EB /* Pods-FritzMaskRecognitionDemo.debug.xcconfig */,\n\t\t\t\t74684289D7E74482826FF46C /* Pods-FritzMaskRecognitionDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t3B3BCBF92360AE3600898CF5 /* FritzMaskRecognitionDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 3B3BCC0E2360AE3700898CF5 /* Build configuration list for PBXNativeTarget \"FritzMaskRecognitionDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t554D1B8F542BE86B6837BAE4 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t3B3BCBF62360AE3600898CF5 /* Sources */,\n\t\t\t\t3B3BCBF72360AE3600898CF5 /* Frameworks */,\n\t\t\t\t3B3BCBF82360AE3600898CF5 /* Resources */,\n\t\t\t\tE87B85420963AC4B34B5AD65 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzMaskRecognitionDemo;\n\t\t\tproductName = FritzObjectDetectionDemo;\n\t\t\tproductReference = 3B3BCBFA2360AE3600898CF5 /* FritzMaskRecognitionDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t3B3BCBF22360AE3600898CF5 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1110;\n\t\t\t\tLastUpgradeCheck = 1110;\n\t\t\t\tORGANIZATIONNAME = \"Fritz AI\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t3B3BCBF92360AE3600898CF5 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 11.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 3B3BCBF52360AE3600898CF5 /* Build configuration list for PBXProject \"FritzObjectDetectionDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 3B3BCBF12360AE3600898CF5;\n\t\t\tproductRefGroup = 3B3BCBFB2360AE3600898CF5 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t3B3BCBF92360AE3600898CF5 /* FritzMaskRecognitionDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t3B3BCBF82360AE3600898CF5 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t457E45E82447915E001FE3E2 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t457E45E72447915E001FE3E2 /* Assets.xcassets in Resources */,\n\t\t\t\t457E45E92447915E001FE3E2 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t554D1B8F542BE86B6837BAE4 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzMaskRecognitionDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tE87B85420963AC4B34B5AD65 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzMaskRecognitionDemo/Pods-FritzMaskRecognitionDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzMaskRecognitionDemo/Pods-FritzMaskRecognitionDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzMaskRecognitionDemo/Pods-FritzMaskRecognitionDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t3B3BCBF62360AE3600898CF5 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t45F2C724247D6C8A00D96754 /* MaskRecognition.mlmodel in Sources */,\n\t\t\t\t457E45EF24479B7B001FE3E2 /* SceneDelegate.swift in Sources */,\n\t\t\t\t457E45EA2447915E001FE3E2 /* AppDelegate.swift in Sources */,\n\t\t\t\t457E45E52447915E001FE3E2 /* ViewController.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t457E45DE2447915E001FE3E2 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t457E45DF2447915E001FE3E2 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t457E45E02447915E001FE3E2 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t457E45E12447915E001FE3E2 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t3B3BCC0C2360AE3700898CF5 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 13.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t3B3BCC0D2360AE3700898CF5 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 13.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t3B3BCC0F2360AE3700898CF5 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 9CAF5A0FC63D224A299B03EB /* Pods-FritzMaskRecognitionDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/FritzMaskRecognitionDemo/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.MaskRecognitionDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t3B3BCC102360AE3700898CF5 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 74684289D7E74482826FF46C /* Pods-FritzMaskRecognitionDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/FritzMaskRecognitionDemo/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.MaskRecognitionDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t3B3BCBF52360AE3600898CF5 /* Build configuration list for PBXProject \"FritzObjectDetectionDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t3B3BCC0C2360AE3700898CF5 /* Debug */,\n\t\t\t\t3B3BCC0D2360AE3700898CF5 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t3B3BCC0E2360AE3700898CF5 /* Build configuration list for PBXNativeTarget \"FritzMaskRecognitionDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t3B3BCC0F2360AE3700898CF5 /* Debug */,\n\t\t\t\t3B3BCC102360AE3700898CF5 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 3B3BCBF22360AE3600898CF5 /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/FritzMaskRecognitionDemo.xcodeproj/xcshareddata/xcschemes/FritzMaskRecognitionDemo.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1140\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"3B3BCBF92360AE3600898CF5\"\n               BuildableName = \"FritzMaskRecognitionDemo.app\"\n               BlueprintName = \"FritzMaskRecognitionDemo\"\n               ReferencedContainer = \"container:FritzMaskRecognitionDemo.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"3B3BCBF92360AE3600898CF5\"\n            BuildableName = \"FritzMaskRecognitionDemo.app\"\n            BlueprintName = \"FritzMaskRecognitionDemo\"\n            ReferencedContainer = \"container:FritzMaskRecognitionDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"3B3BCBF92360AE3600898CF5\"\n            BuildableName = \"FritzMaskRecognitionDemo.app\"\n            BlueprintName = \"FritzMaskRecognitionDemo\"\n            ReferencedContainer = \"container:FritzMaskRecognitionDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzMaskRecognitionDemo' do\n  use_frameworks!\n\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionLabelModel/Fast'\n\nend\n"
  },
  {
    "path": "iOS/FritzMaskRecognitionDemo/README.md",
    "content": "# Mask Recognition\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use the Fritz AI Studio to train a model and create an app that detects whether a person in an image or video is wearing a face mask.\n\nFor the full tutorial, visit [our post on Heartbeat](https://heartbeat.fritz.ai/building-an-on-device-face-mask-detector-with-fritz-ai-studio-874a88ae2702).\n\n<img src=\"https://thumbs.gfycat.com/MasculineShamefulHippopotamus-size_restricted.gif\" width=\"250\"/>\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing?utm_source=github&utm_campaign=mask-recogntion) for a Fritz AI plan in order to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzMaskRecognitionDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzMaskRecognitionDemo`\n\n```\ncd fritz-examples/iOS/FritzMaskRecognitionDemo\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzMaskRecognitionDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=mask-recognition)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=mask-recognition)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=mask-recognition) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=mask-recognition) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=mask-recognition).\n\n## Help\n\nFor any questions or issues, please open an issue on the [Fritz AI Discourse](https://support.fritz.ai).\n"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/FritzObjectDetectionDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzObjectDetectionDemo\n//\n//  Created by Steven Yeung on 10/23/19.\n//  Copyright © 2019 Fritz AI. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        // Override point for customization after application launch.\n        FritzCore.configure()\n        return true\n    }\n\n    func applicationWillResignActive(_ application: UIApplication) {\n        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n    }\n\n    func applicationDidEnterBackground(_ application: UIApplication) {\n        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n    }\n\n    func applicationWillEnterForeground(_ application: UIApplication) {\n        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n    }\n\n    func applicationDidBecomeActive(_ application: UIApplication) {\n        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n    }\n\n    func applicationWillTerminate(_ application: UIApplication) {\n        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n    }\n\n\n}\n"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/FritzObjectDetectionDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/FritzObjectDetectionDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/FritzObjectDetectionDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" xcode11CocoaTouchSystemColor=\"systemBackgroundColor\" cocoaTouchSystemColor=\"whiteColor\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/FritzObjectDetectionDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15705\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"bXN-2g-eap\">\n    <device id=\"retina4_7\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15706\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Detect Objects-->\n        <scene sceneID=\"gga-fV-gqh\">\n            <objects>\n                <viewController id=\"bXN-2g-eap\" userLabel=\"Detect Objects\" customClass=\"ViewController\" customModule=\"FritzObjectDetectionDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"DTw-l1-0kj\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"XOI-62-OJZ\" userLabel=\"Model Version Label\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"595\" width=\"377\" height=\"15\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"7ym-Xz-hjF\" userLabel=\"Model ID Label\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"618\" width=\"377\" height=\"15\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"2CS-If-s4d\" userLabel=\"FPS Label\">\n                                <rect key=\"frame\" x=\"88\" y=\"641\" width=\"200\" height=\"15.5\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <size key=\"shadowOffset\" width=\"1\" height=\"1\"/>\n                            </label>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <constraints>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"leading\" secondItem=\"2CS-If-s4d\" secondAttribute=\"leading\" id=\"2jA-7n-H7f\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"centerX\" secondItem=\"7ym-Xz-hjF\" secondAttribute=\"centerX\" id=\"7PA-r8-ubr\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"centerX\" secondItem=\"DTw-l1-0kj\" secondAttribute=\"centerX\" id=\"96p-ZT-MSS\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"top\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"top\" constant=\"551\" id=\"OLh-lr-EBf\"/>\n                            <constraint firstItem=\"XOI-62-OJZ\" firstAttribute=\"leading\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"leading\" id=\"ayJ-DJ-ZIk\"/>\n                            <constraint firstItem=\"2CS-If-s4d\" firstAttribute=\"top\" secondItem=\"7ym-Xz-hjF\" secondAttribute=\"bottom\" constant=\"8\" id=\"hzG-gT-3qI\"/>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"top\" secondItem=\"XOI-62-OJZ\" secondAttribute=\"bottom\" constant=\"8\" id=\"j0W-WU-A8M\"/>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"trailing\" secondItem=\"2CS-If-s4d\" secondAttribute=\"trailing\" id=\"m1R-Jm-BoQ\"/>\n                            <constraint firstItem=\"7ym-Xz-hjF\" firstAttribute=\"leading\" secondItem=\"CgA-h6-NiT\" secondAttribute=\"leading\" id=\"t9z-e3-fYl\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"CgA-h6-NiT\"/>\n                    </view>\n                    <navigationItem key=\"navigationItem\" title=\"DETECT OBJECTS\" id=\"vW0-XC-6S1\"/>\n                    <simulatedNavigationBarMetrics key=\"simulatedTopBarMetrics\" prompted=\"NO\"/>\n                    <connections>\n                        <outlet property=\"cameraView\" destination=\"DTw-l1-0kj\" id=\"dCi-70-bYu\"/>\n                        <outlet property=\"fpsLabel\" destination=\"2CS-If-s4d\" id=\"LIz-l8-ftX\"/>\n                        <outlet property=\"modelIdLabel\" destination=\"7ym-Xz-hjF\" id=\"Lya-8E-cgA\"/>\n                        <outlet property=\"modelVersionLabel\" destination=\"XOI-62-OJZ\" id=\"vID-DU-bFc\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"pm4-ZZ-n7f\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"18\" y=\"63\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/FritzObjectDetectionDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UIApplicationSceneManifest</key>\n\t<dict>\n\t\t<key>UIApplicationSupportsMultipleScenes</key>\n\t\t<false/>\n\t\t<key>UISceneConfigurations</key>\n\t\t<dict>\n\t\t\t<key>UIWindowSceneSessionRoleApplication</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>UISceneConfigurationName</key>\n\t\t\t\t\t<string>Default Configuration</string>\n\t\t\t\t\t<key>UISceneDelegateClassName</key>\n\t\t\t\t\t<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>\n\t\t\t\t\t<key>UISceneStoryboardFile</key>\n\t\t\t\t\t<string>Main</string>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t</dict>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>NSCameraUsageDescription</key>\n\t<string>For inference</string>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/FritzObjectDetectionDemo/SceneDelegate.swift",
    "content": "//\n//  SceneDelegate.swift\n//  FritzObjectDetectionDemo\n//\n//  Created by Steven Yeung on 10/23/19.\n//  Copyright © 2019 Fritz AI. All rights reserved.\n//\n\nimport UIKit\n\nclass SceneDelegate: UIResponder, UIWindowSceneDelegate {\n\n  var window: UIWindow?\n\n\n  func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {\n    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.\n    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.\n    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).\n    guard let _ = (scene as? UIWindowScene) else { return }\n  }\n\n  func sceneDidDisconnect(_ scene: UIScene) {\n    // Called as the scene is being released by the system.\n    // This occurs shortly after the scene enters the background, or when its session is discarded.\n    // Release any resources associated with this scene that can be re-created the next time the scene connects.\n    // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).\n  }\n\n  func sceneDidBecomeActive(_ scene: UIScene) {\n    // Called when the scene has moved from an inactive state to an active state.\n    // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.\n  }\n\n  func sceneWillResignActive(_ scene: UIScene) {\n    // Called when the scene will move from an active state to an inactive state.\n    // This may occur due to temporary interruptions (ex. an incoming phone call).\n  }\n\n  func sceneWillEnterForeground(_ scene: UIScene) {\n    // Called as the scene transitions from the background to the foreground.\n    // Use this method to undo the changes made on entering the background.\n  }\n\n  func sceneDidEnterBackground(_ scene: UIScene) {\n    // Called as the scene transitions from the foreground to the background.\n    // Use this method to save data, release shared resources, and store enough scene-specific state information\n    // to restore the scene back to its current state.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/FritzObjectDetectionDemo/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  FritzObjectDetectionDemo\n//\n//  Created by Steven Yeung on 10/23/19.\n//  Copyright © 2019 Steven Yeung. All rights reserved.\n//\n\nimport UIKit\nimport CoreML\nimport Vision\nimport AVFoundation\nimport Accelerate\nimport Fritz\n\nextension Double {\n  func format(f: String) -> String {\n    return String(format: \"%\\(f)f\", self)\n  }\n}\n\n\nclass ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {\n  @IBOutlet weak var cameraView: UIView!\n  @IBOutlet weak var fpsLabel: UILabel!\n  @IBOutlet weak var modelIdLabel: UILabel!\n  @IBOutlet weak var modelVersionLabel: UILabel!\n\n  var lastExecution = Date()\n  var screenHeight: Double?\n  var screenWidth: Double?\n\n  // Use a pre-trained object detection model from Fritz AI.\n  lazy var visionModel = FritzVisionObjectModelFast()\n\n  // To use your own custom object detection model, follow the instructions here:\n  // https://docs.fritz.ai/develop/vision/object-detection/ios.html\n  // lazy var visionModel = FritzVisionObjectPredictor(model: YourModelName())\n\n  // Only show detections above a certain confidence threshold. For new models in development,\n  // you may need to lower this to see predictions. As you improve your model, you can\n  // increase this reduce false positives.\n  let confidenceThreshold = 0.1\n\n  private lazy var cameraLayer: AVCaptureVideoPreviewLayer = {\n    let layer = AVCaptureVideoPreviewLayer(session: self.captureSession)\n    layer.videoGravity = .resizeAspectFill\n    return layer\n  }()\n\n  private lazy var captureSession: AVCaptureSession = {\n    let session = AVCaptureSession()\n\n    guard\n      let backCamera = AVCaptureDevice.default(\n        .builtInWideAngleCamera,\n        for: .video,\n        position: .back\n      ),\n      let input = try? AVCaptureDeviceInput(device: backCamera)\n      else { return session }\n    session.addInput(input)\n    return session\n  }()\n\n  let numBoxes = 100\n  var boundingBoxes: [BoundingBoxOutline] = []\n  let multiClass = true\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n    self.cameraView?.layer.addSublayer(self.cameraLayer)\n    // Setup labels\n    self.cameraView?.bringSubviewToFront(self.fpsLabel)\n    self.fpsLabel.textAlignment = .center\n    self.cameraView?.bringSubviewToFront(self.modelIdLabel)\n    self.modelIdLabel.textAlignment = .center\n    self.cameraView?.bringSubviewToFront(self.modelVersionLabel)\n    self.modelVersionLabel.textAlignment = .center\n\n    // Setup video capture.\n    let videoOutput = AVCaptureVideoDataOutput()\n    videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: \"MyQueue\"))\n    self.captureSession.addOutput(videoOutput)\n    self.captureSession.startRunning()\n    setupBoxes()\n    screenWidth = Double(view.frame.width)\n    screenHeight = Double(view.frame.height)\n  }\n\n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n    cameraLayer.frame = cameraView.layer.bounds\n  }\n\n  func setupBoxes() {\n    // Create shape layers for the bounding boxes.\n    for _ in 0..<numBoxes {\n      let box = BoundingBoxOutline()\n      box.addToLayer(cameraView.layer)\n      self.boundingBoxes.append(box)\n    }\n  }\n\n  override func viewDidLayoutSubviews() {\n    super.viewDidLayoutSubviews()\n    self.cameraLayer.frame = self.cameraView?.bounds ?? .zero\n  }\n\n  override func didReceiveMemoryWarning() {\n    super.didReceiveMemoryWarning()\n    // Dispose of any resources that can be recreated.\n  }\n\n  func drawBoxes(predictions: [FritzVisionObject]) {\n    for (index, prediction) in predictions.enumerated() {\n      let textLabel = String(format: \"%.2f - %@\", prediction.confidence, prediction.label)\n      let height = Double(cameraView.frame.height)\n      let width = Double(cameraView.frame.width)\n\n      // Scale the box with respect to the screen size\n      let box = prediction.boundingBox\n      let rect = box.toCGRect(imgHeight: height, imgWidth: width)\n      self.boundingBoxes[index].show(\n        frame: rect,\n        label: textLabel,\n        color: UIColor.red,\n        textColor: UIColor.black\n      )\n    }\n\n    for index in predictions.count..<self.numBoxes {\n      self.boundingBoxes[index].hide()\n    }\n  }\n\n  func updateLabels() {\n    let thisExecution = Date()\n    let executionTime = thisExecution.timeIntervalSince(self.lastExecution)\n    let framesPerSecond: Double = 1 / executionTime\n    self.lastExecution = thisExecution\n\n    DispatchQueue.main.async {\n      self.fpsLabel.text = \"FPS: \\(framesPerSecond.format(f: \".3\"))\"\n      self.modelIdLabel.text = \"Model ID: \\(self.visionModel.managedModel.activeModelConfig.identifier)\"\n      self.modelVersionLabel.text = \"Active Version: \\(self.visionModel.managedModel.activeModelConfig.version)\"\n    }\n  }\n\n  func captureOutput(\n    _ output: AVCaptureOutput,\n    didOutput sampleBuffer: CMSampleBuffer,\n    from connection: AVCaptureConnection) {\n    let image = FritzVisionImage(sampleBuffer: sampleBuffer, connection: connection)\n    let options = FritzVisionObjectModelOptions()\n    options.threshold = confidenceThreshold\n\n    guard let results = try? visionModel.predict(image, options: options) else { return }\n\n    // To record predictions and send data back to Fritz AI via the Data Collection System, use the predictors's record method.\n    // In addition to the input image, predicted model results can be collected as well as user-modified annotations.\n    // This allows developers to both gather data on model performance and have users collect additional ground truth data for future model retraining.\n    // Note, the Data Collection System is only available on paid plans.\n    // visionModel.record(image, predicted: results, modified: nil)\n    if results.count > 0 {\n      DispatchQueue.main.async {\n        self.drawBoxes(predictions: results)\n      }\n    }\n    updateLabels()\n  }\n}\n"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/FritzObjectDetectionDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t3B3BCBFE2360AE3600898CF5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3BCBFD2360AE3600898CF5 /* AppDelegate.swift */; };\n\t\t3B3BCC002360AE3600898CF5 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3BCBFF2360AE3600898CF5 /* SceneDelegate.swift */; };\n\t\t3B3BCC022360AE3600898CF5 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3BCC012360AE3600898CF5 /* ViewController.swift */; };\n\t\t3B3BCC052360AE3600898CF5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3B3BCC032360AE3600898CF5 /* Main.storyboard */; };\n\t\t3B3BCC072360AE3700898CF5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3B3BCC062360AE3700898CF5 /* Assets.xcassets */; };\n\t\t3B3BCC0A2360AE3700898CF5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3B3BCC082360AE3700898CF5 /* LaunchScreen.storyboard */; };\n\t\tBDF6888CDADEB5AF0CCC0FA6 /* Pods_FritzObjectDetectionDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED4D70C2E170B6741E0000FF /* Pods_FritzObjectDetectionDemo.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t3B3BCBFA2360AE3600898CF5 /* FritzObjectDetectionDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzObjectDetectionDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t3B3BCBFD2360AE3600898CF5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t3B3BCBFF2360AE3600898CF5 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = \"<group>\"; };\n\t\t3B3BCC012360AE3600898CF5 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t3B3BCC042360AE3600898CF5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t3B3BCC062360AE3700898CF5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t3B3BCC092360AE3700898CF5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t3B3BCC0B2360AE3700898CF5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t80B57F58F06E412BF8CEA44F /* Pods-FritzObjectDetectionDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzObjectDetectionDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzObjectDetectionDemo/Pods-FritzObjectDetectionDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tA5A66077100E267087F5017C /* Pods-FritzObjectDetectionDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzObjectDetectionDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzObjectDetectionDemo/Pods-FritzObjectDetectionDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tED4D70C2E170B6741E0000FF /* Pods_FritzObjectDetectionDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzObjectDetectionDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t3B3BCBF72360AE3600898CF5 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tBDF6888CDADEB5AF0CCC0FA6 /* Pods_FritzObjectDetectionDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t3B3BCBF12360AE3600898CF5 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B3BCBFC2360AE3600898CF5 /* FritzObjectDetectionDemo */,\n\t\t\t\t3B3BCBFB2360AE3600898CF5 /* Products */,\n\t\t\t\tC4BF6B27527268175F03B925 /* Pods */,\n\t\t\t\t507B40F62954FE952FB51362 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B3BCBFB2360AE3600898CF5 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B3BCBFA2360AE3600898CF5 /* FritzObjectDetectionDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B3BCBFC2360AE3600898CF5 /* FritzObjectDetectionDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B3BCBFD2360AE3600898CF5 /* AppDelegate.swift */,\n\t\t\t\t3B3BCBFF2360AE3600898CF5 /* SceneDelegate.swift */,\n\t\t\t\t3B3BCC012360AE3600898CF5 /* ViewController.swift */,\n\t\t\t\t3B3BCC032360AE3600898CF5 /* Main.storyboard */,\n\t\t\t\t3B3BCC062360AE3700898CF5 /* Assets.xcassets */,\n\t\t\t\t3B3BCC082360AE3700898CF5 /* LaunchScreen.storyboard */,\n\t\t\t\t3B3BCC0B2360AE3700898CF5 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzObjectDetectionDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t507B40F62954FE952FB51362 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tED4D70C2E170B6741E0000FF /* Pods_FritzObjectDetectionDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC4BF6B27527268175F03B925 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA5A66077100E267087F5017C /* Pods-FritzObjectDetectionDemo.debug.xcconfig */,\n\t\t\t\t80B57F58F06E412BF8CEA44F /* Pods-FritzObjectDetectionDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t3B3BCBF92360AE3600898CF5 /* FritzObjectDetectionDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 3B3BCC0E2360AE3700898CF5 /* Build configuration list for PBXNativeTarget \"FritzObjectDetectionDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t05857ECE8C80580563E7EB9D /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t3B3BCBF62360AE3600898CF5 /* Sources */,\n\t\t\t\t3B3BCBF72360AE3600898CF5 /* Frameworks */,\n\t\t\t\t3B3BCBF82360AE3600898CF5 /* Resources */,\n\t\t\t\t6E82804561854BACD8C840FE /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzObjectDetectionDemo;\n\t\t\tproductName = FritzObjectDetectionDemo;\n\t\t\tproductReference = 3B3BCBFA2360AE3600898CF5 /* FritzObjectDetectionDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t3B3BCBF22360AE3600898CF5 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1110;\n\t\t\t\tLastUpgradeCheck = 1110;\n\t\t\t\tORGANIZATIONNAME = \"Fritz AI\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t3B3BCBF92360AE3600898CF5 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 11.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 3B3BCBF52360AE3600898CF5 /* Build configuration list for PBXProject \"FritzObjectDetectionDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 3B3BCBF12360AE3600898CF5;\n\t\t\tproductRefGroup = 3B3BCBFB2360AE3600898CF5 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t3B3BCBF92360AE3600898CF5 /* FritzObjectDetectionDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t3B3BCBF82360AE3600898CF5 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t3B3BCC0A2360AE3700898CF5 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t3B3BCC072360AE3700898CF5 /* Assets.xcassets in Resources */,\n\t\t\t\t3B3BCC052360AE3600898CF5 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t05857ECE8C80580563E7EB9D /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzObjectDetectionDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t6E82804561854BACD8C840FE /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzObjectDetectionDemo/Pods-FritzObjectDetectionDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzObjectDetectionDemo/Pods-FritzObjectDetectionDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzObjectDetectionDemo/Pods-FritzObjectDetectionDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t3B3BCBF62360AE3600898CF5 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t3B3BCC022360AE3600898CF5 /* ViewController.swift in Sources */,\n\t\t\t\t3B3BCBFE2360AE3600898CF5 /* AppDelegate.swift in Sources */,\n\t\t\t\t3B3BCC002360AE3600898CF5 /* SceneDelegate.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t3B3BCC032360AE3600898CF5 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t3B3BCC042360AE3600898CF5 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B3BCC082360AE3700898CF5 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t3B3BCC092360AE3700898CF5 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t3B3BCC0C2360AE3700898CF5 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 13.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t3B3BCC0D2360AE3700898CF5 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 13.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t3B3BCC0F2360AE3700898CF5 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = A5A66077100E267087F5017C /* Pods-FritzObjectDetectionDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzObjectDetectionDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzObjectDetectionDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t3B3BCC102360AE3700898CF5 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 80B57F58F06E412BF8CEA44F /* Pods-FritzObjectDetectionDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzObjectDetectionDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzObjectDetectionDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t3B3BCBF52360AE3600898CF5 /* Build configuration list for PBXProject \"FritzObjectDetectionDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t3B3BCC0C2360AE3700898CF5 /* Debug */,\n\t\t\t\t3B3BCC0D2360AE3700898CF5 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t3B3BCC0E2360AE3700898CF5 /* Build configuration list for PBXNativeTarget \"FritzObjectDetectionDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t3B3BCC0F2360AE3700898CF5 /* Debug */,\n\t\t\t\t3B3BCC102360AE3700898CF5 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 3B3BCBF22360AE3600898CF5 /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/FritzObjectDetectionDemo.xcodeproj/xcshareddata/xcschemes/FritzObjectDetectionDemo.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1140\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"3B3BCBF92360AE3600898CF5\"\n               BuildableName = \"FritzObjectDetectionDemo.app\"\n               BlueprintName = \"FritzObjectDetectionDemo\"\n               ReferencedContainer = \"container:FritzObjectDetectionDemo.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"3B3BCBF92360AE3600898CF5\"\n            BuildableName = \"FritzObjectDetectionDemo.app\"\n            BlueprintName = \"FritzObjectDetectionDemo\"\n            ReferencedContainer = \"container:FritzObjectDetectionDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"3B3BCBF92360AE3600898CF5\"\n            BuildableName = \"FritzObjectDetectionDemo.app\"\n            BlueprintName = \"FritzObjectDetectionDemo\"\n            ReferencedContainer = \"container:FritzObjectDetectionDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "iOS/FritzObjectDetectionDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzObjectDetectionDemo' do\n  use_frameworks!\n\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionObjectModel/Fast'\n\nend\n"
  },
  {
    "path": "iOS/FritzPetStickerDemo/FritzPetStickerDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzPetStickerDemo\n//\n//  Created by Christopher Kelly on 4/19/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n    // Override point for customization after application launch.\n      // Automatically added FritzCore configure.\n    FritzCore.configure()\n    return true\n  }\n\n  func applicationWillResignActive(_ application: UIApplication) {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n  }\n\n  func applicationDidEnterBackground(_ application: UIApplication) {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n  }\n\n  func applicationWillEnterForeground(_ application: UIApplication) {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n  }\n\n  func applicationDidBecomeActive(_ application: UIApplication) {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n  }\n\n  func applicationWillTerminate(_ application: UIApplication) {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzPetStickerDemo/FritzPetStickerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzPetStickerDemo/FritzPetStickerDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzPetStickerDemo/FritzPetStickerDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzPetStickerDemo/FritzPetStickerDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzPetStickerDemo/FritzPetStickerDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string>Uses Camera for Image processing</string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzPetStickerDemo/FritzPetStickerDemo/ViewController.swift",
    "content": "import UIKit\nimport AVFoundation\nimport Fritz\n\nclass ViewController: UIViewController, UIImagePickerControllerDelegate,\n  UINavigationControllerDelegate {\n\n    @IBOutlet var imageView: UIImageView!\n    var maskView: UIImageView!\n    var backgroundView: UIImageView!\n\n    let context = CIContext()\n    private lazy var visionModel = FritzVisionPetSegmentationModelAccurate()\n\n    override func viewDidLoad() {\n      super.viewDidLoad()\n      openPhotoLibrary()\n      backgroundView = UIImageView(frame: view.bounds)\n      backgroundView.backgroundColor = .red\n      view.addSubview(backgroundView)\n\n      imageView = UIImageView(frame: view.bounds)\n      imageView.contentMode = .scaleAspectFit\n      view.addSubview(imageView)\n    }\n\n    override func viewDidAppear(_ animated: Bool) {\n      super.viewDidAppear(animated)\n    }\n\n    func openPhotoLibrary() {\n      if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {\n        let imagePicker = UIImagePickerController()\n        imagePicker.delegate = self\n        imagePicker.sourceType = .photoLibrary\n        imagePicker.allowsEditing = true\n        self.present(imagePicker, animated: true, completion: nil)\n      }\n    }\n\n    @objc func imagePickerController(_ picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) {\n      self.dismiss(animated: true, completion: { () -> Void in\n      })\n      createSticker(image)\n    }\n}\n\n\nextension ViewController {\n\n  /// Scores output from model greater than this value will be set as 1.\n  /// Lowering this value will make the mask more intense for lower confidence values.\n  var clippingScoresAbove: Double { return 0.6 }\n\n  /// Values lower than this value will not appear in the mask.\n  var zeroingScoresBelow: Double { return 0.4 }\n\n  func createSticker(_ image: UIImage) {\n    let fritzImage = FritzVisionImage(image: image)\n    guard let result = try? visionModel.predict(fritzImage),\n      let mask = result.buildSingleClassMask(\n        forClass: FritzVisionPetClass.pet,\n        clippingScoresAbove: clippingScoresAbove,\n        zeroingScoresBelow: zeroingScoresBelow\n      )\n      else { return }\n\n    let petSticker = fritzImage.masked(with: mask)\n\n    DispatchQueue.main.async {\n      self.imageView.image = petSticker\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzPetStickerDemo/FritzPetStickerDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 50;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t07E1F5075AFAB587890D3780 /* Pods_FritzPetStickerDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA9E527705BAFC3AA411D27C /* Pods_FritzPetStickerDemo.framework */; };\n\t\t83E704A6226A4B6200FF678D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E704A5226A4B6200FF678D /* AppDelegate.swift */; };\n\t\t83E704A8226A4B6200FF678D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E704A7226A4B6200FF678D /* ViewController.swift */; };\n\t\t83E704AB226A4B6200FF678D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83E704A9226A4B6200FF678D /* Main.storyboard */; };\n\t\t83E704AD226A4B6200FF678D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83E704AC226A4B6200FF678D /* Assets.xcassets */; };\n\t\t83E704B0226A4B6200FF678D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83E704AE226A4B6200FF678D /* LaunchScreen.storyboard */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t53CD84B8368B34F84E3C28B0 /* Pods-FritzPetStickerDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzPetStickerDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzPetStickerDemo/Pods-FritzPetStickerDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t83E704A2226A4B6200FF678D /* FritzPetStickerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzPetStickerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t83E704A5226A4B6200FF678D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t83E704A7226A4B6200FF678D /* ViewController.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; tabWidth = 2; };\n\t\t83E704AA226A4B6200FF678D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t83E704AC226A4B6200FF678D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t83E704AF226A4B6200FF678D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t83E704B1226A4B6200FF678D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tAA9E527705BAFC3AA411D27C /* Pods_FritzPetStickerDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzPetStickerDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tB79C8AFE929B0A8D4B50AB62 /* Pods-FritzPetStickerDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzPetStickerDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzPetStickerDemo/Pods-FritzPetStickerDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t83E7049F226A4B6200FF678D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t07E1F5075AFAB587890D3780 /* Pods_FritzPetStickerDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t3416539E3282F0B389088B90 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB79C8AFE929B0A8D4B50AB62 /* Pods-FritzPetStickerDemo.debug.xcconfig */,\n\t\t\t\t53CD84B8368B34F84E3C28B0 /* Pods-FritzPetStickerDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83E70499226A4B6200FF678D = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704A4226A4B6200FF678D /* FritzPetStickerDemo */,\n\t\t\t\t83E704A3226A4B6200FF678D /* Products */,\n\t\t\t\t3416539E3282F0B389088B90 /* Pods */,\n\t\t\t\t84BEB48CA4AE3E92296CE6BD /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83E704A3226A4B6200FF678D /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704A2226A4B6200FF678D /* FritzPetStickerDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83E704A4226A4B6200FF678D /* FritzPetStickerDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704A5226A4B6200FF678D /* AppDelegate.swift */,\n\t\t\t\t83E704A7226A4B6200FF678D /* ViewController.swift */,\n\t\t\t\t83E704A9226A4B6200FF678D /* Main.storyboard */,\n\t\t\t\t83E704AC226A4B6200FF678D /* Assets.xcassets */,\n\t\t\t\t83E704AE226A4B6200FF678D /* LaunchScreen.storyboard */,\n\t\t\t\t83E704B1226A4B6200FF678D /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzPetStickerDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t84BEB48CA4AE3E92296CE6BD /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tAA9E527705BAFC3AA411D27C /* Pods_FritzPetStickerDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t83E704A1226A4B6200FF678D /* FritzPetStickerDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 83E704B4226A4B6200FF678D /* Build configuration list for PBXNativeTarget \"FritzPetStickerDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tA87BA6BF21E7427A83460FB4 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t83E7049E226A4B6200FF678D /* Sources */,\n\t\t\t\t83E7049F226A4B6200FF678D /* Frameworks */,\n\t\t\t\t83E704A0226A4B6200FF678D /* Resources */,\n\t\t\t\t75EBBA0EAF846061FEE1D29C /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzPetStickerDemo;\n\t\t\tproductName = FritzPetStickerDemo;\n\t\t\tproductReference = 83E704A2226A4B6200FF678D /* FritzPetStickerDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t83E7049A226A4B6200FF678D /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1020;\n\t\t\t\tLastUpgradeCheck = 1020;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t83E704A1226A4B6200FF678D = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 10.2.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 83E7049D226A4B6200FF678D /* Build configuration list for PBXProject \"FritzPetStickerDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 83E70499226A4B6200FF678D;\n\t\t\tproductRefGroup = 83E704A3226A4B6200FF678D /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t83E704A1226A4B6200FF678D /* FritzPetStickerDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t83E704A0226A4B6200FF678D /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83E704B0226A4B6200FF678D /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t83E704AD226A4B6200FF678D /* Assets.xcassets in Resources */,\n\t\t\t\t83E704AB226A4B6200FF678D /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t75EBBA0EAF846061FEE1D29C /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzPetStickerDemo/Pods-FritzPetStickerDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzPetStickerDemo/Pods-FritzPetStickerDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzPetStickerDemo/Pods-FritzPetStickerDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tA87BA6BF21E7427A83460FB4 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzPetStickerDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t83E7049E226A4B6200FF678D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83E704A8226A4B6200FF678D /* ViewController.swift in Sources */,\n\t\t\t\t83E704A6226A4B6200FF678D /* AppDelegate.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t83E704A9226A4B6200FF678D /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704AA226A4B6200FF678D /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83E704AE226A4B6200FF678D /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83E704AF226A4B6200FF678D /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t83E704B2226A4B6200FF678D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83E704B3226A4B6200FF678D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t83E704B5226A4B6200FF678D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = B79C8AFE929B0A8D4B50AB62 /* Pods-FritzPetStickerDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzPetStickerDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzPetStickerDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83E704B6226A4B6200FF678D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 53CD84B8368B34F84E3C28B0 /* Pods-FritzPetStickerDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzPetStickerDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzPetStickerDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t83E7049D226A4B6200FF678D /* Build configuration list for PBXProject \"FritzPetStickerDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83E704B2226A4B6200FF678D /* Debug */,\n\t\t\t\t83E704B3226A4B6200FF678D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t83E704B4226A4B6200FF678D /* Build configuration list for PBXNativeTarget \"FritzPetStickerDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83E704B5226A4B6200FF678D /* Debug */,\n\t\t\t\t83E704B6226A4B6200FF678D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 83E7049A226A4B6200FF678D /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzPetStickerDemo/FritzPetStickerDemo.xcodeproj/xcshareddata/xcschemes/FritzPetStickerDemo.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1020\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"83E704A1226A4B6200FF678D\"\n               BuildableName = \"FritzPetStickerDemo.app\"\n               BlueprintName = \"FritzPetStickerDemo\"\n               ReferencedContainer = \"container:FritzPetStickerDemo.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"83E704A1226A4B6200FF678D\"\n            BuildableName = \"FritzPetStickerDemo.app\"\n            BlueprintName = \"FritzPetStickerDemo\"\n            ReferencedContainer = \"container:FritzPetStickerDemo.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"83E704A1226A4B6200FF678D\"\n            BuildableName = \"FritzPetStickerDemo.app\"\n            BlueprintName = \"FritzPetStickerDemo\"\n            ReferencedContainer = \"container:FritzPetStickerDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"83E704A1226A4B6200FF678D\"\n            BuildableName = \"FritzPetStickerDemo.app\"\n            BlueprintName = \"FritzPetStickerDemo\"\n            ReferencedContainer = \"container:FritzPetStickerDemo.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "iOS/FritzPetStickerDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzPetStickerDemo' do\n  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks\n  use_frameworks!\n\n  # Pods for FritzPetStickerDemo\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionSegmentationModel/Pet/Accurate'\n\nend\n"
  },
  {
    "path": "iOS/FritzPetStickerDemo/README.md",
    "content": "# Create stickers with Pet Segmentation\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use the Pet Segmentation model by Fritz to create stickers of dogs.\n\n<img src=\"images/pet_sticker_result.jpg\" width=\"250\" />\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzPetStickerDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzPetStickerDemo`\n\n```\ncd fritz-examples/iOS/FritzPetStickerDemo\npod repo update\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzPetStickerDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Final/FritzPizzaDetectorDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzImageLabelingDemo\n//\n//  Created by Christopher Kelly on 4/23/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n    // Override point for customization after application launch.\n      // Automatically added FritzCore configure.\n      FritzCore.configure()\n    return true\n  }\n\n  func applicationWillResignActive(_ application: UIApplication) {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n  }\n\n  func applicationDidEnterBackground(_ application: UIApplication) {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n  }\n\n  func applicationWillEnterForeground(_ application: UIApplication) {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n  }\n\n  func applicationDidBecomeActive(_ application: UIApplication) {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n  }\n\n  func applicationWillTerminate(_ application: UIApplication) {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Final/FritzPizzaDetectorDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Final/FritzPizzaDetectorDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Final/FritzPizzaDetectorDemo/Assets.xcassets/pizza.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"pizza.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Final/FritzPizzaDetectorDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Final/FritzPizzaDetectorDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Final/FritzPizzaDetectorDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string>Pizza Detector</string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Final/FritzPizzaDetectorDemo/ViewController.swift",
    "content": "import UIKit\nimport AVFoundation\nimport Fritz\n\nclass ViewController: UIViewController {\n\n  var timer: Timer?\n\n  lazy var visionModel = FritzVisionLabelModelFast()\n\n  private lazy var cameraSession = AVCaptureSession()\n  private let sessionQueue = DispatchQueue(label: \"com.fritzdemo.pizzadetector.session\")\n  private let captureQueue = DispatchQueue(label: \"com.fritzdemo.pizzadetector.capture\", qos: DispatchQoS.userInitiated)\n\n  private lazy var previewLayer: AVCaptureVideoPreviewLayer = {\n    let preview = AVCaptureVideoPreviewLayer(session: cameraSession)\n    preview.videoGravity = .resizeAspectFill\n    return preview\n  }()\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    // Setup camera\n    guard let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back),\n      let input = try? AVCaptureDeviceInput(device: device)\n      else { return }\n\n    let output = AVCaptureVideoDataOutput()\n\n    // Configure pixelBuffer format for use in model\n    output.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA as UInt32]\n    output.alwaysDiscardsLateVideoFrames = true\n    output.setSampleBufferDelegate(self, queue: captureQueue)\n\n    sessionQueue.async {\n      self.cameraSession.beginConfiguration()\n      self.cameraSession.addInput(input)\n      self.cameraSession.addOutput(output)\n      self.cameraSession.commitConfiguration()\n      self.cameraSession.sessionPreset = .photo\n    }\n\n  }\n\n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n\n    // Set the preview layer to the frame of the screen and start running.\n    previewLayer.frame = view.layer.bounds\n    view.layer.insertSublayer(previewLayer, at: 0)\n    sessionQueue.async {\n      self.cameraSession.startRunning()\n    }\n  }\n}\n\nextension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate {\n\n  func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {\n    // 1\n    let image = FritzVisionImage(sampleBuffer: sampleBuffer, connection: connection)\n\n    // 2\n    let options = FritzVisionLabelModelOptions()\n    options.imageCropAndScaleOption = .centerCrop\n    options.threshold = 0.2\n\n    // 3\n    guard let results = try? visionModel.predict(image, options: options) else { return }\n\n    // 4\n    let pizzaResults = results.filter { $0.label == \"pizza\" }\n    if pizzaResults.count > 0 {\n      print(\"Creating pizza timer\")\n      DispatchQueue.main.async {\n        for _ in 0..<10 {\n          self.createNewPizzaSlice()\n        }\n      }\n    }\n  }\n}\n\n\nextension ViewController {\n\n  /// Generates a random pizza destination along the edge\n  func generateRandomPizzaDestination() -> CGPoint {\n    let width = view.frame.width\n    let height = view.frame.height\n    let multiplier = Int.random(in: 0..<2)\n\n    let sendPizzaToLeftOrRight = Bool.random()\n    if sendPizzaToLeftOrRight {\n      let randomHeight = CGFloat.random(in: 0..<height)\n      return CGPoint(x: width * CGFloat(multiplier), y: randomHeight)\n    }\n\n    let randomWidth = CGFloat.random(in: 0..<height)\n    return CGPoint(x: randomWidth, y: height * CGFloat(multiplier))\n  }\n\n  var randomJitter: CGFloat {\n    return CGFloat.random(in: -50..<50)\n  }\n\n  /// Creates a new Pizza animation\n  func createNewPizzaSlice() {\n    // 1\n    let pizzaView = UIImageView(image: UIImage(named: \"pizza.png\")!)\n    let frame = CGRect(\n      x: self.view.frame.width / 2 - 50 + randomJitter,\n      y: self.view.frame.height / 2 - 50 + randomJitter,\n      width: 100,\n      height: 100\n    )\n    pizzaView.frame = frame\n\n    // 2\n    self.view.addSubview(pizzaView)\n    self.view.bringSubviewToFront(pizzaView)\n\n    // 3\n    UIView.animate(withDuration: 2.0, animations: {\n      pizzaView.center = self.generateRandomPizzaDestination()\n    }) { _ in\n      pizzaView.removeFromSuperview()\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Final/FritzPizzaDetectorDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 50;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t6A365114E207F19C69A39625 /* Pods_FritzPizzaDetectorDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 570E853E8F32BAD4B7B90A7D /* Pods_FritzPizzaDetectorDemo.framework */; };\n\t\t83CF54F8226FC44900F995AA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83CF54F7226FC44900F995AA /* AppDelegate.swift */; };\n\t\t83CF54FA226FC44900F995AA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83CF54F9226FC44900F995AA /* ViewController.swift */; };\n\t\t83CF54FD226FC44900F995AA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83CF54FB226FC44900F995AA /* Main.storyboard */; };\n\t\t83CF54FF226FC44B00F995AA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83CF54FE226FC44B00F995AA /* Assets.xcassets */; };\n\t\t83CF5502226FC44B00F995AA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83CF5500226FC44B00F995AA /* LaunchScreen.storyboard */; };\n\t\t83CF550A227014A400F995AA /* pizza.png in Resources */ = {isa = PBXBuildFile; fileRef = 83CF5509227014A400F995AA /* pizza.png */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t570E853E8F32BAD4B7B90A7D /* Pods_FritzPizzaDetectorDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzPizzaDetectorDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t83CF54F4226FC44900F995AA /* FritzPizzaDetectorDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzPizzaDetectorDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t83CF54F7226FC44900F995AA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t83CF54F9226FC44900F995AA /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t83CF54FC226FC44900F995AA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t83CF54FE226FC44B00F995AA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t83CF5501226FC44B00F995AA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t83CF5503226FC44B00F995AA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t83CF5509227014A400F995AA /* pizza.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pizza.png; sourceTree = \"<group>\"; };\n\t\t9C9624A4DF75E1B643634C33 /* Pods-FritzPizzaDetectorDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzPizzaDetectorDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzPizzaDetectorDemo/Pods-FritzPizzaDetectorDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tC7388CA76CFEBF4411DFDB4A /* Pods-FritzPizzaDetectorDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzPizzaDetectorDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzPizzaDetectorDemo/Pods-FritzPizzaDetectorDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t83CF54F1226FC44900F995AA /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6A365114E207F19C69A39625 /* Pods_FritzPizzaDetectorDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t83CF54EB226FC44900F995AA = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83CF54F6226FC44900F995AA /* FritzPizzaDetectorDemo */,\n\t\t\t\t83CF54F5226FC44900F995AA /* Products */,\n\t\t\t\tCCBBAFAAC2FCE02994D6D09F /* Pods */,\n\t\t\t\tCC69C9D3374DA88503BD4674 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83CF54F5226FC44900F995AA /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83CF54F4226FC44900F995AA /* FritzPizzaDetectorDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83CF54F6226FC44900F995AA /* FritzPizzaDetectorDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83CF54F7226FC44900F995AA /* AppDelegate.swift */,\n\t\t\t\t83CF54F9226FC44900F995AA /* ViewController.swift */,\n\t\t\t\t83CF54FB226FC44900F995AA /* Main.storyboard */,\n\t\t\t\t83CF5509227014A400F995AA /* pizza.png */,\n\t\t\t\t83CF54FE226FC44B00F995AA /* Assets.xcassets */,\n\t\t\t\t83CF5500226FC44B00F995AA /* LaunchScreen.storyboard */,\n\t\t\t\t83CF5503226FC44B00F995AA /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzPizzaDetectorDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tCC69C9D3374DA88503BD4674 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t570E853E8F32BAD4B7B90A7D /* Pods_FritzPizzaDetectorDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tCCBBAFAAC2FCE02994D6D09F /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9C9624A4DF75E1B643634C33 /* Pods-FritzPizzaDetectorDemo.debug.xcconfig */,\n\t\t\t\tC7388CA76CFEBF4411DFDB4A /* Pods-FritzPizzaDetectorDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t83CF54F3226FC44900F995AA /* FritzPizzaDetectorDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 83CF5506226FC44B00F995AA /* Build configuration list for PBXNativeTarget \"FritzPizzaDetectorDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tCB469173CE2DB334D3397BAE /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t83CF54F0226FC44900F995AA /* Sources */,\n\t\t\t\t83CF54F1226FC44900F995AA /* Frameworks */,\n\t\t\t\t83CF54F2226FC44900F995AA /* Resources */,\n\t\t\t\tAF706660276906083F1D83A0 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzPizzaDetectorDemo;\n\t\t\tproductName = FritzImageLabelingDemo;\n\t\t\tproductReference = 83CF54F4226FC44900F995AA /* FritzPizzaDetectorDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t83CF54EC226FC44900F995AA /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1020;\n\t\t\t\tLastUpgradeCheck = 1020;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t83CF54F3226FC44900F995AA = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 10.2.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 83CF54EF226FC44900F995AA /* Build configuration list for PBXProject \"FritzImageLabelingDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 83CF54EB226FC44900F995AA;\n\t\t\tproductRefGroup = 83CF54F5226FC44900F995AA /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t83CF54F3226FC44900F995AA /* FritzPizzaDetectorDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t83CF54F2226FC44900F995AA /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83CF550A227014A400F995AA /* pizza.png in Resources */,\n\t\t\t\t83CF5502226FC44B00F995AA /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t83CF54FF226FC44B00F995AA /* Assets.xcassets in Resources */,\n\t\t\t\t83CF54FD226FC44900F995AA /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\tAF706660276906083F1D83A0 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzPizzaDetectorDemo/Pods-FritzPizzaDetectorDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzPizzaDetectorDemo/Pods-FritzPizzaDetectorDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzPizzaDetectorDemo/Pods-FritzPizzaDetectorDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tCB469173CE2DB334D3397BAE /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzPizzaDetectorDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t83CF54F0226FC44900F995AA /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83CF54FA226FC44900F995AA /* ViewController.swift in Sources */,\n\t\t\t\t83CF54F8226FC44900F995AA /* AppDelegate.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t83CF54FB226FC44900F995AA /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83CF54FC226FC44900F995AA /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83CF5500226FC44B00F995AA /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83CF5501226FC44B00F995AA /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t83CF5504226FC44B00F995AA /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83CF5505226FC44B00F995AA /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t83CF5507226FC44B00F995AA /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 9C9624A4DF75E1B643634C33 /* Pods-FritzPizzaDetectorDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzPizzaDetectorDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzPizzaDetectorDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83CF5508226FC44B00F995AA /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = C7388CA76CFEBF4411DFDB4A /* Pods-FritzPizzaDetectorDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzPizzaDetectorDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzPizzaDetectorDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t83CF54EF226FC44900F995AA /* Build configuration list for PBXProject \"FritzImageLabelingDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83CF5504226FC44B00F995AA /* Debug */,\n\t\t\t\t83CF5505226FC44B00F995AA /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t83CF5506226FC44B00F995AA /* Build configuration list for PBXNativeTarget \"FritzPizzaDetectorDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83CF5507226FC44B00F995AA /* Debug */,\n\t\t\t\t83CF5508226FC44B00F995AA /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 83CF54EC226FC44900F995AA /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Final/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzPizzaDetectorDemo' do\n  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks\n  use_frameworks!\n\n  # Pods for FritzPizzaDetectorDemo\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionLabelModel/Fast'\n\nend\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/README.md",
    "content": "# Pizza Detector Demo with Image Labeling\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use the Image Labeling API by Fritz in order to build a pizza identifier similar to Domino's Points for Pies feature.\n\nFor the full tutorial, visit [our post on Heartbeat](https://heartbeat.fritz.ai/recreate-dominos-points-for-pies-app-on-ios-with-fritz-image-labeling-2ed23398e1c2).\n\n![](images/pizza.gif)\n\nThere are 2 projects to help you get started:\n\n- Starter app - The bare bones app you should use to get started with the tutorial.\n- Final app - The finished app displaying an animation when a pizza is detected.\n\nChoose an app and run it in Xcode.\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzPizzaDetectorDemo (Starter or Final folder)**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzPizzaDetectorDemo/Starter`\n\n```\ncd fritz-examples/iOS/FritzPizzaDetectorDemo/Starter\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzPizzaDetectorDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Starter/FritzPizzaDetectorDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzImageLabelingDemo\n//\n//  Created by Christopher Kelly on 4/23/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n    // Override point for customization after application launch.\n      // Automatically added FritzCore configure.\n      FritzCore.configure()\n    return true\n  }\n\n  func applicationWillResignActive(_ application: UIApplication) {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n  }\n\n  func applicationDidEnterBackground(_ application: UIApplication) {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n  }\n\n  func applicationWillEnterForeground(_ application: UIApplication) {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n  }\n\n  func applicationDidBecomeActive(_ application: UIApplication) {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n  }\n\n  func applicationWillTerminate(_ application: UIApplication) {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Starter/FritzPizzaDetectorDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Starter/FritzPizzaDetectorDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Starter/FritzPizzaDetectorDemo/Assets.xcassets/pizza.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"pizza.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Starter/FritzPizzaDetectorDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Starter/FritzPizzaDetectorDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Starter/FritzPizzaDetectorDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string>Pizza Detector</string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Starter/FritzPizzaDetectorDemo/ViewController.swift",
    "content": "import UIKit\nimport AVFoundation\nimport Fritz\n\nclass ViewController: UIViewController {\n\n  var timer: Timer?\n\n  private lazy var cameraSession = AVCaptureSession()\n  private let sessionQueue = DispatchQueue(label: \"com.fritzdemo.pizzadetector.session\")\n  private let captureQueue = DispatchQueue(label: \"com.fritzdemo.pizzadetector.capture\", qos: DispatchQoS.userInitiated)\n\n  private lazy var previewLayer: AVCaptureVideoPreviewLayer = {\n    let preview =  AVCaptureVideoPreviewLayer(session: cameraSession)\n    preview.videoGravity = .resizeAspectFill\n    return preview\n  }()\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    // Setup camera\n    guard let device = AVCaptureDevice.default(\n      .builtInWideAngleCamera, for: .video, position: .back),\n      let input = try? AVCaptureDeviceInput(device: device)\n      else { return }\n\n    let output = AVCaptureVideoDataOutput()\n\n    // Configure pixelBuffer format for use in model\n    output.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA as UInt32]\n    output.alwaysDiscardsLateVideoFrames = true\n    output.setSampleBufferDelegate(self, queue: captureQueue)\n\n    sessionQueue.async {\n      self.cameraSession.beginConfiguration()\n      self.cameraSession.addInput(input)\n      self.cameraSession.addOutput(output)\n      self.cameraSession.commitConfiguration()\n      self.cameraSession.sessionPreset = .photo\n    }\n\n  }\n\n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n\n    // Set the preview layer to the frame of the screen and start running.\n    previewLayer.frame = view.layer.bounds\n    view.layer.insertSublayer(previewLayer, at: 0)\n    sessionQueue.async {\n      self.cameraSession.startRunning()\n    }\n  }\n}\n\nextension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate {\n\n  func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {\n    // 1\n\n    // 2\n\n    // 3\n\n    // 4\n  }\n}\n\n\nextension ViewController {\n\n  /// Generates a random pizza destination along the edge\n  func generateRandomPizzaDestination() -> CGPoint {\n    let width = view.frame.width\n    let height = view.frame.height\n    let multiplier = Int.random(in: 0..<2)\n\n    let sendPizzaToLeftOrRight = Bool.random()\n    if sendPizzaToLeftOrRight {\n      let randomHeight = CGFloat.random(in: 0..<height)\n      return CGPoint(x: width * CGFloat(multiplier), y: randomHeight)\n    }\n\n    let randomWidth = CGFloat.random(in: 0..<height)\n    return CGPoint(x: randomWidth, y: height * CGFloat(multiplier))\n  }\n\n  /// Creates a new Pizza animation\n  @objc func createNewPizzaSlice() {\n    // 1\n\n    // 2\n\n    // 3\n  }\n}\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Starter/FritzPizzaDetectorDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 50;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t6A365114E207F19C69A39625 /* Pods_FritzPizzaDetectorDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 570E853E8F32BAD4B7B90A7D /* Pods_FritzPizzaDetectorDemo.framework */; };\n\t\t83CF54F8226FC44900F995AA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83CF54F7226FC44900F995AA /* AppDelegate.swift */; };\n\t\t83CF54FA226FC44900F995AA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83CF54F9226FC44900F995AA /* ViewController.swift */; };\n\t\t83CF54FD226FC44900F995AA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83CF54FB226FC44900F995AA /* Main.storyboard */; };\n\t\t83CF54FF226FC44B00F995AA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83CF54FE226FC44B00F995AA /* Assets.xcassets */; };\n\t\t83CF5502226FC44B00F995AA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83CF5500226FC44B00F995AA /* LaunchScreen.storyboard */; };\n\t\t83CF550A227014A400F995AA /* pizza.png in Resources */ = {isa = PBXBuildFile; fileRef = 83CF5509227014A400F995AA /* pizza.png */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t570E853E8F32BAD4B7B90A7D /* Pods_FritzPizzaDetectorDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzPizzaDetectorDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t83CF54F4226FC44900F995AA /* FritzPizzaDetectorDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzPizzaDetectorDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t83CF54F7226FC44900F995AA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t83CF54F9226FC44900F995AA /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t83CF54FC226FC44900F995AA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t83CF54FE226FC44B00F995AA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t83CF5501226FC44B00F995AA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t83CF5503226FC44B00F995AA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t83CF5509227014A400F995AA /* pizza.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = pizza.png; sourceTree = \"<group>\"; };\n\t\t9C9624A4DF75E1B643634C33 /* Pods-FritzPizzaDetectorDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzPizzaDetectorDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzPizzaDetectorDemo/Pods-FritzPizzaDetectorDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tC7388CA76CFEBF4411DFDB4A /* Pods-FritzPizzaDetectorDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzPizzaDetectorDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzPizzaDetectorDemo/Pods-FritzPizzaDetectorDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t83CF54F1226FC44900F995AA /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6A365114E207F19C69A39625 /* Pods_FritzPizzaDetectorDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t83CF54EB226FC44900F995AA = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83CF54F6226FC44900F995AA /* FritzPizzaDetectorDemo */,\n\t\t\t\t83CF54F5226FC44900F995AA /* Products */,\n\t\t\t\tCCBBAFAAC2FCE02994D6D09F /* Pods */,\n\t\t\t\tCC69C9D3374DA88503BD4674 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83CF54F5226FC44900F995AA /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83CF54F4226FC44900F995AA /* FritzPizzaDetectorDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83CF54F6226FC44900F995AA /* FritzPizzaDetectorDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83CF54F7226FC44900F995AA /* AppDelegate.swift */,\n\t\t\t\t83CF54F9226FC44900F995AA /* ViewController.swift */,\n\t\t\t\t83CF54FB226FC44900F995AA /* Main.storyboard */,\n\t\t\t\t83CF5509227014A400F995AA /* pizza.png */,\n\t\t\t\t83CF54FE226FC44B00F995AA /* Assets.xcassets */,\n\t\t\t\t83CF5500226FC44B00F995AA /* LaunchScreen.storyboard */,\n\t\t\t\t83CF5503226FC44B00F995AA /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzPizzaDetectorDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tCC69C9D3374DA88503BD4674 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t570E853E8F32BAD4B7B90A7D /* Pods_FritzPizzaDetectorDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tCCBBAFAAC2FCE02994D6D09F /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9C9624A4DF75E1B643634C33 /* Pods-FritzPizzaDetectorDemo.debug.xcconfig */,\n\t\t\t\tC7388CA76CFEBF4411DFDB4A /* Pods-FritzPizzaDetectorDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t83CF54F3226FC44900F995AA /* FritzPizzaDetectorDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 83CF5506226FC44B00F995AA /* Build configuration list for PBXNativeTarget \"FritzPizzaDetectorDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tCB469173CE2DB334D3397BAE /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t83CF54F0226FC44900F995AA /* Sources */,\n\t\t\t\t83CF54F1226FC44900F995AA /* Frameworks */,\n\t\t\t\t83CF54F2226FC44900F995AA /* Resources */,\n\t\t\t\tAF706660276906083F1D83A0 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzPizzaDetectorDemo;\n\t\t\tproductName = FritzImageLabelingDemo;\n\t\t\tproductReference = 83CF54F4226FC44900F995AA /* FritzPizzaDetectorDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t83CF54EC226FC44900F995AA /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1020;\n\t\t\t\tLastUpgradeCheck = 1020;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t83CF54F3226FC44900F995AA = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 10.2.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 83CF54EF226FC44900F995AA /* Build configuration list for PBXProject \"FritzImageLabelingDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 83CF54EB226FC44900F995AA;\n\t\t\tproductRefGroup = 83CF54F5226FC44900F995AA /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t83CF54F3226FC44900F995AA /* FritzPizzaDetectorDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t83CF54F2226FC44900F995AA /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83CF550A227014A400F995AA /* pizza.png in Resources */,\n\t\t\t\t83CF5502226FC44B00F995AA /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t83CF54FF226FC44B00F995AA /* Assets.xcassets in Resources */,\n\t\t\t\t83CF54FD226FC44900F995AA /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\tAF706660276906083F1D83A0 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzPizzaDetectorDemo/Pods-FritzPizzaDetectorDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzPizzaDetectorDemo/Pods-FritzPizzaDetectorDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzPizzaDetectorDemo/Pods-FritzPizzaDetectorDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tCB469173CE2DB334D3397BAE /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzPizzaDetectorDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t83CF54F0226FC44900F995AA /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83CF54FA226FC44900F995AA /* ViewController.swift in Sources */,\n\t\t\t\t83CF54F8226FC44900F995AA /* AppDelegate.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t83CF54FB226FC44900F995AA /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83CF54FC226FC44900F995AA /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83CF5500226FC44B00F995AA /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83CF5501226FC44B00F995AA /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t83CF5504226FC44B00F995AA /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83CF5505226FC44B00F995AA /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t83CF5507226FC44B00F995AA /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 9C9624A4DF75E1B643634C33 /* Pods-FritzPizzaDetectorDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzPizzaDetectorDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzPizzaDetectorDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83CF5508226FC44B00F995AA /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = C7388CA76CFEBF4411DFDB4A /* Pods-FritzPizzaDetectorDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzPizzaDetectorDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzPizzaDetectorDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t83CF54EF226FC44900F995AA /* Build configuration list for PBXProject \"FritzImageLabelingDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83CF5504226FC44B00F995AA /* Debug */,\n\t\t\t\t83CF5505226FC44B00F995AA /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t83CF5506226FC44B00F995AA /* Build configuration list for PBXNativeTarget \"FritzPizzaDetectorDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83CF5507226FC44B00F995AA /* Debug */,\n\t\t\t\t83CF5508226FC44B00F995AA /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 83CF54EC226FC44900F995AA /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzPizzaDetectorDemo/Starter/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzPizzaDetectorDemo' do\n  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks\n  use_frameworks!\n\n  # Pods for FritzPizzaDetectorDemo\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionLabelModel/Fast'\n\nend\n"
  },
  {
    "path": "iOS/FritzPoseEstimationDemo/FritzPoseEstimationDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzPoseEstimationDemo\n//\n//  Created by Christopher Kelly on 4/17/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n    // Override point for customization after application launch.\n    FritzCore.configure()\n    return true\n  }\n\n  func applicationWillResignActive(_ application: UIApplication) {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n  }\n\n  func applicationDidEnterBackground(_ application: UIApplication) {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n  }\n\n  func applicationWillEnterForeground(_ application: UIApplication) {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n  }\n\n  func applicationDidBecomeActive(_ application: UIApplication) {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n  }\n\n  func applicationWillTerminate(_ application: UIApplication) {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzPoseEstimationDemo/FritzPoseEstimationDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzPoseEstimationDemo/FritzPoseEstimationDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzPoseEstimationDemo/FritzPoseEstimationDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzPoseEstimationDemo/FritzPoseEstimationDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15705\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <device id=\"retina6_1\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15706\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModule=\"FritzPoseEstimationDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"896\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Qb9-gK-sTx\" userLabel=\"Model Version\">\n                                <rect key=\"frame\" x=\"19\" y=\"661\" width=\"377\" height=\"16\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"fa0-Do-U2N\" userLabel=\"Model ID\">\n                                <rect key=\"frame\" x=\"19\" y=\"690\" width=\"377\" height=\"16\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"i0J-m8-ika\" userLabel=\"FPS\">\n                                <rect key=\"frame\" x=\"19\" y=\"719\" width=\"377\" height=\"16\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <nil key=\"highlightedColor\"/>\n                                <color key=\"shadowColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </label>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstItem=\"fa0-Do-U2N\" firstAttribute=\"trailing\" secondItem=\"i0J-m8-ika\" secondAttribute=\"trailing\" id=\"Nsb-06-Nyr\"/>\n                            <constraint firstItem=\"Qb9-gK-sTx\" firstAttribute=\"leading\" secondItem=\"fa0-Do-U2N\" secondAttribute=\"leading\" id=\"PEP-5E-u9p\"/>\n                            <constraint firstItem=\"i0J-m8-ika\" firstAttribute=\"top\" secondItem=\"fa0-Do-U2N\" secondAttribute=\"bottom\" constant=\"13\" id=\"Po5-5M-f4o\"/>\n                            <constraint firstItem=\"Qb9-gK-sTx\" firstAttribute=\"trailing\" secondItem=\"fa0-Do-U2N\" secondAttribute=\"trailing\" id=\"Sbp-Jl-XAH\"/>\n                            <constraint firstItem=\"Qb9-gK-sTx\" firstAttribute=\"leading\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"leading\" constant=\"19\" id=\"Tor-uM-IKG\"/>\n                            <constraint firstItem=\"Qb9-gK-sTx\" firstAttribute=\"top\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"top\" constant=\"617\" id=\"bMq-Fs-lJg\"/>\n                            <constraint firstItem=\"fa0-Do-U2N\" firstAttribute=\"leading\" secondItem=\"i0J-m8-ika\" secondAttribute=\"leading\" id=\"rrv-nt-Xtd\"/>\n                            <constraint firstItem=\"fa0-Do-U2N\" firstAttribute=\"top\" secondItem=\"Qb9-gK-sTx\" secondAttribute=\"bottom\" constant=\"13\" id=\"teU-iL-TtT\"/>\n                            <constraint firstItem=\"Qb9-gK-sTx\" firstAttribute=\"centerX\" secondItem=\"8bC-Xf-vdC\" secondAttribute=\"centerX\" id=\"wC8-Bc-BKE\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                    <connections>\n                        <outlet property=\"fpsLabel\" destination=\"i0J-m8-ika\" id=\"OFp-AU-ifZ\"/>\n                        <outlet property=\"modelIdLabel\" destination=\"fa0-Do-U2N\" id=\"OxN-VO-ieI\"/>\n                        <outlet property=\"modelVersionLabel\" destination=\"Qb9-gK-sTx\" id=\"KkE-cT-nfs\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"137.68115942028987\" y=\"138.61607142857142\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzPoseEstimationDemo/FritzPoseEstimationDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string>For processing camera inputs</string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzPoseEstimationDemo/FritzPoseEstimationDemo/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  FritzStyleTransferDemo\n//\n//  Created by Christopher Kelly on 9/12/18.\n//  Copyright © 2018 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Photos\nimport Fritz\n\n\nextension Double {\n  func format(f: String) -> String {\n    return String(format: \"%\\(f)f\", self)\n  }\n}\n\n\nclass ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {\n\n  var previewView: UIImageView!\n  @IBOutlet weak var fpsLabel: UILabel!\n  @IBOutlet weak var modelIdLabel: UILabel!\n  @IBOutlet weak var modelVersionLabel: UILabel!\n  \n  var lastExecution = Date()\n\n  // Use a pre-trained human pose estimation model from Fritz AI.\n  lazy var poseModel = FritzVisionHumanPoseModelFast()\n  // To use your own pose estimation model, following instructions here:\n  // https://docs.fritz.ai/develop/vision/pose-estimation/custom-pose-estimation/ios.html\n\n  lazy var poseSmoother = PoseSmoother<OneEuroPointFilter, HumanSkeleton>()\n  \n  // Confidence thresholds define the minimum threshold required to show a pose (i.e. an entire skeleton)\n  // as well as the minimum threshold to include a part (i.e. an arm) in a given pose.\n  let minPoseThreshold = 0.4\n  let minPartThreshold = 0.5\n\n  private lazy var captureSession: AVCaptureSession = {\n    let session = AVCaptureSession()\n\n    guard\n      let backCamera = AVCaptureDevice.default(\n          .builtInWideAngleCamera,\n        for: .video,\n        position: .back),\n      let input = try? AVCaptureDeviceInput(device: backCamera)\n      else { return session }\n    session.addInput(input)\n\n    session.sessionPreset = .photo\n    return session\n  }()\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    // Add preview View as a subview\n    previewView = UIImageView(frame: view.bounds)\n    previewView.contentMode = .scaleAspectFill\n    view.addSubview(previewView)\n    view.bringSubviewToFront(fpsLabel)\n    view.bringSubviewToFront(modelIdLabel)\n    view.bringSubviewToFront(modelVersionLabel)\n    fpsLabel.textAlignment = .center\n    modelIdLabel.textAlignment = .center\n    modelVersionLabel.textAlignment = .center\n\n    let videoOutput = AVCaptureVideoDataOutput()\n    videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA as UInt32]\n    videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: \"MyQueue\"))\n    self.captureSession.addOutput(videoOutput)\n    self.captureSession.startRunning()\n  }\n\n  override func viewWillLayoutSubviews() {\n    super.viewWillLayoutSubviews()\n\n    previewView.frame = view.bounds\n  }\n\n  override func didReceiveMemoryWarning() {\n    super.didReceiveMemoryWarning()\n    // Dispose of any resources that can be recreated.\n  }\n\n  func displayInputImage(_ image: FritzVisionImage) {\n    guard let rotated = image.rotate() else { return }\n\n    let image = UIImage(pixelBuffer: rotated)\n    DispatchQueue.main.async {\n      self.previewView.image = image\n    }\n  }\n  \n  func updateLabels() {\n    let thisExecution = Date()\n    let executionTime = thisExecution.timeIntervalSince(self.lastExecution)\n    let framesPerSecond: Double = 1 / executionTime\n    self.lastExecution = thisExecution\n    \n    DispatchQueue.main.async {\n      self.fpsLabel.text = \"FPS: \\(framesPerSecond.format(f: \".3\"))\"\n      self.modelIdLabel.text = \"Model ID: \\(self.poseModel.managedModel.activeModelConfig.identifier)\"\n      self.modelVersionLabel.text = \"Active Version: \\(self.poseModel.managedModel.activeModelConfig.version)\"\n    }\n  }\n\n  func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {\n\n    let image = FritzVisionImage(sampleBuffer: sampleBuffer, connection: connection)\n    let options = FritzVisionPoseModelOptions()\n    options.minPoseThreshold = minPoseThreshold\n    options.minPartThreshold = minPartThreshold\n\n    guard let result = try? poseModel.predict(image, options: options) else {\n      // If there was no pose, display original image\n      displayInputImage(image)\n      return\n    }\n    \n    // To record predictions and send data back to Fritz AI via the Data Collection System, use the predictors's record method.\n    // In addition to the input image, predicted model results can be collected as well as user-modified annotations.\n    // This allows developers to both gather data on model performance and have users collect additional ground truth data for future model retraining.\n    // Note, the Data Collection System is only available on paid plans.\n    // poseModel.record(image, predicted: result.poses(), modified: nil)\n    \n    updateLabels()\n\n    guard let pose = result.pose() else {\n      displayInputImage(image)\n      return\n    }\n\n    // Uncomment to use pose smoothing to smoothe output of model.\n    // Will increase lag of pose a bit.\n    // pose = poseSmoother.smoothe(pose)\n\n    guard let poseResult = image.draw(pose: pose) else {\n      displayInputImage(image)\n      return\n    }\n\n    DispatchQueue.main.async {\n      self.previewView.image = poseResult\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzPoseEstimationDemo/FritzPoseEstimationDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 50;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t835093982266E79700A81041 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835093972266E79700A81041 /* AppDelegate.swift */; };\n\t\t8350939A2266E79700A81041 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 835093992266E79700A81041 /* ViewController.swift */; };\n\t\t8350939D2266E79700A81041 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8350939B2266E79700A81041 /* Main.storyboard */; };\n\t\t8350939F2266E79A00A81041 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8350939E2266E79A00A81041 /* Assets.xcassets */; };\n\t\t835093A22266E79A00A81041 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 835093A02266E79A00A81041 /* LaunchScreen.storyboard */; };\n\t\tCA9D737E8D5937668E813481 /* Pods_FritzPoseEstimationDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF2D3F7F5A85845D830837DA /* Pods_FritzPoseEstimationDemo.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t28CF6E356F53795732B1EEB7 /* Pods-FritzPoseEstimationDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzPoseEstimationDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzPoseEstimationDemo/Pods-FritzPoseEstimationDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t368301A8AEE420980BF157CE /* Pods-FritzPoseEstimationDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzPoseEstimationDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzPoseEstimationDemo/Pods-FritzPoseEstimationDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t835093942266E79700A81041 /* FritzPoseEstimationDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzPoseEstimationDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t835093972266E79700A81041 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t835093992266E79700A81041 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t8350939C2266E79700A81041 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t8350939E2266E79A00A81041 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t835093A12266E79A00A81041 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t835093A32266E79A00A81041 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tBF2D3F7F5A85845D830837DA /* Pods_FritzPoseEstimationDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzPoseEstimationDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t835093912266E79700A81041 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tCA9D737E8D5937668E813481 /* Pods_FritzPoseEstimationDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t0E51049CF64363F30A642B1E /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tBF2D3F7F5A85845D830837DA /* Pods_FritzPoseEstimationDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6B6A0C1CDEA2CB519307802D /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28CF6E356F53795732B1EEB7 /* Pods-FritzPoseEstimationDemo.debug.xcconfig */,\n\t\t\t\t368301A8AEE420980BF157CE /* Pods-FritzPoseEstimationDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8350938B2266E79700A81041 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t835093962266E79700A81041 /* FritzPoseEstimationDemo */,\n\t\t\t\t835093952266E79700A81041 /* Products */,\n\t\t\t\t6B6A0C1CDEA2CB519307802D /* Pods */,\n\t\t\t\t0E51049CF64363F30A642B1E /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t835093952266E79700A81041 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t835093942266E79700A81041 /* FritzPoseEstimationDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t835093962266E79700A81041 /* FritzPoseEstimationDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t835093972266E79700A81041 /* AppDelegate.swift */,\n\t\t\t\t835093992266E79700A81041 /* ViewController.swift */,\n\t\t\t\t8350939B2266E79700A81041 /* Main.storyboard */,\n\t\t\t\t8350939E2266E79A00A81041 /* Assets.xcassets */,\n\t\t\t\t835093A02266E79A00A81041 /* LaunchScreen.storyboard */,\n\t\t\t\t835093A32266E79A00A81041 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzPoseEstimationDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t835093932266E79700A81041 /* FritzPoseEstimationDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 835093A62266E79A00A81041 /* Build configuration list for PBXNativeTarget \"FritzPoseEstimationDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tB7EED0EB740E109F4933347F /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t835093902266E79700A81041 /* Sources */,\n\t\t\t\t835093912266E79700A81041 /* Frameworks */,\n\t\t\t\t835093922266E79700A81041 /* Resources */,\n\t\t\t\tA2DDE3DD10119E3B7E15123B /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzPoseEstimationDemo;\n\t\t\tproductName = FritzPoseEstimationDemo;\n\t\t\tproductReference = 835093942266E79700A81041 /* FritzPoseEstimationDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t8350938C2266E79700A81041 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1020;\n\t\t\t\tLastUpgradeCheck = 1020;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t835093932266E79700A81041 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 10.2;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 8350938F2266E79700A81041 /* Build configuration list for PBXProject \"FritzPoseEstimationDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 8350938B2266E79700A81041;\n\t\t\tproductRefGroup = 835093952266E79700A81041 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t835093932266E79700A81041 /* FritzPoseEstimationDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t835093922266E79700A81041 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t835093A22266E79A00A81041 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t8350939F2266E79A00A81041 /* Assets.xcassets in Resources */,\n\t\t\t\t8350939D2266E79700A81041 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\tA2DDE3DD10119E3B7E15123B /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzPoseEstimationDemo/Pods-FritzPoseEstimationDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzPoseEstimationDemo/Pods-FritzPoseEstimationDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzPoseEstimationDemo/Pods-FritzPoseEstimationDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tB7EED0EB740E109F4933347F /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzPoseEstimationDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t835093902266E79700A81041 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t8350939A2266E79700A81041 /* ViewController.swift in Sources */,\n\t\t\t\t835093982266E79700A81041 /* AppDelegate.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t8350939B2266E79700A81041 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t8350939C2266E79700A81041 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t835093A02266E79A00A81041 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t835093A12266E79A00A81041 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t835093A42266E79A00A81041 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t835093A52266E79A00A81041 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t835093A72266E79A00A81041 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 28CF6E356F53795732B1EEB7 /* Pods-FritzPoseEstimationDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzPoseEstimationDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzPoseEstimationDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t835093A82266E79A00A81041 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 368301A8AEE420980BF157CE /* Pods-FritzPoseEstimationDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzPoseEstimationDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzPoseEstimationDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t8350938F2266E79700A81041 /* Build configuration list for PBXProject \"FritzPoseEstimationDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t835093A42266E79A00A81041 /* Debug */,\n\t\t\t\t835093A52266E79A00A81041 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t835093A62266E79A00A81041 /* Build configuration list for PBXNativeTarget \"FritzPoseEstimationDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t835093A72266E79A00A81041 /* Debug */,\n\t\t\t\t835093A82266E79A00A81041 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 8350938C2266E79700A81041 /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzPoseEstimationDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzPoseEstimationDemo' do\n  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks\n  use_frameworks!\n\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionPoseModel/Human/Fast'\n\nend\n"
  },
  {
    "path": "iOS/FritzPoseEstimationDemo/README.md",
    "content": "# Pose Estimation\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use the Pose Estimation API by Fritz in order to identify and track the movement of different human poses.\n\nFor the full tutorial, visit [our post on Heartbeat](https://heartbeat.fritz.ai/pose-estimation-on-ios-with-fritz-60c8e5f7d195).\n\n<img src=\"images/pose_estimation_ios.jpg\" width=\"250\" />\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzPoseEstimationDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzPoseEstimationDemo`\n\n```\ncd fritz-examples/iOS/FritzPoseEstimationDemo\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzPoseEstimationDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzSkyReplacementDemo/FritzSkyReplacementDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzSkyReplacementDemo\n//\n//  Created by Christopher Kelly on 6/7/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n    // Override point for customization after application launch.\n      // Automatically added FritzCore configure.\n    FritzCore.configure()\n    return true\n  }\n\n  func applicationWillResignActive(_ application: UIApplication) {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n  }\n\n  func applicationDidEnterBackground(_ application: UIApplication) {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n  }\n\n  func applicationWillEnterForeground(_ application: UIApplication) {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n  }\n\n  func applicationDidBecomeActive(_ application: UIApplication) {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n  }\n\n  func applicationWillTerminate(_ application: UIApplication) {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n  }\n\n\n}\n\n"
  },
  {
    "path": "iOS/FritzSkyReplacementDemo/FritzSkyReplacementDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzSkyReplacementDemo/FritzSkyReplacementDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzSkyReplacementDemo/FritzSkyReplacementDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzSkyReplacementDemo/FritzSkyReplacementDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzSkyReplacementDemo/FritzSkyReplacementDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzSkyReplacementDemo/FritzSkyReplacementDemo/ViewController.swift",
    "content": "import UIKit\nimport AVFoundation\nimport Fritz\n\nclass ViewController: UIViewController {\n\n  @IBOutlet var imageView: UIImageView!\n  var backgroundView: UIImageView!\n  var backgroundViewDelayed: UIImageView!\n\n  let context = CIContext()\n\n  /// Scores output from model greater than this value will be set as 1.\n  /// Lowering this value will make the mask more intense for lower confidence values.\n  var clippingScoresAbove: Double { return 0.5 }\n\n  /// Values lower than this value will not appear in the mask.\n\n  var zeroingScoresBelow: Double { return 0.3 }\n\n  /// Controls the opacity the mask is applied to the base image.\n  var opacity: CGFloat { return 1.0 }\n\n  private lazy var visionModel = FritzVisionSkySegmentationModelFast()\n\n  let foreground = UIImage(named: \"mountains.jpg\")\n  let background = UIImage(named: \"clouds.png\")\n\n  var animationDuration = 12.0\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    backgroundView = initialBackground()\n    backgroundViewDelayed = initialBackground()\n\n    imageView = UIImageView(frame: view.bounds)\n    imageView.contentMode = .scaleAspectFill\n    view.addSubview(imageView)\n    createSticker(foreground!)\n    view.addSubview(backgroundView)\n    view.addSubview(backgroundViewDelayed)\n\n    view.bringSubviewToFront(imageView)\n    startAnimation(on: backgroundView, delay: 0.0)\n    startAnimation(on: backgroundViewDelayed, delay: animationDuration / 2)\n\n  }\n\n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n  }\n\n  func initialBackground() -> UIImageView {\n    let shiftedLeft = CGRect(origin: CGPoint(x: -view.bounds.width, y: view.bounds.minY),\n      size: view.bounds.size)\n    let view = UIImageView(frame: shiftedLeft)\n    view.contentMode = .scaleAspectFill\n    view.image = background\n    return view\n  }\n\n  func startAnimation(on imageView: UIImageView, delay: Double) {\n    UIView.animate(withDuration: animationDuration, delay: delay, options: [.repeat, .curveLinear], animations: {\n        imageView.frame = CGRect(\n          origin: CGPoint(x: self.view.bounds.width, y: self.view.bounds.minY),\n          size: self.view.bounds.size\n        )\n      })\n  }\n\n  /// Remove background of input image based on an alpha mask.\n  ///\n  /// - Parameters:\n  ///   - image: Image to mask\n  ///   - mask: Input mask.  Reduces pixel opacity by mask alpha value. For instance,\n  ///       an alpha value of 255 will be completely opaque, 0 will be completely transparent\n  ///       and a value of 125 will be partially transparent.\n  /// - Returns: Image mask with background removed.\n  func createMask(of image: UIImage, fromMask mask: UIImage, withBackground background: UIImage? = nil) -> UIImage? {\n    guard let imageCG = image.cgImage, let maskCI = mask.ciImage else { return nil }\n    let imageCI = CIImage(cgImage: imageCG)\n\n    let background = background?.cgImage != nil ? CIImage(cgImage: background!.cgImage!) : CIImage.empty()\n\n    guard let filter = CIFilter(name: \"CIBlendWithAlphaMask\") else { return nil }\n    filter.setValue(imageCI, forKey: \"inputImage\")\n    filter.setValue(maskCI, forKey: \"inputMaskImage\")\n    filter.setValue(background, forKey: \"inputBackgroundImage\")\n\n    guard let maskedImage = context.createCGImage(filter.outputImage!, from: maskCI.extent) else {\n      return nil\n    }\n\n    return UIImage(cgImage: maskedImage)\n  }\n\n  func createSticker(_ image: UIImage) {\n    let fritzImage = FritzVisionImage(image: image)\n    guard let result = try? visionModel.predict(fritzImage),\n      let mask = result.buildSingleClassMask(\n        forClass: FritzVisionSkyClass.none,\n        clippingScoresAbove: clippingScoresAbove,\n        zeroingScoresBelow: zeroingScoresBelow\n      )\n      else { return }\n\n    // Create a segmentation mask backed by a CIImage\n    guard let skyRemoved = createMask(of: image, fromMask: mask) else { return }\n\n    DispatchQueue.main.async {\n      self.imageView.image = skyRemoved\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzSkyReplacementDemo/FritzSkyReplacementDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 50;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t837BFB8422AAE6FB00010A93 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 837BFB8322AAE6FB00010A93 /* AppDelegate.swift */; };\n\t\t837BFB8622AAE6FB00010A93 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 837BFB8522AAE6FB00010A93 /* ViewController.swift */; };\n\t\t837BFB8922AAE6FB00010A93 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 837BFB8722AAE6FB00010A93 /* Main.storyboard */; };\n\t\t837BFB8B22AAE6FC00010A93 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 837BFB8A22AAE6FC00010A93 /* Assets.xcassets */; };\n\t\t837BFB8E22AAE6FC00010A93 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 837BFB8C22AAE6FC00010A93 /* LaunchScreen.storyboard */; };\n\t\t83BE4F0422B2AE7400C6C5AF /* mountains.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 83BE4F0222B2AE7400C6C5AF /* mountains.jpg */; };\n\t\t83BE4F0522B2AE7400C6C5AF /* clouds.png in Resources */ = {isa = PBXBuildFile; fileRef = 83BE4F0322B2AE7400C6C5AF /* clouds.png */; };\n\t\tAC8F272A1BA87990DFF1B678 /* Pods_FritzSkyReplacementDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B061FC3071D1AEEC931E37C9 /* Pods_FritzSkyReplacementDemo.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t00EB0792BFD114C26D1FBFB7 /* Pods-FritzSkyReplacementDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzSkyReplacementDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzSkyReplacementDemo/Pods-FritzSkyReplacementDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t2F1C790B23BBCD9752B4C44F /* Pods-SkySegmentationGifCreator.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-SkySegmentationGifCreator.release.xcconfig\"; path = \"Target Support Files/Pods-SkySegmentationGifCreator/Pods-SkySegmentationGifCreator.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t7B7D924E3982B893B32FDFBF /* Pods-SkySegmentationGifCreator.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-SkySegmentationGifCreator.debug.xcconfig\"; path = \"Target Support Files/Pods-SkySegmentationGifCreator/Pods-SkySegmentationGifCreator.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t837BFB8022AAE6FB00010A93 /* FritzSkyReplacementDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzSkyReplacementDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t837BFB8322AAE6FB00010A93 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t837BFB8522AAE6FB00010A93 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t837BFB8822AAE6FB00010A93 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t837BFB8A22AAE6FC00010A93 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t837BFB8D22AAE6FC00010A93 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t837BFB8F22AAE6FC00010A93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t83BE4F0222B2AE7400C6C5AF /* mountains.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = mountains.jpg; sourceTree = \"<group>\"; };\n\t\t83BE4F0322B2AE7400C6C5AF /* clouds.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = clouds.png; sourceTree = \"<group>\"; };\n\t\tB061FC3071D1AEEC931E37C9 /* Pods_FritzSkyReplacementDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzSkyReplacementDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tD740A4F1C963ED2A12454102 /* Pods-FritzSkyReplacementDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzSkyReplacementDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzSkyReplacementDemo/Pods-FritzSkyReplacementDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t837BFB7D22AAE6FB00010A93 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tAC8F272A1BA87990DFF1B678 /* Pods_FritzSkyReplacementDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t56A686DE067819B42CDFF837 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB061FC3071D1AEEC931E37C9 /* Pods_FritzSkyReplacementDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t627CFBA9298D5F5109380471 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t7B7D924E3982B893B32FDFBF /* Pods-SkySegmentationGifCreator.debug.xcconfig */,\n\t\t\t\t2F1C790B23BBCD9752B4C44F /* Pods-SkySegmentationGifCreator.release.xcconfig */,\n\t\t\t\tD740A4F1C963ED2A12454102 /* Pods-FritzSkyReplacementDemo.debug.xcconfig */,\n\t\t\t\t00EB0792BFD114C26D1FBFB7 /* Pods-FritzSkyReplacementDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t837BFB7722AAE6FB00010A93 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t837BFB8222AAE6FB00010A93 /* FritzSkyReplacementDemo */,\n\t\t\t\t837BFB8122AAE6FB00010A93 /* Products */,\n\t\t\t\t627CFBA9298D5F5109380471 /* Pods */,\n\t\t\t\t56A686DE067819B42CDFF837 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t837BFB8122AAE6FB00010A93 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t837BFB8022AAE6FB00010A93 /* FritzSkyReplacementDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t837BFB8222AAE6FB00010A93 /* FritzSkyReplacementDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83BE4F0322B2AE7400C6C5AF /* clouds.png */,\n\t\t\t\t83BE4F0222B2AE7400C6C5AF /* mountains.jpg */,\n\t\t\t\t837BFB8322AAE6FB00010A93 /* AppDelegate.swift */,\n\t\t\t\t837BFB8522AAE6FB00010A93 /* ViewController.swift */,\n\t\t\t\t837BFB8722AAE6FB00010A93 /* Main.storyboard */,\n\t\t\t\t837BFB8A22AAE6FC00010A93 /* Assets.xcassets */,\n\t\t\t\t837BFB8C22AAE6FC00010A93 /* LaunchScreen.storyboard */,\n\t\t\t\t837BFB8F22AAE6FC00010A93 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzSkyReplacementDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t837BFB7F22AAE6FB00010A93 /* FritzSkyReplacementDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 837BFB9222AAE6FC00010A93 /* Build configuration list for PBXNativeTarget \"FritzSkyReplacementDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tF4E63DE038EA65B06A534018 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t837BFB7C22AAE6FB00010A93 /* Sources */,\n\t\t\t\t837BFB7D22AAE6FB00010A93 /* Frameworks */,\n\t\t\t\t837BFB7E22AAE6FB00010A93 /* Resources */,\n\t\t\t\tA4FD6B8FAC6FCD2D4936DDF2 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzSkyReplacementDemo;\n\t\t\tproductName = SkySegmentationGifCreator;\n\t\t\tproductReference = 837BFB8022AAE6FB00010A93 /* FritzSkyReplacementDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t837BFB7822AAE6FB00010A93 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1020;\n\t\t\t\tLastUpgradeCheck = 1020;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t837BFB7F22AAE6FB00010A93 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 10.2.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 837BFB7B22AAE6FB00010A93 /* Build configuration list for PBXProject \"SkySegmentationGifCreator\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 837BFB7722AAE6FB00010A93;\n\t\t\tproductRefGroup = 837BFB8122AAE6FB00010A93 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t837BFB7F22AAE6FB00010A93 /* FritzSkyReplacementDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t837BFB7E22AAE6FB00010A93 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t837BFB8E22AAE6FC00010A93 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t83BE4F0522B2AE7400C6C5AF /* clouds.png in Resources */,\n\t\t\t\t837BFB8B22AAE6FC00010A93 /* Assets.xcassets in Resources */,\n\t\t\t\t837BFB8922AAE6FB00010A93 /* Main.storyboard in Resources */,\n\t\t\t\t83BE4F0422B2AE7400C6C5AF /* mountains.jpg in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\tA4FD6B8FAC6FCD2D4936DDF2 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzSkyReplacementDemo/Pods-FritzSkyReplacementDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzSkyReplacementDemo/Pods-FritzSkyReplacementDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzSkyReplacementDemo/Pods-FritzSkyReplacementDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tF4E63DE038EA65B06A534018 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzSkyReplacementDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t837BFB7C22AAE6FB00010A93 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t837BFB8622AAE6FB00010A93 /* ViewController.swift in Sources */,\n\t\t\t\t837BFB8422AAE6FB00010A93 /* AppDelegate.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t837BFB8722AAE6FB00010A93 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t837BFB8822AAE6FB00010A93 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t837BFB8C22AAE6FC00010A93 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t837BFB8D22AAE6FC00010A93 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t837BFB9022AAE6FC00010A93 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t837BFB9122AAE6FC00010A93 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t837BFB9322AAE6FC00010A93 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = D740A4F1C963ED2A12454102 /* Pods-FritzSkyReplacementDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzSkyReplacementDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.SkySegmentationGifCreator;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t837BFB9422AAE6FC00010A93 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 00EB0792BFD114C26D1FBFB7 /* Pods-FritzSkyReplacementDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzSkyReplacementDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.SkySegmentationGifCreator;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t837BFB7B22AAE6FB00010A93 /* Build configuration list for PBXProject \"SkySegmentationGifCreator\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t837BFB9022AAE6FC00010A93 /* Debug */,\n\t\t\t\t837BFB9122AAE6FC00010A93 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t837BFB9222AAE6FC00010A93 /* Build configuration list for PBXNativeTarget \"FritzSkyReplacementDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t837BFB9322AAE6FC00010A93 /* Debug */,\n\t\t\t\t837BFB9422AAE6FC00010A93 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 837BFB7822AAE6FB00010A93 /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzSkyReplacementDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzSkyReplacementDemo' do\n  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks\n  use_frameworks!\n\n  # Pods for FritzSkyReplacementDemo\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionSegmentationModel/Sky/Fast'\n\nend\n"
  },
  {
    "path": "iOS/FritzSkyReplacementDemo/README.md",
    "content": "# Create GIFs with a Moving Sky Using Sky Segmentation by Fritz AI\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use the Sky Segmentation model by Fritz AI to create gifs where the sky moves.\n\n<img src=\"images/sky_segmentation_result.gif\" width=\"250\" />\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzSkyReplacementDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzSkyReplacementDemo`\n\n```\ncd fritz-examples/iOS/FritzSkyReplacementDemo\npod repo update\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzSkyReplacementDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzStyleTransferDemo/FritzStyleTransferDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzStyleTransferDemo\n//\n//  Created by Christopher Kelly on 9/12/18.\n//  Copyright © 2018 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  var window: UIWindow?\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n    // Override point for customization after application launch.\n\n    // Make sure that you have added a Fritz-Info.plist file from the app setup at https://app.fritz.ai\n    FritzCore.configure()\n    return true\n  }\n\n  func applicationWillResignActive(_ application: UIApplication) {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n  }\n\n  func applicationDidEnterBackground(_ application: UIApplication) {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n  }\n\n  func applicationWillEnterForeground(_ application: UIApplication) {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n  }\n\n  func applicationDidBecomeActive(_ application: UIApplication) {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n  }\n\n  func applicationWillTerminate(_ application: UIApplication) {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n  }\n}\n\n"
  },
  {
    "path": "iOS/FritzStyleTransferDemo/FritzStyleTransferDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzStyleTransferDemo/FritzStyleTransferDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzStyleTransferDemo/FritzStyleTransferDemo/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<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\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzStyleTransferDemo/FritzStyleTransferDemo/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" systemVersion=\"17A277\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzStyleTransferDemo/FritzStyleTransferDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSCameraUsageDescription</key>\n\t<string>For processing images from your device's camera</string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzStyleTransferDemo/FritzStyleTransferDemo/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  FritzStyleTransferDemo\n//\n//  Created by Christopher Kelly on 9/12/18.\n//  Copyright © 2018 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Photos\nimport Fritz\n\nclass ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {\n\n  var previewView: UIImageView!\n\n  lazy var styleModel = PaintingStyleModel.Style.starryNight.build()\n\n  private lazy var captureSession: AVCaptureSession = {\n    let session = AVCaptureSession()\n\n    guard\n      let backCamera = AVCaptureDevice.default(\n          .builtInWideAngleCamera,\n        for: .video,\n        position: .back),\n      let input = try? AVCaptureDeviceInput(device: backCamera)\n      else { return session }\n    session.addInput(input)\n\n    // The style transfer takes a 640x480 image as input and outputs an image of the same size.\n    session.sessionPreset = AVCaptureSession.Preset.vga640x480\n    return session\n  }()\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    // Add preview View as a subview\n    previewView = UIImageView(frame: view.bounds)\n    previewView.contentMode = .scaleAspectFill\n    view.addSubview(previewView)\n\n    let videoOutput = AVCaptureVideoDataOutput()\n    // Necessary video settings for displaying pixels using the VideoPreviewView\n    videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA as UInt32]\n    videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: \"MyQueue\"))\n    self.captureSession.addOutput(videoOutput)\n    self.captureSession.startRunning()\n  }\n\n  override func viewWillLayoutSubviews() {\n    super.viewWillLayoutSubviews()\n\n    previewView.frame = view.bounds\n  }\n\n  override func didReceiveMemoryWarning() {\n    super.didReceiveMemoryWarning()\n    // Dispose of any resources that can be recreated.\n  }\n\n  func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {\n    let fritzImage = FritzVisionImage(sampleBuffer: sampleBuffer, connection: connection)\n    guard let stylizedImage = try? styleModel.predict(fritzImage) else { return }\n    let styled = UIImage(pixelBuffer: stylizedImage)\n    DispatchQueue.main.async {\n      self.previewView.image = styled\n    }\n\n  }\n}\n"
  },
  {
    "path": "iOS/FritzStyleTransferDemo/FritzStyleTransferDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t83AC97BA21495DD400E86B44 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83AC97B921495DD400E86B44 /* AppDelegate.swift */; };\n\t\t83AC97BC21495DD400E86B44 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83AC97BB21495DD400E86B44 /* ViewController.swift */; };\n\t\t83AC97BF21495DD400E86B44 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83AC97BD21495DD400E86B44 /* Main.storyboard */; };\n\t\t83AC97C121495DD600E86B44 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83AC97C021495DD600E86B44 /* Assets.xcassets */; };\n\t\t83AC97C421495DD600E86B44 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83AC97C221495DD600E86B44 /* LaunchScreen.storyboard */; };\n\t\tA7D3C0B1300D396F14FDAB29 /* Pods_FritzStyleTransferDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0E29CF34AF2209CD858DA6D /* Pods_FritzStyleTransferDemo.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t474BAFA4BEF2E1D2150FE975 /* Pods-FritzStyleTransferDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzStyleTransferDemo.release.xcconfig\"; path = \"Pods/Target Support Files/Pods-FritzStyleTransferDemo/Pods-FritzStyleTransferDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t83AC97B621495DD400E86B44 /* FritzStyleTransferDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzStyleTransferDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t83AC97B921495DD400E86B44 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t83AC97BB21495DD400E86B44 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t83AC97BE21495DD400E86B44 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t83AC97C021495DD600E86B44 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t83AC97C321495DD600E86B44 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t83AC97C521495DD600E86B44 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tA7D3C2F52479434BCD005E10 /* Pods-FritzStyleTransferDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzStyleTransferDemo.debug.xcconfig\"; path = \"Pods/Target Support Files/Pods-FritzStyleTransferDemo/Pods-FritzStyleTransferDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tC0E29CF34AF2209CD858DA6D /* Pods_FritzStyleTransferDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzStyleTransferDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t83AC97B321495DD400E86B44 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tA7D3C0B1300D396F14FDAB29 /* Pods_FritzStyleTransferDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t120A9D60EB35CB4E7BFB96C3 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA7D3C2F52479434BCD005E10 /* Pods-FritzStyleTransferDemo.debug.xcconfig */,\n\t\t\t\t474BAFA4BEF2E1D2150FE975 /* Pods-FritzStyleTransferDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tname = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83AC97AD21495DD400E86B44 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83AC97B821495DD400E86B44 /* FritzStyleTransferDemo */,\n\t\t\t\t83AC97B721495DD400E86B44 /* Products */,\n\t\t\t\t120A9D60EB35CB4E7BFB96C3 /* Pods */,\n\t\t\t\tBB943EB300172DC593FAF437 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83AC97B721495DD400E86B44 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83AC97B621495DD400E86B44 /* FritzStyleTransferDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83AC97B821495DD400E86B44 /* FritzStyleTransferDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t83AC97B921495DD400E86B44 /* AppDelegate.swift */,\n\t\t\t\t83AC97BB21495DD400E86B44 /* ViewController.swift */,\n\t\t\t\t83AC97BD21495DD400E86B44 /* Main.storyboard */,\n\t\t\t\t83AC97C021495DD600E86B44 /* Assets.xcassets */,\n\t\t\t\t83AC97C221495DD600E86B44 /* LaunchScreen.storyboard */,\n\t\t\t\t83AC97C521495DD600E86B44 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzStyleTransferDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tBB943EB300172DC593FAF437 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC0E29CF34AF2209CD858DA6D /* Pods_FritzStyleTransferDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t83AC97B521495DD400E86B44 /* FritzStyleTransferDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 83AC97C821495DD600E86B44 /* Build configuration list for PBXNativeTarget \"FritzStyleTransferDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t5D1BF771AE4439EF6FE66C95 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t83AC97B221495DD400E86B44 /* Sources */,\n\t\t\t\t83AC97B321495DD400E86B44 /* Frameworks */,\n\t\t\t\t83AC97B421495DD400E86B44 /* Resources */,\n\t\t\t\t861F0BDBE5ADD909627E5917 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzStyleTransferDemo;\n\t\t\tproductName = FritzStyleTransferDemo;\n\t\t\tproductReference = 83AC97B621495DD400E86B44 /* FritzStyleTransferDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t83AC97AE21495DD400E86B44 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 0940;\n\t\t\t\tLastUpgradeCheck = 0940;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t83AC97B521495DD400E86B44 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 9.4.1;\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 83AC97B121495DD400E86B44 /* Build configuration list for PBXProject \"FritzStyleTransferDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 83AC97AD21495DD400E86B44;\n\t\t\tproductRefGroup = 83AC97B721495DD400E86B44 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t83AC97B521495DD400E86B44 /* FritzStyleTransferDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t83AC97B421495DD400E86B44 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83AC97C421495DD600E86B44 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t83AC97C121495DD600E86B44 /* Assets.xcassets in Resources */,\n\t\t\t\t83AC97BF21495DD400E86B44 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t5D1BF771AE4439EF6FE66C95 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzStyleTransferDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t861F0BDBE5ADD909627E5917 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzStyleTransferDemo/Pods-FritzStyleTransferDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzStyleTransferDemo/Pods-FritzStyleTransferDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzStyleTransferDemo/Pods-FritzStyleTransferDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t83AC97B221495DD400E86B44 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t83AC97BC21495DD400E86B44 /* ViewController.swift in Sources */,\n\t\t\t\t83AC97BA21495DD400E86B44 /* AppDelegate.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t83AC97BD21495DD400E86B44 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83AC97BE21495DD400E86B44 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83AC97C221495DD600E86B44 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t83AC97C321495DD600E86B44 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t83AC97C621495DD600E86B44 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83AC97C721495DD600E86B44 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t83AC97C921495DD600E86B44 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = A7D3C2F52479434BCD005E10 /* Pods-FritzStyleTransferDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzStyleTransferDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzStyleTransferDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83AC97CA21495DD600E86B44 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 474BAFA4BEF2E1D2150FE975 /* Pods-FritzStyleTransferDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzStyleTransferDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzStyleTransferDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t83AC97B121495DD400E86B44 /* Build configuration list for PBXProject \"FritzStyleTransferDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83AC97C621495DD600E86B44 /* Debug */,\n\t\t\t\t83AC97C721495DD600E86B44 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t83AC97C821495DD600E86B44 /* Build configuration list for PBXNativeTarget \"FritzStyleTransferDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83AC97C921495DD600E86B44 /* Debug */,\n\t\t\t\t83AC97CA21495DD600E86B44 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 83AC97AE21495DD400E86B44 /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzStyleTransferDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzStyleTransferDemo' do\n  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks\n  use_frameworks!\n\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionStyleModel/Paintings'\n\nend\n"
  },
  {
    "path": "iOS/FritzStyleTransferDemo/README.md",
    "content": "# Style Transfer\n\n[![Twitter](https://img.shields.io/badge/twitter-@fritzlabs-blue.svg?style=flat)](http://twitter.com/fritzlabs)\n\nIn this app, we use the [Style Transfer API by Fritz AI](https://www.fritz.ai/features/style-transfer.html) in order to build different camera filters inspired by some of the greatest artists like Van Gogh and Picasso.\n\nFor the full tutorial, visit [our post on Heartbeat](https://heartbeat.fritz.ai/real-time-style-transfer-for-ios-transform-your-photos-and-videos-into-masterpieces-f04111fcd2ff).\n\n<img src=\"images/style_transfer_ios.jpg\" width=\"250\" />\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 10 or above. You will only be able to use features in iOS 11+, but you still can include Fritz in apps that target iOS 10+ and selectively enable for users on 11+.\n- Swift projects must use Swift 4.1 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzStyleTransferDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzStyleTransferDemo`\n\n```\ncd fritz-examples/iOS/FritzStyleTransferDemo\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzStyleTransferDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n    // Override point for customization after application launch.\n    FritzCore.configure()\n    return true\n  }\n\n  // MARK: UISceneSession Lifecycle\n\n  func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {\n    // Called when a new scene session is being created.\n    // Use this method to select a configuration to create the new scene with.\n    return UISceneConfiguration(name: \"Default Configuration\", sessionRole: connectingSceneSession.role)\n  }\n\n  func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {\n    // Called when the user discards a scene session.\n    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.\n    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.\n  }\n}\n\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Assets.xcassets/ExportIcon.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"export-48.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"export-72.png\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/NavigationController.swift",
    "content": "//\n//  NavigationController.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\n\nclass NavigationController: UINavigationController {\n\n  override var preferredStatusBarStyle: UIStatusBarStyle {\n    return .default\n  }\n\n  override func viewWillAppear(_ animated: Bool) {\n    super.viewWillAppear(animated)\n  }\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n\n    navigationBar.tintColor = .white\n    navigationBar.shadowImage = UIImage()\n    navigationBar.isTranslucent = true\n    navigationBar.setBackgroundImage(UIImage(), for: .default)\n    let blurView = createBlurView()\n    navigationBar.addSubview(blurView)\n\n    let titleFont = UIFont.systemFont(ofSize: 17, weight: .bold)\n    navigationBar.titleTextAttributes = [\n      .font: titleFont,\n      .foregroundColor: UIColor.white\n    ]\n\n    let buttonFont = UIFont.systemFont(ofSize: 14, weight: .semibold)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .normal)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .highlighted)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .disabled)\n    UIBarButtonItem.appearance(whenContainedInInstancesOf: [NavigationController.self])\n      .setTitleTextAttributes([ .font: buttonFont], for: .selected)\n  }\n\n  private func createBlurView() -> UIVisualEffectView {\n    let visualEffectView   = UIVisualEffectView(effect: UIBlurEffect(style: .dark))\n\n    var bounds = navigationBar.bounds\n    let notchHeight: CGFloat = UIDevice.hasNotch ? 30.0 : 0.0\n    bounds.size.height += 20 + notchHeight\n    bounds.origin.y -= 20 + notchHeight\n\n    visualEffectView.isUserInteractionEnabled = false\n    visualEffectView.frame = bounds\n    visualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]\n    visualEffectView.layer.zPosition = -1\n    return visualEffectView\n  }\n}\n\nextension UIDevice {\n  enum DevicePlatform {\n    case other\n    case iPhone6S\n    case iPhone6SPlus\n    case iPhone7\n    case iPhone7Plus\n    case iPhone8\n    case iPhone8Plus\n    case iPhoneX\n    case iPhoneXS\n    case iPhoneXSMax\n    case iPhoneXR\n    case simulator\n  }\n\n  static var hasNotch: Bool {\n    return platform == .iPhoneXSMax ||\n      platform == .iPhoneXS ||\n      platform == .iPhoneXR ||\n      platform == .iPhoneX || platform == .simulator\n  }\n\n  static var platform: DevicePlatform {\n    var sysinfo = utsname()\n    uname(&sysinfo)\n    let platform = String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters)\n    switch platform {\n    case \"x86_64\":\n      return .simulator\n    case \"iPhone11,2\":\n      return .iPhoneXS\n    case \"iPhone11,4\", \"iPhone11,6\":\n      return .iPhoneXSMax\n    case \"iPhone11,8\":\n      return .iPhoneXR\n    case \"iPhone10,1\", \"iPhone10,4\":\n      return .iPhone8\n    case \"iPhone10,2\", \"iPhone10,5\":\n      return .iPhone8Plus\n    case \"iPhone10,3\", \"iPhone10,6\":\n      return .iPhoneX\n    case \"iPhone9,2\", \"iPhone9,4\":\n      return .iPhone7Plus\n    case \"iPhone9,1\", \"iPhone9,3\":\n      return .iPhone7\n    case \"iPhone8,2\":\n      return .iPhone6SPlus\n    case \"iPhone8,1\":\n      return .iPhone6S\n    default:\n      return .other\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/SingleScreenViewController.swift",
    "content": "//\n//  SingleScreenViewController.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\nimport Fritz\n\npublic class SingleScreenViewController: UIViewController {\n\n  @IBOutlet weak var progressBar: UIProgressView!\n  @IBOutlet weak var exportLabel: UILabel!\n\n  public var videoStrategy: VideoFilterStrategy!\n  var videoPicker: VideoPicker?\n  var videoPlayer: FritzVisionVideo?\n  var videoView = FritzVideoView()\n\n  var exporter: AVAssetExportSession?\n  var progressBarTimer: Timer?\n\n  public override func viewDidLoad() {\n    super.viewDidLoad()\n    updateNavBar()\n  }\n\n  public override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n    // Show video picker\n    videoPicker = VideoPicker(controller: self, delegate: self)\n    videoPicker!.present(from: view)\n  }\n\n  public override func viewWillDisappear(_ animated: Bool) {\n    progressBarTimer?.invalidate()\n    exporter?.cancelExport()\n    videoView.pause()\n    view.subviews.forEach({ $0.removeFromSuperview() })\n    super.viewWillDisappear(animated)\n  }\n}\n\n/// For selecting a video from the Camera Roll\nextension SingleScreenViewController: VideoPickerDelegate {\n  \n  @objc public func didSelect(url: URL?) {\n    guard let url = url else { return }\n    videoPlayer = FritzVisionVideo(url: url, applyingFilters: videoStrategy.filters)\n\n    // Add the video view\n    videoView.frame = view.bounds\n    view.addSubview(videoView)\n    view.bringSubviewToFront(videoView)\n\n    // Set the video and start playing it\n    videoView.fritzVideo = videoPlayer\n    videoView.play()\n  }\n}\n\n/// For navigation bar functionality\nextension SingleScreenViewController {\n\n  /// Add the export button to the navigation bar and set the title\n  func updateNavBar() {\n    let exportButton = UIImage(named: \"ExportIcon\")\n    let exportItem = UIBarButtonItem(\n      image: exportButton,\n      style: .plain,\n      target: self,\n      action: #selector(exportButtonTapped)\n    )\n\n    self.navigationItem.rightBarButtonItem = exportItem\n    self.navigationItem.title = videoStrategy.title\n  }\n\n  /// Start the export process\n  @objc func exportButtonTapped(_ button: UIBarButtonItem) {\n    guard exporter == nil, let videoPlayer = videoPlayer else { return }\n    videoView.pause()\n\n    // Create a file to export to\n    let fileName = videoStrategy.title.replacingOccurrences(of: \" \", with: \"_\")\n    var exportUrl = FileManager.default.urls(\n      for: .documentDirectory,\n      in: .userDomainMask\n      )[0].appendingPathComponent(\"\\(fileName).mov\", isDirectory: false)\n    exportUrl = URL(fileURLWithPath: exportUrl.path)\n\n    // Delete the contents of the file if it already exists\n    try? FileManager.default.removeItem(at: exportUrl)\n\n    exporter = videoPlayer.export(to: exportUrl, as: AVFileType.mov) { result in\n      self.progressBarTimer?.invalidate()\n      switch result {\n      case .success:\n        // Notify the user of a successful export\n        DispatchQueue.main.async() {\n          self.progressBar?.setProgress(1, animated: true)\n          self.exportLabel?.text = \"Saved to Camera Roll\"\n        }\n      case .failure:\n        // Notify the user of a failed export\n        DispatchQueue.main.async() {\n          self.exportLabel?.text = \"Export failed\"\n        }\n      }\n    }\n    showExportView()\n  }\n}\n\n/// For viewing and updating export progress\nextension SingleScreenViewController {\n\n  /// Blur the background and show the export progress\n  func showExportView() {\n    let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.regular)\n    let blurEffectView = UIVisualEffectView(effect: blurEffect)\n    blurEffectView.frame = view.bounds\n    blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]\n\n    // Show the progress bar and label\n    progressBar.isHidden = false\n    exportLabel.isHidden = false\n\n    // Start timer to update export progress every second\n    progressBarTimer = Timer.scheduledTimer(\n      timeInterval: 1,\n      target: self,\n      selector: #selector(updateProgress),\n      userInfo: nil,\n      repeats: true\n    )\n\n    view.addSubview(blurEffectView)\n    view.bringSubviewToFront(progressBar)\n    view.bringSubviewToFront(exportLabel)\n  }\n\n  /// Update the export progress\n  @objc func updateProgress(_ timer: Timer) {\n    guard let exportJob = exporter else { return }\n    progressBar.setProgress(exportJob.progress, animated: true)\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/SplitScreenViewController.swift",
    "content": "//\n//  SplitScreenViewController.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/11/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\npublic class SplitScreenViewController: UIViewController {\n\n  public var topStrategy: VideoFilterStrategy!\n  public var bottomStrategy: VideoFilterStrategy!\n\n  let topScreen = FritzVideoView()\n  let bottomScreen = FritzVideoView()\n\n  var videoPicker: VideoPicker?\n\n  public override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n    // Show video picker\n    videoPicker = VideoPicker(controller: self, delegate: self)\n    videoPicker!.present(from: view)\n  }\n\n  public override func viewWillDisappear(_ animated: Bool) {\n    topScreen.pause()\n    bottomScreen.pause()\n    view.subviews.forEach({ $0.removeFromSuperview() })\n    super.viewWillDisappear(animated)\n  }\n}\n\nextension SplitScreenViewController: VideoPickerDelegate {\n\n  public func didSelect(url: URL?) {\n    guard let url = url else { return }\n    let topVideo = FritzVisionVideo(url: url, applyingFilters: topStrategy.filters)\n    let bottomVideo = FritzVisionVideo(url: url, applyingFilters: bottomStrategy.filters)\n\n    // Setup both video views\n    let boundWidth = view.bounds.width\n    let boundHeight = view.bounds.height / 2\n    let topBounds = CGRect(x: 0, y: 0, width: boundWidth, height: boundHeight)\n    let bottomBounds = CGRect(x: 0, y: boundHeight, width: boundWidth, height: boundHeight)\n    topScreen.frame = topBounds\n    topScreen.fritzVideo = topVideo\n    bottomScreen.frame = bottomBounds\n    bottomScreen.fritzVideo = bottomVideo\n\n    // Add both video views\n    view.addSubview(topScreen)\n    view.bringSubviewToFront(topScreen)\n    view.addSubview(bottomScreen)\n    view.bringSubviewToFront(bottomScreen)\n\n    // Start playing both videos\n    topScreen.play()\n    bottomScreen.play()\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/Strategies/DoubleStyleStrategy.swift",
    "content": "//\n//  DoubleStyleStrategy.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/10/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\npublic class DoubleStyleStrategy: StyleOptionStrategy {\n\n  lazy var kaleidoscopeModel = PatternStyleModel.Style.kaleidoscope.build()\n  lazy var horsesModel = PaintingStyleModel.Style.horsesOnSeashore.build()\n\n  public var title = \"Double Style\"\n  public var filters: [FritzVisionImageFilter] {\n    return [\n      FritzVisionStylizeImageCompoundFilter(model: kaleidoscopeModel, options: styleOptions), // Apply first\n      FritzVisionStylizeImageCompoundFilter(model: horsesModel, options: styleOptions) // Apply second\n    ]\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/Strategies/FemmesStrategy.swift",
    "content": "//\n//  FemmesStrategy.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/11/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\npublic class FemmesStrategy: StyleOptionStrategy {\n\n  lazy var femmesModel = PaintingStyleModel.Style.femmes.build()\n\n  public var title = \"Femmes\"\n  public var filters: [FritzVisionImageFilter] {\n    return [FritzVisionStylizeImageCompoundFilter(model: femmesModel, options: styleOptions)]\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/Strategies/ObjectPoseStrategy.swift",
    "content": "//\n//  ObjectPoseStrategy.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\npublic class ObjectPoseStrategy: VideoFilterStrategy {\n\n  lazy var poseModel = FritzVisionHumanPoseModelFast()\n  lazy var objectModel = FritzVisionObjectModelFast()\n\n  public var title = \"Objects and Pose\"\n  public var filters: [FritzVisionImageFilter] {\n    return [\n      FritzVisionDrawSkeletonCompoundFilter(model: poseModel), // Apply first\n      FritzVisionDrawBoxesCompoundFilter(model: objectModel) // Apply second\n    ]\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/Strategies/PoseDoubleMaskStrategy.swift",
    "content": "//\n//  PoseDoubleMaskFilter.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/10/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\npublic class PoseDoubleMaskStrategy: VideoFilterStrategy {\n\n  lazy var poseModel = FritzVisionHumanPoseModelFast()\n  lazy var peopleModel = FritzVisionPeopleSegmentationModelFast()\n  lazy var hairModel = FritzVisionHairSegmentationModelFast()\n\n  /// Segmentation options to make mask red.\n  private var hairOptions: FritzVisionSegmentationMaskOptions {\n    let options = FritzVisionSegmentationMaskOptions()\n    options.maskColor = .red\n    return options\n  }\n\n  /// Segmentation options to reduce mask alpha.\n  private var maskOptions: FritzVisionSegmentationMaskOptions {\n    let options = FritzVisionSegmentationMaskOptions()\n    options.maxAlpha = 10\n    return options\n  }\n\n  public var title = \"Pose and Masks\"\n  public var filters: [FritzVisionImageFilter] {\n    return [\n      FritzVisionDrawSkeletonCompoundFilter(model: poseModel), // Apply first\n      FritzVisionMaskPeopleOverlayFilter(model: peopleModel, options: maskOptions), // Apply second\n      FritzVisionMaskHairOverlayFilter(model: hairModel, options: hairOptions) // Apply last\n    ]\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/Strategies/ScreamStrategy.swift",
    "content": "//\n//  ScreamStrategy'.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/11/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\npublic class ScreamStrategy: StyleOptionStrategy {\n\n  lazy var screamModel = PaintingStyleModel.Style.theScream.build()\n\n  public var title = \"The Scream\"\n  public var filters: [FritzVisionImageFilter] {\n    return [FritzVisionStylizeImageCompoundFilter(model: screamModel, options: styleOptions)]\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/Strategies/StyleOptionStrategy.swift",
    "content": "//\n//  StyleOptionStrategy.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/12/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\nprotocol StyleOptionStrategy: VideoFilterStrategy {}\n\nextension StyleOptionStrategy {\n\n  /// Style model options to reduce the size of the image to process and scale it back up to the input dimensions\n  var styleOptions: FritzVisionStyleModelOptions {\n    let options = FritzVisionStyleModelOptions()\n    options.flexibleModelDimensions = FlexibleModelDimensions(width: 240, height: 426)\n    options.resizeOutputToInputDimensions = true\n    return options\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/Strategies/StylizeBackgroundStrategy.swift",
    "content": "//\n//  StylizeBackgroundStrategy.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/19/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\npublic class StylizeBackgroundStrategy: StyleOptionStrategy {\n\n  lazy var styleModel = PaintingStyleModel.Style.ritmoPlastico.build()\n  lazy var peopleModel = FritzVisionPeopleSegmentationModelFast()\n\n  public var title = \"Stylize Hair\"\n  public var filters: [FritzVisionImageFilter] {\n    return [\n      FritzVisionStylizeImageCompoundFilter(model: styleModel, options: styleOptions), // Apply first\n      FritzVisionCutOutPeopleOverlayFilter(model: peopleModel) // Apply second\n    ]\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/Strategies/StylizeHairStrategy.swift",
    "content": "//\n//  StylizeHairStrategy.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport UIKit\nimport Fritz\n\npublic class StylizeHairStrategy: StyleOptionStrategy {\n\n  lazy var hairModel = FritzVisionHairSegmentationModelFast()\n  lazy var styleModel = PaintingStyleModel.Style.starryNight.build()\n\n  public var title = \"Stylize Hair\"\n  public var filters: [FritzVisionImageFilter] {\n    return [\n      StylizeHairMaskFilter(\n        hairModel: hairModel,\n        styleModel: styleModel,\n        styleOptions: styleOptions\n      )\n    ]\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/Strategies/VideoOptionStrategy.swift",
    "content": "//\n//  VideoFilterStrategy.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/10/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\npublic protocol VideoFilterStrategy {\n\n  var title: String { get }\n  var filters: [FritzVisionImageFilter] { get }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Controllers/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\nimport Fritz\n\nclass ViewController: UITableViewController {\n\n  override var preferredStatusBarStyle: UIStatusBarStyle {\n    return .lightContent\n  }\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n    self.view.backgroundColor = .black\n    title = \"Video Processing\".uppercased()\n    tableView.register(DemoTableViewCell.self, forCellReuseIdentifier: \"DemoTableViewCell\")\n    tableView.register(LinkTableViewCell.self, forCellReuseIdentifier: \"LinkTableViewCell\")\n    clearsSelectionOnViewWillAppear = true\n  }\n\n  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {\n    if let _ = tableView.cellForRow(at: indexPath) as? LinkTableViewCell,\n      let url = URL(string: \"https://www.fritz.ai/pricing\") {\n      UIApplication.shared.open(url)\n      tableView.deselectRow(at: indexPath, animated: true)\n    }\n\n    if let cell = tableView.cellForRow(at: indexPath) as? DemoTableViewCell {\n      guard let identifier = cell.reuseIdentifier else { return }\n\n      var firstStrategy: VideoFilterStrategy?\n      var secondStrategy: VideoFilterStrategy?\n      switch identifier {\n      case \"StarryNightHair\":\n        firstStrategy = StylizeHairStrategy()\n      case \"StylizeBackground\":\n        firstStrategy = StylizeBackgroundStrategy()\n      case \"ObjectPose\":\n        firstStrategy = ObjectPoseStrategy()\n      case \"DoubleStyle\":\n        firstStrategy = DoubleStyleStrategy()\n      case \"ObjectDoubleMask\":\n        firstStrategy = PoseDoubleMaskStrategy()\n      case \"SplitStyle\":\n        firstStrategy = FemmesStrategy()\n        secondStrategy = ScreamStrategy()\n      default:\n        return\n      }\n\n      // Start view controller and set strategies depending on the selected cell\n      if let firstStrategy = firstStrategy, let secondStrategy = secondStrategy {\n        let storyboard = UIStoryboard(name: \"SplitScreenStoryboard\", bundle: Bundle.main)\n        let viewController = storyboard.instantiateViewController(withIdentifier: \"SplitScreen\")\n          as! SplitScreenViewController\n        viewController.topStrategy = firstStrategy\n        viewController.bottomStrategy = secondStrategy\n        self.navigationController?.pushViewController(viewController, animated: true)\n      }\n      else if let firstStrategy = firstStrategy {\n        let storyboard = UIStoryboard(name: \"SingleScreenStoryboard\", bundle: Bundle.main)\n        let viewController = storyboard.instantiateViewController(withIdentifier: \"SingleScreen\")\n            as! SingleScreenViewController\n        viewController.videoStrategy = firstStrategy\n        self.navigationController?.pushViewController(viewController, animated: true)\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UIApplicationSceneManifest</key>\n\t<dict>\n\t\t<key>UIApplicationSupportsMultipleScenes</key>\n\t\t<false/>\n\t\t<key>UISceneConfigurations</key>\n\t\t<dict>\n\t\t\t<key>UIWindowSceneSessionRoleApplication</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>UISceneConfigurationName</key>\n\t\t\t\t\t<string>Default Configuration</string>\n\t\t\t\t\t<key>UISceneDelegateClassName</key>\n\t\t\t\t\t<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>\n\t\t\t\t\t<key>UISceneStoryboardFile</key>\n\t\t\t\t\t<string>Main</string>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t</dict>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>NSPhotoLibraryUsageDescription</key>\n\t<string>Uses video library for post-processing</string>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/SceneDelegate.swift",
    "content": "//\n//  SceneDelegate.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport UIKit\n\nclass SceneDelegate: UIResponder, UIWindowSceneDelegate {\n\n  var window: UIWindow?\n\n  func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {\n    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.\n    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.\n    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).\n    guard let _ = (scene as? UIWindowScene) else { return }\n  }\n\n  func sceneDidDisconnect(_ scene: UIScene) {\n    // Called as the scene is being released by the system.\n    // This occurs shortly after the scene enters the background, or when its session is discarded.\n    // Release any resources associated with this scene that can be re-created the next time the scene connects.\n    // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).\n  }\n\n  func sceneDidBecomeActive(_ scene: UIScene) {\n    // Called when the scene has moved from an inactive state to an active state.\n    // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.\n  }\n\n  func sceneWillResignActive(_ scene: UIScene) {\n    // Called when the scene will move from an active state to an inactive state.\n    // This may occur due to temporary interruptions (ex. an incoming phone call).\n  }\n\n  func sceneWillEnterForeground(_ scene: UIScene) {\n    // Called as the scene transitions from the background to the foreground.\n    // Use this method to undo the changes made on entering the background.\n  }\n\n  func sceneDidEnterBackground(_ scene: UIScene) {\n    // Called as the scene transitions from the foreground to the background.\n    // Use this method to save data, release shared resources, and store enough scene-specific state information\n    // to restore the scene back to its current state.\n  }\n}\n\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Storyboards/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" xcode11CocoaTouchSystemColor=\"systemBackgroundColor\" cocoaTouchSystemColor=\"whiteColor\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Storyboards/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15505\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"SsJ-BJ-qTj\">\n    <device id=\"retina6_1\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15509\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <tableViewController id=\"Cjs-X2-1zP\" customClass=\"ViewController\" customModule=\"FritzVisionVideoDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <tableView key=\"view\" clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" showsHorizontalScrollIndicator=\"NO\" showsVerticalScrollIndicator=\"NO\" dataMode=\"static\" style=\"plain\" separatorStyle=\"default\" rowHeight=\"-1\" estimatedRowHeight=\"-1\" sectionHeaderHeight=\"28\" sectionFooterHeight=\"28\" id=\"ZoN-Fk-Ok9\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"896\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <color key=\"separatorColor\" white=\"0.33333333333333331\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <sections>\n                            <tableViewSection id=\"23A-Yv-yEK\">\n                                <cells>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"StarryNightHair\" textLabel=\"lTu-bC-pQm\" detailTextLabel=\"0Fw-CK-INI\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"pUp-vV-F5l\" customClass=\"DemoTableViewCell\" customModule=\"FritzVisionVideoDemo\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"28\" width=\"414\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"pUp-vV-F5l\" id=\"85h-cn-y1l\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"383\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Starry Night Hair\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"lTu-bC-pQm\" userLabel=\"Hair Color Changer\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"36\" width=\"167\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Stylize your hair with Starry Night by Vincent van Gogh.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"0Fw-CK-INI\" userLabel=\"Change the color of your hair\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"66.5\" width=\"321.5\" height=\"14.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"StylizeBackground\" textLabel=\"OXu-gQ-ZKJ\" detailTextLabel=\"VvY-ow-OMy\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"qTj-KI-ed6\" customClass=\"DemoTableViewCell\" customModule=\"FritzVisionVideoDemo\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"148\" width=\"414\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"qTj-KI-ed6\" id=\"fp1-EP-5IF\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"383\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Stylize Background\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"OXu-gQ-ZKJ\" userLabel=\"Hair Color Changer\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"29\" width=\"193\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Cut out people and paste them on top of a background stylized with Ritmo Plastico by Gino Severini.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"VvY-ow-OMy\" userLabel=\"Change the color of your hair\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"59.5\" width=\"319.5\" height=\"29\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"SplitStyle\" textLabel=\"xiT-S9-Si8\" detailTextLabel=\"Dwa-20-gjV\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"y9X-kV-k7a\" customClass=\"DemoTableViewCell\" customModule=\"FritzVisionVideoDemo\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"268\" width=\"414\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"y9X-kV-k7a\" id=\"bn8-wj-G4L\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"383\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Split Screen Style Transfer\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"2\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"xiT-S9-Si8\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"29\" width=\"264\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Apply Les Femmes d’Alger by Picasso and The Scream by Edvard Munch on two separate video streams.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"2\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"Dwa-20-gjV\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"59.5\" width=\"335.5\" height=\"29\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"DoubleStyle\" textLabel=\"p8k-Le-7jb\" detailTextLabel=\"ytj-pA-vmo\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"aGg-cB-Mdg\" customClass=\"DemoTableViewCell\" customModule=\"FritzVisionVideoDemo\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"388\" width=\"414\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"aGg-cB-Mdg\" id=\"rDh-0h-3TP\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"383\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Double Style Transfer\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"p8k-Le-7jb\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"29\" width=\"215\" height=\"26.5\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Apply a combination of Horses on the Seashore by Giorgio de Chirico and a kaleidoscope pattern.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"2\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"ytj-pA-vmo\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"59.5\" width=\"355\" height=\"29\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"ObjectPose\" textLabel=\"9JU-mk-wuE\" detailTextLabel=\"sN4-oT-Ygr\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"axi-Pb-Hs0\" customClass=\"DemoTableViewCell\" customModule=\"FritzVisionVideoDemo\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"508\" width=\"414\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"axi-Pb-Hs0\" id=\"iDH-co-T30\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"383\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Object Detection and Pose Estimation\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"2\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"9JU-mk-wuE\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"15\" width=\"217\" height=\"53\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Detect and draw boxes around objects while identifying and tracking the body position of a person.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"2\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"sN4-oT-Ygr\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"72\" width=\"349\" height=\"29\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" accessoryType=\"disclosureIndicator\" indentationWidth=\"10\" reuseIdentifier=\"ObjectDoubleMask\" textLabel=\"Drz-Xh-WUU\" detailTextLabel=\"oe3-iA-w4i\" rowHeight=\"120\" style=\"IBUITableViewCellStyleSubtitle\" id=\"GgD-OM-vu1\" customClass=\"DemoTableViewCell\" customModule=\"FritzVisionVideoDemo\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"628\" width=\"414\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"GgD-OM-vu1\" id=\"7zL-en-m4h\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"383\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Pose Estimation with People and Hair Mask\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"2\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"Drz-Xh-WUU\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"15\" width=\"329\" height=\"53\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"semibold\" pointSize=\"22\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                                <label opaque=\"NO\" multipleTouchEnabled=\"YES\" contentMode=\"left\" insetsLayoutMarginsFromSafeArea=\"NO\" text=\"Identify and track the body position of a person while putting a mask over people and hair.\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"2\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"oe3-iA-w4i\">\n                                                    <rect key=\"frame\" x=\"20\" y=\"72\" width=\"355\" height=\"29\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" weight=\"medium\" pointSize=\"12\"/>\n                                                    <color key=\"textColor\" white=\"1\" alpha=\"0.80078125\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                </label>\n                                            </subviews>\n                                        </tableViewCellContentView>\n                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                    </tableViewCell>\n                                </cells>\n                            </tableViewSection>\n                        </sections>\n                        <connections>\n                            <outlet property=\"dataSource\" destination=\"Cjs-X2-1zP\" id=\"Jsy-w9-jmc\"/>\n                            <outlet property=\"delegate\" destination=\"Cjs-X2-1zP\" id=\"vXe-2h-7aU\"/>\n                        </connections>\n                    </tableView>\n                    <navigationItem key=\"navigationItem\" id=\"3sy-ld-ocO\"/>\n                </tableViewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"wbQ-fp-TQ8\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"1917.5999999999999\" y=\"170.46476761619192\"/>\n        </scene>\n        <!--Navigation Controller-->\n        <scene sceneID=\"wqO-nk-NYO\">\n            <objects>\n                <navigationController id=\"SsJ-BJ-qTj\" customClass=\"NavigationController\" customModule=\"FritzVisionVideoDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <navigationBar key=\"navigationBar\" contentMode=\"scaleToFill\" insetsLayoutMarginsFromSafeArea=\"NO\" id=\"VFV-IY-Ee9\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"44\" width=\"414\" height=\"44\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </navigationBar>\n                    <connections>\n                        <segue destination=\"Cjs-X2-1zP\" kind=\"relationship\" relationship=\"rootViewController\" id=\"zWD-QK-1UO\"/>\n                    </connections>\n                </navigationController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"eZ9-sb-vjd\" userLabel=\"First Responder\" customClass=\"UIResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"1078\" y=\"172\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Storyboards/SingleScreenStoryboard.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15505\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"WXX-D2-m06\">\n    <device id=\"retina6_1\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15509\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Single Screen View Controller-->\n        <scene sceneID=\"YMA-Bt-Ajh\">\n            <objects>\n                <viewController storyboardIdentifier=\"SingleScreen\" id=\"WXX-D2-m06\" customClass=\"SingleScreenViewController\" customModule=\"FritzVisionVideoDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"4YX-Yp-28u\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"896\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <label hidden=\"YES\" opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Exporting...\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Ogn-nS-Edt\">\n                                <rect key=\"frame\" x=\"163\" y=\"469\" width=\"88\" height=\"21\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                <nil key=\"textColor\"/>\n                                <nil key=\"highlightedColor\"/>\n                            </label>\n                            <progressView hidden=\"YES\" opaque=\"NO\" clipsSubviews=\"YES\" contentMode=\"center\" verticalHuggingPriority=\"750\" progressViewStyle=\"bar\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"BAg-11-MEQ\">\n                                <rect key=\"frame\" x=\"107\" y=\"444\" width=\"200\" height=\"9\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"200\" id=\"JAN-86-r4y\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"8\" id=\"LNk-xM-WYN\"/>\n                                </constraints>\n                                <color key=\"progressTintColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <color key=\"trackTintColor\" white=\"0.33333333333333331\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <userDefinedRuntimeAttributes>\n                                    <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"layer.masksToBounds\" value=\"YES\"/>\n                                    <userDefinedRuntimeAttribute type=\"number\" keyPath=\"layer.cornerRadius\">\n                                        <integer key=\"value\" value=\"5\"/>\n                                    </userDefinedRuntimeAttribute>\n                                </userDefinedRuntimeAttributes>\n                            </progressView>\n                        </subviews>\n                        <color key=\"backgroundColor\" systemColor=\"systemBackgroundColor\" cocoaTouchSystemColor=\"whiteColor\"/>\n                        <constraints>\n                            <constraint firstItem=\"Ogn-nS-Edt\" firstAttribute=\"centerX\" secondItem=\"4YX-Yp-28u\" secondAttribute=\"centerX\" id=\"1Rz-Fe-TBm\"/>\n                            <constraint firstItem=\"Ogn-nS-Edt\" firstAttribute=\"top\" secondItem=\"BAg-11-MEQ\" secondAttribute=\"bottom\" constant=\"17\" id=\"Drd-Hk-t6Y\"/>\n                            <constraint firstItem=\"BAg-11-MEQ\" firstAttribute=\"centerY\" secondItem=\"4YX-Yp-28u\" secondAttribute=\"centerY\" id=\"dOp-7s-dh8\"/>\n                            <constraint firstItem=\"BAg-11-MEQ\" firstAttribute=\"centerX\" secondItem=\"4YX-Yp-28u\" secondAttribute=\"centerX\" id=\"tsL-tJ-PIB\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"jD1-4u-wX6\"/>\n                    </view>\n                    <connections>\n                        <outlet property=\"exportLabel\" destination=\"Ogn-nS-Edt\" id=\"4rZ-Dh-mDJ\"/>\n                        <outlet property=\"progressBar\" destination=\"BAg-11-MEQ\" id=\"ooj-B4-EWF\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"pqh-NI-shg\" userLabel=\"First Responder\" customClass=\"UIResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"138\" y=\"133\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Storyboards/SplitScreenStoryboard.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15505\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"WXX-D2-m06\">\n    <device id=\"retina6_5\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15509\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Split Screen View Controller-->\n        <scene sceneID=\"YMA-Bt-Ajh\">\n            <objects>\n                <viewController storyboardIdentifier=\"SplitScreen\" id=\"WXX-D2-m06\" customClass=\"SplitScreenViewController\" customModule=\"FritzVisionVideoDemo\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"4YX-Yp-28u\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"414\" height=\"896\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" systemColor=\"systemBackgroundColor\" cocoaTouchSystemColor=\"whiteColor\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"jD1-4u-wX6\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"pqh-NI-shg\" userLabel=\"First Responder\" customClass=\"UIResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"138\" y=\"133\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo/Utils/StylizeHairMaskFilter.swift",
    "content": "//\n//  StylizeHairMaskFilter.swift\n//  FritzVisionVideoDemo\n//\n//  Created by Steven Yeung on 11/8/19.\n//  Copyright © 2019 Fritz. All rights reserved.\n//\n\nimport Foundation\nimport Fritz\n\npublic class StylizeHairMaskFilter: FritzVisionImageFilter {\n\n  // Use the original image as the predictor\n  public let compositionMode = FilterCompositionMode.overlayOnOriginalImage\n  \n  public let hairModel: FritzVisionHairSegmentationModelFast\n  public let styleModel: FritzVisionStylePredictor\n  \n  public let hairOptions: FritzVisionSegmentationMaskOptions\n  public let styleOptions: FritzVisionStyleModelOptions\n  \n  public init(\n    hairModel: FritzVisionHairSegmentationModelFast,\n    styleModel: FritzVisionStylePredictor,\n    hairOptions: FritzVisionSegmentationMaskOptions = .init(),\n    styleOptions: FritzVisionStyleModelOptions = .init()\n  ) {\n    self.hairModel = hairModel\n    self.styleModel = styleModel\n    self.hairOptions = hairOptions\n    self.styleOptions = styleOptions\n  }\n  \n  public func process(_ image: FritzVisionImage) -> FritzVisionFilterResult {\n    do {\n      // Run predictions on the input image\n      let hairResult = try hairModel.predict(image)\n      let styleBuffer = try styleModel.predict(image, options: styleOptions)\n      let stylizedImage = FritzVisionImage(ciImage: CIImage(cvPixelBuffer: styleBuffer))\n      \n      // Create mask of the hair and extract the corresponding area in the stylized image\n      if let mask = hairResult.buildSingleClassMask(\n        forClass: FritzVisionHairClass.hair,\n        options: hairOptions,\n        resize: false\n        ),\n        let styleMasked = stylizedImage.masked(with: mask) {\n        \n        return .success(FritzVisionImage(image: styleMasked))\n      }\n      return .failure(FritzVisionVideoError.invalidPrediction)\n    }\n    catch let error {\n      return .failure(error)\n    }\n  }\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/FritzVisionVideoDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 51;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t3B07C02C2378779C000E5C63 /* VideoOptionStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B07C02B2378779C000E5C63 /* VideoOptionStrategy.swift */; };\n\t\t3B07C02E2378F7AD000E5C63 /* DoubleStyleStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B07C02D2378F7AD000E5C63 /* DoubleStyleStrategy.swift */; };\n\t\t3B07C03223790089000E5C63 /* PoseDoubleMaskStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B07C03123790089000E5C63 /* PoseDoubleMaskStrategy.swift */; };\n\t\t3B17B79D23849CE900869AA8 /* StylizeBackgroundStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B17B79C23849CE900869AA8 /* StylizeBackgroundStrategy.swift */; };\n\t\t3B2395A023760528008E5A89 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B23959F23760528008E5A89 /* AppDelegate.swift */; };\n\t\t3B2395A223760528008E5A89 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2395A123760528008E5A89 /* SceneDelegate.swift */; };\n\t\t3B2395A423760528008E5A89 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2395A323760528008E5A89 /* ViewController.swift */; };\n\t\t3B2395A92376052A008E5A89 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3B2395A82376052A008E5A89 /* Assets.xcassets */; };\n\t\t3B2395B7237605FD008E5A89 /* LinkTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2395B4237605FC008E5A89 /* LinkTableViewCell.swift */; };\n\t\t3B2395B8237605FD008E5A89 /* DemoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2395B5237605FC008E5A89 /* DemoTableViewCell.swift */; };\n\t\t3B2395B9237605FD008E5A89 /* VideoPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2395B6237605FC008E5A89 /* VideoPicker.swift */; };\n\t\t3B2395BC2376063A008E5A89 /* StylizeHairStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2395BB2376063A008E5A89 /* StylizeHairStrategy.swift */; };\n\t\t3B2395BE23760765008E5A89 /* SingleScreenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2395BD23760765008E5A89 /* SingleScreenViewController.swift */; };\n\t\t3B2395C02376093B008E5A89 /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2395BF2376093B008E5A89 /* NavigationController.swift */; };\n\t\t3B2395C2237610E6008E5A89 /* StylizeHairMaskFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B2395C1237610E6008E5A89 /* StylizeHairMaskFilter.swift */; };\n\t\t3B2395CB23761D84008E5A89 /* SingleScreenStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3B2395CA23761D84008E5A89 /* SingleScreenStoryboard.storyboard */; };\n\t\t3B44CF052379052C00A96408 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3B44CF032379052C00A96408 /* LaunchScreen.storyboard */; };\n\t\t3B44CF062379052C00A96408 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3B44CF042379052C00A96408 /* Main.storyboard */; };\n\t\t3B44CF082379B91500A96408 /* SplitScreenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B44CF072379B91500A96408 /* SplitScreenViewController.swift */; };\n\t\t3B44CF0A2379BB9800A96408 /* SplitScreenStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3B44CF092379BB9800A96408 /* SplitScreenStoryboard.storyboard */; };\n\t\t3B44CF0E2379C1D100A96408 /* FemmesStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B44CF0D2379C1D100A96408 /* FemmesStrategy.swift */; };\n\t\t3B44CF102379C20700A96408 /* ScreamStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B44CF0F2379C20700A96408 /* ScreamStrategy.swift */; };\n\t\t3B8CED98237B4B9A004F9E38 /* StyleOptionStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B8CED97237B4B9A004F9E38 /* StyleOptionStrategy.swift */; };\n\t\t3BC5DC2F237626180018FA5A /* ObjectPoseStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BC5DC2E237626180018FA5A /* ObjectPoseStrategy.swift */; };\n\t\tE7B2939D7554BF9F96FF2A45 /* Pods_FritzVisionVideoDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B08A7DB1BFA0EC3AB62A3056 /* Pods_FritzVisionVideoDemo.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t3B07C02B2378779C000E5C63 /* VideoOptionStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoOptionStrategy.swift; sourceTree = \"<group>\"; };\n\t\t3B07C02D2378F7AD000E5C63 /* DoubleStyleStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleStyleStrategy.swift; sourceTree = \"<group>\"; };\n\t\t3B07C03123790089000E5C63 /* PoseDoubleMaskStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoseDoubleMaskStrategy.swift; sourceTree = \"<group>\"; };\n\t\t3B17B79C23849CE900869AA8 /* StylizeBackgroundStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StylizeBackgroundStrategy.swift; sourceTree = \"<group>\"; };\n\t\t3B23959C23760528008E5A89 /* FritzVisionVideoDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FritzVisionVideoDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t3B23959F23760528008E5A89 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t3B2395A123760528008E5A89 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = \"<group>\"; };\n\t\t3B2395A323760528008E5A89 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t3B2395A82376052A008E5A89 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t3B2395AD2376052A008E5A89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t3B2395B4237605FC008E5A89 /* LinkTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LinkTableViewCell.swift; path = ../../../FritzHairColorDemo/FritzHairColorDemo/UI/LinkTableViewCell.swift; sourceTree = \"<group>\"; };\n\t\t3B2395B5237605FC008E5A89 /* DemoTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DemoTableViewCell.swift; path = ../../../FritzHairColorDemo/FritzHairColorDemo/UI/DemoTableViewCell.swift; sourceTree = \"<group>\"; };\n\t\t3B2395B6237605FC008E5A89 /* VideoPicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = VideoPicker.swift; path = ../../../FritzHairColorDemo/FritzHairColorDemo/UI/VideoPicker.swift; sourceTree = \"<group>\"; };\n\t\t3B2395BB2376063A008E5A89 /* StylizeHairStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StylizeHairStrategy.swift; sourceTree = \"<group>\"; };\n\t\t3B2395BD23760765008E5A89 /* SingleScreenViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleScreenViewController.swift; sourceTree = \"<group>\"; };\n\t\t3B2395BF2376093B008E5A89 /* NavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = \"<group>\"; };\n\t\t3B2395C1237610E6008E5A89 /* StylizeHairMaskFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StylizeHairMaskFilter.swift; sourceTree = \"<group>\"; };\n\t\t3B2395CA23761D84008E5A89 /* SingleScreenStoryboard.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SingleScreenStoryboard.storyboard; sourceTree = \"<group>\"; };\n\t\t3B44CF032379052C00A96408 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t3B44CF042379052C00A96408 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = \"<group>\"; };\n\t\t3B44CF072379B91500A96408 /* SplitScreenViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplitScreenViewController.swift; sourceTree = \"<group>\"; };\n\t\t3B44CF092379BB9800A96408 /* SplitScreenStoryboard.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SplitScreenStoryboard.storyboard; sourceTree = \"<group>\"; };\n\t\t3B44CF0D2379C1D100A96408 /* FemmesStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FemmesStrategy.swift; sourceTree = \"<group>\"; };\n\t\t3B44CF0F2379C20700A96408 /* ScreamStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreamStrategy.swift; sourceTree = \"<group>\"; };\n\t\t3B8CED97237B4B9A004F9E38 /* StyleOptionStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyleOptionStrategy.swift; sourceTree = \"<group>\"; };\n\t\t3BC5DC2E237626180018FA5A /* ObjectPoseStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectPoseStrategy.swift; sourceTree = \"<group>\"; };\n\t\t3FA1C947D1C12AF0F4E8E46F /* Pods-FritzVisionVideoDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzVisionVideoDemo.debug.xcconfig\"; path = \"Target Support Files/Pods-FritzVisionVideoDemo/Pods-FritzVisionVideoDemo.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tB08A7DB1BFA0EC3AB62A3056 /* Pods_FritzVisionVideoDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FritzVisionVideoDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tDE6642EEC50958FE85C81047 /* Pods-FritzVisionVideoDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-FritzVisionVideoDemo.release.xcconfig\"; path = \"Target Support Files/Pods-FritzVisionVideoDemo/Pods-FritzVisionVideoDemo.release.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t3B23959923760528008E5A89 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tE7B2939D7554BF9F96FF2A45 /* Pods_FritzVisionVideoDemo.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t2E1A2C1740D460757C9502A3 /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3FA1C947D1C12AF0F4E8E46F /* Pods-FritzVisionVideoDemo.debug.xcconfig */,\n\t\t\t\tDE6642EEC50958FE85C81047 /* Pods-FritzVisionVideoDemo.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B23959323760528008E5A89 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B23959E23760528008E5A89 /* FritzVisionVideoDemo */,\n\t\t\t\t3B23959D23760528008E5A89 /* Products */,\n\t\t\t\t2E1A2C1740D460757C9502A3 /* Pods */,\n\t\t\t\t95D892482B994F057018E4E4 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B23959D23760528008E5A89 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B23959C23760528008E5A89 /* FritzVisionVideoDemo.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B23959E23760528008E5A89 /* FritzVisionVideoDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B2395C923761D48008E5A89 /* Storyboards */,\n\t\t\t\t3B2395BA23760614008E5A89 /* Controllers */,\n\t\t\t\t3B2395B3237605DF008E5A89 /* Utils */,\n\t\t\t\t3B23959F23760528008E5A89 /* AppDelegate.swift */,\n\t\t\t\t3B2395A123760528008E5A89 /* SceneDelegate.swift */,\n\t\t\t\t3B2395A82376052A008E5A89 /* Assets.xcassets */,\n\t\t\t\t3B2395AD2376052A008E5A89 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = FritzVisionVideoDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B2395B3237605DF008E5A89 /* Utils */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B2395B5237605FC008E5A89 /* DemoTableViewCell.swift */,\n\t\t\t\t3B2395B4237605FC008E5A89 /* LinkTableViewCell.swift */,\n\t\t\t\t3B2395B6237605FC008E5A89 /* VideoPicker.swift */,\n\t\t\t\t3B2395C1237610E6008E5A89 /* StylizeHairMaskFilter.swift */,\n\t\t\t);\n\t\t\tpath = Utils;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B2395BA23760614008E5A89 /* Controllers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3BC5DC302376917F0018FA5A /* Strategies */,\n\t\t\t\t3B2395BD23760765008E5A89 /* SingleScreenViewController.swift */,\n\t\t\t\t3B44CF072379B91500A96408 /* SplitScreenViewController.swift */,\n\t\t\t\t3B2395A323760528008E5A89 /* ViewController.swift */,\n\t\t\t\t3B2395BF2376093B008E5A89 /* NavigationController.swift */,\n\t\t\t);\n\t\t\tpath = Controllers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3B2395C923761D48008E5A89 /* Storyboards */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B44CF032379052C00A96408 /* LaunchScreen.storyboard */,\n\t\t\t\t3B44CF042379052C00A96408 /* Main.storyboard */,\n\t\t\t\t3B2395CA23761D84008E5A89 /* SingleScreenStoryboard.storyboard */,\n\t\t\t\t3B44CF092379BB9800A96408 /* SplitScreenStoryboard.storyboard */,\n\t\t\t);\n\t\t\tpath = Storyboards;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t3BC5DC302376917F0018FA5A /* Strategies */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B07C02B2378779C000E5C63 /* VideoOptionStrategy.swift */,\n\t\t\t\t3B8CED97237B4B9A004F9E38 /* StyleOptionStrategy.swift */,\n\t\t\t\t3B2395BB2376063A008E5A89 /* StylizeHairStrategy.swift */,\n\t\t\t\t3B17B79C23849CE900869AA8 /* StylizeBackgroundStrategy.swift */,\n\t\t\t\t3BC5DC2E237626180018FA5A /* ObjectPoseStrategy.swift */,\n\t\t\t\t3B07C03123790089000E5C63 /* PoseDoubleMaskStrategy.swift */,\n\t\t\t\t3B07C02D2378F7AD000E5C63 /* DoubleStyleStrategy.swift */,\n\t\t\t\t3B44CF0D2379C1D100A96408 /* FemmesStrategy.swift */,\n\t\t\t\t3B44CF0F2379C20700A96408 /* ScreamStrategy.swift */,\n\t\t\t);\n\t\t\tpath = Strategies;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t95D892482B994F057018E4E4 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB08A7DB1BFA0EC3AB62A3056 /* Pods_FritzVisionVideoDemo.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t3B23959B23760528008E5A89 /* FritzVisionVideoDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 3B2395B02376052A008E5A89 /* Build configuration list for PBXNativeTarget \"FritzVisionVideoDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tAE3D6FE9F572EAE150B201BE /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t3B23959823760528008E5A89 /* Sources */,\n\t\t\t\t3B23959923760528008E5A89 /* Frameworks */,\n\t\t\t\t3B23959A23760528008E5A89 /* Resources */,\n\t\t\t\t96F28801FC0697D4F454F6CF /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = FritzVisionVideoDemo;\n\t\t\tproductName = FritzVisionVideoDemo;\n\t\t\tproductReference = 3B23959C23760528008E5A89 /* FritzVisionVideoDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t3B23959423760528008E5A89 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1120;\n\t\t\t\tLastUpgradeCheck = 1120;\n\t\t\t\tORGANIZATIONNAME = Fritz;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t3B23959B23760528008E5A89 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 11.2;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 3B23959723760528008E5A89 /* Build configuration list for PBXProject \"FritzVisionVideoDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 3B23959323760528008E5A89;\n\t\t\tproductRefGroup = 3B23959D23760528008E5A89 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t3B23959B23760528008E5A89 /* FritzVisionVideoDemo */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t3B23959A23760528008E5A89 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t3B44CF0A2379BB9800A96408 /* SplitScreenStoryboard.storyboard in Resources */,\n\t\t\t\t3B2395A92376052A008E5A89 /* Assets.xcassets in Resources */,\n\t\t\t\t3B44CF062379052C00A96408 /* Main.storyboard in Resources */,\n\t\t\t\t3B44CF052379052C00A96408 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t3B2395CB23761D84008E5A89 /* SingleScreenStoryboard.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t96F28801FC0697D4F454F6CF /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzVisionVideoDemo/Pods-FritzVisionVideoDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-FritzVisionVideoDemo/Pods-FritzVisionVideoDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-FritzVisionVideoDemo/Pods-FritzVisionVideoDemo-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tAE3D6FE9F572EAE150B201BE /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-FritzVisionVideoDemo-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t3B23959823760528008E5A89 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t3BC5DC2F237626180018FA5A /* ObjectPoseStrategy.swift in Sources */,\n\t\t\t\t3B2395A423760528008E5A89 /* ViewController.swift in Sources */,\n\t\t\t\t3B2395A023760528008E5A89 /* AppDelegate.swift in Sources */,\n\t\t\t\t3B2395BE23760765008E5A89 /* SingleScreenViewController.swift in Sources */,\n\t\t\t\t3B2395A223760528008E5A89 /* SceneDelegate.swift in Sources */,\n\t\t\t\t3B2395C02376093B008E5A89 /* NavigationController.swift in Sources */,\n\t\t\t\t3B2395BC2376063A008E5A89 /* StylizeHairStrategy.swift in Sources */,\n\t\t\t\t3B2395C2237610E6008E5A89 /* StylizeHairMaskFilter.swift in Sources */,\n\t\t\t\t3B8CED98237B4B9A004F9E38 /* StyleOptionStrategy.swift in Sources */,\n\t\t\t\t3B07C02C2378779C000E5C63 /* VideoOptionStrategy.swift in Sources */,\n\t\t\t\t3B44CF082379B91500A96408 /* SplitScreenViewController.swift in Sources */,\n\t\t\t\t3B2395B9237605FD008E5A89 /* VideoPicker.swift in Sources */,\n\t\t\t\t3B44CF0E2379C1D100A96408 /* FemmesStrategy.swift in Sources */,\n\t\t\t\t3B2395B8237605FD008E5A89 /* DemoTableViewCell.swift in Sources */,\n\t\t\t\t3B07C03223790089000E5C63 /* PoseDoubleMaskStrategy.swift in Sources */,\n\t\t\t\t3B44CF102379C20700A96408 /* ScreamStrategy.swift in Sources */,\n\t\t\t\t3B07C02E2378F7AD000E5C63 /* DoubleStyleStrategy.swift in Sources */,\n\t\t\t\t3B17B79D23849CE900869AA8 /* StylizeBackgroundStrategy.swift in Sources */,\n\t\t\t\t3B2395B7237605FD008E5A89 /* LinkTableViewCell.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\t3B2395AE2376052A008E5A89 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 13.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t3B2395AF2376052A008E5A89 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 13.2;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t3B2395B12376052A008E5A89 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 3FA1C947D1C12AF0F4E8E46F /* Pods-FritzVisionVideoDemo.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzVisionVideoDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzVisionVideoDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t3B2395B22376052A008E5A89 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = DE6642EEC50958FE85C81047 /* Pods-FritzVisionVideoDemo.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = FritzVisionVideoDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = ai.fritz.FritzVisionVideoDemo;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t3B23959723760528008E5A89 /* Build configuration list for PBXProject \"FritzVisionVideoDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t3B2395AE2376052A008E5A89 /* Debug */,\n\t\t\t\t3B2395AF2376052A008E5A89 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t3B2395B02376052A008E5A89 /* Build configuration list for PBXNativeTarget \"FritzVisionVideoDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t3B2395B12376052A008E5A89 /* Debug */,\n\t\t\t\t3B2395B22376052A008E5A89 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 3B23959423760528008E5A89 /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '12.0'\n\ntarget 'FritzVisionVideoDemo' do\n  # Comment the next line if you don't want to use dynamic frameworks\n  use_frameworks!\n\n  # Pods for FritzVisionVideoDemo\n  pod 'Fritz', '6.1.1'\n  pod 'Fritz/VisionSegmentationModel/Hair/Fast'\n  pod 'Fritz/VisionSegmentationModel/People/Fast'\n  pod 'Fritz/VisionStyleModel/Paintings'\n  pod 'Fritz/VisionStyleModel/Patterns'\n  pod 'Fritz/VisionPoseModel/Human/Fast'\n  pod 'Fritz/VisionObjectModel/Fast'\n\nend\n"
  },
  {
    "path": "iOS/FritzVisionVideoDemo/README.md",
    "content": "# Video Processing with FritzVisionVideo\n\nIn this app, we use the FritzVisionVideo API to run model predictions on video.\n\n## Fritz AI\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n## Requirements\n\n- Xcode 11.2 or later.\n- Xcode project targeting iOS 11 or above.\n- Swift projects must use Swift 5.0 or later.\n- CocoaPods 1.4.0 or later.\n\n## Getting Started\n\n**Step 1: Choose a Fritz AI Plan**\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n**Step 2: Clone / Fork the fritz-examples repository and open FritzVisionVideoDemo**\n\n```\ngit clone https://github.com/fritzlabs/fritz-examples.git\n```\n\n**Step 3: Setup the project via Cocoapods**\n\nInstall dependencies via Cocoapods by running `pod install` from `fritz-examples/iOS/FritzVisionVideoDemo`\n\n```\ncd fritz-examples/iOS/FritzVisionVideoDemo\npod install\n```\n\n- Note you may need to run `pod update` if you already have Fritz installed locally.\n\n**Step 4: Open up a new XCode project**\n\nXCode > Open > FritzVisionVideoDemo.xcworkspace\n\n**Step 5: Run the app**\n\nAttach a device or use an emulator to run the app. If you get the error \"Please download the Fritz-Info.plist\", you'll need to register the app with Fritz (See Step 2).\n\n## Documentation\n\n[Fritz Docs Home](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS SDK Reference Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  },
  {
    "path": "iOS/README.md",
    "content": "# Fritz iOS Tutorials\n\nFritz AI is the machine learning platform for iOS and Android developers. Teach your mobile apps to see, hear, sense, and think. Start with our ready-to-use feature APIs or connect and deploy your own custom models.\n\n[Sign up](https://www.fritz.ai/pricing/?utm_source=github&utm_campaign=fritz-examples) for a Fritz AI plan to get started.\n\n## Examples for iOS\n\n**Vision API: Prebuilt models that you can simply drop into your apps:**\n\n- [Image Segmentation](https://www.fritz.ai/features/image-segmentation.html?utm_source=github&utm_campaign=fritz-examples): Create pixel level masks of different objects in a scene.\n- [Image Labeling](https://www.fritz.ai/features/image-labeling.html?utm_source=github&utm_campaign=fritz-examples): Classify different objects in an video or image.\n- [Pose Estimation](https://www.fritz.ai/features/pose-estimation.html?utm_source=github&utm_campaign=fritz-examples): Identify and track a person's body position.\n- [Object Detection](https://www.fritz.ai/features/object-detection.html?utm_source=github&utm_campaign=fritz-examples): Detect multiple objects and track their location.\n- [Style Transfer](https://www.fritz.ai/features/style-transfer.html?utm_source=github&utm_campaign=fritz-examples): Transform photos and videos into artistic masterpieces.\n\n**Custom Models: Deploy, Monitor, and Update your own models:**\n\nWe currently support Core ML for iOS.\n\n- [Analytics and Monitoring](https://www.fritz.ai/features/analytics-monitoring.html?utm_source=github&utm_campaign=fritz-examples): Monitor machine learning models running on-device with Fritz.\n- [Model Management](https://www.fritz.ai/features/model-management.html?utm_source=github&utm_campaign=fritz-examples): Iterate on your ML models over-the-air, without having to release your app.\n- [Model Protection](https://www.fritz.ai/features/model-protection.html?utm_source=github&utm_campaign=fritz-examples): Use model protection to keep models from being tampered-with or stolen.\n\n## Example Apps\n\nIf you are new to Fritz, it's recommended to get started with our Fritz AI Studio App. You can also install the latest version from the [App Store](https://apps.apple.com/us/app/fritz-ai-studio/id1325206416):\n\n- Fritz AI Studio App - Our kitchen sink project showcases all on-device Vision APIs and Custom Model usage. ([Open Source Code](https://github.com/fritzlabs/fritz-examples/tree/master/iOS/FritzAIStudio))\n- Fritz Image Segmentation Demo - Create a portrait mode filter with People Segmentation ([tutorial](https://heartbeat.fritz.ai/building-an-image-segmentation-app-in-ios-3377eb4a3e7c?utm_source=github&utm_campaign=fritz-examples)).\n- Fritz Hair Color Demo - Try out different hair colors and styles ([tutorial](https://heartbeat.fritz.ai/try-on-a-new-style-build-an-ios-app-to-change-your-hair-color-with-fritz-hair-segmentation-177324b077b3?utm_source=github&utm_campaign=fritz-examples)).\n- Fritz Pizza Detector Demo - Create Domino's Points for Pies feature by recognizing pizza ([tutorial](https://heartbeat.fritz.ai/recreate-dominos-points-for-pies-app-on-ios-with-fritz-image-labeling-2ed23398e1c2?utm_source=github&utm_campaign=fritz-examples)).\n- Fritz Style Transfer Demo - Transform each frame into a work of art. ([tutorial](https://heartbeat.fritz.ai/real-time-style-transfer-for-ios-transform-your-photos-and-videos-into-masterpieces-f04111fcd2ff?utm_source=github&utm_campaign=fritz-examples)).\n- Fritz Pose Estimation Demo - Track body position and motion. ([tutorial](https://heartbeat.fritz.ai/pose-estimation-on-ios-with-fritz-60c8e5f7d195?utm_source=github&utm_campaign=fritz-examples)).\n\n## Official Documentation\n\n[SDK Documentation](https://docs.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n\n[iOS API Docs](https://docs.fritz.ai/iOS/latest/index.html?utm_source=github&utm_campaign=fritz-examples)\n\n## Join the community\n\n[Heartbeat](https://heartbeat.fritz.ai/?utm_source=github&utm_campaign=fritz-examples) is a community of developers interested in the intersection of mobile and machine learning. [Chat with us in Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples) and stay up to date on the latest mobile ML news with our [Newsletter](https://www.fritz.ai/newsletter?utm_source=github&utm_campaign=fritz-examples).\n\n## Help\n\nFor any questions or issues, you can:\n\n- Submit an issue on this repo\n- Go to [Support](https://support.fritz.ai/?utm_source=github&utm_campaign=fritz-examples)\n- Message us directly in [Slack](https://www.fritz.ai/slack?utm_source=github&utm_campaign=fritz-examples)\n"
  }
]