Code Monkey home page Code Monkey logo

busrouter-sg's Introduction

BusRouter SG

Singapore Bus Routes Explorer 🚌 πŸ—Ί πŸ‡ΈπŸ‡¬

Explore bus stops and routes on the map for all bus services in Singapore, with realtime bus arrival times and per-bus-stop passing routes overview.

Website Β Β Β  Blog Post

Screenshot of BusRouter SG

Screenshot of BusRouter SG

✨ Features

  • All bus stops shown even in low zoom levels.
  • Full routes display with all stops for every service.
  • View all routes passing through a stop.
  • Bus arrival times for every stop.
  • First/last timings for all services.

πŸ•° Previously

Previously known as Singapore Bus Routes Explorer, abbreviated as 'SBRE' and previously looks like this:

Screenshot of Singapore Bus Routes Explorer

Visualization mini-site

A separate mini-site showing ALL stops and routes on a map. All of them.

Check it out: Visualization mini-site (⚠️ Uses a lot of bandwidth).

Technicalities

Data

All data such as bus stops, services and routes are mostly scraped from https://www.lta.gov.sg/, which means they are copyrighted by the Land Transport Authority.

They are available here: cheeaun/sgbusdata.

Web App

The scripts for the web app:

  • npm start - start server for development
  • npm run build - build for production and deployment, in ./dist folder.

Localization

Crowdin

➑️ Start translating ⬅️

Visualization

At least Node.js 14 is required.

The scripts to generate the data, in order:

  1. node visualization/build-routes.mjs
    • Reads data.busrouter.sg/v1/data/stops.min.json and transform routes data with "levels" for 3D extrusion.
    • Generates visualization/data/routes.json and visualization/data/levels.json to be read by the build-stops script.
  2. node visualization/build-stops.mjs
    • Reads data.busrouter.sg/v1/data/stops.min.geojson and buffered into triangle polygons which will be 3D-extruded.
    • Generates visualization/data/stops.3d.json.

πŸ“œ License

Data Β© LTA Β© OneMap Β© OSM contributors. Everything else: MIT

🎀 Feedback

If you have any feedback, leave them on Discussions or tweet me @cheeaun on Twitter.

πŸ™‡β€ Credits

busrouter-sg's People

Contributors

cheeaun avatar cpwc 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

busrouter-sg's Issues

Just curious about list of bus stops and bus numbers

Hi.. one of great projects. Saw the railrouter and taxirouter too. Just curious.
How do you get the list of all bus stops and bus numbers. I checked out in LTA datamall, but it seems like it doesn't provide the whole list. Thanks.

Bus stop routes overview: colours distinguishing up/downroute

I'm not sure how the current colour scheme is programmed, but would it be possible to, for a bus stop routes overview (for example [https://busrouter.sg/#/stops/59051/routes] ) to colour route segments going towards the bus stop (i.e. uproute) in one colour, and segments going away from the bus stop (i.e. downroute) in another? For stops where the same service serving opposite destinations both ply (e.g. 139 at BS 52109 or 856 at BS 47201), two separate lines can be shown.

This is a good-to-have feature of course and doesn't require priority.

Route Amendment of SMRT 951E, Amendments due to Joo Koon Interchange Launch and New Bus Services 47, 117 & 118 Not Reflected

Hi, I have been an avid user of SBRE since I found out about it around half a year ago. However, I have noticed that some of the information has been outdated.

Firstly, the route of SMRT service 951E has been slightly tweaked in Woodlands, with the service skipping parts of Ave 4 and the whole of Ave 1, plying via Ave 5 and a longer section of Ave 12 instead, since 12 October 2015. Diagrams and details can be found here: http://www.smrt.com.sg/Portals/0/PDFs/Press%20Release/2015/SMRT%20Svc%20951E%20Route%20Amendment%20Poster%20final.pdf

Secondly, the routes of numerous SBS services serving Boon Lay and Joo Koon have been amended, while some routes have been added, in conjunction with the launch of Joo Koon Interchange. Due to the long list of route amendments, new bus routes and my lack of knowledge about the bus services in the area, I am only able to provide you with an external link with all the details here: https://publictransportsg.wordpress.com/2015/10/21/joo-koon-bus-interchange-launch-guide/

Lastly, there are 3 new SBS services which were just launched yesterday on 20 December 2015. The services are 47, 117 and 118, plying between Changi Business Park Terminal-Amber Road (Loop), Sembawang-Punggol and Changi Business Park-Punggol, respectively. More information can be found here: https://www.sbstransit.com.sg/download/svcs_47_117_118_979.pdf . In addition, there would be a new SMRT service 979 and a route amendment to service 983, as well as numerous minute amendments to buses serving around the new Bukit Panjang MRT in the upcoming week taking place on 27 December 2015. All information is at this link: https://publictransportsg.wordpress.com/2015/12/08/dtl2-bukit-panjang-bus-service-enhancements/ .

Thank you for your attention :)

Freezes on Firefox Android

Opening busrouter.sg on Firefox Android will work for a few seconds before the tab stops responding. Opening new tabs will only show a black screen and will not load any webpage entered in the address bar. Even killing and restarting Firefox does not fix it. Only after some indefinite duration of not using Firefox after that, then Firefox can work again. It happened to me at least 5 times already but I did not investigate further what causes it or what fixes it. The website works fine on Chrome Android.

Firefox 84.1.4
Android 7.0

Route alignment issues

Hey, please take note of the following services whose routes appear misaligned:

  • 15, 969/A (Tampines Ave 12)
  • 400 (Marina Blvd)
  • 53A, 359 (Pasir Ris Dr 1 beside St 11 closed)
  • 39, 53/A, 81, 89/A, 109, 403, 518/A (Pasir Ris Dr 1 near MRT closed)
  • 30, 79, 143/M, 201, 655 (Realignment of Teban Gardens Rd; BS20201/9 relocated)
  • 65 (Tampines Ave 4 for return route)
  • 66 (Return loop goes via Jln Anak Bukit & Jln Jurong Kechil)
  • 300 (Wrong routing after BS44621)
  • 92/M, 100, 111 (Extension in Ghim Moh)
  • 80 (Amended to Cantonment Link & Rd)
  • 78/A, 160/A, 870/A (Jurong Town Hall Int opening)
  • 75, 121, 162/M, 859 (TEL3 rationalisation)
  • 992/A, 993 (Tengah extensions)

Will add more if I can find them.

Route updates, 2021

Hi, I was checking this site (https://landtransportguru.net/singapore-public-bus-timeline-2020s/ ), and I think there are some service routes to be updated:

[List updated 17 December 2021]

(Misrouted/need update routes)

  • 22, 65, 66, 506
  • 75, 100, 107, 130, 131/A, 167

(Misaligned routes)

  • 15, 89A, 123, 359 (east), 400, 965T, 969

(Bus stops)

  • 14, 18, 69, 155, 168, 222, 225G/W, 228: Bedok North St 1
  • 20: Changi Business Park Cres
  • 35: Aviation Pk Rd

That should be all I can find now, please take note!
If you are busy or need some help with updating the routes, can teach me so as well so I can help during my freetime.

`grunt fixBadRoutes` fails and exits

I get this output:

Running "fixBadRoutes" task
File "data/2/bus-services/7.json" modified with route 1 data.
File "data/2/bus-services/8.json" modified with route 1 data.
File "data/2/bus-services/8.json" modified with route 2 data.
File "data/2/bus-services/13.json" modified with route 1 data.
File "data/2/bus-services/13.json" modified with route 2 data.
File "data/2/bus-services/14.json" modified with route 1 data.
File "data/2/bus-services/16.json" modified with route 1 data.
File "data/2/bus-services/26.json" modified with route 2 data.
File "data/2/bus-services/31.json" modified with route 2 data.
File "data/2/bus-services/48.json" modified with route 2 data.
File "data/2/bus-services/56.json" modified with route 1 data.
File "data/2/bus-services/56.json" modified with route 2 data.
Fatal error: Cannot call method 'split' of undefined

I added an if (line) { condition to encapsulate https://github.com/cheeaun/busrouter-sg/blob/master/tasks/fix-bad-routes.js#L28-L41 plus a debug message and I see quite a few fail:

File "data/2/bus-services/7.json" modified with route 1 data.
File "data/2/bus-services/8.json" modified with route 1 data.
File "data/2/bus-services/8.json" modified with route 2 data.
File "data/2/bus-services/13.json" modified with route 1 data.
File "data/2/bus-services/13.json" modified with route 2 data.
File "data/2/bus-services/14.json" modified with route 1 data.
File "data/2/bus-services/16.json" modified with route 1 data.
File "data/2/bus-services/26.json" modified with route 2 data.
File "data/2/bus-services/31.json" modified with route 2 data.
File "data/2/bus-services/48.json" modified with route 2 data.
File "data/2/bus-services/56.json" modified with route 1 data.
File "data/2/bus-services/56.json" modified with route 2 data.
Fix for service 57/2 failed.
File "data/2/bus-services/61.json" modified with route 2 data.
File "data/2/bus-services/65.json" modified with route 2 data.
Fix for service 66/1 failed.
File "data/2/bus-services/67.json" modified with route 1 data.
File "data/2/bus-services/67.json" modified with route 2 data.
File "data/2/bus-services/77.json" modified with route 2 data.
File "data/2/bus-services/89.json" modified with route 1 data.
File "data/2/bus-services/90.json" modified with route 1 data.
File "data/2/bus-services/97.json" modified with route 1 data.
File "data/2/bus-services/97.json" modified with route 2 data.
File "data/2/bus-services/107.json" modified with route 1 data.
File "data/2/bus-services/107.json" modified with route 2 data.
File "data/2/bus-services/125.json" modified with route 1 data.
File "data/2/bus-services/130.json" modified with route 1 data.
File "data/2/bus-services/131.json" modified with route 1 data.
File "data/2/bus-services/131.json" modified with route 2 data.
File "data/2/bus-services/139.json" modified with route 1 data.
File "data/2/bus-services/139.json" modified with route 2 data.
File "data/2/bus-services/142.json" modified with route 1 data.
File "data/2/bus-services/147.json" modified with route 2 data.
File "data/2/bus-services/151.json" modified with route 1 data.
File "data/2/bus-services/151.json" modified with route 2 data.
File "data/2/bus-services/154.json" modified with route 1 data.
File "data/2/bus-services/162.json" modified with route 2 data.
File "data/2/bus-services/166.json" modified with route 1 data.
Fix for service 166/2 failed.
File "data/2/bus-services/170.json" modified with route 1 data.
File "data/2/bus-services/170.json" modified with route 2 data.
File "data/2/bus-services/171.json" modified with route 2 data.
File "data/2/bus-services/174.json" modified with route 2 data.
Fix for service 175/2 failed.
File "data/2/bus-services/190.json" modified with route 2 data.
File "data/2/bus-services/700.json" modified with route 2 data.
File "data/2/bus-services/851.json" modified with route 1 data.
File "data/2/bus-services/851.json" modified with route 2 data.
File "data/2/bus-services/853.json" modified with route 1 data.
Fix for service 853/2 failed.
File "data/2/bus-services/960.json" modified with route 1 data.
File "data/2/bus-services/960.json" modified with route 2 data.
File "data/2/bus-services/980.json" modified with route 1 data.
File "data/2/bus-services/107M.json" modified with route 1 data.
File "data/2/bus-services/162M.json" modified with route 1 data.
Fix for service 700A/1 failed.
Fix for service 853C/1 failed.
File "data/2/bus-services/853C.json" modified with route 2 data.
File "data/2/bus-services/971E.json" modified with route 2 data.
File "data/2/bus-services/1N.json" modified with route 1 data.
Fix for service 2N/1 failed.
Fix for service 3N/1 failed.
File "data/2/bus-services/4N.json" modified with route 1 data.
File "data/2/bus-services/5N.json" modified with route 1 data.

Is that expected?

Multiple bus routes

Hi! Good work!

I wonder if it is possible to visualize multiple bus lines at the same time.

Best wishes

[feature request] Add NUS bus routes data

Data can be retrieved from:
http://nextbus.comfortdelgro.com.sg/testMethod.asmx/GetBusStops?output=json
and
http://nextbus.comfortdelgro.com.sg/testMethod.asmx/GetShuttleService?busstopname=COM2
Bus routes data can be retrieved from:
http://www.nus.edu.sg/oca/Transport/Getting-around-NUS.html

I am a frequent user of your website, and I appreciate the work. It would be great if you can integrate the internal shuttle buses into your website as well. Thanks πŸ˜„

Offline support

Make the web app work offline. At least show some text and load the stored localStorage data. Currently it's being blocked by the gzip-enabled.js dependency which seems kind of weird.

Location with Firefox Preview

Not sure if it's an issue with site or browser, but on Firefox Preview (Android), requesting location doesn't work and just get stuck so I have to manually pull into my location to check the bus stop bus arrivals.

Bus Routes Overlaying

The ability to view a bus route in Google Map is very informative. But wouldn't it be outstanding if you are able to choose three bus service number and "busrouter-sg" will HIGHLIGHT the bus stops that is COMMON (the two or three buses will stop at the same bus stop) to them.

Rationale: Let us assume that you want to go from Point A to Point B, and you want to know what are your choices and the fastest route to reach Point B. And we want to know at which bus stop(s) will these two or three service numbers will be common. This will allow us to plan our routes more efficiently as we might want to stop over a certain place and the "busrouter-sg" will inform us that if the bus number you were in just now had already passed by the time you came back to the bus stop you alighted, you will still be able to catch up the other two service numbers.

Unintuitive sorting behaviour

Previously, the bus services were sorted by the main service number in ascending order, but currently they are grouped together based on the first digit of the service number. This might be unexpected by people scrolling through the list.

Errors found from routes 853, 853C, and 81

Dear Sir/Mdm,
We found wrong GPS points from routes 853 and 853C, and route 81 should be a single direction route while you provided us with a dual-directional route.

We would appreciate that you let us know upon completion of the updates.

Backporting functionalities to the old version

Hi, I currently have a need to work using a different browser (LibreWolf). It doesn't support the newest map version and redirects me to the older version (v1.busrouter.sg), which unfortunately doesn't have some functions such as multi-service display, display of service numbers on route lines, and the up-to-date routings.

May I ask if you could try, as a test, to backport (a) the up-to-date routings, (b) the multi-service display function (i.e. "services/234")? And if possible also (c) showing service numbers on route lines, and (d) showing bus stop codes and names on zoomed in?

Much thanks~

Add LICENSE

Perhaps you would consider adding a license? Forgive me if I missed it.

Failing to run grunt fetchBusServices task

I download the repo and then attempt the instructions as per README.

$ grunt fetchBusServices
Running "fetchBusServices" task
Request to mytransport.sg
Request to transitlink.com.sg
Fatal error: Cannot read property 'toLowerCase' of null

Am I somehow doing something wrong, or has something about their website changed?

167e wrong route

The express segment of 167e is wrong. Between bus stop 56099 and 50069, 167e takes the SLE -> CTE to the Moulmein Rd exit. The same applies to the opposite direction (btwn 50061 to 56091).

The route displayed on mytransport.sg (https://www.mytransport.sg/content/mytransport/map.html) is wrong too, so I guess that's the source of error.

Is it possible for me to directly edit the routes json in the '3' folder?

Route of bus service 857 is slightly incorrect

Hi,
The route for service 857 (towards Suntec City/Marina Centre) is shown on your map to make a small loop through Toa Payoh, but in reality it seems to head straight to PIE (Jalan Toa Payoh) from the CTE... this might be another bad route from mytransport.sg?

Roads seem to be missing?

Microsoft Edge 103.0.1264.49.

Map renders like that for me with roads missing.

image

If it helps, I use uBlock Origin, but the issue persists even after turning uBO off.

Debug mode (alt mode) gets stuck when Alt-Tabbing

TL:DR Description: Alt keystroke conflicts with Alt-Tab.
Suggestion: Change the debug hotkey or reset the debug state when clicking on a different stop

Reproduced in Microsoft Edge Dev 86.0.601.1


Long story: I was wondering why the Passing Routes and Bus Arrivals buttons were randomly replaced by the Set as Start and Set as End buttons. Dug into the code, and I eventually found out that the Alt keystroke is used to toggle the alt-mode class.

Turns out what was happening was the down keystroke for the Alt key would fire when switching with Alt-Tab, but the key up event wouldn't be captured while out of focus.

20200817_180459

Bus arrivals do not differentiate between directions/visit number

Some bus services call at the same stop multiple times, or while on different directions.

The best example is Serangoon Garden Circus, stop 66271. There, service 136 calls at the stop in both direction 1 and 2, while service 315 and 317 calls at the same stop twice in the same direction (they're loop services so there's only direction 1).

An example of how this is handled by the MyTransport app attached:
image

Proposed solution

It turns out to solve this, changes would be needed both in busrouter-sg as well as in arrivelah:

  • Update arrivelah to include a field that merges both direction and visit number (I don't think there's a situation that has both)
  • Update busrouter-sg bus arrival page logic to handle having to use both service number and direction as identifier

I've also made a quick mockup of how I envision the updated arrival time page to look:
image

I'm willing to work on this, just want to get a go-ahead before I proceed

Wrong link for bus schedules

Dear Chee Aun,

I suspect that there may be an error with the link for "Bus details and schedules" in the Singapore Bus Routes Explorer Chrome app.

Buses, which belong to SBS Transit, are referred to SMRT Buses webpage when I clicked on "Bus details and schedules", causing a nil return from SMRT Buses; "6's Frequency Table is off-line. We apologise for the inconvenience caused.".

Details for SBS buses should be linked to SBS Transit's page so that information can be correctly loaded. (Hopefully someone can find a way to bypass the verification code, if that hinders the pulling of data from SBS's pages.)

Thank you for making such a great app! :)

Regards,
Lee

Missing Bus routes

Hi,
Your json data for the bus routes and bus stops is very useful. There are a few missing bus routes in the data. Can you add the same ?
I am attaching the service numbers of all the missing routes
route_id
103M-1
125X-1
128-0
170#-1
170#-2
177-2
179A-1
180-2
195A-1
1M-1
231-2
24-2
27-2
284M-1
2M-1
34-2
372-2
3M-1
409-1
4M-1
529-1
53-2
530-1
531-1
531-2
532-1
533-1
534-1
535-1
536-1
537-1
538-1
539-1
540-1
542-1
543-1
544-1
545-1
546-1
548-1
549-1
550-1
551-1
552-1
553-1
554-1
555-1
556-1
557-1
558-1
559-1
560-1
561-1
563-1
564-1
565-1
566-1
569-1
575-1
577-1
580-1
585-1
587-1
588-1
589-1
59-12
590-1
598-1
599-1
5M-1
60X-1
68-1
6M-1
761-1
7M-1
7N-1
85X-1
868E-1
8M-1
8N-1
Premium-1-1
Premium-1-2
Premium-10-1
Premium-11-1
Premium-12-1
Premium-2-1
Premium-3-1
Premium-3-2
Premium-4-1
Premium-4-2
Premium-5-1
Premium-521-1
Premium-522-1
Premium-523-1
Premium-524-1
Premium-525-1
Premium-526-1
Premium-528-1
Premium-529-1
Premium-530-1
Premium-531-1
Premium-531-2
Premium-532-1
Premium-533-1
Premium-534-1
Premium-535-1
Premium-536-1
Premium-537-1
Premium-538-1
Premium-539-1
Premium-540-1
Premium-541-1
Premium-541-2
Premium-542-1
Premium-543-1
Premium-544-1
Premium-545-1
Premium-546-1
Premium-547-1
Premium-547-2
Premium-548-1
Premium-549-1
Premium-550-1
Premium-551-1
Premium-552-1
Premium-553-1
Premium-554-1
Premium-555-1
Premium-556-1
Premium-557-1
Premium-558-1
Premium-559-1
Premium-560-1
Premium-561-1
Premium-562-1
Premium-562-2
Premium-563-1
Premium-564-1
Premium-565-1
Premium-566-1
Premium-567-1
Premium-567-2
Premium-568-1
Premium-569-1
Premium-570-1
Premium-571-1
Premium-571-2
Premium-572-1
Premium-572-2
Premium-573-1
Premium-573-2
Premium-574-1
Premium-574-2
Premium-575-1
Premium-576-1
Premium-577-1
Premium-578-1
Premium-579-1
Premium-580-1
Premium-581-1
Premium-582-1
Premium-585-1
Premium-587-1
Premium-588-1
Premium-592-1
Premium-593-1
Premium-6-1
Premium-7-1
Premium-8-1
Premium-9-1
RW88-1
SS1-1
SS2-1
SS3
SS3-1
SS4-1

Fetching alternative services (e.g. CDS)

Hi,

Possible to add the City Direct Services (CDS) by fetching from alternative website? Unfortunately after much scouring the interwebz for a definitive list of CDSes I failed to find any (tsk, LTA) but here are a few links I could perhaps point you to:

thanks so much!

Geo data for bus stops

Hi,

Where did you get the geo data (lat, long) for the bus stops?

Nice work by the way,
Janaka

CORS Issue

Thanks for making this! It's better than anything I've been able to find elsewhere.

I'm having trouble with Cross-Origin Resource Sharing when launching the app from github.io. It looks like the app is trying to AJAX to an S3 instance, but the CORS headers are not allowing the connection. I temporarily fixed the issue for me by disabling CORS in Firefox, but of course this isn't something most people should be doing when visiting the site. Can you look into enabling CORS in S3? This article might help.

P.S. This was the top hit in Google for "singapore bus map". Nice job.

Search for bus number/route

Offer an easy way to search for a specific bus number, instead of scrolling a long list of bus stop numbers.

Option/feature to show bus routes in text bubbles/pop-ups, for all bus stops

Happy New Year!

I would like to ask if it is possible to have an in-map option, where all routes that serve a group of bus stops in the region can be shown at once (in text form), beside the bus stop code; this would be useful to trace all bus routes on a given map and at the same time won't clutter the map too much. This is also helpful for print-outs.

Some examples I have seen are this new town map at Jurong East Int: (they differentiate JEBI and non-JEBI services but you probably don't need to do that yet)

IMG_20210102_110447

As well as from a very old public transport guide I have (and updating), which is now out of print:

IMG_20210106_175526
IMG_20210106_175514

Hope it works out!

Possible feature: Change route colours on multi-route mode

Could there be a feature that allows manual change of colour for routes when on multi-route mode (either at a bus stop or for a custom selection of routes), such that individual routes can be identified by colour (e.g. 168 in red, 858 in green, 969 in blue)? This would be helpful for screenshots and static images.

Might be technically similar to #47, though the purposes are different. Not urgent and a good-to-have, of course.

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.