Giter Site home page Giter Site logo

cadmium-co / cadmium Goto Github PK

View Code? Open in Web Editor NEW
1.4K 22.0 51.0 2.78 MB

A CAD program that runs in the browser

Home Page: https://cadmium-co.github.io/CADmium/

License: Other

JavaScript 2.54% HTML 0.24% Svelte 27.31% CSS 0.07% Rust 51.55% TypeScript 18.27% Shell 0.02%
cad mechanical-design mechanical-engineering

cadmium's Introduction

CADmium

This project aims to create a new CAD program from scratch. It is small, it runs in a web browser, and the source code is available for free here on Github.

Legacy CAD programs have taken many thousands of years of collective engineering time to get where they are so this program will never be able to compete on breadth of features. But CADmium is intended to capture 80% of the most common CAD use cases while doing less than 10% of the work. For now we are targeting the home hobbyist who just wants to design a widget for their 3D printer, not a company that wants to design a car or airplane, although that will come later.

If you're looking for:

  • A simple, modern, parametric CAD UI that runs in a browser
  • That can export solids as .step, .obj, or .cadmium (a json-based CAD format that this project is inventing)
  • That can export sketches as .svg or .dxf
  • That works without an internet connection

Then this project may be for you!

Status: Early prototype. This tool is not yet an MVP, but is being developed in the open. Please do not share this to HN or Reddit or things like that. ha, well I guess that ship has sailed!

Overall Plan

Demos: We are currently racing toward our first demo release, V0.0.1. This is a good first exercise for us to decide on build and release processes.

After that we will do a few more demo (V0.0.*) releases, aggregating features until it feels pretty usable.

Alpha: When it feels like we've reached an MVP that people might actually want to use, it's time to release an Alpha version (V0.1.0) and actively solicit feedback from users. We'll use that feedback to make more improvements, re-inventing things if necessary to achieve a great workflow.

Beyond that, we'll see!

Technology

The boundary representation engine under the hood is truck, which is written in rust and is not dependent on any legacy b-rep engine.

Leveraging truck, we wrote a small rust library called cadmium which provides structs for projects, workspaces, sketches, extrusions, and constraints. Our goal is that this rust library provides all the same functionality as the UI for anyone who prefers code-first CAD. This library is able to save and load projects to disk as json. We have also built a set of javascript bindings so that the whole thing can be compiled to wasm and run in a browser.

The UI is built with SvelteKit and Tailwind. It is hosted with Github Pages. We use three.js for rendering, which in this case uses WebGL under the hood. We use Threlte to manage the scene graph declaratively.

Native builds use Tauri, which is a Rust-based wrapper around OS-specific native webviews that allows us to build a native app from the same codebase.

License

This software is offered under the Elastic License 2.0. In summary, you can do whatever you like with this software except offer it as a service to third parties.

Running The Code

If you're just trying to kick the tires, click here to view the live web demo.

To build locally using pnpm workspace & turbo:

git clone https://github.com/Cadmium-Co/CADmium.git
cd CADmium
pnpm install
pnpm dev

Native Builds

# Development
pnpm tauri dev

# Generate binaries and installers
pnpm tauri build

Tauri can generate icons for the native build with the following command:

pnpm tauri icon applications/web/public/cadmium_logo_min.svg

Tooling setup

pnpm

We use pnpm to manage the monorepo. Please follow the instructions here to install: https://pnpm.io/installation#using-a-standalone-script

If you're new to node you can use pnpm to manage nodejs:

# https://pnpm.io/cli/env#use
pnpm env use --global 20

rust

First install rust using rustup: https://rustup.rs

Then install wasm-pack

cargo install wasm-pack

Running Tests

pnpm test

Playwright is used for e2e testing. You may be prompted with a command to install it.

For manjaro/archlinux folks it may report missing dependencies. On manjaro the missing dependencies are solved thanks to this comment:

yay -S aur/enchant1.6 aur/icu66 aur/libwebp052

Watch vitest unit tests only:

cd applications/web
pnpm test:unit -w

rust

To build and run the Rust tests:

cargo test

rust examples

Simple exaples using the rust code can be found in packages/cadmium/examples

Run simple rust example with:

cargo run --example project_simple_extrusion

Will produce example.obj file and example.step output files, the .step file can be examined in a CAD viewer.

git blame

To ignore commits used purely for formatting changes, to preserve correct authorship, set your local git config:

git config blame.ignoreRevsFile .git-blame-ignore-revs

Contributing

We are actively seeking contributors! Please join the Discord and come help out!

Most especially, we need help in the following areas:

Design: The tool must look and feel good and we are not designers. We would love contributions in the form of:

  • Advice, mockups, or tailwindcss examples of how to make different elements look and behave better
  • In particular, help picking a color palette that works well and is unique
  • Help figuring out how to implement dark mode

Rust: This is our first project in Rust. We need help from experienced Rustaceans to:

  • Figure out how to better lay out the rust code
  • Point out any glaring issues with how I'm using the language (We've thus far completely avoided Lifetimes, Traits, Rc, RefCell, etc and that may be hampering things)

Svelte: This is our first project using Svelte. We'd love an experienced set of eyes to:

  • Look over the basic structure and tell us if we're making any big mistakes
  • Help us migrate to Svelte 5 when it comes out

If you feel like you would be willing and able to help, please join our discord!

License FAQs

What license do you use?

We use the Elastic License v2.0.

What are the terms of that license?

You can do anything you want with the code except offer it as a service to third parties.

Why do you use that license instead of MIT, GPL, etc?

Because we don't want Autodesk, Siemens, Dassault, or PTC to clone our code, change the logo, and start offering it as one of their products.

Can I host a CADmium instance for my family?

Yes.

Can I host a CADmium instance for my company for internal use?

Yes.

Can I host a CADmium instance for my company for my clients as a free service?

No.

Can I host a CADmium instance for my company for my clients as a paid service?

No.

If you choose at some point to stop developing CADmium, what will/can happen to the project?

We would convert the license to MIT, GPL, or something similar.

If I fork the project and change it (rebranding or adding a new feature) can I host it myself?

Yes, so long as your fork is only used by you or your company. You are not permitted to host your fork as a service for third parties.

Do I have to publish my fork?

No.

Immediate TODOs for V0.0.1 release (The Demo)

Github project for tracking progress is here

  • Sketching
    • Implement a standalone first-order 2D constraint solver
    • Integrate that new solver into sketch.rs
    • Ability to create a sketch on the face of a solid
    • Ability to create and modify constraints in the UI
    • Entities: line, rect, circle, arc, 2D fillet
    • Constraints: horiz, vert, parallel, perp, length, radius, coincident, maybe a few others
  • Extrusion
    • Configure an extrusion to create new solid or subtract from existing solid
    • Modes: New, Add, Cut
    • Control: depth, offset
    • Ability to extrude multiple faces (from one sketch) at a time while not extruding every face in the sketch
  • Revolution
    • Same as Extrusions
  • Boolean
    • Union, Intersection, Subtraction
  • Project
    • Ability to rename the project
    • Ability to delete steps
    • bind ctrl + s to .cadmium export, and ctrl + o to .cadmium import
  • Units
    • Make it clear that the whole file uses millimeter units
  • Files
    • Save and load CADmium files
    • Export as STEP, OBJ, STL, SVG, DXF
  • Marketing
    • Youtube video demonstrating how to make:
      • A simple cube
      • A plate with screw holes
      • Something pretty complex like this

cadmium's People

Contributors

av8ta avatar bherbruck avatar bhiwagade-rahul avatar drewbt avatar dzervas avatar eltociear avatar gonblank avatar huangxiaobao-cxx avatar jbcpollak avatar jplatte avatar mattferraro avatar oyvindnetland avatar sebsebmc avatar soshochang 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

cadmium's Issues

Cylindrical Mesh Looks Terrible

Screenshot 2024-06-02 at 8 48 29 PM

Steps to repro:

  1. Create new sketch on any plane
  2. Draw a circle of any radius
  3. Extrude to any depth

I believe this is an issue with the rust side of things, not the UI because if you export as OBJ and open in PrusaSlicer, you can see a bunch of artifacts:

Screenshot 2024-06-02 at 8 50 16 PM

Expected behavior is to have a clean mesh with no artifacts.

Font size should be independent of zoom

Currently, if you zoom in and out the font size for the plane labels "Front", "Top", and "Right" all get bigger or smaller. Zooming in or out makes the labels illegible.

A more aesthetically pleasing effect would be if the text labels stayed one size no matter the zoom level, so they are always legible.

One edge case this creates is what to do when you zoom out so much that the labels are bigger than the planes. It's okay to ignore that case for now.

Escape Key should exit sketch tool without escaping full screen mode (Firefox only bug)

When I'm using any of the sketch tools like rectangle or circle or line, I expect to be able to cancel the current rectangle/circle/line by tapping the escape key. This does work on both Chrome and Firefox, but specifically on Firefox if my browser is full screen the escape switches the browser back into partial-screen mode. This is super annoying because then the page resizes and everything reflows. This does not happen on Chrome

Expected behavior is that escape key should not switch the browser from full screen mode to partial screen mode.

I have only seen this behavior on Firefox on a Mac

remove the /CADmium suffix from the URL

currently when you run locally using pnpm dev, you can access the editor at http://127.0.0.1:5173/ which seems correct.

but the deployed page at https://cadmium-co.github.io/CADmium/ contains a trailing /CADmium/. Let's remove that!

Compilation failed in win11 terminal

I encountered 3 problems when compiling according to the readme document.
The first problem is that when executing the "pnpm dev" command, the console output is as follows:
67b9370acc397c23181621e3a3954a1
Observing the above error, it seems that there is an extra ";" in the command, so I found the "dev" script in "packages/cadmium/package.json" and found that there is indeed an extra ";" in the command. After I deleted it, the error disappeared. But when executing "pnpm dev" again, the second problem appeared:
faed259b5755216f5ce34c83eb44c41
The command RUST_BACKTRACE terminal cannot recognize it. After consulting the information, I found that the command is to set the RUST environment variable, but setting the environment variable in the Windows terminal requires "set", so I changed RUST_BACKTRACE=1 to set RUST_BACKTRACE=1, and ran it again, and the error disappeared.
After modifying "packages/cadmium/package.json", part of its content is:
11067a486365fb333c20ecae4e22a1d
After running "pnpm dev" again, the third problem occurred: the console cannot output UTF-8 text, and the program crashes. Here, you only need to modify the console encoding and execute "chcp 65001". Run "pnpm dev" again and it will be executed successfully. The cadmium web interface is as follows:
1170bd6dbeea9ecb0d379065452738e

Rework CI triggers

Let's change the CI triggers so that it no longer builds on every single commit. Rather, let's have it build on every PR creation/modification, and have a manual button we can push to trigger it.

Move Constraint solver into a separate crate and put it onto a solid mathematical foundation

Current approach

packages/cadmium/src/sketch/constraints.rs is currently one file containing the spring based constraint solver.

If I understand correctly you apply a virtual spring for every constraint that has a stiffness $K_p$ and a damping factor $K_d$. I assume that you are probably doing a full dynamic simulation (basically solving a second order differential equation, namely calculating accelerations $\ddot{q}_t$, then velocities $\dot{q}_t = \dot{q} _{t-1} + \ddot{q}_t \cdot dt$ and then positions $q_t=q _{t-1} + \dot{q} \cdot dt$) then, even though I didnt find this part in the code yet.

I think the idea is good in general and not to far away from how professional CAD systems do it. Modern PCs are powerful enough, and most sketches are simple enough that this will likely be the only approach we ever need. The proof of convergence for a small enough $dt$ is also tirival, because it is just a simulation of a mechanical system that due to the damping will always loose energy at every point in time, until it stops moving.

Limitations of current approach

Only the numerical stabililty is something that I worry about. Coming from robotics I know that these rigid body simulations tend to become unstable quickly and usually require very small $dt$ and manual tuning of the damping factors to get working nicely.

Mathematics behind current approach

Basically, what you do is setup a Loss function (or call it an error function) which is the mechanical energy of the system $L(q)$. $q$ are the parameters of all your geometry. The mechanical energy of the system is the energy stored in each spring $L(q) = \sum \frac{1}{2} D s^2$. On top of that is the kinetic energy of the moving particles and the damping factors, which lead to a more complex optimization problem touching Lagrange Mechanics.

But in the end, once the simulation converged, it will also have minimizied the energy stored in each spring, so $L(q) = \sum \frac{1}{2} D s^2$ is the only term we actually care about.

Removing the second order of the system

We can make our lives a lot easier here. First, instead of making it a second order dynamic simulation, we can remove the damping terms and make it a first order dynamic simulation by doing Gradient Descent:

$$ \min L(q) $$

$$ q_t = q _{t - 1} - \nabla L(q) \cdot dt $$

This will get rid of the problems with the damping factors and converge into the same solution. It will probably be enough for this program already.

Converging even faster and more numerically stable by using convex optimization algorithms

$L(q)$ is a convex quadratic function (since $\frac{1}{2} D s^2$ is convex). This is great, because it allows us to use a whole new suite of faster optimization algorithms specifically targeted at qudratic and convex functions. The most interesting one is the conjugate gradient methods, or methods that require the second order derivative as well: Newtons Method.

Making our lifes even easier by using a finished framework or building our own crate for it

Implementing a conjuage gradient algorithm is fairly straight forward (<300 lines of code), so defenitly a valid approach for us. Also, the algorithm is simple enough that we dont really have to intruduce an additional depenceny for it. However, we shouldn't reinvent the wheel. If we have $L(q)$, we can also just pass it directly into a general nonlinear or convex optimization framework, and have the mathematicans deals with the details such as preconditioning. E.g.

Figuring out which constraints are in conflict with each other

This is relativly simple. If constraints are coherent, they will end up finding a configuration where each spring is relaxed, or the energy stored in each spring is $\frac{1}{2} D s^2 = 0$.

If two or more springs are conflicting with each other, they end up under stress $\frac{1}{2} D s^2 &gt; 0$. The user interface can highlight these constraints.

Call to action

I am more than happy to help with this project. I work at Neura Robotics, and we the whole robotics industry is in desperate need of a Blender like free capable CAD program, e.g. Fusion 360 but free. I started working on my own CAD program in Rust geop, but there is no way for a single person to achieve this. This is why I am very exited to join forces on this project. I can probably contribute this part of the project, after we discussed some of the technical details. You can reach out to me on LinkedIn.

Rectangle Tool does not stop after finishing Rectangle

Currently, when editing a sketch you can tap "r" to activate the rectangle tool. You can click once to place the first point, then as you move the mouse around you can preview the rectangle as you decide where to place the second point. Upon clicking the second point, the rectangle is completed and gets added to the sketch correctly.

What should happen next is that you should continue to be in rectangle mode, but your mouse pointer should now be completely free: you should choosing where to place the first point of a new rectangle.

Instead what happens now is that the first point of the first rectangle seems to stay selected and your mouse cursor is already previewing a second rectangle.

Zoom to sketch when editing a sketch

When a sketch edit is initiated the camera should zoom to the sketch so that perpendicular against its plane

If the camera wasn't moved and the sketch edit is exited the camera should go where it was before.

Implement Zoom To Pointer

The Camera Controller we use now is the default TrackballControls from Three.js, albeit wrapped by Threlte. But this does not implement the zoom-to-mouse behavior that is default on almost every major CAD program. We need to implement that behavior.

This will require diving deep into the TrackballControls code and rewriting parts of it. For inspiration on how to tackle the math, CameraControls has an implementation that feels mostly right, but it is limited in that it experiences gimbal lock at the north and south poles like OrbitControls.

If you can read the source code of TrackballControls and it makes sense to you, then you have all the skills you need to implement this.

Implement Operation Log and Evolution Log

The Operation Log and Evolution Log are described here.

This is a foundational thing that we need to bring in as early as possible because everything downstream depends on this data model being in place

The referenced faces problem

This is a discussion about how to solve the "referenced faces problem", both for 2D and 3D faces. 2D faces are enclosed, "colored" areas of a sketch that one can extrude, 3D faces are the flat surfaces that 3D objects are comprised of (a 3D cube has 6 faces).

The problem is simple: How do you refer to a selected face, e.g. during an extrusion?

Just ID

This is the simplest solution and what we've done till now, but it has a huge deal breaker: we're calculating faces and they're not static.

This simplest way to break this is approach is to create a sketch with 2 rectangles that share a line, do an extrusion on the second rectangle and then edit the sketch and remove the shared line. Now there's only 1 face and the face ID 2 does not exist

Centroid anchor

A very interesting idea @MattFerraro introduced with the document is to use anchors to refer to faces.

Every time a face is generated its centroid is also calculated and thus during extrusion the face centroid is referenced, not the face or its ID

After a sketch edit the face with centroid closest to the saved centroid is selected.

This approach though is also problematic:

  • There's no way to "fail". For example if a sketch defines 3 faces and 3 extrusions are done and then edited to have only 1 extrusion all 3 extrusions will extrude the same face without producing any errors or warnings (as the closest centroid will be the single centroid of the new single face)
  • Co-eccentricity introduces uncertainty. Since the centroid of 2 co-eccentric polygons is the same, the selection of the face is only based on the order of face generation
  • Movement introduces uncertainty. If we have 2 rectangles that have the same size, select 1 of the two, extrude and then edit the sketch to move the selected rectangle more enough (more than width/2 for example) the other rectangle will now be selected

Some possible fixes for the second problem is:

  • More robust face generation ordering - e.g. from the center to edge or vice versa and the introduction of an "index" along with the centroid so that a faces with the same centroid can be "favored" depending on that index
  • Inclusion of the area along with the centroid so the face with the closest area can be used

About the failing problem I can't think of a good enough solution. Maybe we can store the amount of "independant" (they share no features) faces and if that drops we fail?
Do we just throw a warning when more than 1 extrusion with different centroids end up referring to the same face?


I think the correct approach is to introduce some kind of hashing to the faces that is able to produce a "hash distance" or "not found". the face with the closest hash distance (if any) is selected.

But what do we include the hash and how do we hash it so that a "distance" can be found?

Pan speed is too fast

On my macbook, on both Chrome and Firefox, on both a retina screen and a standard DPI screen, the pan functionality of the camera controller is too fast. The screen moves faster than the mouse does.

Strangely, on the retina screen it is only a little bit too fast. On the standard screen it moves much faster.

Expected behavior is a "natural" pan where the scene tracks the mouse cursor exactly no matter the browser or screen density.

Sensible behavior on iPad

CADmium should work very well on an iPad or comparable Android tablet. It should support finger gestures as well as Apple Pencil and comparable Android products.

This could be handled in phases:

  1. Make CADmium render well. Make sure button sizes and gestures are sensible
  2. Support Apple Pencil for detailed sketch work
  3. Figure out file sharing or syncing across devices, because iPads are almost always accessories to a real laptop somewhere

Include Discord Link in UI

Currently there is a github icon in the app bar that links to the repo. Let's also include a Discord icon that links to the Discord

Why are the messages not generated by rust?

At this point the Message enum and trivial methods around it are handwritten all over the project:

  • the project::Message rust enum
  • the Message TS type in types.d.ts (which is not the same as Message_GeneratedFromRust)
  • most of the typeGuards functions
  • more?

is that a design choice for some reason?

My thought was to have a single point of truth (rust) and then auto-generate everything else (using macros, build scripts, you name it). Any reason NOT to sink my time into that/design constraints?

Add CLA and write a FAQ about the chosen license

A lot of people in Discord have raised that the chosen license (elastic) is a bit scary.

I think a FAQ in the readme should address common questions and a CLA (Contributor License Agreement) should be required before the first contribution of a person.

I've gathered some questions:

  • Can I host a CADmium instance for my family?
  • Can I host a CADmium instance for my company for internal use?
  • Can I host a CADmium instance for my company for my clients as a free service?
  • Can I host a CADmium instance for my company for my clients as a paid service?
  • If you choose at some point to stop developing CADmium, what will/can happen to the project?
  • If I fork the project and change it (rebranding or adding a new feature) can I host it myself?
    • Do I have to publish my fork?

Add a Favicon

On Firefox on a Mac, the favicon for CADmium seems to be absent. On Chrome it looks like a globe which I suspect is the default favicon when the page doesn't provide one.

Let's make the project logo the favicon!

Gradual Transitions when resetting View

Currently you can reset the view in two ways:

  1. For any Plane in the history, hit the magnifying glass
  2. Use the Gizmo in the upper right corner to hit a plane

In both cases the view is reset, but it can be disorienting because it happens instantly. It would be much better if the effect was gradual, easing your viewport into the new location.

Very nice :)

Just stopping by to say that I like your work :) I'm also working on something similar.

I was wondering two things:

  • The code you have for doing extrusions from shapes using truck seems to accumulate wires before converting to a face last, and then extruding. Does that approach result in correctly-formed STLs?
  • Your solver seems to be a spring-force solver, which is pretty cool, I've never thought of doing it that way but that makes a ton of sense cuz you can reuse all the best practices from the gamedev world. How has it been working? Does it converge well? (I went the other way and tried doing a numerical solver using derivatives and it kinda works lol)

-Tom

Sometimes Gizmo gets clipped by Scene Contents

If you draw a big plate and then zoom in until it is behind the Gizmo, you can at some angles see interference between the Gizmo and what is drawn in the scene:

Screenshot 2024-06-02 at 11 47 57 PM Screenshot 2024-06-02 at 11 48 13 PM

Expected behavior is that the Gizmo be above the scene no matter what, never getting clipped

Support Dark Mode

We currently use TailwindCSS for the front-end. Tailwind supports Dark Mode.

We should support having a toggle button for switching between Dark and Light mode. We should also support remembering what the user set their preference to, and perhaps support listening to the operating system's default.

For the right person, this should only take a couple hours!

Remove unused UI components

The "mattferraro.dev" in the upper right corner is a placeholder that will one day hold the user's own username. For now it is unused and should be removed.

The "Solve" and "Step" buttons are a holdover from a previous experiment building an iterative 2D constraint solver. They are no longer necessary and should be removed.

Show version or commit in Frontend

cadmium-co.github.io/CADmium/
This is very nice, because we can just test the Application there, but it would be nice to have an Information about which version / commit this is built from. Users could refer to the Version if they find bugs etc.

Maybe this could be done via env variables?

Dark Mode Improvements

We have basic support for Dark Mode, but some things could be improved:

  1. Switch to a different set of SVGs that are optimized for Dark Mode, or at least optimized to be okay in light or dark
  2. Toggle the material for the Gizmo--currently it's just a middle ground that looks okay in both
  3. Toggle the material for solids that you make
  4. Toggle the material for Faces so that you can more clearly see when a Face is being moused over
  5. Toggle the material for Planes so that they are slightly lighter instead of slighter darker in Dark Mode

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.