GithubHelp home page GithubHelp logo

yasirkula / unityingamedebugconsole Goto Github PK

View Code? Open in Web Editor NEW
2.0K 2.0K 216.0 6.5 MB

A uGUI based console to see debug messages and execute commands during gameplay in Unity

License: MIT License

C# 98.94% Objective-C++ 0.08% JavaScript 0.98%

unityingamedebugconsole's People

Contributors

brogan89 avatar emredesu avatar ericbatlle avatar jeffgoku avatar jespersmith avatar tonygiang avatar yasirkula 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unityingamedebugconsole's Issues

Cosmetic issues

So when you click on a log to expand it the LogText moves up slightly in height position by around 1px, just a bit annoying, because you notice the first text line is the same just moving upwards when the lines below are revealed, seems to be bit of a harder issue to fix in code, than the my other minor niggle which I've fixed myself in the DebuglogItem prefab with the LogType anchor position that gets moved to the middle on expansion, instead of just remaining at the top in the same position on log item expansion.

Possible Filtering Logs?

Hi, Where should I start looking to prevent some logs of being displayed?
Like filtering them...

Input issue?

Just wondering what the solution is to this...
Active input handling is set to 'both'
2021.1.0b5
is there some compiler directive I can add to sort it out?

NotSupportedException: The invoked member is not supported in a dynamic module. System.Reflection.Emit.AssemblyBuilder.GetExportedTypes () (at <b54c5f8cbd8a46c6b18a2b3ef785ad6d>:0) IngameDebugConsole.DebugLogConsole..cctor () (at Library/PackageCache/[email protected]/Plugins/IngameDebugConsole/Scripts/DebugLogConsole.cs:160) Rethrow as TypeInitializationException: The type initializer for 'IngameDebugConsole.DebugLogConsole' threw an exception. IngameDebugConsole.DebugLogManager.OnEnable () (at Library/PackageCache/[email protected]/Plugins/IngameDebugConsole/Scripts/DebugLogManager.cs:403)

NotSupportedException: The invoked member is not supported in a dynamic module. System.Reflection.Emit.AssemblyBuilder.GetExportedTypes () (at <b54c5f8cbd8a46c6b18a2b3ef785ad6d>:0) IngameDebugConsole.DebugLogConsole..cctor () (at Library/PackageCache/[email protected]/Plugins/IngameDebugConsole/Scripts/DebugLogConsole.cs:160) Rethrow as TypeInitializationException: The type initializer for 'IngameDebugConsole.DebugLogConsole' threw an exception. IngameDebugConsole.DebugLogManager.RefreshCommandSuggestions (System.String command) (at Library/PackageCache/[email protected]/Plugins/IngameDebugConsole/Scripts/DebugLogManager.cs:960) UnityEngine.Events.InvokableCall1[T1].Invoke (T1 args0) (at :0)
UnityEngine.Events.UnityEvent1[T0].Invoke (T0 arg0) (at <a3210ac464a241f0914b2746575c0be2>:0) UnityEngine.UI.InputField.SendOnValueChanged () (at Library/PackageCache/[email protected]/Runtime/UI/Core/InputField.cs:2276) UnityEngine.UI.InputField.Insert (System.Char c) (at Library/PackageCache/[email protected]/Runtime/UI/Core/InputField.cs:2253) UnityEngine.UI.InputField.Append (System.Char input) (at Library/PackageCache/[email protected]/Runtime/UI/Core/InputField.cs:2368) UnityEngine.UI.InputField.KeyPressed (UnityEngine.Event evt) (at Library/PackageCache/[email protected]/Runtime/UI/Core/InputField.cs:1882) UnityEngine.UI.InputField.OnUpdateSelected (UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/[email protected]/Runtime/UI/Core/InputField.cs:1936) UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IUpdateSelectedHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/[email protected]/Runtime/EventSystem/ExecuteEvents.cs:106) UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction1[T1] functor) (at Library/PackageCache/[email protected]/Runtime/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/[email protected]/Runtime/EventSystem/EventSystem.cs:501)
`

Null Ref with enableSearchbar = false

Description of the bug

In DebugLogManager when enableSeachbar= false there is a null reference.

Its due to

if (!enableSearchbar) { //This is set to null. searchbar = null; searchbarSlotTop.gameObject.SetActive(false); searchbarSlotBottom.gameObject.SetActive(false); }

a few lines later

searchbar.GetComponent<InputField>().onValueChanged.AddListener(SearchTermChanged);

is then null as you cleared the reference.

Option to disable DebugLogPopup and open DebugLogWindow on button press

Your asset is really cool, thank you for that.
But could you add an option to disable DebugLogPopup. Right now it's only possible to Start in Popup Mode, or in Window Mode, but no option to Disable Popup completely.
Currently I'm doing it this way:

  • Deactivating DebugLogPopup
  • Removing DebugLogManager#popupManager, adding ?. to popupManager calls, e.g. popupManager?.OnPointerClick( null );
  • Making DebugLogManager#isLogWindowVisible public
  • Adding following code to some MonoBehaviour#Update with debugManager:
if (Input.GetKeyDown(KeyCode.F4)) {
  if (!debugManager.isLogWindowVisible) {
    debugManager.Show();
  } else {
    debugManager.Hide();
  }
}

Of course KeyCode for opening/closing window should be in options too to be able to modify it.

[Suggestion] Change scripts accessibility levels

Suggestion

I installed the console through OpenUPM, it works super well ! Congrats

For my project, I need to make some small changes. I can't directly change the DebugLogManager script as files in a package are read only.

What would be great would be to let people inherit from scripts, so they can adapt the code without directly modifying the package.

Changes that would be welcoming:

  • Change accessibility levels of fields and methods from private to protected
  • Tag methods as virtual

Large amount of warnings

Hi, I really like this plugin and have been using it for a while in my project, thanks for making it available for free.

Recently I noticed that it was spamming my console with a bunch of warnings. These warnings are harmless and appear to be a result of using private fields but it would be nice to avoid them.

There are a total of 42 warnings, here is one of them:

Field 'DebugLogPopup.debugManager' is never assigned to, and will always have its default value null

From some quick searching online I found a workaround where you give the private fields a default value (like null for example). This removes the warning but I'm not sure if it causes any issues with the plugin. Could you please investigate this?

IsOpen property

Hi, is there something like a IsOpen property? I need to know if the console is open or not to disable game input.

[Feedback] IngameDebugConsole.aar require READ_LOGS permission by default

Hi, thank you for your useful assets.

I used this assets in my project, and noticed IngameDebugConsole.aar require READ_LOGS permission which is not recommended for user privacy reason.

Google says in Android API reference as bellow;

Not for use by third-party applications, because Log entries can contain the user's private information.

So I removed IngameDebugConsole.aar by setting Android checkbox off in import settings.

I would like to recommend you that adding remark about permission in README, or making IngameDebugConsole available without READ_LOGS permission by default because it is easy to overlook to remove permission in release build.

Textmesh vertex limit

I've run into an issue with this asset multiple times where my log is too large and the text in the in-game console doesn't get rendered and throws max vertices limit errors. The editor properly truncates the message, while this asset does not. I was able to hack together an easy solution but I wanted to let you know about it.

My solution:
At about line 506 I put in this line:
if(logString.Length >= maxLogLength) logString = logString.Remove(maxLogLength - stackTrace.Length) + "<Truncated>"; // Cut off log at a given limit minus the stacktrace length

When you press tab for fill up suggestion. In some cases there is an exception

Description of the bug

A clear and concise description of what the bug is. Before reporting a bug, please do a quick search in Issues to see if it is already reported. If the documentation has a FAQ (Frequently Asked Questions), please also check out the entries there.

Reproduction steps

Start to enter text , for example "w" or "u" then pres "tab".
Not always but some times you will have exception

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
System.Collections.Generic.List1[T].get_Item (System.Int32 index) (at <00c558282d074245ab3496e2d108079b>:0) IngameDebugConsole.DebugLogConsole.GetAutoCompleteCommand (System.String commandStart) (at Assets/Libs/IngameConsole/Scripts/DebugLogConsole.cs:599) IngameDebugConsole.DebugLogManager.OnValidateCommand (System.String text, System.Int32 charIndex, System.Char addedChar) (at Assets/Libs/IngameConsole/Scripts/DebugLogManager.cs:852) UnityEngine.UI.InputField.Append (System.Char input) (at Library/PackageCache/[email protected]/Runtime/UI/Core/InputField.cs:2399) UnityEngine.UI.InputField.KeyPressed (UnityEngine.Event evt) (at Library/PackageCache/[email protected]/Runtime/UI/Core/InputField.cs:1922) UnityEngine.UI.InputField.OnUpdateSelected (UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/[email protected]/Runtime/UI/Core/InputField.cs:1976) UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IUpdateSelectedHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/[email protected]/Runtime/EventSystem/ExecuteEvents.cs:106) UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction1[T1] functor) (at Library/PackageCache/[email protected]/Runtime/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/[email protected]/Runtime/EventSystem/EventSystem.cs:501)

problem happens here:
// Find command's index in the list of registered commands using binary search
private static int FindCommandIndex( string command )

Logs inside a catch

Hey! I just realiced this asset is not showing me logs inside the try&catch. I am not sure why. Is there any solution to this?

Start hidden

Your console is a great debugging tool! It would be great if there was a simple option to start hidden or an alternative prefab to use in this manner.

"Hidden" F12 mode

Currently (as I understand it), the console must be visible in order for logs to be collected. I would love to have a built-in "hidden" mode where the console is logging messages but remained hidden until the user presses a key to show it (much like the F12 tools in your browser).

This way games can be released having the console active but invisible and when people have issues you tell them to press F12 and send you the console output to go with their bug report.

Thanks for this great asset!

Feature request - Popup, gesture and support email

Hello.
It would be awesome if we have options to auto popup on error, using gestures like swipe down with two fingers to show the console and have email fields for sending full log to support email address.

Can't enter commands when in an FPS

In first person, the cursor mode is locked:

Cursor.lockState = CursorLockMode.Locked

So the input field cannot be clicked on to gain focus.

One solution is to force the focus when the log window is shown:

public void ShowLogWindow()
{
    // snip for brevity
   if (Cursor.lockState == CursorLockMode.Locked)
   {
      commandInputField.ActivateInputField();
   }
}

If you're happy with this fix, I'll raise a PR.

Thanks for a great asset!

Cannot deploy Google Play build

Google Api Error: forbidden: The maxSdkVersion of permission android.permission.READ_LOGS must be at least 18. - The maxSdkVersion of permission android.permission.READ_LOGS must be at least 18.

New Input System

Hello,
My project uses the new Input System package from Unity. When I start playing, Unity gives me an enormous amount of errors that the old Input System is used. I tried to change your code by myself to adapt it, but it kindof breaks everything... Could it be possible to mqke the plugin work with both versions of the Input System?

(Not an issue) help -> Commands listing Idea

Hi Yasir,
First of all THANKS for all your great assets. SUPER USEFUL.

Today was digging into using console commands.
Everything works well so far.

Small hiccup / user (programmer) experience I had:

I added several commands and was puzzled because when typing help I would only see the first one...
After digging into the code I understood that I have to click on the line in the console to expand it and see all the commands.

UX wise it can lead to think that it does not work...

Ideas:

  • Maybe for this particular command print only the commands directly to the ingame console instead of going through the unityconsole which adds a lot of infos which are not super useful for users (for example my artists/designers).
  • Print one command per line (might scroll too much for many commands).

Anyway for now as I did not want to modify you code I added a fake first command which is called "CLICK_HERE_TO_SEE_COMMANDS" ;-)

Nicolas

Logs do not appear when Debug.Log() called on async callback and not on main thread.

Hello, @yasirkula really love the UnityIngameDebugConsole and your awesome unity plugins, works great, but I have found that logs do not appear in the console if we are using asynchronous callbacks, is there a way to make these visible?

An example of this is using Firebase storage and their ContinueWith() Task callbacks.

The logs appear in adb logcat fine, but I would also like to see them inside the in game console too.

Only Assembly-CSharp is supported for the ConsoleMethodAttribute

I use asmdefs for my game code, and so ConsoleMethodAttribute will not work.
I changed your code to this and it works for me now:

foreach( var (method, attr) in AppDomain.CurrentDomain
    .GetAssemblies()
    .Where(a => !a.IsDynamic)
    .SelectMany(a => a.GetExportedTypes())
    .SelectMany(t => t.GetMethods( BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly ))
    .Select(m => (method: m, attr: m.GetCustomAttributes( typeof( ConsoleMethodAttribute ), false ).OfType<ConsoleMethodAttribute>().FirstOrDefault()))
    .Where(m => m.attr != null)
    )
{
	AddCommand( attr.Command, attr.Description, method );
}

stop editor player error

NullReferenceException: Object reference not set to an instance of an object
IngameDebugConsole.DebugLogManager.LateUpdate () (at Assets/3rd_Plugin/Standard Assets/IngameDebugConsole/Scripts/DebugLogManager.cs:314)

NullReferenceException: Object reference not set to an instance of an object
IngameDebugConsole.DebugLogManager.ReceivedLog (System.String logString, System.String stackTrace, LogType logType) (at Assets/3rd_Plugin/Standard Assets/IngameDebugConsole/Scripts/DebugLogManager.cs:482)
UnityEngine.Application.CallLogCallback (System.String logString, System.String stackTrace, LogType type, Boolean invokedOnMainThread) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Application.cs:121)

Timestamps of log entries

Hi! Firstly I'd like to stress that we're using your asset and we find it very valuable, useful and stable. Thank you for your great work! There is one thing however we (and possible others) would find useful:

When log entry is expanded, it would be great to see when entry was logged. Perfectly with both local time, frame # and Time.time.

Text > TextMeshPro

Any update for just supporting TMP by default as it is free and part of Unity?

[Unity 2020.2.4f1]NotSupportedException error occurs during playback when URP is installed

I'm not an English speaker, I'm using Google Translate. Sorry.

Description of the bug

When I deploy URP, I get a NotSupportedException error when playing.

NotSupportedException: The invoked member is not supported in a dynamic module.

Judging from the error message, it seems that the same phenomenon occurs not only in URP but also in packages where assemblies are dynamically generated.

Reproduction steps

  1. Unity2020.2.4f1, create a project with Mobile2D template
  2. Install this repository from OpenUPM (openupm add com.yasirkula.ingamedebugconsole)
  3. Install Universal RP from Package Manager
  4. Place the InGameDebugConsole prefab in the initial scene
  5. Play
  6. Error occurred

Platform specs

Please provide the following info if this is a Unity 3D repository.

  • Unity version: 2020.2.4f1
  • Platform: Windows 10(UnityEditor)
  • How did you download the plugin: InGameDebugConsole 1.4.1/URP 10.3.1

Additional info

Error Message

NotSupportedException: The invoked member is not supported in a dynamic module.
System.Reflection.Emit.AssemblyBuilder.GetExportedTypes () (at <9577ac7a62ef43179789031239ba8798>:0)
IngameDebugConsole.DebugLogConsole..cctor () (at Packages/[email protected]/Plugins/IngameDebugConsole/Scripts/DebugLogConsole.cs:160)
Rethrow as TypeInitializationException: The type initializer for 'IngameDebugConsole.DebugLogConsole' threw an exception.
IngameDebugConsole.DebugLogManager.OnEnable () (at Packages/[email protected]/Plugins/IngameDebugConsole/Scripts/DebugLogManager.cs:403)

Suppress ReflectionTypeLoadException

My project includes some assemblies (Microsoft.CodeAnalysis, Microsoft.CodeAnalysis.CSharp) to support code generation. Inside Unity Editor, they are just broken and not supposed to work. They are there just to make sure my Editor code compiled without error. So they are not supposed to be searched by the DebugLogConsole class, otherwise ReflectionTypeLoadException will be thrown. And this is the case atm.

image

Ignoring user-defined assemblies seems to be impossible with the way DebugLogConsole is implemented. I suggest we can just ignore this exception.

GetExportedTypes not supported in dynamic modules

Description of the bug

Some unity projects may use dynamic generated assemblies. In this case when enter playing mode, a NotSupportedException will be thrown from the static constructor of DebugLogConsole with these logs:

NotSupportedException: The invoked member is not supported in a dynamic module.
System.Reflection.Emit.AssemblyBuilder.GetExportedTypes () (at <9577ac7a62ef43179789031239ba8798>:0)
IngameDebugConsole.DebugLogConsole..cctor () (at Library/PackageCache/[email protected]/Plugins/IngameDebugConsole/Scripts/DebugLogConsole.cs:160)
Rethrow as TypeInitializationException: The type initializer for 'IngameDebugConsole.DebugLogConsole' threw an exception.
IngameDebugConsole.DebugLogManager.OnDisable () (at Library/PackageCache/[email protected]/Plugins/IngameDebugConsole/Scripts/DebugLogManager.cs:425)

Reproduction steps

URP and HDRP are using dynamic generated assemblies in editor. Projects with these pipelines may run into this issue. Here's a simple reproduction:

  1. Create a new Unity project with template Universal Render Pipeline.
  2. Install In-game debug console and drag the prefab to the scene.
  3. Enter play mode.

Platform specs

Please provide the following info if this is a Unity 3D repository.

  • Plugin version: 1.4.1
  • Unity version: 2020.2.0f1, with URP
  • Platform: Windows
  • How did you download the plugin: UPM

Additional info

Maybe just check Assembly.IsDynamic and bypass dynamic assemblies in the static constructor of DebugLogConsole.

Console not closing using new input system

Description of the bug

When using the new Unity input system, closing the console does not work when clicking the red cross.
The steps to enable the new input system for this plugin were performed.
Same behavior when having both input systems active without the modifications.

Reproduction steps

Trying to close the console overlay when using the new input system.

Platform specs

  • Unity version: 2020.3.8f1
  • Platform: Windows 10
  • How did you download the plugin: GitHub

image

Unity Package System Suggestion

Hi.

I would like to suggest creating a branch where the project is set up as a Unity Package Manager. (e.g. upm)
It makes the project a lot easier to install since unity 2018.

As a suggestion, check how the Naughty Attributes Package did it some days ago:
https://github.com/dbrizov/NaughtyAttributes

Meanwhile, I forked the repo and changed a bit in order for it to work with the new package system:
https://github.com/RicardoBusta/UnityIngameDebugConsole
The directory structure is a bit messy, but was just to validate the idea. And it works great!

PS: Thanks for this awesome add-on!

Rewired/Unity default input seems to override the asset's input

Hi,

Thank you very much for making this (and your other) asset freely available, this one definitely seems to be what I am looking for.

I may be overlooking something or am just not good enough at Unity/coding but when I dropped this asset in my project I am unable to click on the icons as I've already have the mouse click function used in game as an attack function and that seems to take priority. Would it be possible for a keyboard toggle(preferably self assignable) to be added or is there another solution you would suggest to potentially resolve this?

Thanks and kind regards,
Mike

[Feature request] Add async commands support

Would it be possible to add a way to call async commands?

    [ConsoleMethod("/register", "Create a new user")]
    public static async Task Register(string email, string password)
    {
        await _authenticationController.Register(email, password);
    }

Add document about the specification of pop-up, please

The specification of the number displayed in the popup was not written in the readme.
image

As a result of verification, I understood that it is the number of unread logs output to the console window.
I felt that displaying unread counts is very good as a function.
I think that it would be easier to understand if the popup specification was written in the readme, so I would like to add it.

Console text input recording keypresses when minimised with hotkey

Description of the bug

When opening/closing the console with the hotkey, the hotkey character is included and the input is still added to the text input for the console.

Reproduction steps
New scene
Add InGameDebugConsole prefab
Ensure toggle key is Backquote
Run scene
Press to open console **Note** that the console has the character in the console text input field
Press to close the console Press W (simulate walking in game) Press to open console
Note that the console has the ``w` in the console text input field

Platform specs

Windows (Asset store download)

Additional info

Pull request with fix option submitted. #29
Passes all reproduction steps above. Note this clears the console text input on open/closing to remove the hotkey character input. Downside of this is user is no longer able to type something in the input field, minimise the console, reopen the console and have the initial typed text preserved. This may or may not be desired functionality.

Using TextMeshPro

How could I use textmeshpro in the input field?

Try replacing this
private InputField commandInputField; to this private TMP_InputField commandInputField;

But it doesn't work when I try to use some command
i Use "using TMPro;" and I also put the "TMP_inputfield" in the hierarchy

How to hide the persistent counter info?

This is a great asset -- thank you.

I would just like to hide the hovering info window: https://i.imgur.com/lLL14Dj.png

I tried disabling it and other basic approaches, but it either breaks the asset or doesn't fully hide it.

Before I tear into the code, what's the recommended way of hiding it? In my use case, nothing is shown until the user presses a hotkey to show the console.

error add log

Trying to add WarningCount (UnityEngine.UI.Text) for graphic rebuild while we are alreay inside a graphic rebuild loop.this is not supported

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.