[
  {
    "path": ".gitignore",
    "content": ".gradle\n/local.properties\n.DS_Store\n/build\n/captures\n.idea\n*.iml\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: android\n\njdk:\n    - oraclejdk7\n\nandroid:\n  components:\n    - platform-tools\n    - tools\n    - build-tools-23.0.3\n    - android-23\n    - extra-android-support\n    - extra-android-m2repository\n\n# as per http://blog.travis-ci.com/2014-12-17-faster-builds-with-container-based-infrastructure/\nsudo: false\n\nbefore_install:\n    - export JAVA7_HOME=/usr/lib/jvm/java-7-oracle\n    - export JAVA_HOME=$JAVA7_HOME\nscript:\n    - ./gradlew clean assemble check\n"
  },
  {
    "path": "LICENSE",
    "content": "Authors:\nDaniel Zeller <daniel@agens.no>\n\nThe MIT License (MIT)\nCopyright (c) 2016 Agens AS (http://agens.no/)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Depth-LIB-Android\n\nThis library adds depth/thickness to views. \n\n[<img src=\"https://cdn.dribbble.com/users/655449/screenshots/2179342/menu_dribble.gif\" width=\"400\"/>](https://youtu.be/d2H1z6bmD9w)\n\n[See demo on youtube](https://youtu.be/d2H1z6bmD9w)\n\n## Demo \nThe demo code contains some examples of Canvas drawing techniques to create particle systems, waves and grain effect. I wasn't really happy with the default shadows in Android because they start misbehaving when they are rotated so I made my own shadow solution. The project also contains various tweening functions for animations, and uses the Facebook rebound lib for some tweens. Don't expect too much from this lib, it was written as a quick prototype, so the visuals look good but the code behind it could have been better.\n\n\n## More Libraries\nMake sure to also checkout Metaballs LIB:\n\n[<img src=\"https://github.com/danielzeller/MetaBalls-LIB-Android/blob/master/Artwork/TwoClips.gif?raw=true\" width=\"400\"/>](https://github.com/danielzeller/MetaBalls-LIB-Android)\n\n[LINK](https://github.com/danielzeller/MetaBalls-LIB-Android)\n\nand Blur LIB:\n\n[<img src=\"https://github.com/danielzeller/Blur-LIB-Android/blob/master/Artwork/Transition.gif?raw=true\" width=\"400\"/>](https://github.com/danielzeller/Blur-LIB-Android)\n\n[LINK](https://github.com/danielzeller/Blur-LIB-Android)\n\n\n## Contact\n\nYou can reach me on twitter as [@zellah](https://twitter.com/zellah) or [danielzeller.no](http://danielzeller.no/).\n\n\n## Who's behind this?\n\nDeveloped by [@zellah](https://twitter.com/zellah)\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build\napp.iml"
  },
  {
    "path": "app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 28\n    defaultConfig {\n        applicationId \"no.agens.depth\"\n        minSdkVersion 21\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    lintOptions {\n        abortOnError false\n    }\n}\n\ndependencies {\n    implementation fileTree(include: ['*.jar'], dir: 'libs')\n    implementation 'com.android.support:support-v4:28.0.0'\n    implementation 'com.android.support:design:28.0.0'\n    implementation project(':lib')\n}\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/danielzeller/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\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"
  },
  {
    "path": "app/src/androidTest/java/no/agens/depth/ApplicationTest.java",
    "content": "package no.agens.depth;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "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=\"no.agens.depth\" >\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:theme=\"@style/AppTheme\" >\n        <activity\n            android:name=\"no.agens.depth.PlayGroundActivity\"\n            android:label=\"@string/app_name\" >\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\"no.agens.depth.RootActivity\"\n            android:label=\"@string/title_activity_root\" >\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>\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/BearSceneView.java",
    "content": "package no.agens.depth;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.Canvas;\nimport android.graphics.Rect;\nimport android.util.AttributeSet;\nimport android.view.View;\n\nimport no.agens.depth.lib.MathHelper;\nimport no.agens.depth.lib.headers.AuraDrawable;\nimport no.agens.depth.lib.headers.NoiseEffect;\nimport no.agens.depth.lib.headers.ParticleSystem;\nimport no.agens.depth.lib.headers.Renderable;\nimport no.agens.depth.lib.tween.FrameRateCounter;\n\n/**\n * Created by danielzeller on 01.10.14.\n */\npublic class BearSceneView extends View {\n\n\n    public static final int WIND_RANDOMIZE_INTERVAL = 300;\n    private Renderable[] renderables;\n\n    public BearSceneView(Context context) {\n        super(context);\n\n    }\n\n    private float wind = 10f;\n    float windRanomizerTarget;\n    float windRanomizerEased;\n\n    ParticleSystem flames;\n    ParticleSystem sparks;\n    Smoke smoke;\n\n    public BearSceneView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    public BearSceneView(Context context, AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n\n    }\n\n    @Override\n    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {\n        super.onLayout(changed, left, top, right, bottom);\n        if (renderables == null) {\n            init();\n        }\n    }\n\n    private void init() {\n        renderables = new Renderable[17];\n        Bitmap treeB = BitmapFactory.decodeResource(getResources(), R.mipmap.tree);\n        addTree(treeB,getMeasuredWidth() * 0.18f, getMeasuredHeight() * -0.65f, 0.28f, 0.46f);\n        addTree(treeB,getMeasuredWidth() * 0.6f, getMeasuredHeight() * -0.65f, 0.33f, 0.46f);\n        addTree(treeB,getMeasuredWidth() * 0.45f, getMeasuredHeight() * -0.45f, 0.5f, 0.8f);\n        addTree(treeB,getMeasuredWidth() * 0.13f, getMeasuredHeight() * -0.65f, 0.3f, 0.46f);\n        addTree(treeB,getMeasuredWidth() * 0.83f, getMeasuredHeight() * -0.2f, 0.5f, 1f);\n        addTree(treeB,getMeasuredWidth() * 0.02f, getMeasuredHeight() * -0.1f, 0.8f, 1f);\n        addTree(treeB,getMeasuredWidth() * 0.18f, getMeasuredHeight() * 0.15f, 0.8f, 1f);\n        addTree(treeB,getMeasuredWidth() * 0.7f, getMeasuredHeight() * -0.1f, 0.8f, 1f);\n\n        Bitmap bear1 = BitmapFactory.decodeResource(getResources(), R.mipmap.bear_1);\n        Bitmap bear2 = BitmapFactory.decodeResource(getResources(), R.mipmap.bear_2);\n        Bitmap bear3 = BitmapFactory.decodeResource(getResources(), R.mipmap.bear_white);\n        Bitmap stones = BitmapFactory.decodeResource(getResources(), R.drawable.stones);\n        Bitmap smoke = BitmapFactory.decodeResource(getResources(), R.drawable.smoke);\n        Bitmap grunge = BitmapFactory.decodeResource(getResources(), R.drawable.grunge);\n        addFire(smoke, stones, getMeasuredWidth() * 0.61f, getMeasuredHeight() * 0.8f);\n        addBear(getMeasuredWidth() * 0.636f, getMeasuredHeight() * 0.59f, bear1, bear2);\n        addWhiteBear(getMeasuredWidth() * 0.44f, getMeasuredHeight() * 0.66f, bear3);\n        setLayerType(View.LAYER_TYPE_HARDWARE, null);\n        addGrunge(grunge);\n    }\n\n    private void addGrunge(Bitmap grunge) {\n        NoiseEffect noise = new NoiseEffect(grunge, 100, 2.5f);\n        renderables[index] = noise;\n        noise.setNoiseIntensity(0.25f);\n        index += 1;\n    }\n\n    private void addFire(Bitmap smoke, Bitmap stones, float x, float y) {\n\n        renderables[index] = new AuraDrawable(getResources().getDrawable(R.drawable.aura_gradient), new Rect((int) (getMeasuredWidth() * 0.44f), (int) (getMeasuredHeight() * 0.4f), (int) (getMeasuredWidth() * 0.8f), (int) (getMeasuredHeight() * 1.1f)));\n        index += 1;\n        renderables[index] = new AuraDrawable(getResources().getDrawable(R.drawable.aura_gradient_inner), new Rect((int) (getMeasuredWidth() * 0.5f), (int) (getMeasuredHeight() * 0.6f), (int) (getMeasuredWidth() * 0.72f), (int) (getMeasuredHeight() * 1f)));\n        index += 1;\n\n        float density = getResources().getDisplayMetrics().density;\n        float randomXPlacement = 5f * density;\n        flames = new ParticleSystem(x, y, 30, -30f * density, randomXPlacement);\n        sparks = new ParticleSystem(x, y, 600, -30f * density, randomXPlacement);\n\n        renderables[index] = flames;\n        flames.setParticleSize((int) (8f * density));\n        flames.setRandomMovementX(20f * density);\n        flames.setRandomMovementY(1.5f * density);\n        flames.setColors(getResources().getColor(R.color.fire_start_color), getResources().getColor(R.color.fire_end_color));\n        index += 1;\n\n        renderables[index] = sparks;\n        sparks.setParticleSize((int) (1f * density));\n        sparks.setRandomMovementX(25f * density);\n        sparks.setRandomMovementY(2.5f * density);\n        sparks.setRandomMovementChangeInterval(900);\n        sparks.setColors(getResources().getColor(R.color.fire_start_color), getResources().getColor(R.color.fire_start_color));\n        sparks.setMinYCoord(0);\n        index += 1;\n\n        renderables[index] = new Renderable(stones, x - randomXPlacement * 2f, y);\n        index += 1;\n        this.smoke = new Smoke(smoke, x, getMeasuredHeight() * 0.68f, 110 * density, 60 * density, 8, density);\n        renderables[index] = this.smoke;\n        index += 1;\n\n    }\n\n    private void addWhiteBear(float v, float v1, Bitmap bear3) {\n        renderables[index] = new Renderable(bear3, v, v1);\n        index += 1;\n    }\n\n    private void addBear(float v, float v1, Bitmap bear1, Bitmap bear2) {\n        renderables[index] = new RenderableBear(new Bitmap[]{bear1, bear2}, v, v1);\n        index += 1;\n    }\n\n    int index = 0;\n\n    void addTree(Bitmap bitmap, float x, float y, float scale, float alpha) {\n\n        renderables[index] = new RenderableTree(bitmap, x, y, alpha);\n        renderables[index].setScale(scale, scale);\n        index += 1;\n    }\n    @Override\n    protected void onDetachedFromWindow() {\n        super.onDetachedFromWindow();\n        destroyResources();\n    }\n\n    private void destroyResources() {\n\n        for (Renderable renderable: renderables)\n            renderable.destroy();\n    }\n\n    @Override\n    protected void onAttachedToWindow() {\n        super.onAttachedToWindow();\n        if (renderables == null && getWidth() != 0)\n            init();\n    }\n\n    @Override\n    protected void onDraw(Canvas canvas) {\n        super.onDraw(canvas);\n        float deltaTime = FrameRateCounter.timeStep();\n        windRanomizerEased += ((windRanomizerTarget - windRanomizerEased) * 4f) * deltaTime;\n        for (Renderable renderable : renderables) {\n            renderable.draw(canvas);\n            if (renderable instanceof Smoke || renderable instanceof ParticleSystem)\n                renderable.update(deltaTime, wind);\n            else\n                renderable.update(deltaTime, wind + windRanomizerEased);\n        }\n        if (lastWindRandomChange + WIND_RANDOMIZE_INTERVAL < System.currentTimeMillis()) {\n            lastWindRandomChange = System.currentTimeMillis();\n            float randomSpeedInterval = Math.max(wind / 2, 1);\n            windRanomizerTarget = (float) MathHelper.rand.nextInt((int) randomSpeedInterval) - randomSpeedInterval / 2f;\n        }\n        if (!pause)\n            invalidate();\n    }\n\n    public void setPause(boolean pause) {\n        this.pause = pause;\n        if (!pause) {\n            FrameRateCounter.timeStep();\n            invalidate();\n            for (Renderable renderable : renderables)\n                renderable.resume();\n        } else {\n            for (Renderable renderable : renderables)\n                renderable.pause();\n        }\n    }\n\n    private boolean pause = false;\n\n    long lastWindRandomChange;\n\n\n    public void setWind(int wind) {\n        this.wind = wind;\n    }\n\n    float LOWEST_FLAMES_COORD = 0.8f;\n    float HIGHEST_FLAMES_COORD = 0.4f;\n    float HIGHEST_SMOKE_COORD = 0.6f;\n\n    public void setFlamesHeight(int progress) {\n        float flamesHeight = getYCoordByPercent(LOWEST_FLAMES_COORD - ((LOWEST_FLAMES_COORD - HIGHEST_FLAMES_COORD) * ((float) progress / 100f)));\n        flames.setMinYCoord(flamesHeight);\n        float smokeYCoord = getYCoordByPercent(LOWEST_FLAMES_COORD - ((LOWEST_FLAMES_COORD - HIGHEST_SMOKE_COORD) * ((float) progress / 100f)));\n        smoke.setY(smokeYCoord);\n    }\n\n\n    private float getYCoordByPercent(float percent) {\n        return getHeight() * percent;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/Foam.java",
    "content": "package no.agens.depth;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Path;\nimport android.graphics.PathMeasure;\n\nimport no.agens.depth.lib.MathHelper;\nimport no.agens.depth.lib.headers.PathBitmapMesh;\n\npublic class Foam extends PathBitmapMesh {\n    private float verticalOffset;\n\n    void update(float deltaTime) {\n\n        for (int i = 0; i < foamCoords.length; i++) {\n            easedFoamCoords[i] += ((foamCoords[i] - easedFoamCoords[i])) * deltaTime;\n        }\n    }\n\n    float[] foamCoords;\n    float[] easedFoamCoords;\n    float minHeight, maxHeight;\n\n    public Foam(int horizontalSlices, int verticalSlices, Bitmap bitmap, float minHeight, float maxHeight, int animDuration) {\n        super(horizontalSlices, verticalSlices, bitmap,animDuration);\n        setupFoam(horizontalSlices);\n        this.minHeight = minHeight;\n        this.maxHeight = maxHeight;\n\n    }\n\n\n    private void setupFoam(int verts) {\n        foamCoords = new float[verts];\n        easedFoamCoords = new float[verts];\n        for (int i = 0; i < verts; i++) {\n            foamCoords[i] = 0;\n            easedFoamCoords[i] = 0;\n        }\n    }\n\n    void calcWave() {\n        for (int i = 0; i < foamCoords.length; i++) {\n            foamCoords[i] = MathHelper.randomRange(minHeight, maxHeight);\n        }\n    }\n\n\n\n    public void matchVertsToPath(Path path, float extraOffset) {\n        PathMeasure pm = new PathMeasure(path, false);\n        int index = 0;\n        for (int i = 0; i < staticVerts.length / 2; i++) {\n\n            float yIndexValue = staticVerts[i * 2 + 1];\n            float xIndexValue = staticVerts[i * 2];\n\n\n            float percentOffsetX = (0.000001f + xIndexValue) / bitmap.getWidth();\n            float percentOffsetX2 = (0.000001f + xIndexValue) / (bitmap.getWidth() + extraOffset);\n            percentOffsetX2 += pathOffsetPercent;\n            pm.getPosTan(pm.getLength() * (1f - percentOffsetX), coords, null);\n            pm.getPosTan(pm.getLength() * (1f - percentOffsetX2), coords2, null);\n\n            if (yIndexValue == 0) {\n                setXY(drawingVerts, i, coords[0], coords2[1] + verticalOffset);\n            } else {\n                float desiredYCoord = Math.max(coords2[1], coords2[1] + easedFoamCoords[Math.min(easedFoamCoords.length - 1, index)]);\n                setXY(drawingVerts, i, coords[0], desiredYCoord + verticalOffset);\n\n                index += 1;\n\n            }\n        }\n    }\n\n    public void setVerticalOffset(float verticalOffset) {\n        this.verticalOffset = verticalOffset;\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/MenuAnimation.java",
    "content": "package no.agens.depth;\n\npublic interface MenuAnimation {\n      void animateTOMenu();\n      void revertFromMenu();\n      void exitFromMenu();\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/PlayGroundActivity.java",
    "content": "package no.agens.depth;\n\nimport android.app.Activity;\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport android.view.View;\nimport android.widget.ImageView;\nimport android.widget.SeekBar;\n\nimport no.agens.depth.lib.DepthLayout;\nimport no.agens.depth.lib.MaterialMenuDrawable;\n\npublic class PlayGroundActivity extends Activity {\n\n    private DepthLayout depthView;\n    private static final float MAX_ROTATION_X = 90;\n    private static final float MAX_ROTATION_Y = 90;\n    private static final float MAX_ROTATION_Z = 360;\n\n    private static final float MAX_ELEVATION = 50;\n    private static final float MAX_DEPTH = 20;\n    private static final float CAMERA_DISTANCE = 6000f;\n    private int seekBarColor;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.fragment_playground);\n        seekBarColor = getResources().getColor(R.color.fab);\n        depthView = (DepthLayout) findViewById(R.id.depth_view);\n        depthView.setCameraDistance((CAMERA_DISTANCE * getResources().getDisplayMetrics().density));\n        setupSeekBars();\n        makeAppFullscreen();\n        setupMenuButton();\n    }\n    private void setupMenuButton() {\n        ImageView menu = (ImageView) findViewById(R.id.menu);\n        menu.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                finish();\n            }\n        });\n        MaterialMenuDrawable menuIcon = new MaterialMenuDrawable(this, Color.WHITE, MaterialMenuDrawable.Stroke.THIN, WaterFragment.TRANSFORM_DURATION);\n        menu.setImageDrawable(menuIcon);\n        menuIcon.setIconState(MaterialMenuDrawable.IconState.ARROW);\n    }\n    private void setupSeekBars() {\n        setupRotationXSeekbar();\n        setupRotationYSeekbar();\n        setupRotationZSeekbar();\n        setupElevationSeekbar();\n        setupDepthSeekbar();\n\n    }\n\n    private void makeAppFullscreen() {\n        getWindow().setStatusBarColor(Color.TRANSPARENT);\n        getWindow().getDecorView().setSystemUiVisibility(\n                View.SYSTEM_UI_FLAG_LAYOUT_STABLE\n                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);\n    }\n\n    private void setupDepthSeekbar() {\n        SeekBar depth = (SeekBar) findViewById(R.id.depth_seekbar);\n        WindFragment.setProgressBarColor(depth, seekBarColor);\n        depth.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                depthView.setDepth(MAX_DEPTH * getResources().getDisplayMetrics().density * ((float) progress / (float) seekBar.getMax()));\n            }\n        });\n        depth.setProgress((int) (depth.getMax() * 0.1f));\n    }\n\n    private SeekBar setupRotationXSeekbar() {\n        SeekBar rotationX = (SeekBar) findViewById(R.id.rotation_x_seekbar);\n        WindFragment.setProgressBarColor(rotationX, seekBarColor);\n        rotationX.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                depthView.setRotationX(-MAX_ROTATION_X + (MAX_ROTATION_X * 2f) * ((float) progress / (float) seekBar.getMax()));\n            }\n        });\n        rotationX.setProgress((int) (rotationX.getMax() * 0.1f));\n        return rotationX;\n\n    }\n\n    private void setupRotationYSeekbar() {\n        SeekBar rotationY = (SeekBar) findViewById(R.id.rotation_y_seekbar);\n        rotationY.setProgress((int) (rotationY.getMax() * 0.5f));\n        WindFragment.setProgressBarColor(rotationY, seekBarColor);\n        rotationY.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                depthView.setRotationY(-MAX_ROTATION_Y + (MAX_ROTATION_Y * 2f) * ((float) progress / (float) seekBar.getMax()));\n            }\n        });\n    }\n\n    private void setupRotationZSeekbar() {\n        SeekBar rotation = (SeekBar) findViewById(R.id.rotation_z_seekbar);\n        rotation.setProgress(0);\n        WindFragment.setProgressBarColor(rotation, seekBarColor);\n        rotation.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                depthView.setRotation(-MAX_ROTATION_Z * ((float) progress / (float) seekBar.getMax()));\n            }\n        });\n\n    }\n\n    private void setupElevationSeekbar() {\n        SeekBar elevation = (SeekBar) findViewById(R.id.elevation_seekbar);\n        elevation.setProgress(0);\n        WindFragment.setProgressBarColor(elevation, seekBarColor);\n        elevation.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                depthView.setCustomShadowElevation((MAX_ELEVATION * ((float) progress / (float) seekBar.getMax())) * getResources().getDisplayMetrics().density);\n            }\n        });\n        elevation.setProgress((int) (elevation.getMax() * 0.5f));\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/RenderableBear.java",
    "content": "package no.agens.depth;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\n\nimport no.agens.depth.lib.headers.Renderable;\n\npublic class RenderableBear extends Renderable {\n\n    public static final int FRAME_DELAY = 2500;\n    long lastFrameChange;\n    Bitmap[] bitmaps;\n    int bitmapIndex = 0;\n\n    public RenderableBear(Bitmap[] bitmaps, float x, float y) {\n        super(null, x, y);\n        lastFrameChange = System.currentTimeMillis();\n        this.bitmaps = bitmaps;\n    }\n\n    @Override\n    public void draw(Canvas canvas) {\n        canvas.save();\n\n        canvas.drawBitmap(bitmaps[bitmapIndex], x + translationX / 2, y + translationY, null);\n        canvas.restore();\n    }\n\n    @Override\n    public void update(float deltaTime, float wind) {\n        super.update(deltaTime, wind);\n        if (lastFrameChange + FRAME_DELAY < System.currentTimeMillis()) {\n            lastFrameChange = System.currentTimeMillis();\n            bitmapIndex += 1;\n            if (bitmapIndex == bitmaps.length)\n                bitmapIndex = 0;\n        }\n    }\n\n    public void destroy() {\n        for (Bitmap bitmap : bitmaps) {\n            if (bitmap != null && !bitmap.isRecycled()) {\n                bitmap.recycle();\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/RenderableTree.java",
    "content": "package no.agens.depth;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.PathMeasure;\n\nimport no.agens.depth.lib.headers.Renderable;\n\n/**\n * Created by danielzeller on 01.10.14.\n */\npublic class RenderableTree extends Renderable {\n    private final float[] drawingVerts = new float[TOTAL_SLICES_COUNT * 2];\n    private final float[] staticVerts = new float[TOTAL_SLICES_COUNT * 2];\n    private static final int HORIZONTAL_SLICES = 1;\n    private static final int VERTICAL_SLICES = 95;\n    private static final int TOTAL_SLICES_COUNT = (HORIZONTAL_SLICES + 1) * (VERTICAL_SLICES + 1);\n    private Paint p = new Paint();\n    private float offsetInPercent;\n\n    private Path pathLeft = new Path();\n    private Path pathRight = new Path();\n    private boolean isBounceAnimatin = false;\n    private Paint paint = new Paint();\n\n    public RenderableTree(Bitmap bitmap, float x, float y, float alpha) {\n        super(bitmap, x, y );\n        p.setColor(Color.BLACK);\n        p.setStrokeWidth(6);\n        p.setStyle(Paint.Style.STROKE);\n        createVerts();\n        paint.setAlpha((int) (255*alpha));\n    }\n\n    public void setScale(float scaleX, float scaleY) {\n        this.scaleX = scaleX;\n        this.scaleY = scaleY;\n    }\n\n    private void createVerts() {\n\n        float xDimesion = (float) bitmap.getWidth();\n        float yDimesion = (float) bitmap.getHeight();\n\n        int index = 0;\n\n        for (int y = 0; y <= VERTICAL_SLICES; y++) {\n            float fy = yDimesion * y / VERTICAL_SLICES;\n            for (int x = 0; x <= HORIZONTAL_SLICES; x++) {\n                float fx = xDimesion * x / HORIZONTAL_SLICES;\n                setXY(drawingVerts, index, fx, fy);\n                setXY(staticVerts, index, fx, fy);\n                index += 1;\n            }\n        }\n    }\n\n    public void setXY(float[] array, int index, float x, float y) {\n        array[index * 2 + 0] = x;\n        array[index * 2 + 1] = y;\n    }\n\n    public void setXA(float[] array, int index, float x) {\n        array[index * 2 + 0] = x;\n    }\n\n    public void setYA(float[] array, int index, float y) {\n        array[index * 2 + 1] = staticVerts[index * 2 + 1] + y;\n    }\n\n    @Override\n    public void draw(Canvas canvas) {\n        createPath();\n//        alphaCanvas.drawPath(pathLeft, debugPaint);\n//        alphaCanvas.drawPath(pathRight, debugPaint);\n        canvas.save();\n        if (scaleX != 1.f || scaleY != 1f) {\n            canvas.scale(scaleX, scaleY, x + bitmap.getWidth() / 2, y + bitmap.getHeight());\n        }\n        canvas.drawBitmapMesh(bitmap, HORIZONTAL_SLICES, VERTICAL_SLICES, drawingVerts, 0, null, 0, paint);\n        canvas.restore();\n    }\n\n\n    private void createPath() {\n        pathLeft.reset();\n        pathLeft.moveTo(x, y + bitmap.getHeight());\n        pathLeft.cubicTo(x, y + bitmap.getHeight(), x, y, x + bitmap.getWidth() * 1.5f * offsetInPercent, y);\n        pathRight.reset();\n        pathRight.moveTo(x + bitmap.getWidth(), y + bitmap.getHeight());\n        pathRight.cubicTo(x + bitmap.getWidth(), y + bitmap.getHeight(), x + bitmap.getWidth(), y + bitmap.getWidth() * 0.3f * offsetInPercent, x + bitmap.getWidth() + bitmap.getWidth() / 2 * offsetInPercent, y + bitmap.getWidth() * 0.8f * offsetInPercent);\n        matchVertsToPath();\n    }\n\n    private void matchVertsToPath() {\n        PathMeasure pmLeft = new PathMeasure(pathLeft, false);\n        PathMeasure pmRight = new PathMeasure(pathRight, false);\n        float[] coords = new float[2];\n        for (int i = 0; i < staticVerts.length / 2; i++) {\n\n            float yIndexValue = staticVerts[i * 2 + 1];\n            float xIndexValue = staticVerts[i * 2];\n            if (xIndexValue == 0) {\n                float percentOffsetY = (0.000001f + yIndexValue) / bitmap.getHeight();\n                pmLeft.getPosTan(pmLeft.getLength() * (1f - percentOffsetY), coords, null);\n                setXY(drawingVerts, i, coords[0], coords[1]);\n            } else {\n                float percentOffsetY = (0.000001f + yIndexValue) / bitmap.getHeight();\n                pmRight.getPosTan(pmRight.getLength() * (1f - percentOffsetY), coords, null);\n                setXY(drawingVerts, i, coords[0], coords[1]);\n\n            }\n        }\n    }\n\n    public void setOffsetPercent(float offset) {\n        if (!isBounceAnimatin)\n            offsetInPercent = offset ;\n    }\n\n\n    public boolean isBounceAnimatin() {\n        return isBounceAnimatin;\n    }\n\n    public void cancelBounce() {\n        isBounceAnimatin = false;\n    }\n\n    @Override\n    public void update(float deltaTime, float wind) {\n        super.update(deltaTime, wind);\n        setOffsetPercent(wind/100f);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/RootActivity.java",
    "content": "package no.agens.depth;\n\nimport android.animation.ArgbEvaluator;\nimport android.animation.ObjectAnimator;\nimport android.app.Activity;\nimport android.app.Fragment;\nimport android.content.Intent;\nimport android.graphics.BitmapFactory;\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\n\nimport no.agens.depth.lib.CircularSplashView;\nimport no.agens.depth.lib.tween.interpolators.ExpoIn;\nimport no.agens.depth.lib.tween.interpolators.QuintOut;\n\n\npublic class RootActivity extends Activity {\n\n    public static final int WATER_SCREEN_MENU_INDEX = 0;\n    public static final int WIND_SCREEN_MENU_INDEX = 1;\n    public static final int PLAYGROUND_SCREEN_MENU_INDEX = 2;\n    public static final int ABOUT_SCREEN_MENU_INDEX = 3;\n\n    Fragment currentFragment;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n\n        setContentView(R.layout.activity_root);\n        makeAppFullscreen();\n        if (savedInstanceState == null) {\n            currentFragment = new WaterFragment();\n            getFragmentManager().beginTransaction().add(R.id.fragment_container, currentFragment).commit();\n        }\n        setupMenu();\n    }\n\n    public void setCurrentMenuIndex(int currentMenuIndex) {\n        this.currentMenuIndex = currentMenuIndex;\n    }\n\n    int currentMenuIndex = 0;\n\n    private void makeAppFullscreen() {\n        getWindow().setStatusBarColor(Color.TRANSPARENT);\n        getWindow().getDecorView().setSystemUiVisibility(\n                View.SYSTEM_UI_FLAG_LAYOUT_STABLE\n                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);\n    }\n\n    boolean isMenuVisible = false;\n    ViewGroup menu;\n\n    @Override\n    public void onBackPressed() {\n\n        if (isMenuVisible) {\n            hideMenu();\n            ((MenuAnimation) currentFragment).revertFromMenu();\n        } else\n            super.onBackPressed();\n    }\n\n    public void showMenu() {\n        isMenuVisible = true;\n        ObjectAnimator translationY = ObjectAnimator.ofFloat(menu, View.TRANSLATION_Y, menu.getHeight(), 0);\n        translationY.setDuration(1000);\n        translationY.setInterpolator(new QuintOut());\n        translationY.setStartDelay(150);\n        translationY.start();\n        selectMenuItem(currentMenuIndex, ((TextView) menu.getChildAt(currentMenuIndex).findViewById(R.id.item_text)).getCurrentTextColor());\n        ((MenuAnimation) currentFragment).animateTOMenu();\n    }\n\n    public void hideMenu() {\n        isMenuVisible = false;\n        ObjectAnimator translationY = ObjectAnimator.ofFloat(menu, View.TRANSLATION_Y, menu.getHeight());\n        translationY.setDuration(750);\n        translationY.setInterpolator(new ExpoIn());\n        translationY.start();\n    }\n\n\n    private void setupMenu() {\n        menu = (ViewGroup) findViewById(R.id.menu_container);\n        int color = getResources().getColor(R.color.splash1);\n        addMenuItem(menu, \"Water And Noise\", R.drawable.splash1, color, R.drawable.menu_btn, WATER_SCREEN_MENU_INDEX);\n        addMenuItem(menu, \"Two Bears\", R.drawable.splash2, getResources().getColor(R.color.splash2), R.drawable.menu_btn2, WIND_SCREEN_MENU_INDEX);\n        addMenuItem(menu, \"Depth Playground\", R.drawable.splash3, getResources().getColor(R.color.splash3), R.drawable.menu_btn3, PLAYGROUND_SCREEN_MENU_INDEX);\n        addMenuItem(menu, \"About\", R.drawable.splash4, getResources().getColor(R.color.splash4), R.drawable.menu_btn4, ABOUT_SCREEN_MENU_INDEX);\n        selectMenuItem(WATER_SCREEN_MENU_INDEX, color);\n        menu.setTranslationY(20000);\n    }\n\n\n    private void addMenuItem(ViewGroup menu, String text, int drawableResource, int splashColor, int menu_btn, int menuIndex) {\n        ViewGroup item = (ViewGroup) LayoutInflater.from(this).inflate(R.layout.menu_item, menu, false);\n        ((TextView) item.findViewById(R.id.item_text)).setText(text);\n        CircularSplashView ic = (CircularSplashView) item.findViewById(R.id.circle);\n        ic.setSplash(BitmapFactory.decodeResource(getResources(), drawableResource));\n        ic.setSplashColor(splashColor);\n        item.setOnClickListener(getMenuItemCLick(menuIndex, splashColor));\n        if (menuIndex == WATER_SCREEN_MENU_INDEX) {\n            int padding = (int) getResources().getDimension(R.dimen.menu_item_height_padding);\n            menu.addView(item, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.menu_item_height) + padding));\n            item.setPadding(0, padding, 0, 0);\n        } else if (menuIndex == ABOUT_SCREEN_MENU_INDEX) {\n            int padding = (int) getResources().getDimension(R.dimen.menu_item_height_padding);\n            menu.addView(item, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.menu_item_height) + padding));\n            item.setPadding(0, 0, 0, padding);\n        } else\n            menu.addView(item, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.menu_item_height)));\n        item.setBackground(getResources().getDrawable(menu_btn, null));\n\n    }\n\n    private View.OnClickListener getMenuItemCLick(final int menuIndex, final int color) {\n        return new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                if (menuIndex == currentMenuIndex)\n                    onBackPressed();\n                else if (menuIndex == WATER_SCREEN_MENU_INDEX && !(currentFragment instanceof WaterFragment)) {\n                    showWaterFragment(menuIndex, color);\n                } else if (menuIndex == WIND_SCREEN_MENU_INDEX && !(currentFragment instanceof WindFragment)) {\n                    showWindFragment(menuIndex, color);\n                } else if (menuIndex == PLAYGROUND_SCREEN_MENU_INDEX) {\n                    startActivity(new Intent(RootActivity.this, PlayGroundActivity.class));\n                    onBackPressed();\n                }\n            }\n        };\n    }\n\n    private void showWindFragment(int menuIndex, int color) {\n        ((MenuAnimation) currentFragment).exitFromMenu();\n        WindFragment windFragment = new WindFragment();\n        windFragment.setIntroAnimate(true);\n        goToFragment(windFragment);\n        hideMenu();\n        selectMenuItem(menuIndex, color);\n    }\n\n    private void showWaterFragment(int menuIndex, int color) {\n        ((MenuAnimation) currentFragment).exitFromMenu();\n        WaterFragment waterFragment = new WaterFragment();\n        waterFragment.setIntroAnimate(true);\n        goToFragment(waterFragment);\n        hideMenu();\n        selectMenuItem(menuIndex, color);\n    }\n\n    private void selectMenuItem(int menuIndex, int color) {\n        for (int i = 0; i < menu.getChildCount(); i++) {\n            View menuItem = menu.getChildAt(i);\n            if (i == menuIndex)\n                select(menuItem, color);\n            else\n                unSelect(menuItem);\n        }\n        currentMenuIndex = menuIndex;\n    }\n\n    private void unSelect(View menuItem) {\n        final View circle = menuItem.findViewById(R.id.circle);\n        circle.animate().scaleX(0).scaleY(0).setDuration(150).withEndAction(new Runnable() {\n            @Override\n            public void run() {\n                circle.setVisibility(View.INVISIBLE);\n            }\n        }).start();\n        fadeColorTo(Color.BLACK, (TextView) menuItem.findViewById(R.id.item_text));\n    }\n\n    private void fadeColorTo(int newColor, TextView view) {\n        ObjectAnimator color = ObjectAnimator.ofObject(view, \"TextColor\", new ArgbEvaluator(), view.getCurrentTextColor(), newColor);\n        color.setDuration(200);\n        color.start();\n    }\n\n    private void select(View menuItem, int color) {\n        final CircularSplashView circle = (CircularSplashView) menuItem.findViewById(R.id.circle);\n        circle.setScaleX(1f);\n        circle.setScaleY(1f);\n        circle.setVisibility(View.VISIBLE);\n        circle.introAnimate();\n        fadeColorTo(color, (TextView) menuItem.findViewById(R.id.item_text));\n    }\n\n    public void goToFragment(final Fragment newFragment) {\n        getFragmentManager().beginTransaction().add(R.id.fragment_container, newFragment).commit();\n        final Fragment removeFragment = currentFragment;\n        currentFragment = newFragment;\n        getWindow().getDecorView().postDelayed(new Runnable() {\n            @Override\n            public void run() {\n                getFragmentManager().beginTransaction().remove(removeFragment).commit();\n            }\n        }, 2000);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/SeekBarProgressChangeListener.java",
    "content": "package no.agens.depth;\n\nimport android.widget.SeekBar;\n\npublic abstract class SeekBarProgressChangeListener implements SeekBar.OnSeekBarChangeListener {\n    @Override\n    public void onStartTrackingTouch(SeekBar seekBar) {\n    }\n\n    @Override\n    public void onStopTrackingTouch(SeekBar seekBar) {\n    }\n}"
  },
  {
    "path": "app/src/main/java/no/agens/depth/Smoke.java",
    "content": "package no.agens.depth;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.PathMeasure;\nimport android.view.animation.DecelerateInterpolator;\nimport android.view.animation.LinearInterpolator;\n\nimport no.agens.depth.lib.headers.Renderable;\n\npublic class Smoke extends Renderable {\n    public static final float WIND_SENSITIVITY = 7f;\n    float height, width;\n    int numberOfTurns;\n    float density;\n    private final float[] drawingVerts = new float[TOTAL_SLICES_COUNT * 2];\n    private final float[] staticVerts = new float[TOTAL_SLICES_COUNT * 2];\n    private static final int HORIZONTAL_SLICES = 1;\n    private static final int VERTICAL_SLICES = 80;\n    private static final int TOTAL_SLICES_COUNT = (HORIZONTAL_SLICES + 1) * (VERTICAL_SLICES + 1);\n\n\n    private void createVerts() {\n\n        float xDimesion = (float) bitmap.getWidth();\n        float yDimesion = (float) bitmap.getHeight();\n\n        int index = 0;\n\n        for (int y = 0; y <= VERTICAL_SLICES; y++) {\n            float fy = yDimesion * y / VERTICAL_SLICES;\n            for (int x = 0; x <= HORIZONTAL_SLICES; x++) {\n                float fx = xDimesion * x / HORIZONTAL_SLICES;\n                setXY(drawingVerts, index, fx, fy);\n                setXY(staticVerts, index, fx, fy);\n                index += 1;\n            }\n        }\n    }\n\n    public void setXY(float[] array, int index, float x, float y) {\n        array[index * 2 + 0] = x;\n        array[index * 2 + 1] = y;\n    }\n\n    public Smoke(Bitmap bitmap, float x, float y, float height, float width, int numberOfTurns, float density) {\n        super(bitmap, x, y);\n        this.height = height;\n        this.width = width;\n        this.numberOfTurns = numberOfTurns;\n        paint.setStyle(Paint.Style.STROKE);\n        this.density = density;\n        createVerts();\n        createPath();\n\n        pathPointOffsetAnim = ValueAnimator.ofFloat(0, ((bitmap.getHeight() / (float) numberOfTurns) * 2f) / bitmap.getHeight()).setDuration(1500);\n        pathPointOffsetAnim.setRepeatCount(ValueAnimator.INFINITE);\n        pathPointOffsetAnim.setRepeatMode(ValueAnimator.RESTART);\n        pathPointOffsetAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n            @Override\n            public void onAnimationUpdate(ValueAnimator animation) {\n                pathPointOffset = (float) animation.getAnimatedValue();\n            }\n        });\n        pathPointOffsetAnim.setInterpolator(new LinearInterpolator());\n        pathPointOffsetAnim.start();\n\n        createPath();\n    }\n\n    ValueAnimator pathPointOffsetAnim;\n\n    public void destroy() {\n        super.destroy();\n        pathPointOffsetAnim.cancel();\n    }\n\n    @Override\n    public void pause() {\n        super.pause();\n        pathPointOffsetAnim.pause();\n    }\n\n    @Override\n    public void resume() {\n        super.resume();\n        pathPointOffsetAnim.resume();\n    }\n\n    Path smokePath = new Path();\n    Paint paint = new Paint();\n    float pathPointOffset = 1;\n\n    @Override\n    public void draw(Canvas canvas) {\n\n\n        //  alphaCanvas.drawPath(smokePath, paint);\n        canvas.drawBitmapMesh(bitmap, HORIZONTAL_SLICES, VERTICAL_SLICES, drawingVerts, 0, null, 0, paint);\n    }\n\n    public void setY(float y) {\n        this.y = y;\n        createPath();\n    }\n\n    @Override\n    public void update(float deltaTime, float wind) {\n        matchVertsToPath(wind);\n    }\n\n    private void createPath() {\n        smokePath.reset();\n        smokePath.moveTo(x, y);\n\n        int step = (int) (height / numberOfTurns);\n        boolean goLeft = true;\n        for (int i = 0; i < numberOfTurns; i++) {\n            if (goLeft)\n                smokePath.cubicTo(x, y - step * i, x + width, y - step * i - step / 2, x, y - step * i - step);\n            else\n                smokePath.cubicTo(x, y - step * i, x - width, y - step * i - step / 2, x, y - step * i - step);\n\n            goLeft = !goLeft;\n        }\n\n    }\n\n    float[] coords = new float[2];\n    float[] coords2 = new float[2];\n\n    private void matchVertsToPath(float wind) {\n        PathMeasure pm = new PathMeasure(smokePath, false);\n\n        for (int i = 0; i < staticVerts.length / 2; i++) {\n\n            float yIndexValue = staticVerts[i * 2 + 1];\n            float xIndexValue = staticVerts[i * 2];\n\n            float percentOffsetY = (0.000001f + yIndexValue) / bitmap.getHeight();\n            float percentOffsetY2 = (0.000001f + yIndexValue) / (bitmap.getHeight() + ((bitmap.getHeight() / numberOfTurns) * 4f));\n            percentOffsetY2 += pathPointOffset;\n            pm.getPosTan(pm.getLength() * (1f - percentOffsetY), coords, null);\n            pm.getPosTan(pm.getLength() * (1f - percentOffsetY2), coords2, null);\n\n            if (xIndexValue == 0) {\n                float desiredXCoord = coords2[0] - (bitmap.getWidth()) / 2;\n                desiredXCoord -= (desiredXCoord - x) * percentOffsetY;\n                desiredXCoord += (wind / 3f) * density + ((wind * WIND_SENSITIVITY) * (1f - smokeExponentionWindStuff.getInterpolation(percentOffsetY)));\n                setXY(drawingVerts, i, desiredXCoord, coords[1]);\n            } else {\n                float desiredXCoord = coords2[0] + (bitmap.getWidth()) / 2;\n                desiredXCoord -= (desiredXCoord - x) * percentOffsetY;\n                desiredXCoord += (wind / 3f) * density + ((wind * WIND_SENSITIVITY) * (1f - smokeExponentionWindStuff.getInterpolation(percentOffsetY)));\n                setXY(drawingVerts, i, desiredXCoord, coords[1]);\n\n            }\n        }\n    }\n\n    DecelerateInterpolator smokeExponentionWindStuff = new DecelerateInterpolator(1f);\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/TransitionHelper.java",
    "content": "package no.agens.depth;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorListenerAdapter;\nimport android.animation.ObjectAnimator;\nimport android.animation.ValueAnimator;\nimport android.support.annotation.NonNull;\nimport android.view.View;\n\nimport no.agens.depth.lib.DepthLayout;\nimport no.agens.depth.lib.tween.interpolators.BackOut;\nimport no.agens.depth.lib.tween.interpolators.CircInOut;\nimport no.agens.depth.lib.tween.interpolators.ExpoIn;\nimport no.agens.depth.lib.tween.interpolators.ExpoOut;\nimport no.agens.depth.lib.tween.interpolators.QuadInOut;\nimport no.agens.depth.lib.tween.interpolators.QuintInOut;\nimport no.agens.depth.lib.tween.interpolators.QuintOut;\n\npublic class TransitionHelper {\n\n    public static final float TARGET_SCALE = 0.5f;\n    public static final float TARGET_ROTATION = -50f;\n    public static final float TARGET_ROTATION_X = 60f;\n    public static final int MOVE_Y_STEP = 15;\n    public static final int DURATION = 1100;\n    public static final QuintOut VALUEinterpolator = new QuintOut();\n\n    public static final int FISRTDELAY = 300;\n\n    public static void startIntroAnim(View root, AnimatorListenerAdapter introEndListener) {\n        introAnimate((DepthLayout) root.findViewById(R.id.root_dl), 0, 30f, 15, 180);\n        introAnimate((DepthLayout) root.findViewById(R.id.appbar), MOVE_Y_STEP, 20f, 30, 170);\n        introAnimate((DepthLayout) root.findViewById(R.id.fab_container), MOVE_Y_STEP * 2f, 20f, 45, 190);\n        introAnimate((DepthLayout) root.findViewById(R.id.dl2), MOVE_Y_STEP, 20f, 60, 200);\n        introAnimate((DepthLayout) root.findViewById(R.id.dl3), MOVE_Y_STEP * 2, 20f, 75, 210).addListener(introEndListener);\n    }\n\n    static ObjectAnimator introAnimate(final DepthLayout target, final float moveY, final float customElevation, long delay, int subtractDelay) {\n\n        target.setPivotY(getDistanceToCenter(target));\n        target.setPivotX(getDistanceToCenterX(target));\n        target.setCameraDistance(10000 * target.getResources().getDisplayMetrics().density);\n\n        ObjectAnimator translationY2 = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y, target.getResources().getDisplayMetrics().heightPixels, -moveY * target.getResources().getDisplayMetrics().density).setDuration(800);\n        translationY2.setInterpolator(new ExpoOut());\n        translationY2.setStartDelay(700 + subtractDelay);\n        translationY2.start();\n        target.setTranslationY(target.getResources().getDisplayMetrics().heightPixels);\n\n        ObjectAnimator translationX2 = ObjectAnimator.ofFloat(target, View.TRANSLATION_X, -target.getResources().getDisplayMetrics().widthPixels, 0).setDuration(800);\n        translationX2.setInterpolator(new ExpoOut());\n        translationX2.setStartDelay(700 + subtractDelay);\n        translationX2.start();\n        target.setTranslationX(-target.getResources().getDisplayMetrics().widthPixels);\n\n        ObjectAnimator translationY = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y, 0).setDuration(700);\n        translationY.setInterpolator(new BackOut());\n        translationY.setStartDelay(700 + 800);\n        translationY.start();\n\n\n        ObjectAnimator rotationX = ObjectAnimator.ofFloat(target, View.ROTATION_X, TARGET_ROTATION_X, 0).setDuration(1000);\n        rotationX.setInterpolator(new QuintInOut());\n        rotationX.setStartDelay(700 + FISRTDELAY + subtractDelay);\n        rotationX.start();\n        target.setRotationX(TARGET_ROTATION_X);\n\n        ObjectAnimator elevation = ObjectAnimator.ofFloat(target, \"CustomShadowElevation\", customElevation * target.getResources().getDisplayMetrics().density, target.getCustomShadowElevation()).setDuration(1000);\n        elevation.setInterpolator(new QuintInOut());\n        elevation.setStartDelay(700 + FISRTDELAY + subtractDelay * 2);\n        elevation.start();\n        target.setCustomShadowElevation(customElevation * target.getResources().getDisplayMetrics().density);\n\n        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, TARGET_SCALE, target.getScaleX()).setDuration(1000);\n        scaleX.setInterpolator(new CircInOut());\n        scaleX.setStartDelay(700 + FISRTDELAY + subtractDelay);\n        scaleX.start();\n        target.setScaleX(TARGET_SCALE);\n\n        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, TARGET_SCALE, target.getScaleY()).setDuration(1000);\n        scaleY.setInterpolator(new CircInOut());\n        scaleY.setStartDelay(700 + FISRTDELAY + subtractDelay);\n        scaleY.start();\n        target.setScaleY(TARGET_SCALE);\n\n        ObjectAnimator rotation = ObjectAnimator.ofFloat(target, View.ROTATION, TARGET_ROTATION, 0).setDuration(1400);\n        rotation.setInterpolator(new QuadInOut());\n        rotation.setStartDelay(FISRTDELAY + subtractDelay);\n        rotation.start();\n        target.setRotation(TARGET_ROTATION);\n        rotation.addListener(getShowStatusBarListener(target));\n        return scaleY;\n    }\n\n\n    public static void startExitAnim(View root) {\n        exitAnimate((DepthLayout) root.findViewById(R.id.root_dl), 0, 30f, 15, 190, true);\n        exitAnimate((DepthLayout) root.findViewById(R.id.appbar), MOVE_Y_STEP, 20f, 30, 170, true);\n        exitAnimate((DepthLayout) root.findViewById(R.id.fab_container), MOVE_Y_STEP * 2f, 20f, 45, 210, true);\n        exitAnimate((DepthLayout) root.findViewById(R.id.dl2), MOVE_Y_STEP, 20f, 60, 230, true);\n        exitAnimate((DepthLayout) root.findViewById(R.id.dl3), MOVE_Y_STEP * 2, 20f, 75, 250, true);\n        hideStatusBar(root);\n    }\n\n    private static void hideStatusBar(View root) {\n//        View decorView = ((Activity) root.getContext()).getWindow().getDecorView();\n//        int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;\n//        decorView.setSystemUiVisibility(uiOptions);\n    }\n\n\n    static ValueAnimator exitAnimate(final DepthLayout target, final float moveY, final float customElevation, long delay, int subtractDelay, boolean continueOffscreen) {\n\n        target.setPivotY(getDistanceToCenter(target));\n        target.setPivotX(getDistanceToCenterX(target));\n        target.setCameraDistance(10000 * target.getResources().getDisplayMetrics().density);\n\n        ObjectAnimator rotationX = ObjectAnimator.ofFloat(target, View.ROTATION_X, TARGET_ROTATION_X).setDuration(DURATION);\n        rotationX.setInterpolator(VALUEinterpolator);\n        rotationX.setStartDelay(delay);\n        rotationX.start();\n\n        ObjectAnimator elevation = ObjectAnimator.ofFloat(target, \"CustomShadowElevation\", target.getCustomShadowElevation(), customElevation * target.getResources().getDisplayMetrics().density).setDuration(DURATION);\n        elevation.setInterpolator(VALUEinterpolator);\n        elevation.setStartDelay(delay);\n        elevation.start();\n\n        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, TARGET_SCALE).setDuration(DURATION);\n        scaleX.setInterpolator(new QuintOut());\n        scaleX.setStartDelay(delay);\n        scaleX.start();\n\n        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, TARGET_SCALE).setDuration(DURATION);\n        scaleY.setInterpolator(new QuintOut());\n        scaleY.setStartDelay(delay);\n        scaleY.start();\n\n        ObjectAnimator rotation = ObjectAnimator.ofFloat(target, View.ROTATION, TARGET_ROTATION).setDuration(1600);\n        rotation.setInterpolator(VALUEinterpolator);\n        rotation.setStartDelay(delay);\n        rotation.start();\n\n        ObjectAnimator translationY = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y, -moveY * target.getResources().getDisplayMetrics().density).setDuration(subtractDelay);\n        translationY.setInterpolator(VALUEinterpolator);\n        translationY.setStartDelay(delay);\n        translationY.start();\n        if (continueOffscreen) {\n            continueOutToRight(target, moveY, subtractDelay);\n        }\n        return scaleY;\n    }\n\n    private static void continueOutToRight(DepthLayout target, float moveY, int subtractDelay) {\n        ObjectAnimator translationY2 = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y, -moveY * target.getResources().getDisplayMetrics().density, -target.getResources().getDisplayMetrics().heightPixels).setDuration(900);\n        translationY2.setInterpolator(new ExpoIn());\n        translationY2.setStartDelay(0 + subtractDelay);\n\n        translationY2.start();\n\n        ObjectAnimator translationX2 = ObjectAnimator.ofFloat(target, View.TRANSLATION_X, target.getTranslationX(), target.getResources().getDisplayMetrics().widthPixels).setDuration(900);\n        translationX2.setInterpolator(new ExpoIn());\n        translationX2.setStartDelay(0 + subtractDelay);\n        translationX2.start();\n    }\n\n    public static float getDistanceToCenter(View target) {\n        float viewCenter = target.getTop() + target.getHeight() / 2f;\n        float rootCenter = ((View) target.getParent()).getHeight() / 2;\n        return target.getHeight() / 2f + rootCenter - viewCenter;\n    }\n\n    public static float getDistanceToCenterX(View target) {\n        float viewCenter = target.getLeft() + target.getWidth() / 2f;\n        float rootCenter = ((View) target.getParent()).getWidth() / 2;\n        return target.getWidth() / 2f + rootCenter - viewCenter;\n    }\n\n    public static void animateToMenuState(View root, AnimatorListenerAdapter onMenuAnimFinished) {\n        hideStatusBar(root);\n        exitAnimate((DepthLayout) root.findViewById(R.id.root_dl), 0, 30f, 15, 190, false);\n        exitAnimate((DepthLayout) root.findViewById(R.id.appbar), MOVE_Y_STEP, 20f, 30, 170, false);\n        exitAnimate((DepthLayout) root.findViewById(R.id.fab_container), MOVE_Y_STEP * 2f, 20f, 45, 210, false);\n        exitAnimate((DepthLayout) root.findViewById(R.id.dl2), MOVE_Y_STEP, 20f, 60, 230, false);\n        exitAnimate((DepthLayout) root.findViewById(R.id.dl3), MOVE_Y_STEP * 2, 20f, 75, 250, false).addListener(onMenuAnimFinished);\n\n        ObjectAnimator translationY = ObjectAnimator.ofFloat(root, View.TRANSLATION_Y, -90f * root.getResources().getDisplayMetrics().density).setDuration(DURATION);\n        translationY.setInterpolator(VALUEinterpolator);\n        translationY.start();\n    }\n\n    private static void makeAppFullscreen(View target) {\n//        ((Activity) target.getContext()).getWindow().setStatusBarColor(Color.TRANSPARENT);\n//        ((Activity) target.getContext()).getWindow().getDecorView().setSystemUiVisibility(\n//                View.SYSTEM_UI_FLAG_LAYOUT_STABLE\n//                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);\n    }\n\n    public static void animateMenuOut(View root) {\n        continueOutToRight((DepthLayout) root.findViewById(R.id.root_dl), 0, 20);\n        continueOutToRight((DepthLayout) root.findViewById(R.id.appbar), MOVE_Y_STEP, 0);\n        continueOutToRight((DepthLayout) root.findViewById(R.id.fab_container), MOVE_Y_STEP * 2f, 40);\n        continueOutToRight((DepthLayout) root.findViewById(R.id.dl2), MOVE_Y_STEP, 60);\n        continueOutToRight((DepthLayout) root.findViewById(R.id.dl3), MOVE_Y_STEP * 2, 80);\n    }\n\n    public static void startRevertFromMenu(View root, AnimatorListenerAdapter animatorListenerAdapter) {\n\n        revertFromMenu((DepthLayout) root.findViewById(R.id.root_dl), 30f, 10, 0);\n        revertFromMenu((DepthLayout) root.findViewById(R.id.appbar), 20f, 0, 0);\n        revertFromMenu((DepthLayout) root.findViewById(R.id.fab_container), 20f, 20, 6);\n        revertFromMenu((DepthLayout) root.findViewById(R.id.dl2), 20f, 30, 1);\n        revertFromMenu((DepthLayout) root.findViewById(R.id.dl3), 20f, 40, 2).addListener(animatorListenerAdapter);\n        ObjectAnimator translationY = ObjectAnimator.ofFloat(root, View.TRANSLATION_Y, 0).setDuration(DURATION);\n        translationY.setInterpolator(new QuintInOut());\n        translationY.start();\n    }\n\n\n    static ObjectAnimator revertFromMenu(final DepthLayout target, final float customElevation, int subtractDelay, float targetElevation) {\n\n        target.setPivotY(getDistanceToCenter(target));\n        target.setPivotX(getDistanceToCenterX(target));\n        target.setCameraDistance(10000 * target.getResources().getDisplayMetrics().density);\n\n\n        ObjectAnimator translationY = ObjectAnimator.ofFloat(target, View.TRANSLATION_Y, 0).setDuration(700);\n        translationY.setInterpolator(new BackOut());\n        translationY.setStartDelay(250 + FISRTDELAY + subtractDelay);\n        translationY.start();\n\n\n        ObjectAnimator rotationX = ObjectAnimator.ofFloat(target, View.ROTATION_X, target.getRotationX(), 0).setDuration(1000);\n        rotationX.setInterpolator(new QuintInOut());\n        rotationX.setStartDelay(FISRTDELAY + subtractDelay);\n        rotationX.start();\n        target.setRotationX(TARGET_ROTATION_X);\n\n        ObjectAnimator elevation = ObjectAnimator.ofFloat(target, \"CustomShadowElevation\", target.getCustomShadowElevation(), targetElevation * target.getResources().getDisplayMetrics().density).setDuration(1000);\n        elevation.setInterpolator(new QuintInOut());\n        elevation.setStartDelay(FISRTDELAY + subtractDelay * 2);\n        elevation.start();\n        target.setCustomShadowElevation(customElevation * target.getResources().getDisplayMetrics().density);\n\n        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, target.getScaleX(), 1f).setDuration(1000);\n        scaleX.setInterpolator(new CircInOut());\n        scaleX.setStartDelay(FISRTDELAY + subtractDelay);\n        scaleX.start();\n        target.setScaleX(TARGET_SCALE);\n\n        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, target.getScaleY(), 1f).setDuration(1000);\n        scaleY.setInterpolator(new CircInOut());\n        scaleY.setStartDelay(FISRTDELAY + subtractDelay);\n        scaleY.start();\n        target.setScaleY(TARGET_SCALE);\n\n        ObjectAnimator rotation = ObjectAnimator.ofFloat(target, View.ROTATION, target.getRotation(), 0).setDuration(1100);\n        rotation.setInterpolator(new QuintInOut());\n        rotation.setStartDelay(subtractDelay);\n        rotation.start();\n        rotation.addListener(getShowStatusBarListener(target));\n        return scaleY;\n    }\n\n    @NonNull\n    private static AnimatorListenerAdapter getShowStatusBarListener(final DepthLayout target) {\n        return new AnimatorListenerAdapter() {\n            @Override\n            public void onAnimationEnd(Animator animation) {\n                super.onAnimationEnd(animation);\n                makeAppFullscreen(target);\n            }\n        };\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/Water.java",
    "content": "package no.agens.depth;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.Path;\n\nimport no.agens.depth.lib.headers.PathBitmapMesh;\nimport no.agens.depth.lib.headers.Renderable;\n\npublic class Water extends Renderable {\n\n    public static final int VERTS = 6;\n    private float height, width;\n\n    Foam[] foams = new Foam[4];\n    int numberOfWaves;\n    PathBitmapMesh water;\n    private float waveHeight;\n\n    public Water(Bitmap bitmap, Bitmap foam, float y, float height, float width, int waves) {\n        super(bitmap, 0, y);\n        this.height = height;\n        this.width = width;\n        numberOfWaves = waves;\n\n        debugPaint.setColor(Color.RED);\n        debugPaint.setStyle(Paint.Style.STROKE);\n        lastEmit = System.currentTimeMillis();\n        water = new PathBitmapMesh(VERTS, 1, bitmap, 1500);\n        foams[0] = new Foam(VERTS, 1, foam, 0, height / 12, 1500);\n        foams[1] = new Foam(VERTS, 1, foam, -height / 5, height / 5, 1500);\n        foams[1].setAlpha(100);\n        foams[2] = new Foam(VERTS, 1, foam, -height / 12, height / 12, 1450);\n        foams[2].setVerticalOffset(height / 7);\n        foams[3] = new Foam(VERTS, 1, foam, -height / 12, height / 12, 1400);\n        foams[3].setVerticalOffset(height / 4);\n        waveHeight = height / 10;\n        createPath();\n    }\n\n    @Override\n    public void pause() {\n        super.pause();\n        water.pause();\n        for (Foam foam : foams)\n            foam.pause();\n    }\n\n    @Override\n    public void resume() {\n        super.resume();\n        water.resume();\n        for (Foam foam : foams)\n            foam.resume();\n    }\n\n    @Override\n    public void destroy() {\n        super.destroy();\n        for (Foam foam : foams)\n            foam.destroy();\n    }\n\n    Paint debugPaint = new Paint();\n\n    @Override\n    public void draw(Canvas canvas) {\n\n        water.draw(canvas);\n        for (Foam foam : foams) {\n            foam.draw(canvas);\n        }\n    }\n\n    @Override\n    public void update(float deltaTime, float wind) {\n        super.update(deltaTime, wind);\n        for (Foam foam : foams) {\n            foam.update(deltaTime);\n        }\n        water.matchVertsToPath(waterPath, height, ((bitmap.getWidth() / numberOfWaves) * 4f));\n        for (Foam foam : foams) {\n            foam.matchVertsToPath(waterPath, foam.getBitmap().getWidth() / numberOfWaves * 4f);\n        }\n        if (lastEmit + emitInterWall < System.currentTimeMillis()) {\n            for (Foam foam : foams) {\n                foam.calcWave();\n            }\n            lastEmit = System.currentTimeMillis();\n        }\n\n    }\n\n    private Path waterPath = new Path();\n\n    private void createPath() {\n        waterPath.reset();\n        waterPath.moveTo(0, y);\n\n        int step = (int) (width / numberOfWaves);\n        boolean goLeft = true;\n        for (int i = 0; i < numberOfWaves; i++) {\n            if (goLeft)\n                waterPath.cubicTo(x + step * i, y, x + step * i + step / 2f, y + waveHeight, x + step * i + step, y);\n            else\n                waterPath.cubicTo(x + step * i, y, x + step * i + step / 2f, y - waveHeight, x + step * i + step, y);\n\n            goLeft = !goLeft;\n        }\n\n    }\n\n\n    long lastEmit;\n    private int emitInterWall = 1000;\n\n\n    public void setWaveHeight(float waveHeight) {\n        this.waveHeight = waveHeight;\n        createPath();\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/WaterFragment.java",
    "content": "package no.agens.depth;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorListenerAdapter;\nimport android.animation.ObjectAnimator;\nimport android.app.Fragment;\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.ViewTreeObserver;\nimport android.widget.ImageView;\nimport android.widget.SeekBar;\n\nimport no.agens.depth.lib.MaterialMenuDrawable;\n\npublic class WaterFragment extends Fragment implements MenuAnimation {\n\n    public static final int TRANSFORM_DURATION = 900;\n    private boolean introAnimate;\n\n    public WaterFragment() {\n    }\n\n    public void setIntroAnimate(boolean introAnimate) {\n        this.introAnimate = introAnimate;\n    }\n\n    View root;\n    MaterialMenuDrawable menuIcon;\n    WaterSceneView waterScene;\n\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\n                             Bundle savedInstanceState) {\n        root = inflater.inflate(R.layout.fragment_water, container, false);\n        waterScene = (WaterSceneView) root.findViewById(R.id.water_scene);\n        setupFab();\n        introAnimate();\n        setupSeekbars();\n        setupMenuButton();\n        ((RootActivity) getActivity()).setCurrentMenuIndex(RootActivity.WATER_SCREEN_MENU_INDEX);\n\n        return root;\n    }\n\n    private void setupSeekbars() {\n        SeekBar waveSeekBar = (SeekBar) root.findViewById(R.id.wave_seekbar);\n        SeekBar noiseSeekBar = (SeekBar) root.findViewById(R.id.noise_seekbar);\n\n        WindFragment.setProgressBarColor(waveSeekBar, getResources().getColor(R.color.fab));\n        WindFragment.setProgressBarColor(noiseSeekBar, getResources().getColor(R.color.fab));\n\n        noiseSeekBar.setProgress(50);\n        waveSeekBar.setProgress(50);\n\n        waveSeekBar.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                waterScene.setWaveHeight(progress / 4f * getResources().getDisplayMetrics().density);\n            }\n        });\n        noiseSeekBar.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                waterScene.setNoiseIntensity((float) progress / 100f);\n            }\n        });\n    }\n\n    private void setupMenuButton() {\n        ImageView menu = (ImageView) root.findViewById(R.id.menu);\n        menu.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                if (!((RootActivity) getActivity()).isMenuVisible)\n                    ((RootActivity) getActivity()).showMenu();\n                else\n                    ((RootActivity) getActivity()).onBackPressed();\n            }\n        });\n        menuIcon = new MaterialMenuDrawable(getActivity(), Color.WHITE, MaterialMenuDrawable.Stroke.THIN, TRANSFORM_DURATION);\n        menu.setImageDrawable(menuIcon);\n    }\n\n    private void introAnimate() {\n        if (introAnimate)\n            root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {\n                @Override\n                public void onGlobalLayout() {\n                    root.getViewTreeObserver().removeOnGlobalLayoutListener(this);\n                    TransitionHelper.startIntroAnim(root, showShadowListener);\n                    hideShadow();\n                    waterScene.postDelayed(new Runnable() {\n                        @Override\n                        public void run() {\n                            waterScene.setPause(true);\n                        }\n                    }, 10);\n                }\n            });\n    }\n\n    private void setupFab() {\n        root.findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {\n                    @Override\n                    public void onGlobalLayout() {\n                        root.getViewTreeObserver().removeOnGlobalLayoutListener(this);\n                        TransitionHelper.startExitAnim(root);\n                    }\n                });\n                WindFragment windFragment = new WindFragment();\n                windFragment.setIntroAnimate(true);\n                ((RootActivity) getActivity()).goToFragment(windFragment);\n                if (((RootActivity) getActivity()).isMenuVisible)\n                    ((RootActivity) getActivity()).hideMenu();\n                hideShadow();\n                waterScene.setPause(true);\n            }\n        });\n    }\n\n    AnimatorListenerAdapter showShadowListener = new AnimatorListenerAdapter() {\n        @Override\n        public void onAnimationEnd(Animator animation) {\n            super.onAnimationEnd(animation);\n            showShadow();\n            waterScene.setPause(false);\n        }\n    };\n\n    private void hideShadow() {\n        View actionbarShadow = root.findViewById(R.id.actionbar_shadow);\n        actionbarShadow.setVisibility(View.GONE);\n    }\n\n    private void showShadow() {\n        View actionbarShadow = root.findViewById(R.id.actionbar_shadow);\n        actionbarShadow.setVisibility(View.VISIBLE);\n        ObjectAnimator.ofFloat(actionbarShadow, View.ALPHA, 0, 0.8f).setDuration(400).start();\n    }\n\n    @Override\n    public void animateTOMenu() {\n        TransitionHelper.animateToMenuState(root, new AnimatorListenerAdapter() {\n            @Override\n            public void onAnimationEnd(Animator animation) {\n                super.onAnimationEnd(animation);\n                waterScene.setPause(false);\n            }\n        });\n        menuIcon.animateIconState(MaterialMenuDrawable.IconState.ARROW);\n        hideShadow();\n        waterScene.setPause(true);\n    }\n\n    @Override\n    public void revertFromMenu() {\n        TransitionHelper.startRevertFromMenu(root, showShadowListener);\n        menuIcon.animateIconState(MaterialMenuDrawable.IconState.BURGER);\n        waterScene.setPause(true);\n    }\n\n    @Override\n    public void exitFromMenu() {\n        TransitionHelper.animateMenuOut(root);\n        waterScene.setPause(true);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/WaterSceneView.java",
    "content": "package no.agens.depth;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.Canvas;\nimport android.util.AttributeSet;\nimport android.view.View;\n\nimport no.agens.depth.lib.headers.NoiseEffect;\nimport no.agens.depth.lib.headers.Renderable;\nimport no.agens.depth.lib.tween.FrameRateCounter;\n\n/**\n * Created by danielzeller on 01.10.14.\n */\npublic class WaterSceneView extends View {\n\n\n    private Renderable[] renderables;\n    private Water water;\n    private NoiseEffect noiseScratchEffect;\n    private NoiseEffect noise;\n\n    public WaterSceneView(Context context) {\n        super(context);\n\n    }\n\n    public WaterSceneView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    public WaterSceneView(Context context, AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n\n    }\n\n    @Override\n    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {\n        super.onLayout(changed, left, top, right, bottom);\n        if (renderables == null) {\n            init();\n        }\n    }\n\n    private void init() {\n        renderables = new Renderable[4];\n        Bitmap waterBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.water);\n        Bitmap foam = BitmapFactory.decodeResource(getResources(), R.drawable.foam);\n        setLayerType(View.LAYER_TYPE_HARDWARE, null);\n        water = new Water(waterBitmap, foam, getYCoordByPercent(0.65f), getYCoordByPercent(1f), getXCoordByPercent(1f), 6);\n        renderables[0] = water;\n        Bitmap aura = BitmapFactory.decodeResource(getResources(), R.drawable.sun_aura);\n        renderables[1] = new Renderable(aura, getXCoordByPercent(0.5f), getYCoordByPercent(0.35f));\n\n        Bitmap noiseScratch = BitmapFactory.decodeResource(getResources(), R.drawable.noise_scratch);\n        Bitmap noiseReg = BitmapFactory.decodeResource(getResources(), R.drawable.noise);\n\n        noiseScratchEffect = new NoiseEffect(noiseScratch, 100, 2f);\n        renderables[2] = noiseScratchEffect;\n        noise = new NoiseEffect(noiseReg, 30, 1.5f);\n        renderables[3] = noise;\n        setNoiseIntensity(0.5f);\n        setWaveHeight(50);\n    }\n\n    @Override\n    protected void onDetachedFromWindow() {\n        super.onDetachedFromWindow();\n        destroyResources();\n    }\n\n    private void destroyResources() {\n        for (Renderable renderable : renderables)\n            renderable.destroy();\n    }\n\n    @Override\n    protected void onAttachedToWindow() {\n        super.onAttachedToWindow();\n        if (renderables == null && getWidth() != 0)\n            init();\n    }\n\n    @Override\n    protected void onDraw(Canvas canvas) {\n        super.onDraw(canvas);\n        float deltaTime = FrameRateCounter.timeStep();\n\n        for (Renderable renderable : renderables) {\n            renderable.draw(canvas);\n            renderable.update(deltaTime, 0);\n        }\n        if (!pasuse)\n            invalidate();\n    }\n\n    public void setPause(boolean pause) {\n//        this.pasuse = pause;\n//        if (!pause) {\n//            FrameRateCounter.timeStep();\n//            invalidate();\n//            for (Renderable renderable : renderables)\n//                renderable.resume();\n//        } else {\n//            for (Renderable renderable : renderables)\n//                renderable.pause();\n//        }\n    }\n\n    private boolean pasuse = false;\n\n    private float getYCoordByPercent(float percent) {\n        return getHeight() * percent;\n    }\n\n    private float getXCoordByPercent(float percent) {\n        return getWidth() * percent;\n    }\n\n    public void setWaveHeight(float height) {\n        water.setWaveHeight(height);\n    }\n\n    public void setNoiseIntensity(float noiseAmount) {\n        noiseScratchEffect.setNoiseIntensity(noiseAmount);\n        noise.setNoiseIntensity(noiseAmount);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/no/agens/depth/WindFragment.java",
    "content": "package no.agens.depth;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorListenerAdapter;\nimport android.animation.ObjectAnimator;\nimport android.app.Fragment;\nimport android.graphics.Color;\nimport android.graphics.PorterDuff;\nimport android.graphics.drawable.Drawable;\nimport android.graphics.drawable.LayerDrawable;\nimport android.graphics.drawable.StateListDrawable;\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.ViewTreeObserver;\nimport android.widget.ImageView;\nimport android.widget.SeekBar;\n\nimport no.agens.depth.lib.MaterialMenuDrawable;\n\n\npublic class WindFragment extends Fragment implements MenuAnimation {\n\n\n    public static final int FLAMES_INITIAL_HEIGHT = 50;\n    private boolean introAnimate;\n\n    public WindFragment() {\n    }\n\n    View root;\n    MaterialMenuDrawable menuIcon;\n    BearSceneView bearsScene;\n\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\n                             Bundle savedInstanceState) {\n        root = inflater.inflate(R.layout.fragment_wind, container, false);\n        bearsScene = (BearSceneView) root.findViewById(R.id.water_scene);\n\n        doIntroAnimation();\n        setupFabButton();\n        setupMenuButton();\n        ((RootActivity) getActivity()).setCurrentMenuIndex(RootActivity.WIND_SCREEN_MENU_INDEX);\n        setupSliders();\n        return root;\n    }\n\n    private void setupSliders() {\n        SeekBar windSeekbar = (SeekBar) root.findViewById(R.id.wind_seekbar);\n        final SeekBar flamesSeekbar = (SeekBar) root.findViewById(R.id.flames_seekbar);\n        setProgressBarColor(windSeekbar, getResources().getColor(R.color.fab2));\n        setProgressBarColor(flamesSeekbar, getResources().getColor(R.color.fab2));\n\n        windSeekbar.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                bearsScene.setWind(progress);\n            }\n        });\n\n        flamesSeekbar.setOnSeekBarChangeListener(new SeekBarProgressChangeListener() {\n            @Override\n            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {\n                bearsScene.setFlamesHeight(progress);\n            }\n        });\n        bearsScene.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {\n            @Override\n            public void onGlobalLayout() {\n                bearsScene.getViewTreeObserver().removeOnGlobalLayoutListener(this);\n                flamesSeekbar.setProgress(FLAMES_INITIAL_HEIGHT);\n            }\n        });\n\n    }\n\n    private void doIntroAnimation() {\n        if (introAnimate)\n            root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {\n                @Override\n                public void onGlobalLayout() {\n                    root.getViewTreeObserver().removeOnGlobalLayoutListener(this);\n                    TransitionHelper.startIntroAnim(root, showShadowListener);\n                    hideShadow();\n                    bearsScene.postDelayed(new Runnable() {\n                        @Override\n                        public void run() {\n                            bearsScene.setPause(true);\n                        }\n                    }, 10);\n                }\n            });\n    }\n\n    private void setupFabButton() {\n        root.findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {\n                    @Override\n                    public void onGlobalLayout() {\n                        root.getViewTreeObserver().removeOnGlobalLayoutListener(this);\n                        TransitionHelper.startExitAnim(root);\n                    }\n                });\n                WaterFragment waterFragment = new WaterFragment();\n                waterFragment.setIntroAnimate(true);\n                ((RootActivity) getActivity()).goToFragment(waterFragment);\n                if (((RootActivity) getActivity()).isMenuVisible)\n                    ((RootActivity) getActivity()).hideMenu();\n                hideShadow();\n                bearsScene.setPause(true);\n            }\n        });\n    }\n\n    private void setupMenuButton() {\n        ImageView menu = (ImageView) root.findViewById(R.id.menu);\n        menu.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                if (!((RootActivity) getActivity()).isMenuVisible)\n                    ((RootActivity) getActivity()).showMenu();\n                else\n                    getActivity().onBackPressed();\n            }\n        });\n        menuIcon = new MaterialMenuDrawable(getActivity(), Color.WHITE, MaterialMenuDrawable.Stroke.THIN, WaterFragment.TRANSFORM_DURATION);\n        menu.setImageDrawable(menuIcon);\n    }\n\n    public static void setProgressBarColor(SeekBar progressBar, int newColor) {\n        if (progressBar.getProgressDrawable() instanceof StateListDrawable) {\n            StateListDrawable ld = (StateListDrawable) progressBar.getProgressDrawable();\n            ld.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);\n            progressBar.getThumb().setColorFilter(newColor, PorterDuff.Mode.SRC_IN);\n        } else if (progressBar.getProgressDrawable() instanceof LayerDrawable) {\n            LayerDrawable ld = (LayerDrawable) progressBar.getProgressDrawable();\n            for (int i = 0; i < ld.getNumberOfLayers(); i++) {\n                Drawable d1 = ld.getDrawable(i);\n                d1.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);\n            }\n            progressBar.getThumb().setColorFilter(newColor, PorterDuff.Mode.SRC_IN);\n        }\n\n    }\n\n    public void setIntroAnimate(boolean introAnimate) {\n        this.introAnimate = introAnimate;\n    }\n\n    @Override\n    public void animateTOMenu() {\n        TransitionHelper.animateToMenuState(root, new AnimatorListenerAdapter() {\n            @Override\n            public void onAnimationEnd(Animator animation) {\n                super.onAnimationEnd(animation);\n                bearsScene.setPause(false);\n            }\n        });\n        menuIcon.animateIconState(MaterialMenuDrawable.IconState.ARROW);\n        hideShadow();\n        bearsScene.setPause(true);\n    }\n\n    private void hideShadow() {\n        View actionbarShadow = root.findViewById(R.id.actionbar_shadow);\n        actionbarShadow.setVisibility(View.GONE);\n    }\n\n    @Override\n    public void revertFromMenu() {\n        TransitionHelper.startRevertFromMenu(root, showShadowListener);\n        menuIcon.animateIconState(MaterialMenuDrawable.IconState.BURGER);\n        bearsScene.setPause(true);\n    }\n\n    AnimatorListenerAdapter showShadowListener = new AnimatorListenerAdapter() {\n        @Override\n        public void onAnimationEnd(Animator animation) {\n            super.onAnimationEnd(animation);\n            showShadow();\n            bearsScene.setPause(false);\n        }\n    };\n\n    private void showShadow() {\n        View actionbarShadow = root.findViewById(R.id.actionbar_shadow);\n        actionbarShadow.setVisibility(View.VISIBLE);\n        ObjectAnimator.ofFloat(actionbarShadow, View.ALPHA, 0, 0.8f).setDuration(400).start();\n    }\n\n    @Override\n    public void exitFromMenu() {\n        TransitionHelper.animateMenuOut(root);\n        bearsScene.setPause(true);\n    }\n}\n"
  },
  {
    "path": "app/src/main/res/drawable/bear_bg_gradient.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <gradient\n        android:startColor=\"#C68C94\"\n        android:centerColor=\"#3A5067\"\n        android:endColor=\"#3A5067\"\n        android:angle=\"315\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/circle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\" android:color=\"@color/fab\">\n    <item>\n        <shape android:shape=\"oval\">\n            <solid android:color=\"@color/fab_highlight\" />\n        </shape>\n    </item>\n</ripple>"
  },
  {
    "path": "app/src/main/res/drawable/fab_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:color=\"@color/fab\">\n    <item android:id=\"@android:id/mask\">\n        <shape android:shape=\"oval\">\n            <solid android:color=\"@color/white\" />\n        </shape>\n        <color android:color=\"@color/white\" />\n    </item>\n</ripple>"
  },
  {
    "path": "app/src/main/res/drawable/menu_btn.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:color=\"@color/splash1\">\n    <item android:drawable=\"@android:color/white\"/>\n</ripple>"
  },
  {
    "path": "app/src/main/res/drawable/menu_btn2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:color=\"@color/splash2\">\n    <item android:drawable=\"@android:color/white\"/>\n</ripple>"
  },
  {
    "path": "app/src/main/res/drawable/menu_btn3.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:color=\"@color/splash3\">\n    <item android:drawable=\"@android:color/white\"/>\n</ripple>"
  },
  {
    "path": "app/src/main/res/drawable/menu_btn4.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:color=\"@color/splash4\">\n    <item android:drawable=\"@android:color/white\"/>\n</ripple>"
  },
  {
    "path": "app/src/main/res/layout/activity_root.xml",
    "content": "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n    >\n\n    <FrameLayout\n        android:id=\"@+id/fragment_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        >\n\n\n    </FrameLayout>\n\n    <LinearLayout\n        android:id=\"@+id/menu_container\"\n        android:orientation=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:elevation=\"6dp\"\n        android:layout_alignParentBottom=\"true\"\n        android:layerType=\"hardware\" >\n    </LinearLayout>\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_playground.xml",
    "content": "<no.agens.depth.lib.DepthRendrer xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                                 xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n                                 xmlns:tools=\"http://schemas.android.com/tools\"\n                                 android:layout_width=\"match_parent\"\n                                 android:layout_height=\"match_parent\"\n                                 android:background=\"#DCDCDC\"\n                                 tools:context=\".MainActivity\"\n    >\n    <RelativeLayout\n        android:id=\"@+id/appbar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/appbar_height\"\n        android:background=\"@color/green\"\n        android:layerType=\"hardware\"\n        app:edge_color=\"@color/statusbar2\"\n        >\n\n\n        <ImageView\n\n            android:id=\"@+id/staturbar_bg\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"24dp\"\n            android:background=\"@color/statusbar2\"\n            />\n\n        <ImageView\n            android:id=\"@+id/menu\"\n            android:layout_width=\"56dp\"\n            android:layout_height=\"56dp\"\n            android:layout_alignParentBottom=\"true\"\n            android:src=\"@drawable/ic_menu\"\n            android:scaleType=\"centerInside\"\n            />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_gravity=\"bottom\"\n            android:layout_marginBottom=\"@dimen/activity_horizontal_margin\"\n            android:layout_marginLeft=\"65dp\"\n            android:text=\"Depth\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"18sp\"\n            />\n    </RelativeLayout>\n\n    <ImageView\n        android:id=\"@+id/actionbar_shadow\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"5dp\"\n        android:layout_below=\"@+id/appbar\"\n        android:background=\"@drawable/actionbar_shadow\"\n        />\n\n    <ScrollView\n        android:id=\"@+id/scrollView\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginTop=\"324dp\"\n\n        >\n\n\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n\n                android:background=\"@color/white\"\n                android:orientation=\"vertical\"\n                >\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n                    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                    android:text=\"Depth\"\n                    android:textAppearance=\"?android:attr/textAppearanceMedium\"\n                    />\n\n                <SeekBar\n                    android:id=\"@+id/depth_seekbar\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginLeft=\"@dimen/seekbar_margin_sides\"\n                    android:layout_marginRight=\"@dimen/seekbar_margin_sides\"\n                    android:layout_marginTop=\"@dimen/seekbar_margin_top\"\n                    android:padding=\"@dimen/seekbar_padding\"\n                    />\n\n                <View\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"1dp\"\n                    android:background=\"@color/divider_color\"\n                    />\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n                    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                    android:text=\"Elevation\"\n                    android:textAppearance=\"?android:attr/textAppearanceMedium\"\n                    />\n\n                <SeekBar\n                    android:id=\"@+id/elevation_seekbar\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginLeft=\"@dimen/seekbar_margin_sides\"\n                    android:layout_marginRight=\"@dimen/seekbar_margin_sides\"\n                    android:layout_marginTop=\"@dimen/seekbar_margin_top\"\n                    android:padding=\"@dimen/seekbar_padding\"\n                    />\n\n                <View\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"1dp\"\n                    android:background=\"@color/divider_color\"\n                    />\n\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n                    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                    android:text=\"Rotation X\"\n                    android:textAppearance=\"?android:attr/textAppearanceMedium\"\n                    />\n\n                <SeekBar\n                    android:id=\"@+id/rotation_x_seekbar\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginLeft=\"@dimen/seekbar_margin_sides\"\n                    android:layout_marginRight=\"@dimen/seekbar_margin_sides\"\n                    android:layout_marginTop=\"@dimen/seekbar_margin_top\"\n                    android:padding=\"@dimen/seekbar_padding\"\n                    />\n\n                <View\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"1dp\"\n                    android:background=\"@color/divider_color\"\n                    />\n\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n                    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                    android:text=\"Rotation Y\"\n                    android:textAppearance=\"?android:attr/textAppearanceMedium\"\n                    />\n\n                <SeekBar\n                    android:id=\"@+id/rotation_y_seekbar\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginLeft=\"@dimen/seekbar_margin_sides\"\n                    android:layout_marginRight=\"@dimen/seekbar_margin_sides\"\n                    android:layout_marginTop=\"@dimen/seekbar_margin_top\"\n                    android:padding=\"@dimen/seekbar_padding\"\n                    />\n\n                <View\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"1dp\"\n                    android:background=\"@color/divider_color\"\n                    />\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n                    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                    android:text=\"Rotation Z\"\n                    android:textAppearance=\"?android:attr/textAppearanceMedium\"\n                    />\n\n                <SeekBar\n                    android:id=\"@+id/rotation_z_seekbar\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginLeft=\"@dimen/seekbar_margin_sides\"\n                    android:layout_marginRight=\"@dimen/seekbar_margin_sides\"\n                    android:layout_marginTop=\"@dimen/seekbar_margin_top\"\n                    android:padding=\"@dimen/seekbar_padding\"\n                    />\n\n\n            </LinearLayout>\n\n    </ScrollView>\n\n\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/depth_view\"\n        android:layout_width=\"140dp\"\n        android:layout_height=\"140dp\"\n        android:layout_centerHorizontal=\"true\"\n        android:layout_marginTop=\"130dp\"\n        app:is_circle=\"false\"\n        >\n\n        <ImageView\n\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:background=\"@drawable/sun\"\n            />\n    </no.agens.depth.lib.DepthLayout>\n\n    <ImageView\n        android:id=\"@+id/imageView\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginLeft=\"25dp\"\n        android:layout_marginTop=\"195dp\"\n        android:src=\"@drawable/x_y\"\n        />\n\n</no.agens.depth.lib.DepthRendrer>\n"
  },
  {
    "path": "app/src/main/res/layout/fragment_water.xml",
    "content": "<no.agens.depth.lib.DepthRendrer xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                                 xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n                                 xmlns:tools=\"http://schemas.android.com/tools\"\n                                 android:layout_width=\"match_parent\"\n                                 android:layout_height=\"match_parent\"\n                                 tools:context=\".sample.WaterFragment\"\n                                 android:layerType=\"hardware\"\n\n    >\n\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/root_dl\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:background=\"@color/white\"\n        android:layerType=\"hardware\"\n        android:paddingTop=\"@dimen/appbar_height\"\n        >\n\n        <no.agens.depth.WaterSceneView\n            android:id=\"@+id/water_scene\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"180dp\"\n            android:background=\"@drawable/water_scene_background\"\n            />\n    </no.agens.depth.lib.DepthLayout>\n\n\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/appbar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/appbar_height\"\n        android:background=\"@color/blue\"\n        android:layerType=\"hardware\"\n        app:edge_color=\"@color/black\"\n        >\n\n\n        <ImageView\n\n            android:id=\"@+id/staturbar_bg\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"24dp\"\n            android:background=\"@color/statusbar\"\n            />\n        <ImageView\n            android:id=\"@+id/menu\"\n            android:layout_width=\"56dp\"\n            android:layout_height=\"56dp\"\n            android:layout_alignParentBottom=\"true\"\n\n            android:src=\"@drawable/ic_menu\"\n            android:scaleType=\"centerInside\"\n            />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_gravity=\"bottom\"\n            android:layout_marginBottom=\"@dimen/activity_horizontal_margin\"\n            android:layout_marginLeft=\"65dp\"\n            android:text=\"Depth\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"18sp\"\n            android:fitsSystemWindows=\"true\"\n            />\n    </no.agens.depth.lib.DepthLayout>\n    <ImageView\n        android:id=\"@+id/actionbar_shadow\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_below=\"@+id/appbar\"\n        android:background=\"@drawable/actionbar_shadow\"\n        />\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/dl2\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"260dp\"\n        android:background=\"@color/white\"\n        app:custom_elevation=\"1dp\"\n        android:layerType=\"hardware\"\n        >\n\n        <LinearLayout\n            android:id=\"@+id/sliders_container\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\"\n            >\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n                android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                android:text=\"Noise\"\n                android:textAppearance=\"?android:attr/textAppearanceMedium\"\n                android:textColor=\"@color/blue\"\n                android:textSize=\"16sp\"\n                />\n\n            <SeekBar\n                android:id=\"@+id/noise_seekbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginLeft=\"@dimen/seekbar_margin_sides\"\n                android:layout_marginRight=\"@dimen/seekbar_margin_sides\"\n                android:layout_marginTop=\"@dimen/seekbar_margin_top\"\n                android:padding=\"@dimen/seekbar_padding\"\n                />\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"1dp\"\n                android:background=\"@color/divider_color\"\n                />\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n                android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                android:text=\"Wave Strength\"\n                android:textColor=\"@color/blue\"\n                android:textSize=\"16sp\"\n                />\n\n            <SeekBar\n                android:id=\"@+id/wave_seekbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginLeft=\"@dimen/seekbar_margin_sides\"\n                android:layout_marginRight=\"@dimen/seekbar_margin_sides\"\n                android:layout_marginTop=\"@dimen/seekbar_margin_top\"\n                android:padding=\"@dimen/seekbar_padding\"\n                />\n\n\n        </LinearLayout>\n    </no.agens.depth.lib.DepthLayout>\n\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/dl3\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginTop=\"450dp\"\n        android:background=\"@color/white\"\n        app:custom_elevation=\"2dp\"\n        android:layerType=\"hardware\"\n        >\n\n        <TextView\n            android:id=\"@+id/about_heading\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n            android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n            android:text=\"Water And Noise\"\n            android:textColor=\"@color/black\"\n            android:textSize=\"16sp\"\n            />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_below=\"@+id/about_heading\"\n            android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n            android:text=\"A water experiment developed\nby Agens in 2015, as an example of how to draw\nadvanced canvas based graphics with the Android\nSDK. \"\n            android:textColor=\"@color/text_primary\"\n            android:textSize=\"14sp\"\n            />\n\n    </no.agens.depth.lib.DepthLayout>\n\n\n\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/fab_container\"\n        android:layout_width=\"56dp\"\n        android:layout_height=\"56dp\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_marginRight=\"@dimen/fab_margin\"\n        android:layout_marginTop=\"232dp\"\n        android:background=\"@drawable/circle\"\n        app:custom_elevation=\"6dp\"\n        android:layerType=\"hardware\"\n        app:edge_color=\"@color/fab\"\n        app:is_circle=\"true\"\n        >\n\n        <ImageButton\n            android:id=\"@+id/fab\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clickable=\"true\"\n            android:src=\"@drawable/ic_forward\"\n            android:background=\"@drawable/fab_bg\"\n            android:layerType=\"hardware\"\n            />\n    </no.agens.depth.lib.DepthLayout>\n</no.agens.depth.lib.DepthRendrer>\n"
  },
  {
    "path": "app/src/main/res/layout/fragment_wind.xml",
    "content": "<no.agens.depth.lib.DepthRendrer xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                                 xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n                                 xmlns:tools=\"http://schemas.android.com/tools\"\n                                 android:layout_width=\"match_parent\"\n                                 android:layout_height=\"match_parent\"\n                                 tools:context=\".sample.WaterFragment\"\n\n    >\n\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/root_dl\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:background=\"@color/white\"\n        android:layerType=\"hardware\"\n        android:paddingTop=\"@dimen/appbar_height\"\n        >\n\n        <no.agens.depth.BearSceneView\n            android:id=\"@+id/water_scene\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"180dp\"\n            android:scaleType=\"centerCrop\"\n            android:background=\"@drawable/bear_bg_gradient\"\n            />\n    </no.agens.depth.lib.DepthLayout>\n\n\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/appbar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/appbar_height\"\n        android:background=\"@color/green\"\n        android:layerType=\"hardware\"\n        app:edge_color=\"@color/statusbar2\"\n        >\n\n\n        <ImageView\n\n            android:id=\"@+id/staturbar_bg\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"24dp\"\n            android:background=\"@color/statusbar2\"\n            />\n\n        <ImageView\n            android:id=\"@+id/menu\"\n            android:layout_width=\"56dp\"\n            android:layout_height=\"56dp\"\n            android:layout_alignParentBottom=\"true\"\n            android:src=\"@drawable/ic_menu\"\n            android:scaleType=\"centerInside\"\n            />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_gravity=\"bottom\"\n            android:layout_marginBottom=\"@dimen/activity_horizontal_margin\"\n            android:layout_marginLeft=\"65dp\"\n            android:text=\"Depth\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"18sp\"\n            />\n    </no.agens.depth.lib.DepthLayout>\n\n    <ImageView\n        android:id=\"@+id/actionbar_shadow\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_below=\"@+id/appbar\"\n        android:background=\"@drawable/actionbar_shadow\"\n        />\n\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/dl2\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"260dp\"\n        android:background=\"@color/white\"\n        android:layerType=\"hardware\"\n        app:custom_elevation=\"1dp\"\n        >\n\n        <LinearLayout\n            android:id=\"@+id/sliders_container\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\"\n            >\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n                android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                android:text=\"Wind Strength\"\n                android:textAppearance=\"?android:attr/textAppearanceMedium\"\n                android:textColor=\"@color/black\"\n                android:textSize=\"16sp\"\n                />\n\n            <SeekBar\n                android:id=\"@+id/wind_seekbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginLeft=\"@dimen/seekbar_margin_sides\"\n                android:layout_marginRight=\"@dimen/seekbar_margin_sides\"\n                android:layout_marginTop=\"@dimen/seekbar_margin_top\"\n                android:padding=\"@dimen/seekbar_padding\"\n                />\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"1dp\"\n                android:background=\"@color/divider_color\"\n                />\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n                android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                android:text=\"Flames Height\"\n                android:textColor=\"@color/black\"\n                android:textSize=\"16sp\"\n                />\n\n            <SeekBar\n                android:id=\"@+id/flames_seekbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginLeft=\"@dimen/seekbar_margin_sides\"\n                android:layout_marginRight=\"@dimen/seekbar_margin_sides\"\n                android:layout_marginTop=\"@dimen/seekbar_margin_top\"\n                android:padding=\"@dimen/seekbar_padding\"\n                />\n\n\n        </LinearLayout>\n    </no.agens.depth.lib.DepthLayout>\n\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/dl3\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginTop=\"450dp\"\n        android:background=\"@color/white\"\n        android:layerType=\"hardware\"\n        app:custom_elevation=\"2dp\"\n        >\n\n        <TextView\n            android:id=\"@+id/about_heading\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginTop=\"@dimen/default_subheading_margin_top\"\n            android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n            android:text=\"Two Bears\"\n            android:textColor=\"@color/black\"\n            android:textSize=\"16sp\"\n            />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_below=\"@+id/about_heading\"\n            android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n            android:text=\"A particle experiment developed\nby Agens in 2015, as an example of how to draw advanced\ncanvas based graphic´s with the Android\nSDK. \"\n            android:textColor=\"@color/text_primary\"\n            android:textSize=\"14sp\"\n            />\n\n    </no.agens.depth.lib.DepthLayout>\n\n\n    <no.agens.depth.lib.DepthLayout\n        android:id=\"@+id/fab_container\"\n        android:layout_width=\"56dp\"\n        android:layout_height=\"56dp\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_marginRight=\"@dimen/fab_margin\"\n        android:layout_marginTop=\"232dp\"\n        android:background=\"@drawable/circle\"\n        android:layerType=\"hardware\"\n        app:custom_elevation=\"6dp\"\n        app:edge_color=\"#9A6A70\"\n        app:is_circle=\"true\"\n        >\n\n        <ImageButton\n            android:id=\"@+id/fab\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clickable=\"true\"\n            android:src=\"@drawable/ic_forward\"\n            android:background=\"@drawable/fab_bg\"\n            android:layerType=\"hardware\"\n            />\n    </no.agens.depth.lib.DepthLayout>\n</no.agens.depth.lib.DepthRendrer>\n"
  },
  {
    "path": "app/src/main/res/layout/menu_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"match_parent\"\n                android:gravity=\"center_vertical\"\n                android:orientation=\"horizontal\"\n    >\n\n    <no.agens.depth.lib.CircularSplashView\n        android:id=\"@+id/circle\"\n        android:layout_width=\"15dp\"\n        android:layout_height=\"15dp\"\n        android:layout_centerVertical=\"true\"\n        android:layout_marginLeft=\"25dp\"\n        />\n\n    <TextView\n        android:id=\"@+id/item_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerVertical=\"true\"\n        android:layout_marginLeft=\"65dp\"\n        android:textColor=\"@color/black\"\n        android:textSize=\"16sp\"\n        />\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/menu/menu_root.xml",
    "content": "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n      xmlns:tools=\"http://schemas.android.com/tools\"\n      tools:context=\".sample.RootActivity\">\n    <item android:id=\"@+id/action_settings\"\n          android:title=\"@string/action_settings\"\n          android:orderInCategory=\"100\"\n          app:showAsAction=\"never\"/>\n</menu>\n"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"light_grey\">#8C9CA4</color>\n    <color name=\"white\">#FFFFFF</color>\n    <color name=\"divider_color\">#DBDBDB</color>\n    <color name=\"edge_color\">#FFFFFF</color>\n    <color name=\"fab\">#f9aab0</color>\n    <color name=\"fab_highlight\">#CB747B</color>\n    <color name=\"blue\">#323453</color>\n    <color name=\"green\">#4E8186</color>\n\n    <color name=\"statusbar\">#282942</color>\n    <color name=\"statusbar2\">#3E676B</color>\n    <color name=\"text_primary\">#727272</color>\n    <color name=\"black\">#000000</color>\n    <color name=\"fab2\">#DC8F9A</color>\n    <color name=\"splash1\">#F19BA2</color>\n    <color name=\"splash2\">#323453</color>\n    <color name=\"splash3\">#649692</color>\n    <color name=\"splash4\">#C68C94</color>\n\n    <color name=\"fire_end_color\">#E89183</color>\n    <color name=\"fire_start_color\">#FCFBEB</color>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n    <dimen name=\"fab_margin\">16dp</dimen>\n    <dimen name=\"appbar_height\">80dp</dimen>\n\n    <dimen name=\"seekbar_padding\">10dp</dimen>\n    <dimen name=\"seekbar_margin_top\">11dp</dimen>\n    <dimen name=\"default_subheading_margin_top\">12dp</dimen>\n    <dimen name=\"seekbar_margin_sides\">8dp</dimen>\n    <dimen name=\"menu_item_height\">53dp</dimen>\n    <dimen name=\"menu_item_height_padding\">6dp</dimen>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Depth</string>\n\n    <string name=\"hello_world\">Hello world!</string>\n    <string name=\"action_settings\">Settings</string>\n    <string name=\"title_activity_root\">Depth Demo</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <item name=\"android:statusBarColor\">@android:color/transparent</item>\n        <item name=\"android:windowDrawsSystemBarBackgrounds\">true</item>\n        <item name=\"colorAccent\">@color/fab</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-w820dp/dimens.xml",
    "content": "<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as screen margins) for screens with more than 820dp of available width. This\n         would include 7\" and 10\" devices in landscape (~960dp and ~1280dp respectively). -->\n    <dimen name=\"activity_horizontal_margin\">64dp</dimen>\n</resources>\n"
  },
  {
    "path": "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    dependencies {\n\n        classpath 'com.android.tools.build:gradle:3.2.1'\n        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'\n        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'\n        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Tue Oct 16 12:59:36 CEST 2018\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.6-all.zip\n"
  },
  {
    "path": "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.\n# Default value: -Xmx10248m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\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"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\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\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\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\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched.\nif $cygwin ; then\n    [ -n \"$JAVA_HOME\" ] && JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\nfi\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\\\"`/\" >&-\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >&-\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\" ] ; 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\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# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "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\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\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\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 Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_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\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\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": "lib/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "lib/build.gradle",
    "content": "apply plugin: 'com.android.library'\napply plugin: 'com.github.dcendents.android-maven'\napply plugin: 'com.jfrog.bintray'\n\nandroid {\n    compileSdkVersion 28\n\n    defaultConfig {\n        minSdkVersion 21\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"1.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    testImplementation 'junit:junit:4.12'\n}\n\n\next {\n    bintrayRepo = 'maven'\n    bintrayName = 'depth-lib-android'\n\n    publishedGroupId = 'no.agens'\n    libraryName = 'Depth-Lib-Android'\n    artifact = 'depthlib'\n\n    libraryDescription = 'This library adds depth/thickness to views.'\n\n    siteUrl = 'https://github.com/danielzeller/Depth-LIB-Android-'\n    gitUrl = 'https://github.com/danielzeller/Depth-LIB-Android-.git'\n\n    libraryVersion = '1.0.1'\n\n    developerId = 'danielzeller'\n    developerName = 'Daniel Zeller'\n    developerEmail = 'daniel@danielzeller.no'\n\n    licenseName = 'The Apache Software License, Version 2.0'\n    licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'\n    allLicenses = [\"Apache-2.0\"]\n}\n\n\ngroup = publishedGroupId\nversion = libraryVersion\n\ninstall {\n    repositories.mavenInstaller {\n        pom.project {\n            packaging 'aar'\n            groupId publishedGroupId\n            artifactId artifact\n\n            name libraryName\n            description libraryDescription\n            url siteUrl\n\n            licenses {\n                license {\n                    name licenseName\n                    url licenseUrl\n                }\n            }\n            developers {\n                developer {\n                    id developerId\n                    name developerName\n                    email developerEmail\n                }\n            }\n            scm {\n                connection gitUrl\n                developerConnection gitUrl\n                url siteUrl\n            }\n        }\n    }\n}\n\ntask sourcesJar(type: Jar) {\n    classifier = 'sources'\n    from android.sourceSets.main.java.srcDirs\n}\n\ntask javadoc(type: Javadoc) {\n    source = android.sourceSets.main.java.srcDirs\n    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))\n}\n\ntask javadocJar(type: Jar, dependsOn: javadoc) {\n    classifier = 'javadoc'\n    from javadoc.destinationDir\n}\n\nartifacts {\n    archives javadocJar\n    archives sourcesJar\n}\n\nProperties properties = new Properties()\nproperties.load(project.rootProject.file('local.properties').newDataInputStream())\n\nbintray {\n    user = properties.getProperty(\"bintray.user\")\n    key = properties.getProperty(\"bintray.apikey\")\n\n    configurations = ['archives']\n    pkg {\n        repo = bintrayRepo\n        name = bintrayName\n        desc = libraryDescription\n        websiteUrl = siteUrl\n        vcsUrl = gitUrl\n        licenses = allLicenses\n        dryRun = false\n        publish = true\n        override = false\n        publicDownloadNumbers = true\n        version {\n            desc = libraryDescription\n        }\n    }\n}\n\n\n\n"
  },
  {
    "path": "lib/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in C:\\Users\\Jawn\\Develop\\Android\\sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\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"
  },
  {
    "path": "lib/src/androidTest/java/no/agens/depth/ApplicationTest.java",
    "content": "package no.agens.depth;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "lib/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          package=\"no.agens.depth.lib\">\n\n    <application />\n\n</manifest>\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/CircularSplashView.java",
    "content": "package no.agens.depth.lib;\n\nimport android.animation.ValueAnimator;\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.util.AttributeSet;\nimport android.view.View;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport no.agens.depth.lib.tween.interpolators.QuintOut;\n\n\n/**\n * Created by danielzeller on 03.09.14.\n */\npublic class CircularSplashView extends View {\n\n    private final List<CircledDrawable> circles = new ArrayList<>();\n\n    public CircularSplashView(Context context) {\n        super(context);\n    }\n\n    public CircularSplashView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    public CircularSplashView(Context context, AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n    }\n\n    public void setSplash(Bitmap splash) {\n        this.splash = splash;\n    }\n\n    public void setSplashColor(int splashColor) {\n        this.splashColor = splashColor;\n    }\n\n    private Bitmap splash;\n    private int splashColor;\n\n    @Override\n    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {\n        super.onLayout(changed, left, top, right, bottom);\n        if (circles.size() == 0) {\n            introAnimate();\n        }\n    }\n\n    public void introAnimate() {\n        circles.clear();\n        RectF expandedSizeFloat = new RectF(0, 0, getWidth(), getHeight());\n        Rect expandedSizeInt = new Rect(0, 0, getWidth(), getHeight());\n        RectF biggerRect = new RectF(-1, -1, getWidth() + 1, getHeight() + 1);\n        circles.add(new CircleColorExpand(expandedSizeFloat, 0, 600, splashColor));\n        circles.add(new CircleColorExpand(biggerRect, 70, 600, Color.WHITE));\n        circles.add(new CircleBitmapExpand(expandedSizeInt, 130, 800, splash));\n        for (CircledDrawable c : circles)\n            c.startAnim();\n    }\n\n    @Override\n    protected void onDraw(Canvas canvas) {\n        super.onDraw(canvas);\n        for (CircledDrawable circle : circles)\n            circle.draw(canvas);\n    }\n\n    interface CircledDrawable {\n        void startAnim();\n\n        void draw(Canvas canvas);\n    }\n\n    public class CircleBitmapExpand implements CircledDrawable {\n        Rect targetSize;\n        Rect drawingRect;\n        long startDelay;\n        long animDuration;\n        Bitmap bitmap;\n\n        public CircleBitmapExpand(Rect targetSize, long startDelay, long animDuration, Bitmap inBitmap) {\n            this.targetSize = targetSize;\n            this.startDelay = startDelay;\n            this.animDuration = animDuration;\n            bitmap = inBitmap;\n\n        }\n\n        public Bitmap GetBitmapClippedCircle(Bitmap bitmap) {\n\n            final int width = bitmap.getWidth();\n            final int height = bitmap.getHeight();\n            final Bitmap outputBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);\n\n            final Path path = new Path();\n            path.addCircle(\n                    (float) (width / 2)\n                    , (float) (height / 2)\n                    , (float) Math.min(width, (height / 2))\n                    , Path.Direction.CCW);\n\n            final Canvas canvas = new Canvas(outputBitmap);\n            canvas.clipPath(path);\n            canvas.drawBitmap(bitmap, 0, 0, null);\n            bitmap.recycle();\n            return outputBitmap;\n        }\n\n        public void startAnim() {\n            Rect startRect = new Rect(targetSize.centerX(), targetSize.centerY(), targetSize.centerX(), targetSize.centerY());\n            drawingRect = startRect;\n            ValueAnimator rectSize = ValueAnimator.ofObject(new RectEvaluator(), startRect, targetSize);\n            rectSize.setDuration(animDuration);\n            rectSize.setInterpolator(new QuintOut());\n            rectSize.setStartDelay(startDelay);\n            rectSize.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n                @Override\n                public void onAnimationUpdate(ValueAnimator animation) {\n                    drawingRect = (Rect) animation.getAnimatedValue();\n                    invalidate();\n                }\n            });\n            rectSize.start();\n        }\n\n        public void draw(Canvas canvas) {\n            if (drawingRect != null)\n                canvas.drawBitmap(bitmap, null, drawingRect, null);\n        }\n    }\n\n    public class CircleColorExpand implements CircledDrawable {\n        private Paint paint = new Paint(Color.BLACK);\n        RectF targetSize;\n        RectF drawingRect;\n        long startDelay;\n        long animDuration;\n\n        public CircleColorExpand(RectF targetSize, long startDelay, long animDuration, int paintColor) {\n            this.targetSize = targetSize;\n            this.startDelay = startDelay;\n            this.animDuration = animDuration;\n            paint.setColor(paintColor);\n            paint.setAntiAlias(true);\n            paint.setDither(true);\n        }\n\n        public void startAnim() {\n            RectF startRect = new RectF(targetSize.centerX(), targetSize.centerY(), targetSize.centerX(), targetSize.centerY());\n            ValueAnimator rectSize = ValueAnimator.ofObject(new RectFEvaluator(), startRect, targetSize);\n            rectSize.setDuration(animDuration);\n            rectSize.setInterpolator(new QuintOut());\n            rectSize.setStartDelay(startDelay);\n            rectSize.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n                @Override\n                public void onAnimationUpdate(ValueAnimator animation) {\n                    drawingRect = (RectF) animation.getAnimatedValue();\n                    invalidate();\n                }\n            });\n            rectSize.start();\n        }\n\n        public void draw(Canvas canvas) {\n            if (drawingRect != null)\n                canvas.drawOval(drawingRect, paint);\n        }\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/ColorAnimator.java",
    "content": "\npackage no.agens.depth.lib;\n\nimport android.animation.ObjectAnimator;\nimport android.animation.TypeEvaluator;\nimport android.graphics.Color;\nimport android.graphics.drawable.ColorDrawable;\nimport android.view.View;\n\npublic class ColorAnimator {\n\n    public static ObjectAnimator ofColor(Object target, String propertyName, int from, int to) {\n\t\treturn ObjectAnimator.ofObject(target, propertyName, new ColorEvaluator(), from, to);\n\t}\n\n\tpublic static ObjectAnimator ofColor(Object target, String propertyName, int to) {\n\t\treturn ObjectAnimator.ofObject(target, propertyName, new ColorEvaluator(), to);\n\t}\n\t\n\tpublic static ObjectAnimator ofBackgroundColor(View target, int from, int to) {\n\t\treturn ObjectAnimator.ofObject(new ViewBackgroundWrapper(target), \"backgroundColor\", new ColorEvaluator(), from, to);\n\t}\n\t\n\tpublic static ObjectAnimator ofBackgroundColor(View target, int to) {\n\t\treturn ObjectAnimator.ofObject(new ViewBackgroundWrapper(target), \"backgroundColor\", new ColorEvaluator(), to);\n\t}\n\n\tprivate static class ColorEvaluator implements TypeEvaluator<Integer> {\n\n\t\t@Override\n\t\tpublic Integer evaluate(float fraction, Integer startValue, Integer endValue) {\n\t\t\tint startA, startR, startG, startB;\n\t\t\tint aDelta = (int) ((Color.alpha(endValue) - (startA = Color.alpha(startValue))) * fraction);\n\t\t\tint rDelta = (int) ((Color.red(endValue) - (startR = Color.red(startValue))) * fraction);\n\t\t\tint gDelta = (int) ((Color.green(endValue) - (startG = Color.green(startValue))) * fraction);\n\t\t\tint bDelta = (int) ((Color.blue(endValue) - (startB = Color.blue(startValue))) * fraction);\n\t\t\treturn Color.argb(startA + aDelta, startR + rDelta, startG + gDelta, startB + bDelta);\n\t\t}\n\t}\n\n\t/**\n\t * Helper class which allows retrieval of a {@link View}'s background as a color.\n\t */\n\tpublic static class ViewBackgroundWrapper {\n\n\t\tprivate final View mView;\n\n\t\tpublic ViewBackgroundWrapper(View v) {\n\t\t\tmView = v;\n\t\t}\n\n\t\tpublic int getBackgroundColor() {\n\t\t\ttry {\n\t\t\t\treturn ((ColorDrawable) mView.getBackground()).getColor();\n\t\t\t} catch (ClassCastException cce) {\n\t\t\t\t// The background isn't a ColorDrawable (could be BitmapDrawable etc.) - throw a more descriptive error\n\t\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\tString.format(\"Attempt to read View background color when background isn't a ColorDrawable (is %s instead)\",\n\t\t\t\t\t\t\t\tmView.getBackground().getClass().getSimpleName()));\n\t\t\t}\n\t\t}\n\n\t\tpublic void setBackgroundColor(int color) {\n\t\t\tmView.setBackgroundColor(color);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/CustomShadow.java",
    "content": "package no.agens.depth.lib;\n\nimport android.content.res.Resources;\nimport android.graphics.Canvas;\nimport android.graphics.ColorFilter;\nimport android.graphics.LinearGradient;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.PixelFormat;\nimport android.graphics.RadialGradient;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.graphics.Shader;\nimport android.graphics.drawable.Drawable;\n\n/**\n * A rounded rectangle drawable which also includes a shadow around.\n */\npublic class CustomShadow extends Drawable {\n    final static double COS_45 = Math.cos(Math.toRadians(45));\n\n    final static float SHADOW_MULTIPLIER = 1.5f;\n\n    final int mInsetShadow; // extra shadow to avoid gaps between card and shadow\n\n    /*\n    * This helper is set by CardView implementations.\n    * <p>\n    * Prior to API 17, canvas.drawRoundRect is expensive; which is why we need this interface\n    * to draw efficient rounded rectangles before 17.\n    * */\n    static RoundRectHelper sRoundRectHelper;\n\n    final Paint mPaint;\n\n    Paint mCornerShadowPaint;\n\n    Paint mEdgeShadowPaint;\n\n    final RectF mCardBounds;\n\n    float mCornerRadius;\n\n    Path mCornerShadowPath;\n\n    // updated value with inset\n    float mMaxShadowSize;\n\n    // actual value set by developer\n    float mRawMaxShadowSize;\n\n    // multiplied value to account for shadow offset\n    float mShadowSize;\n\n    // actual value set by developer\n    float mRawShadowSize;\n\n    private boolean mDirty = true;\n\n    private final int mShadowStartColor;\n\n    private final int mShadowEndColor;\n\n    private boolean mAddPaddingForCorners = true;\n\n    /**\n     * If shadow size is set to a value above max shadow, we print a warning\n     */\n    private boolean mPrintedShadowClipWarning = false;\n\n    public CustomShadow(\n            Resources resources, int backgroundColor, float radius,\n            float shadowSize, float maxShadowSize\n    ) {\n        mShadowStartColor = resources.getColor(R.color.cardview_shadow_start_color);\n        mShadowEndColor = resources.getColor(R.color.cardview_shadow_end_color);\n        mInsetShadow = resources.getDimensionPixelSize(R.dimen.cardview_compat_inset_shadow);\n        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);\n        mPaint.setColor(backgroundColor);\n        mCornerShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);\n        mCornerShadowPaint.setStyle(Paint.Style.FILL);\n        mCornerRadius = (int) (radius + .5f);\n        mCardBounds = new RectF();\n        mEdgeShadowPaint = new Paint(mCornerShadowPaint);\n        mEdgeShadowPaint.setAntiAlias(false);\n        setShadowSize(shadowSize, maxShadowSize);\n\n        CustomShadow.sRoundRectHelper = new CustomShadow.RoundRectHelper() {\n            @Override\n            public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius,\n                                      Paint paint) {\n                canvas.drawRoundRect(bounds, cornerRadius, cornerRadius, paint);\n            }\n        };\n    }\n\n    /**\n     * Casts the value to an even integer.\n     */\n    private int toEven(float value) {\n        int i = (int) (value + .5f);\n        if (i % 2 == 1) {\n            return i - 1;\n        }\n        return i;\n    }\n\n    public void setAddPaddingForCorners(boolean addPaddingForCorners) {\n        mAddPaddingForCorners = addPaddingForCorners;\n        invalidateSelf();\n    }\n\n    @Override\n    public void setAlpha(int alpha) {\n        mPaint.setAlpha(alpha);\n        mCornerShadowPaint.setAlpha(alpha);\n        mEdgeShadowPaint.setAlpha(alpha);\n    }\n\n    @Override\n    protected void onBoundsChange(Rect bounds) {\n        super.onBoundsChange(bounds);\n        mDirty = true;\n    }\n\n    void setShadowSize(float shadowSize, float maxShadowSize) {\n        if (shadowSize < 0 || maxShadowSize < 0) {\n            throw new IllegalArgumentException(\"invalid shadow size\");\n        }\n        shadowSize = toEven(shadowSize);\n        maxShadowSize = toEven(maxShadowSize);\n        if (shadowSize > maxShadowSize) {\n            shadowSize = maxShadowSize;\n            if (!mPrintedShadowClipWarning) {\n                mPrintedShadowClipWarning = true;\n            }\n        }\n        if (mRawShadowSize == shadowSize && mRawMaxShadowSize == maxShadowSize) {\n            return;\n        }\n        mRawShadowSize = shadowSize;\n        mRawMaxShadowSize = maxShadowSize;\n        mShadowSize = (int) (shadowSize * SHADOW_MULTIPLIER + mInsetShadow + .5f);\n        mMaxShadowSize = maxShadowSize + mInsetShadow;\n        mDirty = true;\n        invalidateSelf();\n    }\n\n    @Override\n    public boolean getPadding(Rect padding) {\n        int vOffset = (int) Math.ceil(calculateVerticalPadding(mRawMaxShadowSize, mCornerRadius,\n                mAddPaddingForCorners));\n//        int hOffset = (int) Math.ceil(calculateHorizontalPadding(mRawMaxShadowSize, mCornerRadius,\n//                mAddPaddingForCorners));\n//        padding.set(hOffset, vOffset, hOffset, vOffset);\n        padding.set(0, vOffset, 0, 0);\n        return true;\n    }\n\n    static float calculateVerticalPadding(float maxShadowSize, float cornerRadius,\n                                          boolean addPaddingForCorners) {\n        if (addPaddingForCorners) {\n            return (float) (maxShadowSize * SHADOW_MULTIPLIER + (1 - COS_45) * cornerRadius);\n        } else {\n            return maxShadowSize * SHADOW_MULTIPLIER;\n        }\n    }\n\n    static float calculateHorizontalPadding(float maxShadowSize, float cornerRadius,\n                                            boolean addPaddingForCorners) {\n        if (addPaddingForCorners) {\n            return (float) (maxShadowSize + (1 - COS_45) * cornerRadius);\n        } else {\n            return maxShadowSize;\n        }\n    }\n\n    @Override\n    public void setColorFilter(ColorFilter cf) {\n        mPaint.setColorFilter(cf);\n        mCornerShadowPaint.setColorFilter(cf);\n        mEdgeShadowPaint.setColorFilter(cf);\n    }\n\n    @Override\n    public int getOpacity() {\n        return PixelFormat.TRANSLUCENT;\n    }\n\n    void setCornerRadius(float radius) {\n        radius = (int) (radius + .5f);\n        if (mCornerRadius == radius) {\n            return;\n        }\n        mCornerRadius = radius;\n        mDirty = true;\n        invalidateSelf();\n    }\n\n    @Override\n    public void draw(Canvas canvas) {\n        if (mDirty) {\n            buildComponents(getBounds());\n            mDirty = false;\n        }\n        canvas.translate(0, -mRawShadowSize / 2);\n        drawShadow(canvas);\n        canvas.translate(0, +mRawShadowSize / 2);\n        sRoundRectHelper.drawRoundRect(canvas, mCardBounds, mCornerRadius, mPaint);\n    }\n\n    private void drawShadow(Canvas canvas) {\n        final float edgeShadowTop = -mCornerRadius - mShadowSize;\n        final float insetVertical = mCornerRadius + mInsetShadow + mRawShadowSize / 2;\n        final float insetHorizontal = -mInsetShadow;\n        // LT top\n        int saved = canvas.save();\n        canvas.translate(mCardBounds.left + insetHorizontal, mCardBounds.top + insetVertical);\n        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);\n        canvas.drawRect(0, edgeShadowTop,    mCardBounds.width() - 2 * insetHorizontal, -mCornerRadius + mShadowSize,  mEdgeShadowPaint);\n        canvas.restoreToCount(saved);\n\n        // RT right\n        saved = canvas.save();\n        canvas.translate(mCardBounds.right - insetHorizontal, mCardBounds.top + insetVertical);\n        canvas.rotate(90f);\n        canvas.drawPath(mCornerShadowPath, mCornerShadowPaint);\n        canvas.restoreToCount(saved);\n    }\n\n    private void buildShadowCorners() {\n        RectF innerBounds = new RectF(-mCornerRadius, -mCornerRadius, mCornerRadius, mCornerRadius);\n        RectF outerBounds = new RectF(innerBounds);\n        outerBounds.inset(-mShadowSize, -mShadowSize);\n\n        if (mCornerShadowPath == null) {\n            mCornerShadowPath = new Path();\n        } else {\n            mCornerShadowPath.reset();\n        }\n        mCornerShadowPath.setFillType(Path.FillType.EVEN_ODD);\n        mCornerShadowPath.moveTo(-mCornerRadius, 0);\n        mCornerShadowPath.rLineTo(-mShadowSize, 0);\n        // outer arc\n        mCornerShadowPath.arcTo(outerBounds, 180f, 90f, false);\n        // inner arc\n        mCornerShadowPath.arcTo(innerBounds, 270f, -90f, false);\n        mCornerShadowPath.close();\n        float startRatio = mCornerRadius / (mCornerRadius + mShadowSize);\n        mCornerShadowPaint.setShader(new RadialGradient(0, 0, mCornerRadius + mShadowSize,\n                new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor},\n                new float[]{0f, startRatio, 1f}\n                , Shader.TileMode.CLAMP));\n\n        // we offset the content shadowSize/2 pixels up to make it more realistic.\n        // this is why edge shadow shader has some extra space\n        // When drawing bottom edge shadow, we use that extra space.\n        mEdgeShadowPaint.setShader(new LinearGradient(0, -mCornerRadius + mShadowSize, 0,\n                -mCornerRadius - mShadowSize,\n                new int[]{mShadowStartColor, mShadowStartColor, mShadowEndColor},\n                new float[]{0f, .5f, 1f}, Shader.TileMode.CLAMP));\n        mEdgeShadowPaint.setAntiAlias(false);\n    }\n\n    private void buildComponents(Rect bounds) {\n        // Card is offset SHADOW_MULTIPLIER * maxShadowSize to account for the shadow shift.\n        // We could have different top-bottom offsets to avoid extra gap above but in that case\n        // center aligning Views inside the CardView would be problematic.\n        final float verticalOffset = mRawMaxShadowSize * SHADOW_MULTIPLIER;\n        mCardBounds.set(bounds.left + mRawMaxShadowSize, bounds.top + verticalOffset,\n                bounds.right - mRawMaxShadowSize, bounds.bottom - verticalOffset);\n        buildShadowCorners();\n    }\n\n    float getCornerRadius() {\n        return mCornerRadius;\n    }\n\n    void getMaxShadowAndCornerPadding(Rect into) {\n        getPadding(into);\n    }\n\n    void setShadowSize(float size) {\n        setShadowSize(size, mRawMaxShadowSize);\n    }\n\n    void setMaxShadowSize(float size) {\n        setShadowSize(mRawShadowSize, size);\n    }\n\n    float getShadowSize() {\n        return mRawShadowSize;\n    }\n\n    float getMaxShadowSize() {\n        return mRawMaxShadowSize;\n    }\n\n    float getMinWidth() {\n        final float content = 2 *\n                Math.max(mRawMaxShadowSize, mCornerRadius + mInsetShadow + mRawMaxShadowSize / 2);\n        return content + (mRawMaxShadowSize + mInsetShadow) * 2;\n    }\n\n    float getMinHeight() {\n        final float content = 2 * Math.max(mRawMaxShadowSize, mCornerRadius + mInsetShadow\n                + mRawMaxShadowSize * SHADOW_MULTIPLIER / 2);\n        return content + (mRawMaxShadowSize * SHADOW_MULTIPLIER + mInsetShadow) * 2;\n    }\n\n    public void setColor(int color) {\n        mPaint.setColor(color);\n        invalidateSelf();\n    }\n\n    interface RoundRectHelper {\n        void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius, Paint paint);\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/DepthLayout.java",
    "content": "package no.agens.depth.lib;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Matrix;\nimport android.graphics.Outline;\nimport android.graphics.Paint;\nimport android.graphics.PointF;\nimport android.graphics.drawable.Drawable;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport android.view.ViewOutlineProvider;\nimport android.widget.RelativeLayout;\n\npublic class DepthLayout extends RelativeLayout {\n\n\n    public static final int DEFAULT_EDGE_COLOR = Color.WHITE;\n    public static final int DEFAULT_THICKNESS = 2;\n    Paint edgePaint = new Paint();\n\n    public DepthLayout(Context context) {\n        super(context);\n        initView(null);\n\n    }\n\n    @Override\n    public boolean hasOverlappingRendering() {\n        return false;\n    }\n\n    public Paint getEdgePaint() {\n        return edgePaint;\n    }\n\n\n    public void setEdgePaint(Paint edgePaint) {\n        this.edgePaint = edgePaint;\n    }\n\n    private void initView(AttributeSet attrs) {\n\n        edgePaint.setColor(DEFAULT_EDGE_COLOR);\n        edgePaint.setAntiAlias(true);\n        TypedArray arr = getContext().obtainStyledAttributes(attrs, R.styleable.DepthView);\n        if (attrs != null) {\n            try {\n                edgePaint.setColor(arr.getInt(R.styleable.DepthView_edge_color, DEFAULT_EDGE_COLOR));\n                setIsCircle(arr.getBoolean(R.styleable.DepthView_is_circle, false));\n                depth = arr.getDimension(R.styleable.DepthView_depth, DEFAULT_THICKNESS * getResources().getDisplayMetrics().density);\n                customShadowElevation = arr.getDimension(R.styleable.DepthView_custom_elevation, 0);\n            } finally {\n                arr.recycle();\n            }\n\n        } else {\n            edgePaint.setColor(DEFAULT_EDGE_COLOR);\n            depth = DEFAULT_THICKNESS * getResources().getDisplayMetrics().density;\n        }\n        setOutlineProvider(new ViewOutlineProvider() {\n            @Override\n            public void getOutline(View view, Outline outline) {\n\n            }\n        });\n    }\n\n\n    public DepthLayout(Context context, AttributeSet attrs) {\n        super(context, attrs);\n        initView(attrs);\n\n    }\n\n    public DepthLayout(Context context, AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n        initView(attrs);\n    }\n\n\n    private float depth;\n\n\n    public float getDepth() {\n        return depth;\n    }\n\n    public void setDepth(float depth) {\n        this.depth = depth;\n        ((View) getParent()).invalidate();\n    }\n\n    public boolean isCircle() {\n        return isCircle;\n    }\n\n    public void setIsCircle(boolean isCircle) {\n        this.isCircle = isCircle;\n    }\n\n    private boolean isCircle = false;\n\n    float[] prevSrc = new float[8];\n\n    public boolean calculateBounds() {\n\n        float[] src = new float[8];\n        float[] dst = new float[]{0, 0, getWidth(), 0, 0, getHeight(), getWidth(), getHeight()};\n        Matrix matrix = getMatrix();\n\n        matrix.mapPoints(src, dst);\n        topLeft.x = src[0] + getLeft();\n        topLeft.y = src[1] + getTop();\n        topRight.x = src[2] + getLeft();\n        topRight.y = src[3] + getTop();\n\n        bottomLeft.x = src[4] + getLeft();\n        bottomLeft.y = src[5] + getTop();\n        bottomRight.x = src[6] + getLeft();\n        bottomRight.y = src[7] + getTop();\n        boolean returnValue = hasMatrixChanged(src);\n        prevSrc = src;\n        float percentFrom90X = (getRotationX()) / 90f;\n        float percentFrom90Y = (-getRotationY()) / 90f;\n\n\n        matrix.postTranslate(percentFrom90Y * getDepth(), percentFrom90X * getDepth());\n        src = new float[8];\n        dst = new float[]{0, 0, getWidth(), 0, 0, getHeight(), getWidth(), getHeight()};\n        matrix.mapPoints(src, dst);\n\n        topLeftBack.x = src[0] + getLeft();\n        topLeftBack.y = src[1] + getTop();\n        topRightBack.x = src[2] + getLeft();\n        topRightBack.y = src[3] + getTop();\n\n        bottomLeftBack.x = src[4] + getLeft();\n        bottomLeftBack.y = src[5] + getTop();\n        bottomRightBack.x = src[6] + getLeft();\n        bottomRightBack.y = src[7] + getTop();\n        customShadow.calculateBounds(this);\n\n        return returnValue;\n    }\n\n    boolean hasMatrixChanged(float[] newSrc) {\n        for (int i = 0; i < 8; i++) {\n            if (newSrc[i] != prevSrc[i])\n                return true;\n        }\n        return false;\n    }\n\n    public PointF getTopLeft() {\n        return topLeft;\n    }\n\n    public PointF getTopRight() {\n        return topRight;\n    }\n\n    public PointF getBottomLeft() {\n        return bottomLeft;\n    }\n\n    public PointF getBottomRight() {\n        return bottomRight;\n    }\n\n    public PointF getTopLeftBack() {\n        return topLeftBack;\n    }\n\n    public PointF getTopRightBack() {\n        return topRightBack;\n    }\n\n    public PointF getBottomLeftBack() {\n        return bottomLeftBack;\n    }\n\n    public PointF getBottomRightBack() {\n        return bottomRightBack;\n    }\n\n    final PointF topLeft = new PointF(0, 0);\n    PointF topRight = new PointF(0, 0);\n    PointF bottomLeft = new PointF(0, 0);\n    PointF bottomRight = new PointF(0, 0);\n\n\n    PointF topLeftBack = new PointF(0, 0);\n    PointF topRightBack = new PointF(0, 0);\n    PointF bottomLeftBack = new PointF(0, 0);\n    PointF bottomRightBack = new PointF(0, 0);\n\n\n    private CustomShadow customShadow = new CustomShadow();\n\n    public CustomShadow getCustomShadow() {\n        return customShadow;\n    }\n\n    public void setCustomShadowElevation(float customShadowElevation) {\n        this.customShadowElevation = customShadowElevation;\n        ((View) getParent()).invalidate();\n    }\n\n    public float getCustomShadowElevation() {\n        return customShadowElevation;\n    }\n\n    float customShadowElevation;\n\n    class CustomShadow {\n\n        public static final float DEFAULT_SHADOW_PADDING = 10f;\n        PointF topLeftBack = new PointF(0, 0);\n        PointF topRightBack = new PointF(0, 0);\n        PointF bottomLeftBack = new PointF(0, 0);\n        PointF bottomRightBack = new PointF(0, 0);\n        int padding;\n\n        public void calculateBounds(DepthLayout target) {\n            float[] src = new float[8];\n            float density = getResources().getDisplayMetrics().density;\n            float offsetY = customShadowElevation;\n            float offsetX = customShadowElevation / 5;\n            padding = (int) (customShadowElevation / 4f + DEFAULT_SHADOW_PADDING * density);\n\n            float[] dst = new float[]{-padding, -padding, target.getWidth() + padding, -padding, -padding, target.getHeight() + padding, target.getWidth() + padding, target.getHeight() + padding};\n            Matrix matrix = getMatrix();\n            matrix.mapPoints(src, dst);\n\n            topLeftBack.x = src[0] + target.getLeft() + offsetX;\n            topLeftBack.y = src[1] + target.getTop() + offsetY;\n            topRightBack.x = src[2] + target.getLeft() + offsetX;\n            topRightBack.y = src[3] + target.getTop() + offsetY;\n\n            bottomLeftBack.x = src[4] + target.getLeft() + offsetX;\n            bottomLeftBack.y = src[5] + target.getTop() + offsetY;\n            bottomRightBack.x = src[6] + target.getLeft() + offsetX;\n            bottomRightBack.y = src[7] + target.getTop() + offsetY;\n\n        }\n\n        Matrix matrix = new Matrix();\n\n        public void drawShadow(Canvas canvas, DepthLayout dl, Drawable shadow) {\n\n            shadow.setBounds(-padding, -padding, dl.getWidth() + padding, dl.getHeight() + padding);\n            float[] src = new float[]{0, 0, dl.getWidth(), 0, dl.getWidth(), dl.getHeight(), 0, dl.getHeight()};\n            float[] dst = new float[]{topLeftBack.x, topLeftBack.y, topRightBack.x, topRightBack.y, bottomRightBack.x, bottomRightBack.y, bottomLeftBack.x, bottomLeftBack.y};\n            int count = canvas.save();\n            matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);\n            canvas.concat(matrix);\n            shadow.draw(canvas);\n            canvas.restoreToCount(count);\n        }\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/DepthRendrer.java",
    "content": "package no.agens.depth.lib;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.PointF;\nimport android.graphics.drawable.Drawable;\nimport android.graphics.drawable.NinePatchDrawable;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport android.view.ViewTreeObserver;\nimport android.widget.RelativeLayout;\n\n\npublic class DepthRendrer extends RelativeLayout {\n\n    private final Paint shadowPaint = new Paint();\n    private NinePatchDrawable softShadow;\n    private Drawable roundSoftShadow;\n\n    private Path edgePath = new Path();\n\n    public DepthRendrer(Context context) {\n        super(context);\n        setup();\n\n    }\n\n    public DepthRendrer(Context context, AttributeSet attrs) {\n        super(context, attrs);\n        setup();\n    }\n\n    public DepthRendrer(Context context, AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n        setup();\n    }\n\n    public DepthRendrer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {\n        super(context, attrs, defStyleAttr, defStyleRes);\n        setup();\n    }\n\n    public float getTopEdgeLength(DepthLayout dl) {\n        return getDistance(dl.getTopLeftBack(), dl.getTopRightBack());\n    }\n\n    float getDistance(PointF p1, PointF p2) {\n        return (float) Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));\n    }\n\n    public float getShadowAlpha() {\n        return shadowAlpha;\n    }\n\n    public void setShadowAlpha(float shadowAlpha) {\n        this.shadowAlpha = Math.min(1f, Math.max(0, shadowAlpha));\n    }\n\n    private float shadowAlpha = 0.3f;\n\n    void setup() {\n        getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {\n            @Override\n            public boolean onPreDraw() {\n                for (int i = 0; i < getChildCount(); i++) {\n                    View child = getChildAt(i);\n                    if (child instanceof DepthLayout) {\n                        boolean hasChangedBounds = ((DepthLayout) child).calculateBounds();\n                        if (hasChangedBounds)\n                            invalidate();\n                    }\n                }\n                return true;\n            }\n        });\n\n        shadowPaint.setColor(Color.BLACK);\n        shadowPaint.setAntiAlias(true);\n        softShadow = (NinePatchDrawable) getResources().getDrawable(R.drawable.shadow, null);\n        roundSoftShadow = getResources().getDrawable(R.drawable.round_soft_shadow, null);\n    }\n\n    @Override\n    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {\n        if (child instanceof DepthLayout && !isInEditMode()) {\n            DepthLayout dl = (DepthLayout) child;\n\n\n            float[] src = new float[]{0, 0, dl.getWidth(), 0, dl.getWidth(), dl.getHeight(), 0, dl.getHeight()};\n            if (dl.isCircle()) {\n                dl.getCustomShadow().drawShadow(canvas, dl, roundSoftShadow);\n                if (Math.abs(dl.getRotationX()) > 1 || Math.abs(dl.getRotationY()) > 1)\n                    drawCornerBaseShape(dl, canvas, src);\n            } else {\n                dl.getCustomShadow().drawShadow(canvas, dl, softShadow);\n                if (dl.getRotationX() != 0 || dl.getRotationY() != 0) {\n                    if (getLongestHorizontalEdge(dl) > getLongestVerticalEdge(dl))\n                        drawVerticalFirst(dl, canvas, src);\n                    else\n                        drawHorizontalFist(dl, canvas, src);\n                }\n            }\n        }\n        return super.drawChild(canvas, child, drawingTime);\n    }\n\n    private void drawCornerBaseShape(DepthLayout dl, Canvas canvas, float[] src) {\n        float[] dst = new float[]{dl.getTopLeftBack().x, dl.getTopLeftBack().y, dl.getTopRightBack().x, dl.getTopRightBack().y, dl.getBottomRightBack().x, dl.getBottomRightBack().y, dl.getBottomLeftBack().x, dl.getBottomLeftBack().y};\n        int count = canvas.save();\n        matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);\n        canvas.concat(matrix);\n        edgePath.reset();\n        edgePath.addRoundRect(0, 0, dl.getWidth(), dl.getHeight(), dl.getWidth() / 2f, dl.getHeight() / 2f, Path.Direction.CCW);\n\n        canvas.drawPath(edgePath, dl.getEdgePaint());\n        shadowPaint.setAlpha((int) (shadowAlpha * 0.5f * 255));\n        canvas.drawPath(edgePath, shadowPaint);\n\n        canvas.restoreToCount(count);\n    }\n\n\n    private void drawHorizontalFist(DepthLayout dl, Canvas canvas, float[] src) {\n        if (getLeftEdgeLength(dl) <= getRightEdgeLength(dl)) {\n            drawLeftEdge(dl, canvas, src);\n        } else {\n            drawRightEdge(dl, canvas, src);\n        }\n\n        drawTopEdge(dl, canvas, src);\n        drawBottomEdge(dl, canvas, src);\n\n        if (getLeftEdgeLength(dl) >= getRightEdgeLength(dl)) {\n            drawLeftEdge(dl, canvas, src);\n        } else {\n            drawRightEdge(dl, canvas, src);\n        }\n    }\n\n    private void drawVerticalFirst(DepthLayout dl, Canvas canvas, float[] src) {\n\n        if (getTopEdgeLength(dl) <= getBottomEdgeLength(dl)) {\n            drawTopEdge(dl, canvas, src);\n        } else {\n            drawBottomEdge(dl, canvas, src);\n        }\n\n        drawLeftEdge(dl, canvas, src);\n        drawRightEdge(dl, canvas, src);\n\n\n        if (getTopEdgeLength(dl) >= getBottomEdgeLength(dl)) {\n            drawTopEdge(dl, canvas, src);\n        } else {\n            drawBottomEdge(dl, canvas, src);\n        }\n\n    }\n\n    float getLongestHorizontalEdge(DepthLayout dl) {\n        float topEdgeLength = getTopEdgeLength(dl);\n        float bottomEdgeLength = getBottomEdgeLength(dl);\n        if (topEdgeLength > bottomEdgeLength) {\n            return topEdgeLength;\n        } else {\n            return bottomEdgeLength;\n        }\n    }\n\n    float getLongestVerticalEdge(DepthLayout dl) {\n        float leftEdgeLength = getLeftEdgeLength(dl);\n        float rightEdgeLength = getRightEdgeLength(dl);\n        if (leftEdgeLength > rightEdgeLength) {\n            return leftEdgeLength;\n        } else {\n            return rightEdgeLength;\n        }\n    }\n\n    private float getRightEdgeLength(DepthLayout dl) {\n        return getDistance(dl.getTopRightBack(), dl.getBottomRightBack());\n    }\n\n    private float getLeftEdgeLength(DepthLayout dl) {\n        return getDistance(dl.getTopLeftBack(), dl.getBottomLeftBack());\n    }\n\n\n    private float getBottomEdgeLength(DepthLayout dl) {\n        return getDistance(dl.getBottomLeftBack(), dl.getBottomRightBack());\n    }\n\n\n    void drawShadow(PointF point1, PointF point2, float correctionValue, Canvas canvas, DepthLayout dl) {\n        float angle = Math.abs(Math.abs(getAngle(point1, point2)) + correctionValue);\n        float alpha = angle / 180f;\n        shadowPaint.setAlpha((int) (alpha * 255f * shadowAlpha));\n\n        canvas.drawRect(0, 0, dl.getWidth(), dl.getHeight(), shadowPaint);\n    }\n\n\n    private void drawRectancle(DepthLayout dl, Canvas canvas) {\n        canvas.drawRect(0, 0, dl.getWidth(), dl.getHeight(), dl.getEdgePaint());\n    }\n\n    public float getAngle(PointF point1, PointF point2) {\n\n        return (float) Math.toDegrees(Math.atan2(point1.y - point2.y, point1.x - point2.x));\n    }\n\n    private void drawLeftEdge(DepthLayout dl, Canvas canvas, float[] src) {\n        float[] dst = new float[]{dl.getTopLeft().x, dl.getTopLeft().y, dl.getTopLeftBack().x, dl.getTopLeftBack().y, dl.getBottomLeftBack().x, dl.getBottomLeftBack().y, dl.getBottomLeft().x, dl.getBottomLeft().y};\n        int count = canvas.save();\n        matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);\n        canvas.concat(matrix);\n        drawRectancle(dl, canvas);\n        drawShadow(dl.getTopLeft(), dl.getBottomLeft(), 0, canvas, dl);\n\n        canvas.restoreToCount(count);\n\n    }\n\n    private void drawRightEdge(DepthLayout dl, Canvas canvas, float[] src) {\n        float[] dst = new float[]{dl.getTopRight().x, dl.getTopRight().y, dl.getTopRightBack().x, dl.getTopRightBack().y, dl.getBottomRightBack().x, dl.getBottomRightBack().y, dl.getBottomRight().x, dl.getBottomRight().y};\n        int count = canvas.save();\n        matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);\n        canvas.concat(matrix);\n        drawRectancle(dl, canvas);\n        drawShadow(dl.getTopRight(), dl.getBottomRight(), -180f, canvas, dl);\n        canvas.restoreToCount(count);\n    }\n\n    android.graphics.Matrix matrix = new android.graphics.Matrix();\n\n    private void drawTopEdge(DepthLayout dl, Canvas canvas, float[] src) {\n\n        float[] dst = new float[]{dl.getTopLeft().x, dl.getTopLeft().y, dl.getTopRight().x, dl.getTopRight().y, dl.getTopRightBack().x, dl.getTopRightBack().y, dl.getTopLeftBack().x, dl.getTopLeftBack().y};\n        int count = canvas.save();\n        matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);\n        canvas.concat(matrix);\n        drawRectancle(dl, canvas);\n        drawShadow(dl.getTopLeft(), dl.getTopRight(), -180f, canvas, dl);\n        canvas.restoreToCount(count);\n    }\n\n    private void drawBottomEdge(DepthLayout dl, Canvas canvas, float[] src) {\n\n        float[] dst = new float[]{dl.getBottomLeft().x, dl.getBottomLeft().y, dl.getBottomRight().x, dl.getBottomRight().y, dl.getBottomRightBack().x, dl.getBottomRightBack().y, dl.getBottomLeftBack().x, dl.getBottomLeftBack().y};\n        int count = canvas.save();\n        matrix.setPolyToPoly(src, 0, dst, 0, dst.length >> 1);\n        canvas.concat(matrix);\n        drawRectancle(dl, canvas);\n        drawShadow(dl.getBottomLeft(), dl.getBottomRight(), 0, canvas, dl);\n        canvas.restoreToCount(count);\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/MaterialMenuDrawable.java",
    "content": "package no.agens.depth.lib;\n        import android.animation.Animator;\n        import android.animation.AnimatorListenerAdapter;\n        import android.animation.ObjectAnimator;\n        import android.content.Context;\n        import android.content.res.Resources;\n        import android.graphics.Canvas;\n        import android.graphics.Color;\n        import android.graphics.ColorFilter;\n        import android.graphics.Paint;\n        import android.graphics.PixelFormat;\n        import android.graphics.drawable.Animatable;\n        import android.graphics.drawable.Drawable;\n        import android.util.Property;\n        import android.util.TypedValue;\n        import android.view.animation.DecelerateInterpolator;\n        import android.view.animation.Interpolator;\n\n        import static android.graphics.Paint.Style;\n\npublic class MaterialMenuDrawable extends Drawable implements Animatable {\n\n    public enum IconState {\n        BURGER, ARROW, X, CHECK\n    }\n\n    public enum AnimationState {\n        BURGER_ARROW, BURGER_X, ARROW_X, ARROW_CHECK, BURGER_CHECK, X_CHECK;\n\n        public IconState getFirstState() {\n            switch (this) {\n                case BURGER_ARROW:\n                    return IconState.BURGER;\n                case BURGER_X:\n                    return IconState.BURGER;\n                case ARROW_X:\n                    return IconState.ARROW;\n                case ARROW_CHECK:\n                    return IconState.ARROW;\n                case BURGER_CHECK:\n                    return IconState.BURGER;\n                case X_CHECK:\n                    return IconState.X;\n                default:\n                    return null;\n            }\n        }\n\n        public IconState getSecondState() {\n            switch (this) {\n                case BURGER_ARROW:\n                    return IconState.ARROW;\n                case BURGER_X:\n                    return IconState.X;\n                case ARROW_X:\n                    return IconState.X;\n                case ARROW_CHECK:\n                    return IconState.CHECK;\n                case BURGER_CHECK:\n                    return IconState.CHECK;\n                case X_CHECK:\n                    return IconState.CHECK;\n                default:\n                    return null;\n            }\n        }\n    }\n\n    public enum Stroke {\n        /**\n         * 3 dip\n         */\n        REGULAR(3),\n        /**\n         * 2 dip\n         */\n        THIN(2),\n        /**\n         * 1 dip\n         */\n        EXTRA_THIN(1);\n\n        private final int strokeWidth;\n\n        Stroke(int strokeWidth) {\n            this.strokeWidth = strokeWidth;\n        }\n\n        protected static Stroke valueOf(int strokeWidth) {\n            switch (strokeWidth) {\n                case 3:\n                    return REGULAR;\n                case 2:\n                    return THIN;\n                case 1:\n                    return EXTRA_THIN;\n                default:\n                    return THIN;\n            }\n        }\n    }\n\n    public static final int     DEFAULT_COLOR              = Color.WHITE;\n    public static final int     DEFAULT_SCALE              = 1;\n    public static final int     DEFAULT_TRANSFORM_DURATION = 800;\n    public static final boolean DEFAULT_VISIBLE            = true;\n\n    private static final int BASE_DRAWABLE_WIDTH  = 40;\n    private static final int BASE_DRAWABLE_HEIGHT = 40;\n    private static final int BASE_ICON_WIDTH      = 20;\n    private static final int BASE_CIRCLE_RADIUS   = 18;\n\n    private static final float ARROW_MID_LINE_ANGLE = 180;\n    private static final float ARROW_TOP_LINE_ANGLE = 135;\n    private static final float ARROW_BOT_LINE_ANGLE = 225;\n    private static final float X_TOP_LINE_ANGLE     = 44;\n    private static final float X_BOT_LINE_ANGLE     = -44;\n    private static final float X_ROTATION_ANGLE     = 90;\n    private static final float CHECK_MIDDLE_ANGLE   = 135;\n    private static final float CHECK_BOTTOM_ANGLE   = -90;\n\n    private static final float TRANSFORMATION_START = 0;\n    private static final float TRANSFORMATION_MID   = 1.0f;\n    private static final float TRANSFORMATION_END   = 2.0f;\n\n    private static final int DEFAULT_CIRCLE_ALPHA = 200;\n\n    private final float diph;\n    private final float dip1;\n    private final float dip2;\n    private final float dip3;\n    private final float dip4;\n    private final float dip8;\n\n    private final int   width;\n    private final int   height;\n    private final float strokeWidth;\n    private final float iconWidth;\n    private final float topPadding;\n    private final float sidePadding;\n    private final float circleRadius;\n\n    private final Stroke stroke;\n\n    private final Object lock = new Object();\n\n    private final Paint iconPaint   = new Paint();\n    private final Paint circlePaint = new Paint();\n\n    private float   transformationValue   = 0f;\n    private boolean transformationRunning = false;\n\n    private IconState      currentIconState = IconState.BURGER;\n    private AnimationState animationState   = AnimationState.BURGER_ARROW;\n\n    private IconState animatingIconState;\n    private boolean   visible;\n    private boolean   rtlEnabled;\n\n    private ObjectAnimator transformation;\n    private Animator.AnimatorListener animatorListener;\n\n    private MaterialMenuState materialMenuState;\n\n    public MaterialMenuDrawable(Context context, int color, Stroke stroke) {\n        this(context, color, stroke, DEFAULT_SCALE, DEFAULT_TRANSFORM_DURATION);\n    }\n\n    public MaterialMenuDrawable(Context context, int color, Stroke stroke, int transformDuration) {\n        this(context, color, stroke, DEFAULT_SCALE, transformDuration);\n    }\n\n    public MaterialMenuDrawable(Context context, int color, Stroke stroke, int scale, int transformDuration) {\n        Resources resources = context.getResources();\n        // convert each separately due to various densities\n        this.dip1 = dpToPx(resources, 1) * scale;\n        this.dip2 = dpToPx(resources, 2) * scale;\n        this.dip3 = dpToPx(resources, 3) * scale;\n        this.dip4 = dpToPx(resources, 4) * scale;\n        this.dip8 = dpToPx(resources, 8) * scale;\n        this.diph = dip1 / 2;\n\n        this.stroke = stroke;\n        this.visible = DEFAULT_VISIBLE;\n        this.width = (int) (dpToPx(resources, BASE_DRAWABLE_WIDTH) * scale);\n        this.height = (int) (dpToPx(resources, BASE_DRAWABLE_HEIGHT) * scale);\n        this.iconWidth = dpToPx(resources, BASE_ICON_WIDTH) * scale;\n        this.circleRadius = dpToPx(resources, BASE_CIRCLE_RADIUS) * scale;\n        this.strokeWidth = dpToPx(resources, stroke.strokeWidth) * scale;\n\n        this.sidePadding = (width - iconWidth) / 2;\n        this.topPadding = (height - 5 * dip3) / 2;\n\n        initPaint(color);\n        initAnimations(transformDuration);\n\n        materialMenuState = new MaterialMenuState();\n    }\n\n    private MaterialMenuDrawable(int color, Stroke stroke, long transformDuration, int width, int height,\n                                 float iconWidth, float circleRadius, float strokeWidth, float dip1\n    ) {\n        this.dip1 = dip1;\n        this.dip2 = dip1 * 2;\n        this.dip3 = dip1 * 3;\n        this.dip4 = dip1 * 4;\n        this.dip8 = dip1 * 8;\n        this.diph = dip1 / 2;\n        this.stroke = stroke;\n        this.width = width;\n        this.height = height;\n        this.iconWidth = iconWidth;\n        this.circleRadius = circleRadius;\n        this.strokeWidth = strokeWidth;\n        this.sidePadding = (width - iconWidth) / 2;\n        this.topPadding = (height - 5 * dip3) / 2;\n\n        initPaint(color);\n        initAnimations((int) transformDuration);\n\n        materialMenuState = new MaterialMenuState();\n    }\n\n    private void initPaint(int color) {\n        iconPaint.setAntiAlias(true);\n        iconPaint.setStyle(Style.STROKE);\n        iconPaint.setStrokeWidth(strokeWidth);\n        iconPaint.setColor(color);\n\n        circlePaint.setAntiAlias(true);\n        circlePaint.setStyle(Style.FILL);\n        circlePaint.setColor(color);\n        circlePaint.setAlpha(DEFAULT_CIRCLE_ALPHA);\n\n        setBounds(0, 0, width, height);\n    }\n\n    /*\n     * Drawing\n     */\n\n    @Override public void draw(Canvas canvas) {\n        if (!visible) return;\n\n        final float ratio = transformationValue <= 1 ? transformationValue : 2 - transformationValue;\n\n        if (rtlEnabled) {\n            canvas.save();\n            canvas.scale(-1, 1, 0, 0);\n            canvas.translate(-getIntrinsicWidth(), 0);\n        }\n\n        drawTopLine(canvas, ratio);\n        drawMiddleLine(canvas, ratio);\n        drawBottomLine(canvas, ratio);\n\n        if (rtlEnabled) {\n            canvas.restore();\n        }\n    }\n\n    private void drawMiddleLine(Canvas canvas, float ratio) {\n        canvas.restore();\n        canvas.save();\n\n        float rotation = 0;\n        float pivotX = width / 2;\n        float pivotY = width / 2;\n        float startX = sidePadding;\n        float startY = topPadding + dip3 / 2 * 5;\n        float stopX = width - sidePadding;\n        float stopY = topPadding + dip3 / 2 * 5;\n        int alpha = 255;\n\n        switch (animationState) {\n            case BURGER_ARROW:\n                // rotate by 180\n                if (isMorphingForward()) {\n                    rotation = ratio * ARROW_MID_LINE_ANGLE;\n                } else {\n                    rotation = ARROW_MID_LINE_ANGLE + (1 - ratio) * ARROW_MID_LINE_ANGLE;\n                }\n                // shorten one end\n                stopX -= ratio * resolveStrokeModifier(ratio) / 2;\n                break;\n            case BURGER_X:\n                // fade out\n                alpha = (int) ((1 - ratio) * 255);\n                break;\n            case ARROW_X:\n                // fade out and shorten one end\n                alpha = (int) ((1 - ratio) * 255);\n                startX += (1 - ratio) * dip2;\n                break;\n            case ARROW_CHECK:\n                if (isMorphingForward()) {\n                    // rotate until required angle\n                    rotation = ratio * CHECK_MIDDLE_ANGLE;\n                } else {\n                    // rotate back to starting angle\n                    rotation = CHECK_MIDDLE_ANGLE - CHECK_MIDDLE_ANGLE * (1 - ratio);\n                }\n                // shorten one end and lengthen the other\n                startX += dip3 / 2 + dip4 - (1 - ratio) * dip2;\n                stopX += ratio * dip1;\n                pivotX = width / 2 + dip3 + diph;\n                break;\n            case BURGER_CHECK:\n                // rotate until required angle\n                rotation = ratio * CHECK_MIDDLE_ANGLE;\n                // lengthen both ends\n                startX += ratio * (dip4 + dip3 / 2);\n                stopX += ratio * dip1;\n                pivotX = width / 2 + dip3 + diph;\n                break;\n            case X_CHECK:\n                // fade in\n                alpha = (int) (ratio * 255);\n                // rotation to check angle\n                rotation = ratio * CHECK_MIDDLE_ANGLE;\n                // lengthen both ends\n                startX += ratio * (dip4 + dip3 / 2);\n                stopX += ratio * dip1;\n                pivotX = width / 2 + dip3 + diph;\n                break;\n        }\n\n        iconPaint.setAlpha(alpha);\n        canvas.rotate(rotation, pivotX, pivotY);\n        canvas.drawLine(startX, startY, stopX, stopY, iconPaint);\n        iconPaint.setAlpha(255);\n    }\n\n    private void drawTopLine(Canvas canvas, float ratio) {\n        canvas.save();\n\n        float rotation = 0, pivotX = 0, pivotY = 0;\n        float rotation2 = 0;\n        // pivot at center of line\n        float pivotX2 = width / 2 + dip3 / 2;\n        float pivotY2 = topPadding + dip2;\n\n        float startX = sidePadding;\n        float startY = topPadding + dip2;\n        float stopX = width - sidePadding;\n        float stopY = topPadding + dip2;\n        int alpha = 255;\n\n        switch (animationState) {\n            case BURGER_ARROW:\n                if (isMorphingForward()) {\n                    // rotate until required angle\n                    rotation = ratio * ARROW_BOT_LINE_ANGLE;\n                } else {\n                    // rotate back to start doing a 360\n                    rotation = ARROW_BOT_LINE_ANGLE + (1 - ratio) * ARROW_TOP_LINE_ANGLE;\n                }\n                // rotate by middle\n                pivotX = width / 2;\n                pivotY = height / 2;\n\n                // shorten both ends\n                stopX -= resolveStrokeModifier(ratio);\n                startX += dip3 * ratio;\n\n                break;\n            case BURGER_X:\n                // rotate until required angles\n                rotation = X_TOP_LINE_ANGLE * ratio;\n                rotation2 = X_ROTATION_ANGLE * ratio;\n\n                // pivot at left corner of line\n                pivotX = sidePadding + dip4;\n                pivotY = topPadding + dip3;\n\n                // shorten one end\n                startX += dip3 * ratio;\n                break;\n            case ARROW_X:\n                // rotate from ARROW angle to x angle\n                rotation = ARROW_BOT_LINE_ANGLE + (X_TOP_LINE_ANGLE - ARROW_BOT_LINE_ANGLE) * ratio;\n                rotation2 = X_ROTATION_ANGLE * ratio;\n\n                // move pivot from ARROW pivot to x pivot\n                pivotX = width / 2 + (sidePadding + dip4 - width / 2) * ratio;\n                pivotY = height / 2 + (topPadding + dip3 - height / 2) * ratio;\n\n                // lengthen both ends\n                stopX -= resolveStrokeModifier(ratio);\n                startX += dip3;\n                break;\n            case ARROW_CHECK:\n                // fade out\n                alpha = (int) ((1 - ratio) * 255);\n                // retain starting arrow configuration\n                rotation = ARROW_BOT_LINE_ANGLE;\n                pivotX = width / 2;\n                pivotY = height / 2;\n\n                // shorted both ends\n                stopX -= resolveStrokeModifier(1);\n                startX += dip3;\n                break;\n            case BURGER_CHECK:\n                // fade out\n                alpha = (int) ((1 - ratio) * 255);\n                break;\n            case X_CHECK:\n                // retain x configuration\n                rotation = X_TOP_LINE_ANGLE;\n                rotation2 = X_ROTATION_ANGLE;\n                pivotX = sidePadding + dip4;\n                pivotY = topPadding + dip3;\n                stopX += dip3 - dip3 * (1 - ratio);\n                startX += dip3;\n\n                // fade out\n                alpha = (int) ((1 - ratio) * 255);\n                break;\n        }\n\n        iconPaint.setAlpha(alpha);\n        canvas.rotate(rotation, pivotX, pivotY);\n        canvas.rotate(rotation2, pivotX2, pivotY2);\n        canvas.drawLine(startX, startY, stopX, stopY, iconPaint);\n        iconPaint.setAlpha(255);\n    }\n\n    private void drawBottomLine(Canvas canvas, float ratio) {\n        canvas.restore();\n        canvas.save();\n\n        float rotation = 0, pivotX = 0, pivotY = 0;\n        float rotation2 = 0;\n        // pivot at center of line\n        float pivotX2 = width / 2 + dip3 / 2;\n        float pivotY2 = height - topPadding - dip2;\n\n        float startX = sidePadding;\n        float startY = height - topPadding - dip2;\n        float stopX = width - sidePadding;\n        float stopY = height - topPadding - dip2;\n\n        switch (animationState) {\n            case BURGER_ARROW:\n                if (isMorphingForward()) {\n                    // rotate to required angle\n                    rotation = ARROW_TOP_LINE_ANGLE * ratio;\n                } else {\n                    // rotate back to start doing a 360\n                    rotation = ARROW_TOP_LINE_ANGLE + (1 - ratio) * ARROW_BOT_LINE_ANGLE;\n                }\n                // pivot center of canvas\n                pivotX = width / 2;\n                pivotY = height / 2;\n\n                // shorten both ends\n                stopX = width - sidePadding - resolveStrokeModifier(ratio);\n                startX = sidePadding + dip3 * ratio;\n                break;\n            case BURGER_X:\n                if (isMorphingForward()) {\n                    // rotate around\n                    rotation2 = -X_ROTATION_ANGLE * ratio;\n                } else {\n                    // rotate directly\n                    rotation2 = X_ROTATION_ANGLE * ratio;\n                }\n                // rotate to required angle\n                rotation = X_BOT_LINE_ANGLE * ratio;\n\n                // pivot left corner of line\n                pivotX = sidePadding + dip4;\n                pivotY = height - topPadding - dip3;\n\n                // shorten one end\n                startX += dip3 * ratio;\n                break;\n            case ARROW_X:\n                // rotate from ARROW angle to x angle\n                rotation = ARROW_TOP_LINE_ANGLE + (360 + X_BOT_LINE_ANGLE - ARROW_TOP_LINE_ANGLE) * ratio;\n                rotation2 = -X_ROTATION_ANGLE * ratio;\n\n                // move pivot from ARROW pivot to x pivot\n                pivotX = width / 2 + (sidePadding + dip4 - width / 2) * ratio;\n                pivotY = height / 2 + (height / 2 - topPadding - dip3) * ratio;\n\n                // lengthen both ends\n                stopX -= resolveStrokeModifier(ratio);\n                startX += dip3;\n                break;\n            case ARROW_CHECK:\n                // rotate from ARROW angle to CHECK angle\n                rotation = ARROW_TOP_LINE_ANGLE + ratio * CHECK_BOTTOM_ANGLE;\n\n                // move pivot from ARROW pivot to CHECK pivot\n                pivotX = width / 2 + dip3 * ratio;\n                pivotY = height / 2 - dip3 * ratio;\n\n                // length stays same as ARROW\n                stopX -= resolveStrokeModifier(1);\n                startX += dip3 + (dip4 + dip1) * ratio;\n                break;\n            case BURGER_CHECK:\n                // rotate from ARROW angle to CHECK angle\n                rotation = ratio * (CHECK_BOTTOM_ANGLE + ARROW_TOP_LINE_ANGLE);\n\n                // move pivot from BURGER pivot to CHECK pivot\n                pivotX = width / 2 + dip3 * ratio;\n                pivotY = height / 2 - dip3 * ratio;\n\n                // length stays same as BURGER\n                startX += dip8 * ratio;\n                stopX -= resolveStrokeModifier(ratio);\n                break;\n            case X_CHECK:\n                // rotate from x to CHECK angles\n                rotation2 = -X_ROTATION_ANGLE * (1 - ratio);\n                rotation = X_BOT_LINE_ANGLE + (CHECK_BOTTOM_ANGLE + ARROW_TOP_LINE_ANGLE - X_BOT_LINE_ANGLE) * ratio;\n\n                // move pivot from x to CHECK\n                pivotX = sidePadding + dip4 + (width / 2 + dip3 - sidePadding - dip4) * ratio;\n                pivotY = height - topPadding - dip3 + (topPadding + height / 2 - height) * ratio;\n\n                // shorten both ends\n                startX += dip8 - (dip4 + dip1) * (1 - ratio);\n                stopX -= resolveStrokeModifier(1 - ratio);\n                break;\n        }\n\n        canvas.rotate(rotation, pivotX, pivotY);\n        canvas.rotate(rotation2, pivotX2, pivotY2);\n        canvas.drawLine(startX, startY, stopX, stopY, iconPaint);\n    }\n\n    private boolean isMorphingForward() {\n        return transformationValue <= TRANSFORMATION_MID;\n    }\n\n    private float resolveStrokeModifier(float ratio) {\n        switch (stroke) {\n            case REGULAR:\n                if (animationState == AnimationState.ARROW_X || animationState == AnimationState.X_CHECK) {\n                    return dip3 - (dip3 * ratio);\n                }\n                return ratio * dip3;\n            case THIN:\n                if (animationState == AnimationState.ARROW_X || animationState == AnimationState.X_CHECK) {\n                    return dip3 + diph - (dip3 + diph) * ratio;\n                }\n                return ratio * (dip3 + diph);\n            case EXTRA_THIN:\n                if (animationState == AnimationState.ARROW_X || animationState == AnimationState.X_CHECK) {\n                    return dip4 - ((dip3 + dip1) * ratio);\n                }\n                return ratio * dip4;\n        }\n        return 0;\n    }\n\n    @Override public void setAlpha(int alpha) {\n        iconPaint.setAlpha(alpha);\n    }\n\n    @Override public void setColorFilter(ColorFilter cf) {\n        iconPaint.setColorFilter(cf);\n    }\n\n    @Override public int getOpacity() {\n        return PixelFormat.TRANSPARENT;\n    }\n\n    /*\n     * Accessor methods\n     */\n\n    public void setColor(int color) {\n        iconPaint.setColor(color);\n        circlePaint.setColor(color);\n        invalidateSelf();\n    }\n\n    public void setTransformationDuration(int duration) {\n        transformation.setDuration(duration);\n    }\n\n    public void setInterpolator(Interpolator interpolator) {\n        transformation.setInterpolator(interpolator);\n    }\n\n    public void setAnimationListener(Animator.AnimatorListener listener) {\n        if (animatorListener != null) {\n            transformation.removeListener(animatorListener);\n        }\n\n        if (listener != null) {\n            transformation.addListener(listener);\n        }\n\n        animatorListener = listener;\n    }\n\n    public void setIconState(IconState iconState) {\n        synchronized (lock) {\n            if (transformationRunning) {\n                transformation.cancel();\n                transformationRunning = false;\n            }\n\n            if (currentIconState == iconState) return;\n\n            switch (iconState) {\n                case BURGER:\n                    animationState = AnimationState.BURGER_ARROW;\n                    transformationValue = TRANSFORMATION_START;\n                    break;\n                case ARROW:\n                    animationState = AnimationState.BURGER_ARROW;\n                    transformationValue = TRANSFORMATION_MID;\n                    break;\n                case X:\n                    animationState = AnimationState.BURGER_X;\n                    transformationValue = TRANSFORMATION_MID;\n                    break;\n                case CHECK:\n                    animationState = AnimationState.BURGER_CHECK;\n                    transformationValue = TRANSFORMATION_MID;\n            }\n            currentIconState = iconState;\n            invalidateSelf();\n        }\n    }\n\n    public void animateIconState(IconState state) {\n        synchronized (lock) {\n            if (transformationRunning) {\n                transformation.end();\n            }\n            animatingIconState = state;\n            start();\n        }\n    }\n\n    public IconState setTransformationOffset(AnimationState animationState, float offset) {\n        if (offset < TRANSFORMATION_START || offset > TRANSFORMATION_END) {\n            throw new IllegalArgumentException(\n                    String.format(\"Value must be between %s and %s\", TRANSFORMATION_START, TRANSFORMATION_END)\n            );\n        }\n\n        this.animationState = animationState;\n\n        final boolean isFirstIcon = offset < TRANSFORMATION_MID || offset == TRANSFORMATION_END;\n\n        currentIconState = isFirstIcon ? animationState.getFirstState() : animationState.getSecondState();\n        animatingIconState = isFirstIcon ? animationState.getSecondState() : animationState.getFirstState();\n\n        setTransformationValue(offset);\n\n        return currentIconState;\n    }\n\n    public void setVisible(boolean visible) {\n        this.visible = visible;\n        invalidateSelf();\n    }\n\n    public void setRTLEnabled(boolean rtlEnabled) {\n        this.rtlEnabled = rtlEnabled;\n        invalidateSelf();\n    }\n\n    public IconState getIconState() {\n        return currentIconState;\n    }\n\n    public boolean isDrawableVisible(){\n        return visible;\n    }\n\n    /*\n     * Animations\n     */\n    private final Property<MaterialMenuDrawable, Float> transformationProperty\n            = new Property<MaterialMenuDrawable, Float>(Float.class, \"transformation\") {\n        @Override\n        public Float get(MaterialMenuDrawable object) {\n            return object.getTransformationValue();\n        }\n\n        @Override\n        public void set(MaterialMenuDrawable object, Float value) {\n            object.setTransformationValue(value);\n        }\n    };\n\n    public Float getTransformationValue() {\n        return transformationValue;\n    }\n\n    public void setTransformationValue(Float value) {\n        this.transformationValue = value;\n        invalidateSelf();\n    }\n\n    private void initAnimations(int transformDuration) {\n        transformation = ObjectAnimator.ofFloat(this, transformationProperty, 0);\n        transformation.setInterpolator(new DecelerateInterpolator(3));\n        transformation.setDuration(transformDuration);\n        transformation.addListener(new AnimatorListenerAdapter() {\n            @Override public void onAnimationEnd(Animator animation) {\n                transformationRunning = false;\n                setIconState(animatingIconState);\n            }\n        });\n    }\n\n    private boolean resolveTransformation() {\n        boolean isCurrentBurger = currentIconState == IconState.BURGER;\n        boolean isCurrentArrow = currentIconState == IconState.ARROW;\n        boolean isCurrentX = currentIconState == IconState.X;\n        boolean isCurrentCheck = currentIconState == IconState.CHECK;\n        boolean isAnimatingBurger = animatingIconState == IconState.BURGER;\n        boolean isAnimatingArrow = animatingIconState == IconState.ARROW;\n        boolean isAnimatingX = animatingIconState == IconState.X;\n        boolean isAnimatingCheck = animatingIconState == IconState.CHECK;\n\n        if ((isCurrentBurger && isAnimatingArrow) || (isCurrentArrow && isAnimatingBurger)) {\n            animationState = AnimationState.BURGER_ARROW;\n            return isCurrentBurger;\n        }\n\n        if ((isCurrentArrow && isAnimatingX) || (isCurrentX && isAnimatingArrow)) {\n            animationState = AnimationState.ARROW_X;\n            return isCurrentArrow;\n        }\n\n        if ((isCurrentBurger && isAnimatingX) || (isCurrentX && isAnimatingBurger)) {\n            animationState = AnimationState.BURGER_X;\n            return isCurrentBurger;\n        }\n\n        if ((isCurrentArrow && isAnimatingCheck) || (isCurrentCheck && isAnimatingArrow)) {\n            animationState = AnimationState.ARROW_CHECK;\n            return isCurrentArrow;\n        }\n\n        if ((isCurrentBurger && isAnimatingCheck) || (isCurrentCheck && isAnimatingBurger)) {\n            animationState = AnimationState.BURGER_CHECK;\n            return isCurrentBurger;\n        }\n\n        if ((isCurrentX && isAnimatingCheck) || (isCurrentCheck && isAnimatingX)) {\n            animationState = AnimationState.X_CHECK;\n            return isCurrentX;\n        }\n\n        throw new IllegalStateException(\n                String.format(\"Animating from %s to %s is not supported\", currentIconState, animatingIconState)\n        );\n    }\n\n    @Override public void start() {\n        if (transformationRunning) return;\n\n        if (animatingIconState != null && animatingIconState != currentIconState) {\n            transformationRunning = true;\n\n            final boolean direction = resolveTransformation();\n            transformation.setFloatValues(\n                    direction ? TRANSFORMATION_START : TRANSFORMATION_MID,\n                    direction ? TRANSFORMATION_MID : TRANSFORMATION_END\n            );\n            transformation.start();\n        }\n\n        invalidateSelf();\n    }\n\n    @Override public void stop() {\n        if (isRunning() && transformation.isRunning()) {\n            transformation.end();\n        } else {\n            transformationRunning = false;\n            invalidateSelf();\n        }\n    }\n\n    @Override public boolean isRunning() {\n        return transformationRunning;\n    }\n\n    @Override\n    public int getIntrinsicWidth() {\n        return width;\n    }\n\n    @Override\n    public int getIntrinsicHeight() {\n        return height;\n    }\n\n\n    @Override\n    public ConstantState getConstantState() {\n        materialMenuState.changingConfigurations = getChangingConfigurations();\n        return materialMenuState;\n    }\n\n    @Override\n    public Drawable mutate() {\n        materialMenuState = new MaterialMenuState();\n        return this;\n    }\n\n    private final class MaterialMenuState extends ConstantState {\n        private int changingConfigurations;\n\n        private MaterialMenuState() {\n        }\n\n        @Override\n        public Drawable newDrawable() {\n            MaterialMenuDrawable drawable = new MaterialMenuDrawable(\n                    circlePaint.getColor(), stroke, transformation.getDuration(),\n                    width, height, iconWidth, circleRadius, strokeWidth, dip1\n            );\n            drawable.setIconState(animatingIconState != null ? animatingIconState : currentIconState);\n            drawable.setVisible(visible);\n            drawable.setRTLEnabled(rtlEnabled);\n            return drawable;\n        }\n\n        @Override\n        public int getChangingConfigurations() {\n            return changingConfigurations;\n        }\n    }\n\n    static float dpToPx(Resources resources, float dp) {\n        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.getDisplayMetrics());\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/MathHelper.java",
    "content": "package no.agens.depth.lib;\n\nimport java.util.Random;\n\npublic class MathHelper {\n    public static final Random rand = new Random();\n    public static float randomRange(float min, float max) {\n\n\n        return rand.nextInt(((int) max - (int) min) + 1) + (int) min;\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/RectEvaluator.java",
    "content": "package no.agens.depth.lib;\n\nimport android.animation.TypeEvaluator;\nimport android.graphics.Rect;\n\npublic class RectEvaluator implements TypeEvaluator<Rect> {\n\n    @Override\n    public Rect evaluate(float fraction, Rect startValue, Rect endValue) {\n\n        return new Rect(startValue.left + (int) ((endValue.left - startValue.left) * fraction),\n                startValue.top + (int) ((endValue.top - startValue.top) * fraction),\n                startValue.right + (int) ((endValue.right - startValue.right) * fraction),\n                startValue.bottom + (int) ((endValue.bottom - startValue.bottom) * fraction));\n    }\n\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/RectFEvaluator.java",
    "content": "package no.agens.depth.lib;\n\nimport android.animation.TypeEvaluator;\nimport android.graphics.RectF;\n\npublic class RectFEvaluator implements TypeEvaluator<RectF> {\n\n    @Override\n    public RectF evaluate(float fraction, RectF startValue, RectF endValue) {\n\n        return new RectF(startValue.left + (int) ((endValue.left - startValue.left) * fraction),\n                startValue.top + (int) ((endValue.top - startValue.top) * fraction),\n                startValue.right + (int) ((endValue.right - startValue.right) * fraction),\n                startValue.bottom + (int) ((endValue.bottom - startValue.bottom) * fraction));\n    }\n\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/RippleHelper.java",
    "content": "package no.agens.depth.lib;\n\nimport android.content.res.ColorStateList;\nimport android.graphics.drawable.ColorDrawable;\nimport android.graphics.drawable.RippleDrawable;\n\npublic class RippleHelper {\n    public static RippleDrawable getPressedColorRippleDrawable(int normalColor, int pressedColor)\n    {\n        return new RippleDrawable(getPressedColorSelector(normalColor, pressedColor), getColorDrawableFromColor(normalColor), null);\n    }\n\n    public static ColorStateList getPressedColorSelector(int normalColor, int pressedColor)\n    {\n        return new ColorStateList(\n                new int[][]\n                        {\n                                new int[]{android.R.attr.state_pressed},\n                                new int[]{android.R.attr.state_focused},\n                                new int[]{android.R.attr.state_activated},\n                                new int[]{}\n                        },\n                new int[]\n                        {\n                                pressedColor,\n                                pressedColor,\n                                pressedColor,\n                                normalColor\n                        }\n        );\n    }\n\n    public static ColorDrawable getColorDrawableFromColor(int color)\n    {\n        return new ColorDrawable(color);\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/AuraDrawable.java",
    "content": "package no.agens.depth.lib.headers;\n\nimport android.graphics.Canvas;\nimport android.graphics.Rect;\nimport android.graphics.drawable.Drawable;\n\nimport no.agens.depth.lib.MathHelper;\n\npublic class AuraDrawable extends Renderable {\n    private final Drawable drawable;\n    private long lastFlicker;\n\n    public AuraDrawable(Drawable drawable, Rect position) {\n        super(null, 0, 0);\n        drawable.setBounds(position);\n        this.drawable = drawable;\n        lastFlicker = System.currentTimeMillis();\n    }\n\n    @Override\n    public void draw(Canvas canvas) {\n        drawable.draw(canvas);\n    }\n\n    public void update(float deltaTime, float wind) {\n        if (lastFlicker + 50 < System.currentTimeMillis()) {\n            drawable.setAlpha((int) (255 * (30f + (float) MathHelper.rand.nextInt(25)) / 100f));\n            lastFlicker = System.currentTimeMillis();\n        }\n    }\n\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/NoiseEffect.java",
    "content": "package no.agens.depth.lib.headers;\n\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapShader;\nimport android.graphics.Canvas;\nimport android.graphics.Matrix;\nimport android.graphics.Paint;\nimport android.graphics.PorterDuff;\nimport android.graphics.PorterDuffXfermode;\nimport android.graphics.Shader;\nimport android.graphics.Xfermode;\nimport no.agens.depth.lib.MathHelper;\n\npublic class NoiseEffect extends Renderable {\n\n    private final Paint paint = new Paint();\n    BitmapShader shader;\n    Matrix matrix;\n    float scale;\n\n    public NoiseEffect(Bitmap bitmap, int grainFPS, float scale) {\n        super(bitmap, 0, 0);\n        shader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);\n        matrix = new Matrix();\n\n        shader.setLocalMatrix(matrix);\n        paint.setShader(shader);\n        paint.setAlpha(144);\n        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));\n        lastGrainOffset = System.currentTimeMillis();\n        this.grainFPS = grainFPS;\n        this.scale=scale;\n    }\n\n    @Override\n    public void draw(Canvas canvas) {\n\n        canvas.drawPaint(paint);\n    }\n\n    long lastGrainOffset;\n    private int grainFPS;\n\n    @Override\n    public void update(float deltaTime, float wind) {\n        if (lastGrainOffset + grainFPS < System.currentTimeMillis()) {\n            matrix.reset();\n            matrix.setScale(scale, scale);\n            matrix.postTranslate(MathHelper.randomRange(-bitmap.getWidth() * 10f, bitmap.getWidth() * 10f), MathHelper.randomRange(-bitmap.getHeight() * 10f, bitmap.getHeight() * 10f));\n            shader.setLocalMatrix(matrix);\n            lastGrainOffset = System.currentTimeMillis();\n\n        }\n    }\n\n    private static final Xfermode[] sModes = {\n            new PorterDuffXfermode(PorterDuff.Mode.CLEAR),\n            new PorterDuffXfermode(PorterDuff.Mode.SRC),\n            new PorterDuffXfermode(PorterDuff.Mode.DST),\n            new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER),\n            new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),\n            new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),\n            new PorterDuffXfermode(PorterDuff.Mode.DST_IN),\n            new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),\n            new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),\n            new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),\n            new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),\n            new PorterDuffXfermode(PorterDuff.Mode.XOR),\n            new PorterDuffXfermode(PorterDuff.Mode.DARKEN),\n            new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),\n            new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),\n            new PorterDuffXfermode(PorterDuff.Mode.SCREEN)\n    };\n\n    public void setNoiseIntensity(float noiseIntensity) {\n        paint.setAlpha((int) (255f * noiseIntensity));\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/Particle.java",
    "content": "package no.agens.depth.lib.headers;\n\npublic class Particle extends Renderable {\n\n    float randomSpeedX;\n    float randomSpeedY;\n    public Particle(float x, float y,float randomSpeedX, float randomSpeedY) {\n        super(null, x, y );\n        this.randomSpeedX = randomSpeedX;\n        this.randomSpeedY = randomSpeedY;\n        lastRandomizeChange = System.currentTimeMillis();\n    }\n\n    long lastRandomizeChange;\n    public void setRandomSpeed( float randomSpeedX, float randomSpeedY){\n        this.randomSpeedX = randomSpeedX;\n        this.randomSpeedY = randomSpeedY;\n\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/ParticleSystem.java",
    "content": "package no.agens.depth.lib.headers;\n\nimport android.animation.ArgbEvaluator;\nimport android.animation.ValueAnimator;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport no.agens.depth.lib.MathHelper;\n\npublic class ParticleSystem extends Renderable {\n    public static final int DURATION = 10000;\n    final Paint particlePaint = new Paint();\n    long lastEmit;\n    private int emitInterWall;\n    private float gravityY;\n    private float randomXPlacement;\n    private float minYCoord;\n    private float randomMovementY;\n    int startColor;\n    int endColor;\n    private int randomMovementChangeInterval=2000;\n\n    public void setParticleSize(int particleSize) {\n        this.particleSize = particleSize;\n    }\n\n    int particleSize = 20;\n\n    public void setRandomMovementX(float randomMovement) {\n        this.randomMovementX = randomMovement;\n    }\n\n    float randomMovementX = 10;\n\n    public ParticleSystem(float x, float y, int emitInterWall, float gravityY, float randomXPlacement) {\n        super(null, x, y);\n        lastEmit = System.currentTimeMillis();\n        particlePaint.setColor(Color.RED);\n        this.emitInterWall = emitInterWall;\n        this.gravityY = gravityY;\n        this.randomXPlacement = randomXPlacement;\n    }\n\n    public void setColors(int startColor, int endColor) {\n        this.startColor = startColor;\n        this.endColor = endColor;\n        color = ValueAnimator.ofObject(new ArgbEvaluator(), startColor, endColor, Color.TRANSPARENT).setDuration(DURATION);\n    }\n\n    List<Particle> particles = new ArrayList<>();\n\n    @Override\n    public void draw(Canvas canvas) {\n\n        for (int i = 0; i < particles.size(); i++) {\n            Particle p = particles.get(i);\n            setParticlePaintColor(p);\n            canvas.drawRect(p.x, p.y, p.x + particleSize, p.y + particleSize, particlePaint);\n        }\n    }\n\n    @Override\n    public void update(float deltaTime, float wind) {\n        long currentTimeMillis = System.currentTimeMillis();\n        if (lastEmit + emitInterWall < currentTimeMillis) {\n            addParticle();\n        }\n        for (int i = 0; i < particles.size(); i++) {\n            Particle particle = particles.get(i);\n            particle.y += gravityY * deltaTime;\n            particle.y += particle.randomSpeedY * deltaTime;\n            particle.x += particle.randomSpeedX * deltaTime;\n            particle.x += wind * deltaTime;\n\n            if (particle.lastRandomizeChange + randomMovementChangeInterval < currentTimeMillis) {\n                particle.lastRandomizeChange = System.currentTimeMillis();\n                particle.setRandomSpeed(MathHelper.randomRange(-randomMovementX,randomMovementX), MathHelper.randomRange(-randomMovementY,randomMovementY));\n            }\n            if (particle.y < minYCoord) {\n                particles.remove(i);\n                i--;\n            }\n        }\n    }\n\n    private void addParticle() {\n        particles.add(new Particle(x + MathHelper.randomRange(-randomXPlacement,randomXPlacement), y, MathHelper.randomRange(-randomMovementX,randomMovementX), MathHelper.randomRange(-randomMovementY, randomMovementY)));\n        lastEmit = System.currentTimeMillis();\n    }\n\n\n\n    public void setMinYCoord(float minYCoord) {\n        this.minYCoord = minYCoord;\n    }\n\n    public void setRandomMovementY(float randomMovementY) {\n        this.randomMovementY = randomMovementY;\n    }\n\n    ValueAnimator color;\n\n    public void setParticlePaintColor(Particle particle) {\n        float currentY = y - particle.y;\n        float maxMoveDistance = y - minYCoord;\n        float travelDistanceInPercentOfMax = currentY / maxMoveDistance;\n        color.setCurrentPlayTime((long) (DURATION * travelDistanceInPercentOfMax));\n        particlePaint.setColor((Integer) color.getAnimatedValue());\n    }\n\n    public void setRandomMovementChangeInterval(int randomMovementChangeInterval) {\n        this.randomMovementChangeInterval = randomMovementChangeInterval;\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/PathBitmapMesh.java",
    "content": "package no.agens.depth.lib.headers;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.PathMeasure;\nimport android.view.animation.LinearInterpolator;\n\npublic class PathBitmapMesh {\n    public final float[] drawingVerts;\n    public final float[] staticVerts;\n    private static final int HORIZONTAL_SLICES = 6;\n    private static final int VERTICAL_SLICES = 1;\n    int horizontalSlices, verticalSlices;\n    public Bitmap bitmap;\n\n    public PathBitmapMesh(int horizontalSlices, int verticalSlices, Bitmap bitmap, int animDuration) {\n        int totalSlicesCount = (HORIZONTAL_SLICES + 1) * (VERTICAL_SLICES + 1);\n        drawingVerts = new float[totalSlicesCount * 2];\n        staticVerts = new float[totalSlicesCount * 2];\n        this.horizontalSlices = horizontalSlices;\n        this.verticalSlices = verticalSlices;\n        this.bitmap = bitmap;\n        createVerts();\n        startWaveAnim(bitmap, horizontalSlices, animDuration);\n    }\n\n    private void startWaveAnim(Bitmap bitmap, float waves, int animDuration) {\n        pathOffset = ValueAnimator.ofFloat(0, ((bitmap.getWidth() / waves) * 2f) / bitmap.getWidth()).setDuration(animDuration);\n        pathOffset.setRepeatCount(ValueAnimator.INFINITE);\n        pathOffset.setRepeatMode(ValueAnimator.RESTART);\n        pathOffset.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {\n            @Override\n            public void onAnimationUpdate(ValueAnimator animation) {\n\n                pathOffsetPercent = (float) animation.getAnimatedValue();\n            }\n        });\n        pathOffset.setInterpolator(new LinearInterpolator());\n        pathOffset.start();\n    }\n\n    public ValueAnimator pathOffset;\n\n    public void destroy() {\n        pathOffset.cancel();\n        if (bitmap != null && !bitmap.isRecycled()) {\n            bitmap.recycle();\n            bitmap = null;\n        }\n    }\n\n    public void setAlpha(int alpha) {\n        paint.setAlpha(alpha);\n    }\n\n    private void createVerts() {\n\n        float xDimension = (float) bitmap.getWidth();\n        float yDimension = (float) bitmap.getHeight();\n\n        int index = 0;\n\n        for (int y = 0; y <= VERTICAL_SLICES; y++) {\n            float fy = yDimension * y / VERTICAL_SLICES;\n            for (int x = 0; x <= HORIZONTAL_SLICES; x++) {\n                float fx = xDimension * x / HORIZONTAL_SLICES;\n                setXY(drawingVerts, index, fx, fy);\n                setXY(staticVerts, index, fx, fy);\n                index += 1;\n            }\n        }\n    }\n\n    Paint paint = new Paint();\n\n\n    public void setXY(float[] array, int index, float x, float y) {\n        array[index * 2 + 0] = x;\n        array[index * 2 + 1] = y;\n    }\n\n    public void matchVertsToPath(Path path, float bottomCoord, float extraOffset) {\n        PathMeasure pm = new PathMeasure(path, false);\n\n        for (int i = 0; i < staticVerts.length / 2; i++) {\n\n            float yIndexValue = staticVerts[i * 2 + 1];\n            float xIndexValue = staticVerts[i * 2];\n\n\n            float percentOffsetX = (0.000001f + xIndexValue) / bitmap.getWidth();\n            float percentOffsetX2 = (0.000001f + xIndexValue) / (bitmap.getWidth() + extraOffset);\n            percentOffsetX2 += pathOffsetPercent;\n            pm.getPosTan(pm.getLength() * (1f - percentOffsetX), coords, null);\n            pm.getPosTan(pm.getLength() * (1f - percentOffsetX2), coords2, null);\n\n            if (yIndexValue == 0) {\n                setXY(drawingVerts, i, coords[0], coords2[1]);\n            } else {\n                setXY(drawingVerts, i, coords[0], bottomCoord);\n\n            }\n        }\n    }\n\n    public Bitmap getBitmap() {\n        return bitmap;\n    }\n\n\n    public float[] coords = new float[2];\n    public float[] coords2 = new float[2];\n    public float pathOffsetPercent = 1;\n\n    public void draw(Canvas canvas) {\n        canvas.drawBitmapMesh(bitmap, HORIZONTAL_SLICES, VERTICAL_SLICES, drawingVerts, 0, null, 0, paint);\n    }\n\n    public void pause() {\n        pathOffset.pause();\n    }\n\n    public void resume() {\n        pathOffset.resume();\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/headers/Renderable.java",
    "content": "package no.agens.depth.lib.headers;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.RectF;\n\n/**\n * Created by danielzeller on 01.10.14.\n */\npublic class Renderable {\n    public float x;\n\n    public void setY(float y) {\n        this.y = y;\n    }\n\n    public float y;\n\n    public float translationY;\n    public float translationX;\n    public Bitmap bitmap;\n\n    public float scaleX = 1f;\n    public float scaleY = 1f;\n\n    public Renderable(Bitmap bitmap, float x, float y) {\n        this.x = x;\n        this.y = y;\n        this.bitmap = bitmap;\n    }\n\n    public void draw(Canvas canvas) {\n        canvas.save();\n        canvas.drawBitmap(bitmap, x + translationX / 2, y + translationY, null);\n        canvas.restore();\n    }\n\n    public void drawStretched(Canvas canvas, float parentWidth) {\n        canvas.save();\n        canvas.drawBitmap(bitmap, null, new RectF(x + translationX / 2, y + translationY, x + translationX / 2 + parentWidth, y + translationY + bitmap.getHeight()), null);\n        canvas.restore();\n    }\n\n    public void setTranslationY(Float translationY) {\n        this.translationY = translationY;\n    }\n\n    public float getTranslationY() {\n        return translationY;\n    }\n\n    public void setTranslationY(float translationY) {\n        this.translationY = translationY;\n    }\n\n    public float getTranslationX() {\n        return translationX;\n    }\n\n    public void setTranslationX(float translationX) {\n        this.translationX = translationX;\n    }\n\n    public void setScale(float scale, float scale1) {\n\n    }\n\n    public void update(float deltaTime, float wind) {\n\n    }\n\n    public void destroy() {\n        if (bitmap != null && !bitmap.isRecycled()) {\n            bitmap.recycle();\n            bitmap = null;\n        }\n    }\n\n    public void pause() {\n\n    }\n\n    public void resume() {\n\n    }\n}\n\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/FrameRateCounter.java",
    "content": "package no.agens.depth.lib.tween;\n\nimport android.os.SystemClock;\n\n/**\n * Created by danielzeller on 26.03.14.\n*/\n\npublic class FrameRateCounter {\n    private static long mLastTime;\n\n    public static float timeStep() {\n        final long time = SystemClock.uptimeMillis();\n        final long timeDelta = time - mLastTime;\n        float timeDeltaSeconds = mLastTime > 0.0f ? timeDelta / 1000.0f : 0.0f;\n        mLastTime = time;\n        return Math.min(0.021f, timeDeltaSeconds);\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/TRectFEvaluator.java",
    "content": "package no.agens.depth.lib.tween;\n\nimport android.animation.TypeEvaluator;\nimport android.graphics.RectF;\n\n/**\n * Created by danielzeller on 19.08.14.\n */\npublic class TRectFEvaluator implements TypeEvaluator<RectF> {\n\n    /**\n     * This function returns the result of linearly interpolating the start and\n     * end Rect values, with <code>fraction</code> representing the proportion\n     * between the start and end values. The calculation is a simple parametric\n     * calculation on each of the separate components in the Rect objects\n     * (left, top, right, and bottom).\n     *\n     * @param fraction   The fraction from the starting to the ending values\n     * @param startValue The start Rect\n     * @param endValue   The end Rect\n     * @return A linear interpolation between the start and end values, given the\n     * <code>fraction</code> parameter.\n     */\n    @Override\n    public RectF evaluate(float fraction, RectF startValue, RectF endValue) {\n\n        return new RectF(startValue.left + (int) ((endValue.left - startValue.left) * fraction),\n                startValue.top + (int) ((endValue.top - startValue.top) * fraction),\n                startValue.right + (int) ((endValue.right - startValue.right) * fraction),\n                startValue.bottom + (int) ((endValue.bottom - startValue.bottom) * fraction));\n    }\n\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/BackIn.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class BackIn implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        float s = param_s;\n        return t*t*((s+1)*t - s);\n    }\n    private float param_s = 1.70158f;\n\n    public BackIn amount(float s) {\n        param_s = s;\n        return this;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/BackInOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class BackInOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        float s = param_s;\n        if ((t*=2) < 1) return 0.5f*(t*t*(((s*=(1.525f))+1)*t - s));\n        return 0.5f*((t-=2)*t*(((s*=(1.525f))+1)*t + s) + 2);\n    }\n    private float param_s = 1.70158f;\n\n    public BackInOut amount(float s) {\n        param_s = s;\n        return this;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/BackOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class BackOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        float s = param_s;\n        return (t-=1)*t*((s+1)*t + s) + 1;\n    }\n    private float param_s = 1.70158f;\n\n    public BackOut amount(float s) {\n        param_s = s;\n        return this;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/CircIn.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 14.04.15.\n */\nclass CircIn implements TimeInterpolator {\n\n    @Override\n    public float getInterpolation(float t) {\n        return  (float)Math.sqrt(1f - t*t);\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/CircInOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 14.04.15.\n */\npublic class CircInOut implements TimeInterpolator {\n\n    @Override\n    public float getInterpolation(float t) {\n        if ((t*=2) < 1) return -0.5f * ((float)Math.sqrt(1 - t*t) - 1);\n        return 0.5f* ((float)Math.sqrt(1 - (t-=2)*t) + 1);\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/CircOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 14.04.15.\n */\nclass CircOut implements TimeInterpolator {\n\n    @Override\n    public float getInterpolation(float t) {\n\n        return   ((float)Math.sqrt(1f - (t-1f)*t) + 1f);\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ElasticIn.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class ElasticIn implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        float a = param_a;\n        float p = param_p;\n        if (t==0) return 0;  if (t==1) return 1; if (!setP) p=.3f;\n        float s;\n        if (!setA || a < 1) { a=1; s=p/4f; }\n        else s = p/(2f*(float)Math.PI) * (float)Math.asin(1/a);\n        return -(a*(float)Math.pow(2,10*(t-=1)) * (float)Math.sin( (t-s)*(2*Math.PI)/p ));\n    }\n    protected float param_a;\n    protected float param_p;\n    protected boolean setA = false;\n    protected boolean setP = false;\n\n    public ElasticIn a(float a) {\n        param_a = a;\n        this.setA = true;\n        return this;\n    }\n\n    public ElasticIn p(float p) {\n        param_p = p;\n        this.setP = true;\n        return this;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ElasticInOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class ElasticInOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        float a = param_a;\n        float p = param_p;\n        if (t==0) return 0;  if ((t*=2)==2) return 1; if (!setP) p=.3f*1.5f;\n        float s;\n        if (!setA || a < 1) { a=1; s=p/4; }\n        else s = p/(2*(float)Math.PI) * (float)Math.asin(1/a);\n        if (t < 1) return -.5f*(a*(float)Math.pow(2,10*(t-=1)) * (float)Math.sin( (t-s)*(2*(float)Math.PI)/p ));\n        return a*(float)Math.pow(2,-10*(t-=1)) * (float)Math.sin( (t-s)*(2*(float)Math.PI)/p )*.5f + 1;\n    }\n    protected float param_a;\n    protected float param_p;\n    protected boolean setA = false;\n    protected boolean setP = false;\n\n    public ElasticInOut a(float a) {\n        param_a = a;\n        this.setA = true;\n        return this;\n    }\n\n    public ElasticInOut p(float p) {\n        param_p = p;\n        this.setP = true;\n        return this;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ElasticOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class ElasticOut implements TimeInterpolator {\n\n    protected float param_a;\n    protected float param_p;\n    protected boolean setA = false;\n    protected boolean setP = false;\n\n\n    @Override\n    public float getInterpolation(float t) {\n        float a = param_a;\n        float p = param_p;\n        if (t==0) return 0;  if (t==1) return 1; if (!setP) p=.3f;\n        float s;\n        if (!setA || a < 1) { a=1; s=p/4; }\n        else s = p/(2*(float)Math.PI) * (float)Math.asin(1/a);\n        return a*(float)Math.pow(2,-10*t) * (float)Math.sin( (t-s)*(2*Math.PI)/p ) + 1;\n    }\n\n    public ElasticOut a(float a) {\n        param_a = a;\n        this.setA = true;\n        return this;\n    }\n\n    public ElasticOut p(float p) {\n        param_p = p;\n        this.setP = true;\n        return this;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ExpoIn.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class ExpoIn implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return (t==0) ? 0 : (float) Math.pow(2, 10 * (t - 1));\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ExpoInOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class ExpoInOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        if (t==0) return 0;\n        if (t==1) return 1;\n        if ((t*=2) < 1) return 0.5f * (float) Math.pow(2, 10 * (t - 1));\n        return 0.5f * (-(float)Math.pow(2, -10 * --t) + 2);\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/ExpoOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class ExpoOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return (t==1) ? 1 : -(float) Math.pow(2, -10 * t) + 1;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuadIn.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class QuadIn implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return t*t;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuadInOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class QuadInOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        if ((t*=2) < 1) return 0.5f*t*t;\n        return -0.5f * ((--t)*(t-2) - 1);\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuadOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class QuadOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return -t*(t-2);\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuartIn.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class QuartIn implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return t*t*t*t;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuartInOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class QuartInOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        if ((t*=2) < 1) return 0.5f*t*t*t*t;\n        return -0.5f * ((t-=2)*t*t*t - 2);\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuartOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class QuartOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return -((t-=1)*t*t*t - 1);\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuintIn.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 30.05.14.\n */\npublic class QuintIn implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return t*t*t*t*t;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuintInOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 29.05.14.\n */\npublic class QuintInOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        if ((t*=2) < 1) return 0.5f*t*t*t*t*t;\n        return 0.5f*((t-=2)*t*t*t*t + 2);\n    }\n}\n"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/QuintOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class QuintOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return (t-=1)*t*t*t*t + 1;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/SineIn.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class SineIn implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return (float) -Math.cos(t * (Math.PI/2)) + 1;\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/SineInOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class SineInOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return -0.5f * ((float) Math.cos(Math.PI*t) - 1);\n    }\n}"
  },
  {
    "path": "lib/src/main/java/no/agens/depth/lib/tween/interpolators/SineOut.java",
    "content": "package no.agens.depth.lib.tween.interpolators;\n\nimport android.animation.TimeInterpolator;\n\n/**\n * Created by danielzeller on 09.04.15.\n */\npublic class SineOut implements TimeInterpolator {\n    @Override\n    public float getInterpolation(float t) {\n        return (float) Math.sin(t * (Math.PI/2));\n    }\n}"
  },
  {
    "path": "lib/src/main/res/values/dept_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <declare-styleable name=\"DepthView\">\n\n        <attr name=\"is_circle\" format=\"boolean\"/>\n\n        <attr name=\"edge_color\" format=\"color\"/>\n        <attr name=\"depth\" format=\"dimension\"/>\n        <attr name=\"custom_elevation\" format=\"dimension\"/>\n    </declare-styleable>\n\n</resources>\n"
  },
  {
    "path": "lib/src/main/res/values/values.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"cardview_shadow_end_color\">#03000000</color>\n    <color name=\"cardview_shadow_start_color\">#47000000</color>\n    <dimen name=\"cardview_compat_inset_shadow\">1dp</dimen>\n</resources>"
  },
  {
    "path": "lib/src/test/java/no/agens/depth/ExampleUnitTest.java",
    "content": "package no.agens.depth;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * To work on unit tests, switch the Test Artifact in the Build Variants view.\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "settings.gradle",
    "content": "include ':app', ':lib'\n"
  }
]