Coder Social home page Coder Social logo

varkor / quiver Goto Github PK

View Code? Open in Web Editor NEW
2.3K 24.0 75.0 8.38 MB

A modern commutative diagram editor for the web.

Home Page: https://q.uiver.app

License: MIT License

HTML 1.58% CSS 5.13% JavaScript 90.20% Makefile 0.75% TeX 2.34%
commutative-diagrams category-theory editor tikz tikzcd latex tikz-cd pasting-diagrams commutative diagram

quiver's Introduction

quiver: a modern commutative diagram editor

quiver

quiver is a modern, graphical editor for commutative and pasting diagrams, capable of rendering high-quality diagrams for screen viewing, and exporting to LaTeX via tikz-cd.

Creating and modifying diagrams with quiver is orders of magnitude faster than writing the equivalent LaTeX by hand and, with a little experience, competes with pen-and-paper.

Try quiver out: q.uiver.app

Features & screenshots

quiver features an efficient, intuitive interface for creating complex commutative diagrams and pasting diagrams. It's easy to draw diagrams involving pullbacks and pushouts,

Pullback

adjunctions,

Adjunction

and higher cells.

3-cell

Object placement is based on a flexible grid that resizes according to the size of the labels.

Flexible grid

Arrow styles

There is a wide range of composable arrow styles.

Colours

And full use of colour for labels and arrows.

Screenshot mode

quiver is intended to look good for screenshots, as well as to export LaTeX that looks as close as possible to the original diagram.

Keyboard hints

Diagrams may be created and modified using either the mouse, by clicking and dragging, or using the keyboard, with a complete set of keyboard shortcuts for performing any action.

Export to LaTeX

When you export diagrams to LaTeX, quiver will embed a link to the diagram, which will allow you to return to it later if you decide it needs to be modified, or to share it with others.

Other features

  • Multiple selection, making mass changes easy and fast.
  • A history system, allowing you to undo/redo actions.
  • Support for custom macro definitions: simply paste a URL corresponding to the file containing your \newcommands.
  • Export embeddable diagrams to HTML.
  • Panning and zooming, for large diagrams.
  • Smart label alignment and edge offset.

Importing macros and colours

To use custom macros and colours in quiver, create a file containing the definitions, like the following.

\newcommand{\cat}{\mathscr}
\newcommand{\psh}{\widehat}
\newcommand{\smcat}{\mathbb}
\newcommand{\yo}{よ}

Upload the file to a publicly accessible URL (for instance, gist.github.com), and paste the URL for the raw text into the "Macros" input at the bottom of quiver.

Currently, macros may be defined using \newcommand, \newcommand*, \renewcommand, \renewcommand*, \DeclareMathOperator, and \DeclareMathOperator*; and colours may be defined using \definecolor (using the colour modes: rgb, RGB or gray).

Editor integration

See Editor integration on the quiver wiki.

Building

Run make from the command line, and then open src/index.html in your favourite web browser.

If this fails, you might be using an incompatible version of Make or Bash. In this case, you can manually download the latest release of KaTeX and place it under src/ as src/KaTeX/. Then open src/index.html in your favourite web browser. If KaTeX has not been given the correct path, you will get an error telling you that KaTeX failed to load.

If you have any other problems building quiver, open an issue detailing the problem and I'll try to help.

Thanks to

  • S. C. Steenkamp, for helpful discussions regarding the aesthetic rendering of arrows.
  • AndréC, for the custom TikZ style for curves of a fixed height.
  • Nathan Corbyn, for adding the ability to export embeddable diagrams to HTML.
  • Paolo Brasolin, for adding offline support.
  • Carl Davidson, for discussing and prototyping loop rendering.
  • Everyone who has improved quiver by reporting issues or suggesting improvements.

quiver's People

Contributors

cartesiancat avatar doctorn avatar paolobrasolin avatar syvb avatar varkor 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

quiver's Issues

Allow arrow style to be set for subsequent arrows

It would be really convenient if one could:

  • Move nodes with corresponding arrows.
  • Adjust curvature through dragging the middle of the arrow.
  • Adjust the length of an arrow through dragging.
  • Change the arrow style for all subsequently created arrows.

The first three things would need to be toggled by a modifier key e.g. shift for the first two and alt for the third.

Add line breaks between arrows in the exported tikz-cd code

Currently line breaks are only added between arrows at different levels (e.g. 1-cells and 2-cells), so all morphisms are exported in one line. It would be good to separate arrows at the same level into their individual lines so the code becomes a bit more readable and editable, if necessary. That is, instead of

\[\begin{tikzcd}
	{S} & {1} \\
	{A} & {\Omega}
	\arrow["{m}"', from=1-1, to=2-1, tail] \arrow["{\mathit{true}}", from=1-2, to=2-2] \arrow["{!_S}"{name=0}, from=1-1, to=1-2] \arrow["{\chi_S}"{name=1, swap}, from=2-1, to=2-2, dashed]
\]

it would be better to export

\[\begin{tikzcd}
	{S} & {1} \\
	{A} & {\Omega}
	\arrow["{m}"', from=1-1, to=2-1, tail]
 	\arrow["{\mathit{true}}", from=1-2, to=2-2] 
	\arrow["{!_S}"{name=0}, from=1-1, to=1-2] 
	\arrow["{\chi_S}"{name=1, swap}, from=2-1, to=2-2, dashed]
\]

Should just be a matter of adding some whitespace to

output += `\\arrow[${style}` +

Arrows at different levels can be separated by an empty line, for example.

1.0 release

I'd like to push for a "version 1.0" and make an announcement post and advertise quiver on various media once I think that it's ready. I'll use this issue to track what should happen as part of this push.

Implementation

  • Move to dedicated domain.
  • No JavaScript support.
  • Custom .sty.
  • Add a version number.
  • Open Graph protocol support.
  • Test in Chrome, Safari, Firefox.

Publicity

Other suggestions are welcome.

Curved arrows

This is the main feature that quiver is currently missing. It's actually been partially-implemented on a branch (https://github.com/varkor/quiver/tree/curves) for over a year. I just need to get around to finishing it off. The main difficulty is accounting for all of the possible arrow styles, which now need to be potentially curved too. In addition, the circular bounding "boxes" for the vertices doesn't work quite so well with curved edges.
image
(An example curved arrow from the branch.)

Pressing `;`, `'`, `,`, `.`, `/` on iOS triggers command input

Usually, pressing one of these keys triggers an orange command input like this:
image
However, this is not supposed to happen if the label input is currently focused. For some reason, this focus check does not seem to succeed on iOS, triggering the command input whenever a user types one of these letters.

Request: Doubled edges

It would be really useful to have headless arrows with double lines (i.e. long ``equals signs'').

Ubuntu installation

The yarn package in Ubuntu comes in cmdtest package and needs to be removed and installed from the yarn Debian package repository.

remove cmdtest

sudo apt-get remove cmdtest

install yarn

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update
sudo apt install yarn

You can add this info under installation instructions.

Best regards,
Klemen Bregar

Handle LaTeX parse errors gracefully

At the moment, if there are any parse errors in a label, the entire label will not be rendered as LaTeX. This is due to the lack of error recovery in KaTeX: KaTeX/KaTeX#428. It would be nice to improve the handling of parse errors (which may require modifying KaTeX itself).

Investigate performance improvements

On larger diagrams at the moment, quiver can seem a little slow. So far I haven't paid much attention to performance, and it's likely that there are some easy wins here: for instance, I imagine arrows are being redrawn too frequently, and the grid is being resized too eagerly.

VS Code Extension

I'm probably not going to create commutative diagrams any time soon. However, I think a VS Code extension that wraps this editor might be a good thing if you are already using vscode to write latex.

It could offer a custom editor for *.commutative.latex files that reads and writes diagrams from/into such files. You could directly import this file from latex without needing to export anything.

I'm willing to help!

SVG export

Currently, quiver draws arrows using SVG, but makes use of a lot of CSS styling, which is badly supported outside of browsers. This makes it difficult to export a diagram as an SVG. Implementing curved arrows (#5) is going to require rewriting the arrow rendering and we should make sure to use SVG attributes rather than CSS styles, so that it becomes possible to export the entire diagram as an SVG file.

Being able to export to an image format (rather than just LaTeX) would mean quiver could be used as a standalone commutative diagram editor, rather than something that has to be used in conjunction with LaTeX.

A desktop client version of the app

Are you considering a desktop client for this app? If you wanted to reuse the Javascript, you could use react native for Windows and Mac. This would be really useful since any time there is a graphic editor in a website there is too much overhead from the browser, plus it wouldn't require going to a site to use the app.

Add zooming

This could be achieved naïvely simply by scaling the entire canvas.

Proportional grid

At the moment, we only support a square grid cell of a fixed size. This isn't quite how tikz-cd works: instead, rows and columns may be expanded to fit their largest content. This is often not hugely noticeable in quiver, because we resize cell contents to fit the grid, but when cell content is very wide, it becomes difficult to read. We should instead resize the grid like tikz-cd does.

Parsing tikzcd code

It would be great if we could copy & paste some existing tikzcd code (for which we do not have the quiver hashcode) on quiver in order to make some adjustments.

Allow offset to depend on length

The offset slider has a static range, but it would be nicer if this range could be proportional to the length of the arrow.

Example of problem:
image

Dragging Vertices

One of the nicest features of another tikz-cd graphical interface is that you can grab a vertex and drag it and the arrows that are pinned to it will be changed accordingly. For instance I might add an arrow from A to B but then realize it's too small so move B over one square and the arrow will stay going from A to B.

Playing with quiver, it seems like I can move the edge of an arrow, but not a vertex. Does this feature exist and I'm not aware of it? If it doesn't exist it's very convenient for me because often I make a square that's 1x1 and realize later I want to label the interior of the square and need to expand the grid to be 2x2.

Swap ordering of label alignment buttons for down and left pointing arrows

If an arrow is pointing down, the button to put the label to the left of the arrow is on the right, and the button to put the label on the right of the arrow is to the left (the tooltips for the buttons also seem to be mixed up, but they say the same thing for all directions). Would be great to have these swapped around so the directions are more intuitive! Similar inconsistency (though not as confusing) for left-pointing arrows, where the leftmost label alignment button is for bottom alignment and vice versa (it's the other way around for left-pointing arrows).

image

Correct label position on edges

At the moment, label position (and the centre of an edge) are calculated with respect to the source and target. They should instead be calculated with respect to the endpoints. Otherwise, we get situations like below.
image

UI and UX redesign

Although overall, quiver works well, there are several aspects of the design I'm not quite happy with at the moment. For instance, the label input is too small; the side panel takes up too much room; the interface isn't very discoverable. I plan to revisit the interface soon to make everything more intuitive and slick.

There are several related issues that I'll tackle at the same time.

Redo keyboard shortcut doesn't work

Ctrl+Shift+Z doesn't seem to work for me, but the Redo button works. Ctrl+Z and Undo buttons work. I was able to reproduce it on both chrome and firefox.

Difficult to select arrows

The circles that allow dragging the endpoint around are quite large and can't be hidden, so sometimes it becomes difficult to select the arrow itself because the grey area around it is mostly taken up by these circles. It would be great to either

  • make the circles smaller
  • hide them until the user holds down some key (it's less common to want to drag the endpoint of an arrow around than just selecting it to change its label, alignment, etc.)
  • select the arrow when the user clicks on the circle

image

Touchscreen support

Would it be possible to add support for touch screens? Is this something you are considering?

List of common actions / shortcuts

In designing the keyboard interface for quiver, I'll need to have an idea of what commands or actions we want to invoke. All the user interface elements will be triggerable by keyboard, but there may be some commands that are only accessible via the keyboard (or a menu, if I add one).

It will help to collect these actions now, so that when I come to design the system, I'll be well-informed.

Improve discoverability of features

This is intentionally vague, as there are several ways in which this could be achieved and I'll have to investigate to work out how best to tackle this. E.g. an interface rehaul, a tutorial, or so on.

Decoding nodes from numbers

In the exported LaTeX, the nodes are encoded using numbers. Quite often, I want to edit the exported LaTeX to tweak the diagram, rather than editing in quiver. Currently, it is a bit difficult to decode the text node from the vertex numbers. Would it be possible to do either of these two options?

  • Not encode nodes using numbers. This could be an option in the export if no higher cells were used.
  • Include the node-number mapping as a comment in the generated code.

Loops

Loops are useful for endomorphisms, like identity morphisms.

Shorten edges bidirectionally

It would be useful to be able to shorten edges asymmetrically, especially when we have an arrow between an object on one side and an edge on the other, as in the example below.
image
The renderer already supports shortening arrows asymmetrically, but I haven't decided what the UI should look like: I'd like a two-handled slider, but these aren't supported in HTML, so I'd have to create my own.

Improve TikZ output

There are currently a number of situations that quiver struggles to replicate in LaTeX (currently the user will be warned about these situations, and quiver will fall back on an easier style, e.g. replacing a 3-cell with a 1-cell). We would really like to support exporting every diagram that quiver supports. I'm keeping a list here of the remaining problems.

  • Triple-cells or higher (i.e. arrows with level greater than 2). There is a TikZ style Rightarrow for double arrows, but no built-in style for triple arrows or higher. There are some ad hoc solutions to be found on TeX.SE, but all the ones I found were inflexible, e.g. didn't support curved edges, or weren't the correct size.
  • Shortened curved arrows. TikZ's shorten <= and shorten >= do not interact correctly with curved arrows. We would ideally like to be able to shorten a curved arrow by a proportion of its length. I opened a TeX.SE question regarding this here, but so far no-one has had any ideas.
  • Double arrows with various head/tail styles. TikZ does not cope with these very well: see astoff/tikz-cd#1 for examples, as well as a possible solution to one of the combinations.
  • Output proportional lengths instead of absolute lengths. Currently quiver guesses the right measurements in pt by applying a fixed multiplier to the absolute length in quiver:

    quiver/src/quiver.js

    Lines 355 to 364 in b1e9145

    // For curves and shortening, we need to try to convert proportional measurements
    // into absolute distances (in `pt`) for TikZ. There are several subtleties, one of
    // which is that the grid cell size in tikz-cd has a greater width than height, so
    // when we scale things, we need to scale differently in the horizontal and vertical
    // directions. For now, we simply multiply by constants that, heuristically, give
    // reasonable results for various diagrams I tested. It would be nice to eventually
    // correct this by using proportional lengths, but that requires a custom TikZ style
    // I do not currently possess the skills to create.
    const TIKZ_HORIZONTAL_MULTIPLIER = 1/4;
    const TIKZ_VERTICAL_MULTIPLIER = 1/6;

    This is entirely heuristic-based and doesn't look quite right in some cases (especially for curved in large diagrams). It would be better if we could output all distances proportional to the distances between grid cells (or arrow arc length). I imagine there are some handy TikZ commands (probably involving calc) to accomplish this, but I lack the familiarity to know how.

If you feel you may have a solution to one of these issues, I would love to hear from you: please leave a comment! (If it requires extended discussion, we can get in touch through another medium.) Thank you!

Keyboard controls

There are some keyboard controls in quiver already, but it's not possible to create new objects or arrows solely using the keyboard. Keyboard controls would make using quiver even more efficient and satisfying.

Two headed arrows

I'd like to draw two-headed arrows in my diagrams.
Drawing two different overlapping arrows currently looks like this.
image

Dynamically updated diagram urls

I have a minor issue that happens when I leave a quiver tab open with an incomplete diagram, and then the tab gets snoozed by my browser, so when I return to it, the tab refreshes and I lose my work.

I wonder if the diagram could be encoded as a uri hash fragment in the url (rather than a query string as it is currently done), that updates dynamically while drawing the diagram. This would make it possible to use the browser history/forward/back buttons to interact with the diagram history.

Changing arrow lengths

Would it be possible to have a slider to change arrow lengths? This could be achieved using the tikzcd shorten option, and is very useful for the 2-arrows in pasting diagrams.

Crossing over arrows

For 3d diagrams, could a button be added for using "crossing over" in tikzcd? This is something I often have to add manually after exporting.

Using within align environment

The code

\documentclass{article}
\usepackage{amsmath}
\usepackage{quiver}

\begin{document}

% https://q.uiver.app/?q=WzAsMixbMCwwLCJQIl0sWzEsMCwiUSJdLFswLDEsIlxcdmFycGhpIiwwLHsib2Zmc2V0IjotMX1dLFswLDEsIjAiLDIseyJvZmZzZXQiOjF9XV0=
\begin{align}
    \begin{tikzcd}
    	{P} & {Q}
    	\arrow["{\varphi}", from=1-1, to=1-2, shift left=1]
    	\arrow["{0}"', from=1-1, to=1-2, shift right=1]
    \end{tikzcd}
\end{align}

\end{document}

produces the error
image

When align is replaced by equation, this doesn't happen. Is this a problem with tikzcd or with quiver?

Show 2-arrow while drawing

This is a very minor nitpick that I just noticed.

While drawing an arrow starting at a node, a 1-arrow is shown. If the arrow is incident on a 1-arrow, it becomes a 2-arrow as expected. However, this only happens when you let go of the mouse after drawing. I wonder if it could become a 2-arrow as soon as the incident 1-arrow is chosen.

Support for more general purpose diagrams

Intro

I think people looking to make great looking network or flow diagrams don't have many options available. Especially for free and on any OS. This has led me to mainly stick with ASCII, but its limits are so painfully obvious. After seeing Quiver on HN, I tried making one of my most recent ASCII diagrams using Quiver.

The issues

  • Quiver needs a rich text editor to be able to support richer nodes (suggestion: Markdown)
  • Wrapping nodes in boxes or circles will help group rich text and will aid folks in making DAGs

The example ASCII diagram

ELB (production) / Nginx Reverse Proxy (development)
+--------------------+---------------------------+----------------------------+--------------------+
                     v                           v                            v
                     v                           v                            v
                     v                           v                            v
           +---------v---------+         +-------v-------+         +----------v---------+
           |                   |         |               |         |                    |
           |   platform-link   >>>>>>>>>>>   challenge   >>>>>>>>>>>   real-time-read   |
           |                   |         |               |         |                    |
           |           keycloak|         |       keycloak|         |            keycloak|
           |              mongo|         |       postgres|         |               mongo|
           |              redis|         |          mongo|         |               redis|
           +------------------v+         |          redis|         +--------------------+
                              v          +v---------v--^-+         
                              v           v         v  ^
                              v           v         v  ^
                              v           v         v  ^
                              v           v         v  ^
                              v           v         v  ^
                            +-v-----------v+       +v--^----------+
                            |              |       |              |
                            |   geofence   |       |   schedule   |
                            |              |       |              |
                            |         mongo|       |      postgres|
                            |         redis|       |         redis|
                            +--------------+       +--------------+

The example Quiver diagram

quiver

Summary

I realize this isn't the exact intended usage of Quiver, but it could be that your audience is larger than you had originally imagined. Thanks for the great tool and the permissive license.

Add an option to flip the corner symbol (for Cartesian squares)

First of all, thank you for making this beautiful diagram editor.

Quiver uses \lrcorner at the top left to denote pullback squares. I typically use a different convention: \ulcorner at the same position. And similarly with the pushout squares. I'm sure I stole the notation from some seminar talk, so I'm not the only one who does that. Modifying the exported LaTeX code to follow my preferred notation is trivial with find-and-replace, but maybe an option in the editor would be nice as well.

Perhaps clicking on the "flip" button on an arrow styled as the corner symbol should switch the corners?

Multiple selections with Ctrl

Shift+click is used for multiple selections, but I'd also like to be able to use Ctrl+click, since that's the more nautral multi-select key.

Couldn't find a package.json file.

When I try to build quiver on MacOS, some errors are printed

git submodule update --init --recursive
Cloning into '/Users/hammerfunctor/Documents/tools/quiver/src/KaTeX'...
Submodule path 'src/KaTeX': checked out '062a28f35affa7e9419bcf7809c2c044d2806210'
Submodule 'submodules/katex-fonts' (https://github.com/KaTeX/katex-fonts) registered for path 'src/KaTeX/submodules/katex-fonts'
Submodule 'submodules/katex-test-fonts' (https://github.com/KaTeX/katex-test-fonts.git) registered for path 'src/KaTeX/submodules/katex-test-fonts'
Cloning into '/Users/hammerfunctor/Documents/tools/quiver/src/KaTeX/submodules/katex-fonts'...
Cloning into '/Users/hammerfunctor/Documents/tools/quiver/src/KaTeX/submodules/katex-test-fonts'...
Submodule path 'src/KaTeX/submodules/katex-fonts': checked out 'a09ea0bbe0c6a7dd18118207449654f929388eba'
Submodule path 'src/KaTeX/submodules/katex-test-fonts': checked out '371f4a7947293ada30ccacdbf403d713d128c944'
cd src/KaTeX
yarn
yarn install v1.22.5
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 0.12s.
yarn build
yarn run v1.22.5
error Couldn't find a package.json file in "/Users/hammerfunctor/Documents/tools/quiver"
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
make: *** [all] Error 1

I have known nothing on node, and thus no idea to deal with it.
Thank you.

how to use it in beamer?

\begin{frame}

[\begin{tikzcd}
{M(f,d,y)} && {G} \
\
{E} &&&&& {A}
\arrow["{(m_0,m_1)\longleftarrow F^G(E)}"', from=3-6, to=3-1, shift right=1, curve={height=18pt}]
\arrow["{\alpha \longleftarrow y||s}"', from=3-1, to=3-6, shift right=1, curve={height=18pt}]
\arrow["{r \ or \ random \ string }"', from=3-6, to=1-3]
\end{tikzcd}]

\end{frame}

when i compile it tells me wrong,but i can compile without \begin{frame}

Copy & paste

It would be useful to be able to copy and paste diagrams. It might make sense to be able to copy and paste edges too, although we'd have to figure out how they should be attached to vertices when pasting.

Immovable vertex bug

Occasionally some vertices cannot be moved. Loading the sharable link allows them to move again.

Using Google Chrome 86.0.4240.198 (Official Build) (64-bit)

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.