Giter VIP home page Giter VIP logo

toolargetool's Introduction

toolargetool

A tool for debugging TransactionTooLargeException on Android.

"Most underrated solution." - Kedar Paranjape, Jun 7 '18 at 14:26

Usage

  1. Include toolargetool as a dependency (you can remove it again once you've debugged your crash):

    • toolargetool is available from mavenCentral()

    • Add implementation 'com.gu.android:toolargetool:0.3.0' in your module's build.gradle:

      dependencies {
          ...
          implementation 'com.gu.android:toolargetool:0.3.0'
      }
      
  2. Import The package

    import com.gu.toolargetool.TooLargeTool;
    
  3. Add code to start logging during app start, for example in your Application.onCreate method:

    TooLargeTool.startLogging(this);
    
  4. Monitor logcat output to see which components are writing substantial data to the transaction buffer and when:

    $ adb logcat -s TooLargeTool
    

    Example logcat output (TODO: improve this example):

    D/TooLargeTool: MainActivity.onSaveInstanceState wrote: Bundle@200090398 contains 1 keys and measures 0.6 KB when serialized as a Parcel
                                                                            * android:viewHierarchyState = 0.6 KB
    

Release process

Note: these instructions will only work if you have the required credentials for publishing to the com.gu Sonatype repository.

  1. Increase all the version number in toolargetool/build.gradle
  2. Make a commit and tag it with git tag -a v<version number> -m "<message>".
  3. Run ./gradlew publishReleasePublicationToSnapshotRepository.

toolargetool's People

Contributors

ab-gnm avatar enochhankombo92 avatar friedenberg avatar iamrare avatar jdtremblay avatar jehartzog avatar kenoir avatar kisty avatar maxspencer avatar michaelclapham avatar sebaslogen avatar usilitel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

toolargetool's Issues

logBundleBreakdown should show additional logs?

I'm calling logBundleBreakDown before calling startActivity

But log only shows


10-12 19:17:10.376 13893 13893 D TooLargeTool: ReviewMetaActivity.onSaveInstanceState wrote: Bundle@6242526 contains 2 keys and measures 38.9 KB when serialized as a Parcel
10-12 19:17:10.376 13893 13893 D TooLargeTool: * android:viewHierarchyState = 38.7 KB
10-12 19:17:10.376 13893 13893 D TooLargeTool: * com.google.firebase.analytics.screen_service = 0.2 KB

Is there something I'm missing?

causes static method cannot be referenced from a non static context

causes non static method 'startLogging(android.app.Application) cannot be referenced from a static context

I have a class which extends Application when I tried to use TooLargeTool.startLogging(this); in oncreate method it causes non static method 'startLogging(android.app.Application) cannot be referenced from a static context

even when i tried to use it in Mainactivity which extends activity in oncreate method it caused same error

pelase can you proivde a proper soultion and an example app as early as possible

ps: I am using Androidx, could this be causing some issues

集成时,报错崩溃

在Application中初始化以下代码时,直接报以下错误崩溃
TooLargeTool.startLogging(this);

log崩溃日志:

Process: com.nacai.bocai, PID: 20013
java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/fragment/app/FragmentManager$FragmentLifecycleCallbacks;
at com.gu.toolargetool.TooLargeTool.startLogging(TooLargeTool.kt:96)
at com.gu.toolargetool.TooLargeTool.startLogging(TooLargeTool.kt:90)
at com.gu.toolargetool.TooLargeTool.startLogging$default(TooLargeTool.kt:89)
at com.gu.toolargetool.TooLargeTool.startLogging(Unknown Source:3)

App crashes while calling startLogging

sdk 25, google pixel

Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.app.FragmentManager$FragmentLifecycleCallbacks" on path: DexPathList[[zip file "/data/app/com.testapp.dev-1/base.apk"],nativeLibraryDirectories=[/data/app/com.testapp.dev-1/lib/arm64, /system/lib64, /vendor/lib64]] 04-19 12:35:07.060 20080-20080/? I/art: at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:56) 04-19 12:35:07.060 20080-20080/? I/art: at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:380) 04-19 12:35:07.061 20080-20080/? I/art: at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312) 04-19 12:35:07.061 20080-20080/? I/art: at void com.gu.toolargetool.TooLargeTool.startLogging(android.app.Application, int, java.lang.String) (TooLargeTool.java:155) 04-19 12:35:07.061 20080-20080/? I/art: at void com.gu.toolargetool.TooLargeTool.startLogging(android.app.Application) (TooLargeTool.java:144) 04-19 12:35:07.061 20080-20080/? I/art: at void com.testapp.app.App.onCreate() (App.java:51) 04-19 12:35:07.061 20080-20080/? I/art: at void android.app.Instrumentation.callApplicationOnCreate(android.app.Application) (Instrumentation.java:1024) 04-19 12:35:07.061 20080-20080/? I/art: at void android.app.ActivityThread.handleBindApplication(android.app.ActivityThread$AppBindData) (ActivityThread.java:5405) 04-19 12:35:07.061 20080-20080/? I/art: at void android.app.ActivityThread.-wrap2(android.app.ActivityThread, android.app.ActivityThread$AppBindData) (ActivityThread.java:-1) 04-19 12:35:07.061 20080-20080/? I/art: at void android.app.ActivityThread$H.handleMessage(android.os.Message) (ActivityThread.java:1546) 04-19 12:35:07.061 20080-20080/? I/art: at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:102) 04-19 12:35:07.061 20080-20080/? I/art: at void android.os.Looper.loop() (Looper.java:154) 04-19 12:35:07.061 20080-20080/? I/art: at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6121) 04-19 12:35:07.061 20080-20080/? I/art: at java.lang.Object java.lang.reflect.Method.invoke!(java.lang.Object, java.lang.Object[]) (Method.java:-2) 04-19 12:35:07.061 20080-20080/? I/art: at void com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run() (ZygoteInit.java:889) 04-19 12:35:07.061 20080-20080/? I/art: at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:779) 04-19 12:35:07.061 20080-20080/? D/AndroidRuntime: Shutting down VM 04-19 12:35:07.061 20080-20080/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.testapp.dev, PID: 20080 java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/app/FragmentManager$FragmentLifecycleCallbacks; at com.gu.toolargetool.TooLargeTool.startLogging(TooLargeTool.java:155) at com.gu.toolargetool.TooLargeTool.startLogging(TooLargeTool.java:144) at com.testapp.app.App.onCreate(App.java:51) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1024) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5405) at android.app.ActivityThread.-wrap2(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1546) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6121) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.app.FragmentManager$FragmentLifecycleCallbacks" on path: DexPathList[[zip file "/data/app/com.testapp.dev-1/base.apk"],nativeLibraryDirectories=[/data/app/com.testapp.dev-1/lib/arm64, /system/lib64, /vendor/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:380) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at com.gu.toolargetool.TooLargeTool.startLogging(TooLargeTool.java:155)  at com.gu.toolargetool.TooLargeTool.startLogging(TooLargeTool.java:144)  at com.testapp.app.App.onCreate(App.java:51)  at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1024)  at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5405)  at android.app.ActivityThread.-wrap2(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1546)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:154)  at android.app.ActivityThread.main(ActivityThread.java:6121)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) 

Library doesn't support JAVA only application?

I came across your library while searching for a solution for Transaction Too Large exception, I added the library as a dependency and added the starlogging method in application class but now the app refuses to open and crashes on each run saying:

java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics; at com.gu.toolargetool.TooLargeTool.startLogging(Unknown Source:2) at com.gu.toolargetool.TooLargeTool.startLogging$default(TooLargeTool.kt:89) at com.gu.toolargetool.TooLargeTool.startLogging(Unknown Source:3) at com.mytheresa.app.mytheresa.app.MythApplication.onCreate(MythApplication.java:80) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1122) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6517) at android.app.ActivityThread.-wrap2(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1963) at android.os.Handler.dispatchMessage(Handler.java:108) at android.os.Looper.loop(Looper.java:166) at android.app.ActivityThread.main(ActivityThread.java:7425) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) Caused by: java.lang.ClassNotFoundException: Didn't find class "kotlin.jvm.internal.Intrinsics" on path: DexPathList[[zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/base.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_dependencies_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_resources_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_slice_0_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_slice_1_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_slice_2_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_slice_3_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_slice_4_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_slice_5_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_slice_6_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_slice_7_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_slice_8_apk.apk", zip file "/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/lib/arm64, /system/lib64, /vendor/lib64, /product/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at com.gu.toolargetool.TooLargeTool.startLogging(Unknown Source:2)  at com.gu.toolargetool.TooLargeTool.startLogging$default(TooLargeTool.kt:89)  at com.gu.toolargetool.TooLargeTool.startLogging(Unknown Source:3)  at com.mytheresa.app.mytheresa.app.MythApplication.onCreate(MythApplication.java:80)  at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1122)  at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6517)  at android.app.ActivityThread.-wrap2(Unknown Source:0)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1963)  at android.os.Handler.dispatchMessage(Handler.java:108)  at android.os.Looper.loop(Looper.java:166)  at android.app.ActivityThread.main(ActivityThread.java:7425)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)  Suppressed: java.io.IOException: No original dex files found for dex location /data/app/com.mytheresa.app.mytheresa.debug-uMfWxQLpaIfjBZ034cV8YA==/split_lib_resources_apk.apk at dalvik.system.DexFile.openDexFileNative(Native Method) at dalvik.system.DexFile.openDexFile(DexFile.java:353) at dalvik.system.DexFile.<init>(DexFile.java:100) at dalvik.system.DexFile.<init>(DexFile.java:74) at dalvik.system.DexPathList.loadDexFile(DexPathList.java:374) at dalvik.system.DexPathList.makeDexElements(DexPathList.java:337) at dalvik.system.DexPathList.<init>(DexPathList.java:157) at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:65) at dalvik.system.PathClassLoader.<init>(PathClassLoader.java:64) at com.android.internal.os.PathClassLoaderFactory.createClassLoader(PathClassLoaderFactory.java:43) at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:75) at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:38) 2019-07-11 13:25:39.232 16997-16997/com.mytheresa.app.mytheresa.debug E/AndroidRuntime: at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:716) at android.app.LoadedApk.getClassLoader(LoadedApk.java:749) at android.app.LoadedApk.getResources(LoadedApk.java:996) at android.app.ContextImpl.createAppContext(ContextImpl.java:2489) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6398)

Any suggestions? Must I add configuration for Kotlin inside the project in order to be able to use the library? Thanks in advance.

Strange specification of "allowBackup" and "supportsRtl"

The library into toolargetool/toolargetool/src/main/AndroidManifest.xml has

android:allowBackup="true"
android:supportsRtl="true"

into <application> tag. Why are they here? Could you remove them? It's necessary to use tools:replace="android:allowBackup,android:supportsRtl" in my AndroidManifest.

Logs aren't displaying

No Logs are displaying for me in the given format

D/TooLargeTool: MainActivity.onSaveInstanceState wrote: Bundle@200090398 contains 1 keys and measures 0.6 KB when serialized as a Parcel
                                                                        * android:viewHierarchyState = 0.6 KB

Does this ONLY work for devices on 7.0? or is it 7.0+ . Are there steps to troubleshoot this?

Using old com.gu package name

I will move everything to com.theguardian.toolargetool at some point, but this will break imports so I might leave it for version 1.0.

logBundleBreakDown should show additional logs?

I'm calling logBundleBreakDown before calling startActivity

      Intent i = new Intent(activity, ReviewMetaActivity.class);
      i.putExtra(ReviewMetaActivity.ARG_FULL_PATH, fullPath);
      i.putExtra(ReviewMetaActivity.REVIEW_META_ID, review_meta_id);
      i.putExtra(ReviewMetaActivity.REVIEW_THREAD_ID, review_thread_id);
      i.putExtra(ReviewMetaActivity.REVIEW_META_JSONSTRING, review_meta_jsonstring);

      TooLargeTool.logBundleBreakdown("review-meta", i.getExtras());
      activity.startActivity(i);

But log only shows


10-12 19:17:10.376 13893 13893 D TooLargeTool: ReviewMetaActivity.onSaveInstanceState wrote: Bundle@6242526 contains 2 keys and measures 38.9 KB when serialized as a Parcel
10-12 19:17:10.376 13893 13893 D TooLargeTool: * android:viewHierarchyState = 38.7 KB
10-12 19:17:10.376 13893 13893 D TooLargeTool: * com.google.firebase.analytics.screen_service = 0.2 KB

Is there something I'm missing?

Sample application

Create a sample application which demonstrates how TooLargeTool is used and which provides some sample output.

Started work on the add-sample branch.

Getting crash java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2750)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2811)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6316)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter savedInstanceState
at com.gu.toolargetool.ActivitySavedStateLogger.onActivityCreated(ActivitySavedStateLogger.kt)
at android.app.Application.dispatchActivityCreated(Application.java:197)

Drill into viewHierarchyState

This library is great!

10-11 11:53:13.179 D/TooLargeTool(21791): MainActivity.onSaveInstanceState wrote: Bundle@161550193 contains 7 keys and measures 821.2 KB when serialized as a Parcel
10-11 11:53:13.179 D/TooLargeTool(21791): * android:sessionId = 0.1 KB
10-11 11:53:13.179 D/TooLargeTool(21791): * com.google.app_measurement.screen_service = 0.2 KB
10-11 11:53:13.179 D/TooLargeTool(21791): * map_state = 0.2 KB
10-11 11:53:13.179 D/TooLargeTool(21791): * android:fragments = 0.8 KB
10-11 11:53:13.179 D/TooLargeTool(21791): * @android:autofillResetNeeded = 0.1 KB
10-11 11:53:13.179 D/TooLargeTool(21791): * android:lastAutofillId = 0.1 KB
10-11 11:53:13.179 D/TooLargeTool(21791): * android:viewHierarchyState = 819.7 KB

I'd like to figure out what part of the viewHierarchyState is taking up so much room. Any thoughts on how to best allow drilling-down in a situation like this? I could specify keys that I want to be drilled-down into when I call TooLargeTool.startLogging(this)? Or we could automatically drill down into the keys above a certain size? Happy to put together a PR if you give me some guidance on what approach(es) you'd be ok with.

no logcat output

Somehow, no logcat output like
D/TooLargeTool: MainActivity.onSaveInstanceState wrote: Bundle@200090398 contains 1 keys and measures 0.6 KB when serialized as a Parcel * android:viewHierarchyState = 0.6 KB

is being shown in my app after adding the toolargetool as described in the readme.

I even added this code to my app:
Intent intent = new Intent(this, ActivityB.class); intent.putExtra("bytes", new byte[1000 * 1000]); startActivity(intent);

to make the app throw the TransactionTooLargeException. The Exception is indeed being thrown, but no TooLargeTool output to be found.

valueSizes broken when value is a Bitmap

If you call TooLargeTool.valueSizes with a Bundle containing a Bitmap (or possibly other Parcelable values), then copy contains all the same keys, but is much smaller (i.e. sizeAsParcel returns a much smaller value) than the original bundle. This causes the results of valueSizes to be wrong.

App close information gathering

Hello! This looks awesome/helpful/interesting, thanks!

Upon app close, when saving state, it is bringing up the "App has crashed" error dialog for me. In this thread a target app developer took a video and posted a similar issue. Does this tool help debug those things too?

Note: I'd expect that a lot of Bundle serializing boosts parcel size, but doesn't crash til app close. Does this tool work until app close..?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.