Code Monkey home page Code Monkey logo

phantomjs-gem's Introduction

PhantomJS as a RubyGem

Build Status

DISCLAIMER: Alpha status, YMMV!

I am lazy as hell, and wanted to be able to install PhantomJS via Rubygems/Bundler when using poltergeist.

It keeps installations of phantomjs in $HOME/.phantomjs/VERSION/PLATFORM. When you call Phantomjs.path, it will return the path to the phantomjs executable in there. If that is not present, it will first fetch and install the prebuilt packages suitable for the current plattform (currently Linux 32/64 or OS X supported).

If there is a phantomjs executable in your $PATH that matches the version number packaged in this gem, this one will be used instead of installing one in your $HOME/.phantomjs.

You will need cURL or wget on your system. For extraction, bunzip2 and tar are required on Linux, and unzip on OS X. They should be installed already.

TL;DR: Instead of manually installing phantomjs on your machines, use this gem. It will take care of it.

Example

require 'phantomjs'
Phantomjs.path # => path to a phantom js executable suitable to your current platform. Will install before return when not installed yet.

# Or run phantomjs with the passed arguments:
Phantomjs.run('./path/to/script.js') # => returns stdout

# Also takes a block to receive each line of output:
Phantomjs.run('./path/to/script.js') { |line| puts line }

Usage with Poltergeist/Capybara

Add this to your Gemfile:

group :test do
    gem 'poltergeist'
    gem 'phantomjs', :require => 'phantomjs/poltergeist'
end

This will automatically require (and install) phantomjs and configure Capybara in the same way as noted below for manual setup.

Note that you need to add poltergeist as a dependency explicitly since it is not a dependency of this gem in order to avoid forcing users to install poltergeist if the just want to use phantomjs itself.

Manual setup

Add gem 'phantomjs', :group => :test to your Gemfile and run bundle. In your test/spec helper, re-configure the Poltergeist capybara driver to use the phantomjs package from this gem:

require 'phantomjs' # <-- Not required if your app does Bundler.require automatically (e.g. when using Rails)
Capybara.register_driver :poltergeist do |app|
    Capybara::Poltergeist::Driver.new(app, :phantomjs => Phantomjs.path)
end

Check out the poltergeist docs for all the options you can pass in there.

A note about versions.

The gem version consists of 4 digits: The first 3 indicate the phantomjs release installed via this gem, the last one is the internal version of this gem, in case I screw things up and need to push another release in the interim.

Contributing

Warning: The spec_helper calls Phantomjs.implode when it is loaded, which purges the ~/.phantomjs directory. This is no bad thing, it just means every time you run the specs you'll download and install all three packages over, so tread with caution please. :)

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Copyright

(c) 2013-2014 Christoph Olszowka

Note that this project merely simplifies the installation of the entirely separate PhantomJS project via a Ruby gem. You can find the license information for PhantomJS at http://phantomjs.org/

phantomjs-gem's People

Contributors

attilaolah avatar bjeanes avatar brianhawley avatar carl-betts avatar colszowka avatar danielbayerlein avatar francois2metz avatar jabr avatar jeffborg avatar kirs avatar kofno avatar lencioni avatar lukasztackowiak avatar mgrachev avatar raphaelpierquin avatar robinboening avatar sashee 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

phantomjs-gem's Issues

Patch for 1.9.x and 2.1.x releases

I'm looking to submit a few patches. My goal is to get this change merged in both 1.9.x and 2.1.x versions. What should be my target branch for these changes?

As a suggestion, I've seen other projects have dedicated to branches for each minor+ releases. For example: 1.9.3 would be cut from 1.9.x branch.

Support JRuby missing

This gem does not seem to support JRuby.

I get the following message:

Phantomjs::UnknownPlatform: Could not find an appropriate PhantomJS library for your platform (java :( Please install manually.

Install path

Why do you install phantomjs into a hidden folder in the user´s home dir?

Isnt it a way better to store the files in /usr/local/bin ?

You are...

...a gentleperson and a scholar.

🙇

How to pass arguments to a javascript file

I could run a javascript file named 'highcharts-convert.js' which can generate images of charts on server side.
With original phantomjs command, I just run the command lke below:
%phantomjs highcharts-convert.js -infile option.json -outfile chart.png -scale 4 -width 1000 -constr Chart

I just want to do same thing with phantomjs-gem in ruby program, but I can not find a way to pass arguments, e.g., "-infile option.json -outfile chart.png -scale 4 -width 1000 -constr Chart".

Is it possible to pass arguments to the javascript file with phantomjs-gem?

Consider adding a collaborator?

@colszowka: I was wondering if you would consider adding a collaborator to this project. I know maintaining open source code can be a bit of a chore at times, and I would be happy to help with the routine PR's (e.g. binary updates) and what-not.

Thanks!

Linux i486

The gem fails to find a proper binary for my 32 bit Debian server.

The problem is that RbConfig::CONFIG['host_cpu'] reports i486, while uname -m gives me i686.

I guess that RbConfig::CONFIG['host_cpu'] reports the compile configuration of Ruby, not the actual platform. It also will report a 32 bit architecture if you run a 32 bit ruby binary on a 64 bit platform.

I'm not sure if there's a proper way to detect the architecture of the actual platform ruby is running on instead of what it was compiled for (https://github.com/rdp/os does not do this either). Of course one could invoke a shell and ask e. g. uname, but...

The easiest fix would be to install the i686 version of phantom even if RbConfig::CONFIG['host_cpu'] reports i486. The probability of running on an actual i486 or Pentium should be quite low. You could give a warning in that situation. Would be nicer than just giving up.

I can prepare a PR if we agree on a solution for this.

i386-mingw32 is not supported

😞

Could not find an appropriate PhantomJS library for your platform (i386-mingw32 :( Please install manually. (Phantomjs::UnknownPlatform)

Pure Ruby downloader and unzipper

Hey @colszowka,

My fork contains some changes around the download and unzipping of the phantomjs binaries. I work mostly on Windows where curl, wget, unzip and the like are not available without further work. I've added code to use pure Ruby to download (with progress) and Ruby's zip instead of unzip. For Linux it stays the same with bunzip2 and tar.

Are you interested? I'd send a pull request.

Thanks,

Alex

Configurable CDN URL

It'd be useful to be able to download from a different source in case Bitbucket is down (as it currently seems to be). Maybe it's worth just doing what npm's phantomjs-prebuilt does and adding a phantomjs_cdnurl config value.

License missing from gemspec

RubyGems.org doesn't report a license for your gem. This is because it is not specified in the gemspec of your last release.

via e.g.

  spec.license = 'MIT'
  # or
  spec.licenses = ['MIT', 'GPL-2']

Including a license in your gemspec is an easy way for rubygems.org and other tools to check how your gem is licensed. As you can imagine, scanning your repository for a LICENSE file or parsing the README, and then attempting to identify the license or licenses is much more difficult and more error prone. So, even for projects that already specify a license, including a license in your gemspec is a good practice. See, for example, how rubygems.org uses the gemspec to display the rails gem license.

There is even a License Finder gem to help companies/individuals ensure all gems they use meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough issue that even Bundler now generates gems with a default 'MIT' license.

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue with a nice message. In either case, I'll follow up. Thanks for your time!

Appendix:

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), GitHub has created a license picker tool. Code without a license specified defaults to 'All rights reserved'-- denying others all rights to use of the code.
Here's a list of the license names I've found and their frequencies

p.s. In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :). See the previous link or my blog post about this project for more information.

Silence which output to STDOUT

Unsure how good/bad idea this is

But at least locally I've made these changes:

      def system_phantomjs_path
        #`which phantomjs`.delete("\n")
        (system 'which phantomjs', STDOUT: '/dev/null').delete("\n")
      rescue
      end

Maybe others find this a good idea

Cliver::Dependency::NotFound: Could not find an executable ["phantomjs"] on your path

Doesn't work on ubuntu 😢

lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 16.04.2 LTS
Release:	16.04
Codename:	xenial

Cliver::Dependency::NotFound: Could not find an executable ["phantomjs"] on your path.
/var/lib/gems/2.3.0/gems/cliver-0.3.2/lib/cliver/dependency.rb:143:in `raise_not_found!'
/var/lib/gems/2.3.0/gems/cliver-0.3.2/lib/cliver/dependency.rb:116:in `detect!'
/var/lib/gems/2.3.0/gems/cliver-0.3.2/lib/cliver.rb:24:in `detect!'
/var/lib/gems/2.3.0/gems/poltergeist-1.16.0/lib/capybara/poltergeist/client.rb:51:in `initialize'
/var/lib/gems/2.3.0/gems/poltergeist-1.16.0/lib/capybara/poltergeist/client.rb:14:in `new'
/var/lib/gems/2.3.0/gems/poltergeist-1.16.0/lib/capybara/poltergeist/client.rb:14:in `start'
/var/lib/gems/2.3.0/gems/poltergeist-1.16.0/lib/capybara/poltergeist/driver.rb:44:in `client'
/var/lib/gems/2.3.0/gems/poltergeist-1.16.0/lib/capybara/poltergeist/driver.rb:25:in `browser'
/var/lib/gems/2.3.0/gems/poltergeist-1.16.0/lib/capybara/poltergeist/driver.rb:97:in `visit'
/var/lib/gems/2.3.0/gems/capybara-2.15.1/lib/capybara/session.rb:269:in `visit'
/home/ubuntu/repos/slack-queries/lib/tasks/sand.rake:7:in `block in <top (required)>'
/var/lib/gems/2.3.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
Tasks: TOP => sand

CI Issue

Phantomjs does not appear to be installed in /root/.phantomjs/1.9.7/x86_64-linux/bin/phantomjs, installing!
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed

Later on

Phantomjs does not appear to be installed in /root/.phantomjs/1.9.7/x86_64-linux/bin/phantomjs, installing!
/home/ciuser/.rvm/rubies/ruby-2.1.2/lib/ruby/gems/2.1.0/gems/phantomjs-1.9.7.1/lib/phantomjs/platform.rb:53: warning: conflicting chdir during another chdir block

and this might not be related to your gem but:
[06:46:39][Execute spec] 0 12.5M 0 26563 0 0 13245 0 0:16:33 0:00:02 0:16:31 28198/home/ciuser/secondAgent/plugins/rake-runner/rb/patch/bdd/teamcity/spec/runner/formatter/teamcity/rspec3_formatter.rb:251:in dump_summary': undefined local variable or methodcount_notification' for #Spec::Runner::Formatter::TeamcityFormatter:0x00000007ed9908 (NameError)

Doesn't work on Freebsd.

Require ok, but

irb(main):010:0> Phantomjs.path
Phantomjs::UnknownPlatform: Could not find an appropriate PhantomJS library for your platform (amd64-freebsd9 :( Please install manually.

Hope in the future it can be solved.
Thanks :)

Conflicts with brew

I have phantomjs installed in my OS X from brew, but each time I run my specs this gem is trying to install phantomjs one more time. Is it a bug or feature or it's impossible to check if it's already installed in the system?

Configurable download folder?

Maybe this is a dumb idea but I wanted to create an issue page to maybe help somebody in the future who has the problem I just had. I'm setting up Cucumber and Poltergeist and PhantomJS in a Docker container. I'm using the phantomjs gem to install PhantomJS because apt-get can't find the phantomjs package. The gem initially failed to install:

$ docker-compose run web bundle 
exec cucumber
Phantomjs does not appear to be installed in /root/.phantomjs/2.1.1/x86_64-linux/bin/phantomjs, installing!
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:100   333    0   333    0     0    567      0 --:--:-- --:--:-- --:--:--  4162
bunzip2: phantomjs-2.1.1-linux-x86_64.tar.bz2 is not a bzip2 file.
tar: phantomjs-2.1.1-linux-x86_64.tar: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now
There was an error while trying to load the gem 'phantomjs/poltergeist'. (Bundler::GemRequireError)
/usr/local/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:80:in `rescue in block (2 levels) in require'
/usr/local/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
/usr/local/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:72:in `each'
/usr/local/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:72:in `block in require'
/usr/local/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:61:in `each'
/usr/local/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:61:in `require'
/usr/local/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler.rb:99:in `require'
/ticket-driver/config/application.rb:7:in `<top (required)>'
/ticket-driver/config/environment.rb:2:in `require_relative'
/ticket-driver/config/environment.rb:2:in `<top (required)>'
/usr/local/bundle/gems/cucumber-rails-1.4.4/lib/cucumber/rails.rb:7:in `require'
/usr/local/bundle/gems/cucumber-rails-1.4.4/lib/cucumber/rails.rb:7:in `<top (required)>'
/ticket-driver/features/support/env.rb:7:in `require'
/ticket-driver/features/support/env.rb:7:in `<top (required)>'
/usr/local/bundle/gems/cucumber-2.4.0/lib/cucumber/rb_support/rb_language.rb:96:in `load'
/usr/local/bundle/gems/cucumber-2.4.0/lib/cucumber/rb_support/rb_language.rb:96:in `load_code_file'
/usr/local/bundle/gems/cucumber-2.4.0/lib/cucumber/runtime/support_code.rb:142:in `load_file'
/usr/local/bundle/gems/cucumber-2.4.0/lib/cucumber/runtime/support_code.rb:84:in `block in load_files!'
/usr/local/bundle/gems/cucumber-2.4.0/lib/cucumber/runtime/support_code.rb:83:in `each'
/usr/local/bundle/gems/cucumber-2.4.0/lib/cucumber/runtime/support_code.rb:83:in `load_files!'
/usr/local/bundle/gems/cucumber-2.4.0/lib/cucumber/runtime.rb:253:in `load_step_definitions'
/usr/local/bundle/gems/cucumber-2.4.0/lib/cucumber/runtime.rb:61:in `run!'
/usr/local/bundle/gems/cucumber-2.4.0/lib/cucumber/cli/main.rb:32:in `execute!'
/usr/local/bundle/gems/cucumber-2.4.0/bin/cucumber:8:in `<top (required)>'
/usr/local/bundle/bin/cucumber:16:in `load'
/usr/local/bundle/bin/cucumber:16:in `<main>'

It failed because it's trying to download the distribution file to the $HOME folder. That folder didn't exist for that user in my Ruby container.

I solved the problem by adding this to my Dockerfile:

ENV home=/var/tmp

Maybe it might have been nice to be able to specify that somehow through the Gemfile? Not sure if that's even possible? Maybe this is a dumb suggestion you should close, I just wanted to post my story to get it onto the Google radar of anybody who can't figure out how to install PhantomJS in a Docker container using this gem.

Run PhantomJS from user specified directory

It would be helpful to be able to configure the directory that Phantomjs runs from, rather than expecting it to be part of the %PATH%

For Continuous Integration we would like to be able to use a common build tools folder that contains the PhantomJs exe.

Thanks

PhantomJS unresolved dependencies on Debian/Ubuntu

I used your gem, and PhantomJS got installed, but i got an error when trying to use it:

/home/somefolder/.phantomjs/1.9.7/x86_64-linux/bin/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory

Is the same issue they mention here: ariya/phantomjs#10904

After running $ sudo apt-get install libfontconfig everything went great.

Thanks for this gem!

How to stub Phantomjs in Rspec

I'm using Phantomjs to generate Google Charts and convert them to SVG on the server side.

I'm trying to stub this like this:

Phantomjs.stub(:run).and_return("<svg></svg>".html_safe)

But I get:

undefined method `stub' for Phantomjs:Module

Your thoughts?

Thanks,

Steven.

Poltergeist

Hi Colszowka,

We're using your gem in our gem which runs Jasmine with PhantomJS. It works great, thank you for making it.

In our case, though, we do not require poltergeist. It would be nice to use your gem without pulling in that dependency (and it's sub-dependencies, which include large libraries like Capybara and Selenium-webdriver).

It seems to us that it may be preferred that a project which uses phantomjs-gem for capybara might be better served to include the poltergeist dependency itself, rather than automatically through phantomjs.

Would you be able to remove the poltergeist dependency from phantomjs-gem? We would happily fork and create a pull request if this is something that you would consider merging in.

Sincerely,
Phil Kuryloski, Pivotal Labs

not updated to 2.0

phantomjs now has a stable version at 2.0, this should be updated from 1.9.8

specify Phantomjs.path ?

what are thoughts on making Phantomjs.path a writable attribute rather than relying on the path derived from the Phantomjs.VERSION? Is there any way to target another locally built PhantomJS version (ie, another version of PhantomJS or a custom build)?

I assume the only way to use a custom PhantomJS build would be to include it in $PATH with the same version number as the current Phantomjs.VERSION. If that's the case, it would make any code that is reliant on that specific build very difficult to maintain as it would require modifying the files in $PATH whenever I update this gem.

Better error message when bitbucket rate limit is reached

Currently phantomjs gem does this:

unless system "curl -L -O #{package_url}" or system "wget #{package_url}"
  ...

wget will return error code when it fails, so that makes sense, but curl won't - it will get 429 Rate Limit error, save html, and then try to "bunzip2" that, resulting in error message like:

bunzip2: phantomjs-2.1.1-linux-x86_64.tar.bz2 is not a bzip2 file.
tar: phantomjs-2.1.1-linux-x86_64.tar: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

Passing -f to curl will "fix" that problem, and instead of failing with meaningless error message, it will raise

raise "\n\nFailed to load phantomjs! :(\nYou need to have cURL or wget installed on your system.\nIf you have, the source of phantomjs might be unavailable: #{package_url}\n\n"

which still leaves the problem of everybody's CIs failing transiently due to bitbucket rate limit error, but at least they'll fail with a meaningful error message.

Possible better "fix" for this would be to just retry loop 10 times with 1s in between or something like that, or try multiple sources (bitbucket→s3, github→s3 etc.), but this is a start.

Everything is sad if bitbucket is down

Bitbucket is currently down, which causes the following.

One solution is to rescue and not re-raise this error if there is already a matching version of phantomjs in the PATH.

phantomjs does not appear to be installed in /home/rof/.phantomjs/2.1.1/x86_64-linux/bin/phantomjs, installing!
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100 64146    0 64146    0     0  3127k      0 --:--:-- --:--:-- --:--:-- 3296k
bunzip2: phantomjs-2.1.1-linux-x86_64.tar.bz2 is not a bzip2 file.
tar: phantomjs-2.1.1-linux-x86_64.tar: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now
rake aborted!
TypeError: no implicit conversion of nil into String
/home/rof/cache/bundler/ruby/2.2.0/gems/phantomjs-2.1.1.0/lib/phantomjs/platform.rb:72:in `block in install!'
/home/rof/cache/bundler/ruby/2.2.0/gems/phantomjs-2.1.1.0/lib/phantomjs/platform.rb:53:in `chdir'
/home/rof/cache/bundler/ruby/2.2.0/gems/phantomjs-2.1.1.0/lib/phantomjs/platform.rb:53:in `install!'
/home/rof/cache/bundler/ruby/2.2.0/gems/phantomjs-2.1.1.0/lib/phantomjs/platform.rb:86:in `ensure_installed!'
/home/rof/cache/bundler/ruby/2.2.0/gems/phantomjs-2.1.1.0/lib/phantomjs.rb:30:in `platform'
/home/rof/cache/bundler/ruby/2.2.0/gems/phantomjs-2.1.1.0/lib/phantomjs.rb:25:in `path'
/home/rof/cache/bundler/ruby/2.2.0/gems/phantomjs-2.1.1.0/lib/phantomjs/poltergeist.rb:10:in `<top (required)>'
/home/rof/.rvm/gems/ruby-2.2.2/gems/bundler-1.9.5/lib/bundler/runtime.rb:76:in `require'
/home/rof/.rvm/gems/ruby-2.2.2/gems/bundler-1.9.5/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
/home/rof/.rvm/gems/ruby-2.2.2/gems/bundler-1.9.5/lib/bundler/runtime.rb:72:in `each'
/home/rof/.rvm/gems/ruby-2.2.2/gems/bundler-1.9.5/lib/bundler/runtime.rb:72:in `block in require'
/home/rof/.rvm/gems/ruby-2.2.2/gems/bundler-1.9.5/lib/bundler/runtime.rb:61:in `each'
/home/rof/.rvm/gems/ruby-2.2.2/gems/bundler-1.9.5/lib/bundler/runtime.rb:61:in `require'
/home/rof/.rvm/gems/ruby-2.2.2/gems/bundler-1.9.5/lib/bundler.rb:134:in `require'
...
(See full trace by running task with --trace)

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.