Code Monkey home page Code Monkey logo

juliusjs's Introduction

JuliusJS

A speech recognition library for the web

Try the live demo.

JuliusJS is an opinionated port of Julius to JavaScript.
It actively listens to the user to transcribe what they are saying through a callback.

// bootstrap JuliusJS
var julius = new Julius();

julius.onrecognition = function(sentence) {
    console.log(sentence);
};

// say "Hello, world!"
// console logs: `> HELLO WORLD`
Features:
  • Real-time transcription
  • Use the provided grammar, or write your own
  • 100% JavaScript implementation
  • All recognition is done in-browser through a Worker
  • Familiar event-inspired API
  • No external server calls

Quickstart

Using Express 4.0
  1. Grab the latest version with bower
  • bower install juliusjs --save
  1. Include julius.js in your html
  • <script src="julius.js"></script>
  1. Make the scripts available to the client through your server
var express = require('express'),
    app     = express();

app.use(express.static('path/to/dist'));
  1. In your main script, bootstrap JuliusJS and register an event listener for recognition events
// bootstrap JuliusJS
var julius = new Julius();

// register listener
julius.onrecognition = function(sentence, score) {
    // ...
    console.log(sentence);
};
  • Your site now has real-time speech recognition baked in!

Configure your own recognition grammar

In order for JuliusJS to use it, your grammar must follow the Julius grammar specification. The site includes a tutorial on writing grammars.
By default, phonemes are defined in voxforge/hmmdefs, though you might find other sites more useful as reference.

  • Building your own grammar requires the mkdfa.pl script and associated binaries, distributed with Julius.
  • On Mac OS X
    • Use ./bin/mkdfa.pl, included with this repo
  • On other OS
    • Run emscripten.sh to populate bin with the necessary files
  1. Write a yourGrammar.voca file with words to be recognized
  • The .voca file defines "word candidates" and their pronunciations.
  1. Write a yourGrammar.grammar file with phrases composed of those words
  • The .grammar file defines "category-level syntax, i.e. allowed connection of words by their category name."
  1. Compile the grammar using ./bin/mkdfa.pl yourGrammar
  • The .voca and .grammar must be prefixed with the same name
  • This will generate yourGrammar.dfa and yourGrammar.dict
  1. Give the new .dfa and .dict files to the Julius constructor
// when bootstrapping JuliusJS
var julius = new Julius('path/to/dfa', 'path/to/dict');

Advanced Use

Configuring the engine

The Julius constructor takes three arguments which can be used to tune the engine:

new Julius('path/to/dfa', 'path/to/dict', options)

Both 'path/to/dfa' and 'path/to/dict' must be set to use a custom grammar

'path/to/dfa'
  • path to a valid .dfa file, generated as described above
  • if left null, the default grammar will be used
'path/to/dict'
  • path to a valid .dict file, generated as described above
  • if left null, the default grammar will be used
options
  • options.verbose - if true, JuliusJS will log to the console
  • options.stripSilence - if true, silence phonemes will not be included in callbacks
  • true by default
  • options.transfer - if true, captured microphone input will be piped to your speakers
  • this is mostly useful for debugging
  • options.*
  • Julius supports a wide range of options. Most of these are made available here, by specifying the flag name as a key. For example: options.zc = 30 will lower the zero-crossing threshold to 30.
    Some of these options will break JuliusJS, so use with caution.
  • A reference to available options can be found in the JuliusBook.
  • Currently, the only supported hidden markov model is from voxforge. The h and hlist options are unsupported.

Examples

Voice Command

Coming soon...

Keyword Spotting (e.g., API integration)

Coming soon...

In the wild

If you use JuliusJS let me know, and I'll add your project to this list (or issue a pull request yourself).

  1. Coming soon...

Motivation

  • Implement speech recognition in...
  • 100% JavaScript - no external dependencies
  • A familiar and easy-to-use context
    • Follow standard eventing patterns (e.g., onrecognition)
  • As far as accessibility, allow...
  • Out-of-the-box use
    • Minimal barrier to use
      • This means commited sample files (e.g. commited emscripted library)
    • Minimal configuration
      • Real-time (opinionated) use only
        • Hide mfcc/wav/rawfile configurations
  • Useful examples (not so much motivation, as my motivating goals)
    • Voice command
    • Keyword spotting

Future goals

  • Better sample recognition grammar (improves out-of-the-box usability)
  • Examples

Developers

Contributions are welcome! See CONTRIBUTING.md for guidelines.

Build from source

You'll need emscripten, the LLVM to JS compiler, to build this from the C source. Once you have that, run ./emscript.sh. If you are missing other tools, the script will let you know.

As emscript.sh reloads and recompiles static libraries, ./reemscript.sh is available once you've already run emscript.sh. reemscript.sh will only recompile to JavaScript based on your latest changes. This can also be run with npm make.

Additionally, tests are set will be made to run using npm test.
In the meantime, a blank page with the JuliusJS library can be served using npm start.

Codemap

emscript.sh / reemscript.sh

These scripts will compile/recompile Julius C source to JavaScript, as well as copy all other necessary files, to the js folder.

emscript.sh will also compile binaries, which you can use to create recognition grammars or compile grammars to smaller binary files. These are copied to the bin folder.

src

This is where the source for Julius will go once emscript.sh is run. emscript.sh will replace certain files in src/julius4 with those in src/include in order to make src/emscripted, the files eventually compiled to JavaScript.

  • src/include/julius/app.h - the main application header
  • src/include/julius/main.c - the main application
  • src/include/julius/recogloop.c - a wrapper around the recognition loop
  • src/include/libjulius/src/adin_cut.c - interactions with a microphone
  • src/include/libjulius/src/m_adin.c - initialization to Web Audio
  • src/include/libjulius/src/recogmain.c - the main recognition loop
  • src/include/libsent/configure[.in] - configuration to add Web Audio
  • src/include/libsent/src/adin/adin_mic_webaudio.c - input on Web Audio

Files in bold were changed to replace a loop with eventing, to simulate multithreading in a Worker.

js

The home to the testing server run with npm start. Files are copied to this folder from dist with emscript.sh and reemscript.sh. If they are modified, they should be commited back to the dist folder.

dist

The home for committed copies of the compiled library, as well as the wrappers that make them work: julius.js and worker.js. dist/listener/converter.js is the file that actually pipes Web Audio to Julius (the compiled C program).


JuliusJS is a port of the "Large Vocabulary Continuous Speech Recognition Engine Julius" to JavaScript

juliusjs's People

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

juliusjs's Issues

The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.

During the page loading ,
in chrome console it is showing

julius.js:22 The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu

problem is here

var initializeAudio = function(audio) {
audio.context = new (window.AudioContext || window.webkitAudioContext)();
audio.processor = audio.context.createScriptProcessor(4096, 1, 1);
};

Please somebody tell me how to solve this..

Log dump of current experience, it was really insistant on speaking to kenneth.

04:38:13.805 navigator.mozGetUserMedia has been replaced by navigator.mediaDevices.getUserMedia julius.js:37:16
04:38:28.033 First pass:  <s> GET juliusjs:23:15
04:38:31.736 First pass:  <s> DIAL FOUR ONE TWO </s> juliusjs:23:15
04:38:31.833 Sentence:  DIAL FOUR ONE TWO juliusjs:19:15
04:38:34.883 First pass:  <s> GET juliusjs:23:15
04:38:41.242 First pass:  <s> PHONE KEN </s> juliusjs:23:15
04:38:41.376 Sentence:  PHONE KEN juliusjs:19:15
04:38:41.861 First pass:  <s> GET juliusjs:23:15
04:38:54.431 First pass:  <s> DIAL OH </s> juliusjs:23:15
04:38:54.653 Sentence:  DIAL OH juliusjs:19:15
04:39:00.726 First pass:  <s> DIAL OH </s> juliusjs:23:15
04:39:00.894 Sentence:  DIAL TWO juliusjs:19:15
04:39:06.012 First pass:  <s> DIAL ONE </s> juliusjs:23:15
04:39:06.026 Sentence:  DIAL ONE juliusjs:19:15
04:39:08.606 First pass:  <s> GET juliusjs:23:15
04:39:16.799 First pass:  <s> CALL ME KENNETH juliusjs:23:15
04:39:16.816 Sentence:  DIAL EIGHT ONE juliusjs:19:15
04:39:26.178 First pass:  <s> CALL ME KENNETH </s> juliusjs:23:15
04:39:26.292 Sentence:  CALL ME KENNETH juliusjs:19:15
04:39:27.402 First pass:  <s> GET juliusjs:23:15
04:39:30.432 First pass:  <s> CALL ME KENNETH juliusjs:23:15
04:39:30.439 Sentence:  CALL ME KENNETH juliusjs:19:15
04:39:33.035 First pass:  <s> CALL ME KENNETH juliusjs:23:15
04:39:33.040 Sentence:  CALL ME KENNETH juliusjs:19:15
04:39:36.007 First pass:  <s> GET ME KENNETH juliusjs:23:15
04:39:36.013 Sentence:  GET ME YOUNG juliusjs:19:15
04:39:37.770 First pass:  <s> GET juliusjs:23:15
04:39:43.440 Sentence:  PHONE YOUNG juliusjs:19:15
04:39:46.412 First pass:  <s> DIAL OH EIGHT FIVE SEVEN FOUR FOUR OH OH FIVE juliusjs:23:15
04:39:46.439 Sentence:  DIAL EIGHT FIVE SEVEN FOUR FOUR OH juliusjs:19:15
04:39:59.222 First pass:  <s> GET juliusjs:23:15
04:39:59.433 First pass:  <s> DIAL ONE TWO FIVE juliusjs:23:15
04:39:59.450 Sentence:  DIAL ONE TWO juliusjs:19:15
04:40:00.440 First pass:  <s> GET juliusjs:23:15
04:40:05.912 First pass:  <s> DIAL EIGHT SEVEN TWO OH ONE TWO OH FIVE juliusjs:23:15
04:40:05.926 Sentence:  DIAL TWO TWO SEVEN TWO OH OH ONE TWO juliusjs:19:15
04:40:06.747 First pass:  <s> GET juliusjs:23:15
04:40:06.749 Sentence:  GET KEN juliusjs:19:15
04:40:11.917 First pass:  <s> GET KEN </s> juliusjs:23:15
04:40:11.918 Sentence:  GET KEN juliusjs:19:15
04:40:12.784 First pass:  <s> GET juliusjs:23:15
04:40:12.786 Sentence:  DIAL OH juliusjs:19:15
04:40:14.830 First pass:  <s> GET juliusjs:23:15
04:40:14.832 Sentence:  DIAL OH juliusjs:19:15
04:40:16.128 First pass:  <s> GET juliusjs:23:15
04:40:16.132 Sentence:  DIAL EIGHT juliusjs:19:15
04:40:17.894 First pass:  <s> CALL STEVE juliusjs:23:15
04:40:17.898 Sentence:  DIAL OH OH juliusjs:19:15
04:40:19.380 First pass:  <s> GET juliusjs:23:15
04:40:19.381 Sentence:  GET KEN juliusjs:19:15
04:40:21.143 First pass:  <s> CALL STEVE juliusjs:23:15
04:40:21.146 Sentence:  CALL STEVE juliusjs:19:15
04:40:24.397 First pass:  <s> DIAL TWO SEVEN TWO EIGHT SEVEN FIVE juliusjs:23:15
04:40:24.406 Sentence:  DIAL TWO OH EIGHT EIGHT SEVEN juliusjs:19:15
04:40:29.972 First pass:  <s> GET juliusjs:23:15
04:40:29.973 Sentence:  GET YOUNG juliusjs:19:15
04:40:37.034 First pass:  <s> DIAL EIGHT </s> juliusjs:23:15
04:40:37.047 Sentence:  DIAL EIGHT juliusjs:19:15
04:40:39.723 First pass:  <s> GET juliusjs:23:15
04:40:39.727 Sentence:  PHONE YOUNG juliusjs:19:15
04:40:43.436 First pass:  <s> CALL KENNETH juliusjs:23:15
04:40:43.439 Sentence:  PHONE YOUNG juliusjs:19:15
04:40:45.714 First pass:  <s> CALL STEVEN YOUNG </s> juliusjs:23:15
04:40:45.719 Sentence:  CALL STEVEN YOUNG juliusjs:19:15
04:40:47.429 First pass:  <s> GET KENNETH juliusjs:23:15
04:40:47.432 Sentence:  GET KEN juliusjs:19:15
04:40:49.288 First pass:  <s> CALL KENNETH </s> juliusjs:23:15
04:40:49.292 Sentence:  CALL KENNETH juliusjs:19:15
04:40:51.423 First pass:  <s> GET ME KENNETH juliusjs:23:15
04:40:51.429 Sentence:  DIAL TWO NINE SEVEN juliusjs:19:15
04:41:00.632 First pass:  <s> CALL STEVEN YOUNG </s> juliusjs:23:15
04:41:00.636 Sentence:  CALL STEVEN YOUNG juliusjs:19:15
04:41:00.761 First pass:  <s> CALL STEVEN YOUNG </s> juliusjs:23:15
04:41:00.766 Sentence:  CALL STEVEN YOUNG juliusjs:19:15
04:41:21.238 First pass:  <s> PHONE KENNETH juliusjs:23:15
04:41:21.241 Sentence:  PHONE KENNETH juliusjs:19:15
04:41:23.282 First pass:  <s> GET ME KENNETH juliusjs:23:15
04:41:23.287 Sentence:  GET ME MACLEAN juliusjs:19:15
04:41:33.126 First pass:  <s> GET MACLEAN </s> juliusjs:23:15
04:41:33.130 Sentence:  GET MACLEAN juliusjs:19:15
04:41:39.721 First pass:  <s> GET juliusjs:23:15
04:41:39.723 Sentence:  PHONE KEN juliusjs:19:15
04:41:42.135 First pass:  <s> GET juliusjs:23:15
04:41:42.139 Sentence:  DIAL EIGHT juliusjs:19:15
04:41:45.860 First pass:  <s> GET juliusjs:23:15
04:41:45.861 Sentence:  DIAL FIVE juliusjs:19:15
04:41:48.174 First pass:  <s> GET juliusjs:23:15
04:41:48.176 Sentence:  DIAL FIVE juliusjs:19:15
04:41:50.680 First pass:  <s> PHONE ME KENNETH juliusjs:23:15
04:41:50.683 Sentence:  DIAL FIVE juliusjs:19:15
04:41:52.074 First pass:  <s> GET STEVE juliusjs:23:15
04:41:57.277 First pass:  <s> GET juliusjs:23:15
04:41:57.279 Sentence:  GET KEN juliusjs:19:15
04:42:02.426 First pass:  <s> GET STEVE juliusjs:23:15
04:42:02.428 Sentence:  PHONE KEN juliusjs:19:15
04:42:03.126 First pass:  <s> PHONE KENNETH juliusjs:23:15
04:42:03.127 Sentence:  PHONE KEN juliusjs:19:15
04:42:06.006 First pass:  <s> GET juliusjs:23:15
04:42:06.008 Sentence:  GET KEN juliusjs:19:15
04:42:07.863 First pass:  <s> GET juliusjs:23:15
04:42:07.865 Sentence:  GET KEN juliusjs:19:15
04:42:18.824 First pass:  <s> GET juliusjs:23:15
04:42:18.828 Sentence:  GET KEN juliusjs:19:15
04:42:24.678 First pass:  <s> GET juliusjs:23:15
04:42:24.690 Sentence:  DIAL TWO juliusjs:19:15
04:42:41.062 First pass:  <s> DIAL ZERO(2) SEVEN TWO EIGHT TWO OH FIVE OH TWO TWO TWO FIVE juliusjs:23:15
04:42:41.085 Sentence:  DIAL ZERO(2) SEVEN EIGHT TWO OH FIVE EIGHT TWO TWO juliusjs:19:15
04:42:41.184 First pass:  <s> GET ME KENNETH juliusjs:23:15
04:42:41.192 Sentence:  DIAL NINE TWO FOUR OH OH EIGHT juliusjs:19:15
04:42:41.319 First pass:  <s> DIAL NINE TWO FIVE TWO FIVE TWO FIVE juliusjs:23:15
04:42:41.327 Sentence:  DIAL NINE TWO FIVE TWO FIVE juliusjs:19:15
04:42:41.595 First pass:  <s> DIAL TWO TWO SIX FOUR OH SEVEN TWO FIVE TWO OH TWO TWO TWO TWO FIVE juliusjs:23:15
04:42:41.635 Sentence:  DIAL TWO TWO SIX FOUR OH SEVEN TWO FIVE TWO OH THREE TWO TWO TWO juliusjs:19:15
04:42:42.137 First pass:  <s> DIAL OH </s> juliusjs:23:15
04:42:42.141 Sentence:  DIAL OH OH juliusjs:19:15
04:42:44.646 First pass:  <s> DIAL NINE FOUR OH FIVE juliusjs:23:15
04:42:44.652 Sentence:  DIAL NINE FOUR OH juliusjs:19:15
04:42:47.432 First pass:  <s> DIAL FOUR FIVE TWO TWO FIVE ONE EIGHT SEVEN FIVE juliusjs:23:15
04:42:47.446 Sentence:  DIAL FOUR FIVE TWO TWO FIVE ONE EIGHT SEVEN juliusjs:19:15

May I ask if this is a reasonable presentation of the current state of this project? To clarify this is at 0% accuracy. Is it possessed?

How can I contribute to improving usability and accuracy?
Who is Kenneth? Maybe he can help.

Demo doesn't work on Safari 7.1

webAudioContext is there but not AudioContext, could the constructor code be replaced with this:

var AudioContext = window.AudioContext || window.webkitAudioContext;
audio.contex = new AudioContext();

Simplify distribution with a build system

The presence of the worker makes it nearly impossible to distribute as a single file - need to investigate possibilities to improve this.

One possibility is workerify, as the worker will need access to additional files.

Audio conversion appears to be invalid

FYI: I'm working on this now, as it appears to be a blocker to using the library. I'm not sure when this stopped working, but I'll try to have it up again ASAP.

ERROR: Error in loading model

worker.js is logging

ERROR: Error in loading model

I've been able to successfully run the demo with the sample data, but sometimes I get that error and I was wondering if it's something you're familiar with before I start troubleshooting the workers.

Thanks a bunch

Error Status:0 when trying to load dfa and dict files via constructor

Is there a working example of loading a custom vocabulary?

I've tried, but whenever I pass the location of the dfa and dict files to the Julius constructor I get the error message below. Even passing in the same sample files that the system defaults to gives the same error message. Please note that the error is different than not finding the file which gives an XMLHttpRequest exception instead, so the system is finding the file.

julius = new Julius(); //works
julius = new Julius('voxforge/sample.dfa','voxforge/sample.dict'); //fails
julius = new Julius('< full path >/voxforge/sample.dfa','< full path >/voxforge/sample.dict'); //fails

Error: Couldn't load file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/voxforge/sample.dfa. Status: 0 : Error
    at stackTrace (file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/recognizer.js:1235:15)
    at Object.FS.handleFSError (file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/recognizer.js:2650:62)
    at _read (file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/recognizer.js:5828:12)
    at ew (file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/recognizer.js:7641:99089)
    at kw (file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/recognizer.js:7641:105411)
    at iw (file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/recognizer.js:7641:103573)
    at dw (file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/recognizer.js:7641:98074)
    at hw (file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/recognizer.js:7641:101813)
    at st (file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/recognizer.js:7625:89226)
    at Ft (file:///Users/brian/software/src/static/plugin_components/juliusjs/dist/recognizer.js:7625:102550) VM146:93recognizer.onmessage 

Only listen on command

Hi!

Is it possible, to pause, resume or abort the Listening?
I don't want the mic to listen contentiously, but only on command.

Compared to the Web Speech API I am basically looking for something like

var recognition = new webkitSpeechRecognition();
recognition.continuous = false;

and then I am manually calling

recognition.start();

is this possibile with JuliusJS?

Best regards

Improve eventing syntax/semantics with better system

Replace .onrecognition, etc. with a more full-fledged eventing system:

  • More established syntax for registering listeners
  • Ability to register multiple listeners to an event, and unregister, etc.

Currently considering browserify, with node's EventEmitter, or the pwn library. Both require refactoring the build system to reduce the amount of files necessary for dist - see #2.

Runtime grammars

Hi,

is there a way to create grammars/dictionaries at runtime?

Provide a demo page

If this is really serverless, then it would be neat to have a demo page. I can't get it to work, but I tried this: iffy@72b6a99

What would it take to have a static page example?

Other Acoustic Models

Hi,

I use custom acoustic (.am.bin) and language (.lm.bin) models in Portuguese for Julius. How can I change the voxforge default acoustic and language models in juliusjs so that I can use my own portuguese grammar? What is the role of the file recognizer.data in julius.js?

Best regards,
Fabio.

International

I am guessing there is probably no support for international grammar even for a set of 4 to 5k words in say arabic or german ?

Make tests

Pipe audio in through an OfflineAudioContext to have standardized tests.

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.