Giter Site home page Giter Site logo

anticontainer's Introduction

DownThemAll!

DownThemAll! WE

The DownThemAll! WebExtension.

For those still on supported browser: Non-WebExtension legacy code.

About

This is the WebExtension version of DownThemAll!, a complete re-development from scratch. Being a WebExtension it lacks a ton of features the original DownThemAll! had. Sorry, but there is no way around it since Mozilla decided to adopt WebExtensions as the only extension type and WebExtensions are extremely limited in what they can do.

For what is planned (and not planned because impossible to do in WebExtensions), see TODO.md.

What this furthermore means is that some bugs we fixed in the original DownThemAll! are back, as we cannot do our own downloads any longer but have to go through the browser download manager always, which is notoriously bad at handling certain "quirks" real web servers in the wild show. It doesn't even handle regular 404 errors.

I spent countless hours evaluating various workarounds to enable us to do our own downloads instead of relying on the downloads API (the browser built-in downloader). From using IndexedDB to store retrieved chunks via XHR, to doing nasty service-worker tricks to fake a download that the backend would retrieve with XHR. The last one looks promising but I have yet to get it to work in a manner that is reliable, performs well enough and doesn't eat all the system memory for breakfast. Maybe in the future...

What this also means is that we have to write our user interface in HTML, which never looks "native" and cannot offer deep OS integration.

But it is what it is...

What we can do and did do is bring the mass selection, organizing (renaming masks, etc) and queueing tools of DownThemAll! over to the WebExtension, so you can easily queue up hundreds or thousands files at once without the downloads going up in flames because the browser tried to download them all at once.

Translations

If you would like to help out translating DTA, please see our translation guide.

Development

Requirements

Setup

You will want to run yarn to install the development dependencies such as webpack first.

Making changes

Just use your favorite text editor to edit the files.

You will want to run yarn watch. This will run the webpack bundler in watch mode, transpiling the TypeScript to Javascript and updating bundles as you change the source.

Please note: You have to run yarn watch or yarn build (at least once) as it builds the actual script bundles.

Running in Firefox

I recommend you install the web-ext tools from mozilla. It is not listed as a dependency by design at it causes problems with dependency resolution in yarn right now if installed in the same location as the rest of the dependencies.

If you did, then running yarn webext (additionally to yarn watch) will run the WebExtension in a development profile. This will use the directory ../dtalite.p to keep a development profile. You might need to create this directory before you use this command. Furthermore yarn webext will watch for changes to the sources and automatically reload the extension.

Alternatively, you can also yarn build, which then builds an unsigned zip that you can then install permanently in a browser that does not enforce signing (i.e. Nightly or the Unbranded Firefox with the right about:config preferences).

Running in Chrome/Chromium/etc

You have to build the bundles first, of course.

Then put your Chrome into Developement Mode on the Extensions page, and Load Unpacked the directory of your downthemall clone.

Making release zips

To get a basic unofficial set of zips for Firefox and chrome, run yarn build.

If you want to generate release builds like the ones that are eventually released in the extension stores, use python3 util/build.py --mode=release.

The output is located in web-ext-artifacts.

  • -fx.zip are Firefox builds
  • -crx.zip are Chrome/Chromium builds
  • -opr.zip are Opera builds (essentially like the Chrome one, but without sounds)

The AMO Editors tl;dr guide

  1. Install the requirements.
  2. yarn && python3 util/build.py --mode=release
  3. Have a look in web-ext-artifacts/dta-*-fx.zip

Patches

Before submitting patches, please make sure you run eslint (if this isn't done automatically in your text editor/IDE), and eslint does not report any open issues. Code contributions should favor typescript code over javascript code. External dependencies that would ship with the final product (including all npm/yarn packages) should be kept to a bare minimum and need justification.

Please submit your patches as Pull Requests, and rebase your commits onto the current master before submitting.

Code structure

The code base is comparatively large for a WebExtension, with over 11K sloc of typescript. It isn't as well organized as it should be in some places; hope you don't mind.

  • uikit/ - The base User Interface Kit, which currently consists of
    • the VirtualTable implementation, aka that interactive HTML table with columns, columns resizing and hiding, etc you see in the Manager, Select and Preferences windows/tabs
    • the ContextMenu and related classes that drive the HTML-based context menus
  • lib/ - The "backend stuff" and assorted library routines and classes.
  • windows/ - The "frontend stuff" so all the HTML and corresponding code to make that HTML into something interactive
  • style/ - CSS and images

anticontainer's People

Contributors

derbenx avatar dzmitry-lakisau avatar garyblankenship avatar julien-langlois avatar kennydude avatar marianocarrazana avatar megascience avatar nmaier avatar onurtag avatar poke 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

anticontainer's Issues

Unable to do case sensitive match on URL

In file modules/plugins.jsm
for each (let x in ['match', 'pattern', 'gone']) {
if (x in o) {
o['str' + x] = o[x];
o[x] = new RegExp(o[x], 'im');
}

matching rules are compiled case insensitive, however my requirement is to match on certain uppercase URLs only.
I'm requesting a way to modify this behaviour.

Extract Image 2 Levels Down

What is the best way to extract an image that's 2 levels down? For example, egotastic.com gallery page is http://egotastic.com/2011/09/rihanna-takes-her-world-hot-and-naughty-tour-down-to-rio/. Clicking on one of the image links takes you to http://egotastic.com/2011/09/rihanna-takes-her-world-hot-and-naughty-tour-down-to-rio/rihanna-concert-brazil-06/ which is a scaled image. On the same page as the scaled image is a button that takes you to another page http://egotastic.com/full-size-image/455931. This page has the full size image http://cdn03.cdn.egotastic.com/wp-content/uploads/2011/09/rihanna-concert-brazil-06-830x1245.jpg.

I imagine I'll have to use the sandbox plugin type but I'm not sure how to get it to examine 2 pages for the final image.

Help with plugin for Danbooru

I've been trying to write a plugin for http://danbooru.donmai.us/ but it isn't working so far.
I have been looking at the IMDb plugin because it seems to use a fairly similar structure.

I'm not an experienced developer, I've just researched regrex on Google to try and make sense of it.

Here is what I've been trying:

{ "type": "resolver", "ns": "mordaga.com", "author": "Mordaga", "prefix": "Danbooru Photos", "match": "^http://(danbooru\\.)?donmai\\.us/post/show/[0-9]+/[\x20-\x7E]+", "finder": "<img[^>]+id=\"image\"[^>]+src=\"([^\"]+)\"", "builder": "{1}", "useDefaultClean" : false }

Any help would be appreciated.

Thanks,
Mordaga

XMLHTTPRequest/Request not working with FF 4 Beta 11

Hi all, I wrote a sandbox plugin for mass-downloading full res pictures from webshots.com and it uses the Request object. I will post it in a few hours.
It works perfectly in FF 3.6.13 but it stalls on 4 Beta 11 as soon as I call "open". Does FF4 changes it? I read of new features but it should work the same.
Cheers!

Release 1.3

  • QA DTA release
  • QA DTA 3
  • Create XPI
  • AMO
  • GH

Have Debug Option to Assist in Developing

I am working on the following plugin:

{
  "type": "resolver",
  "ns": "krohn.ky",
  "author": "kmon",
  "prefix": "egotastic.com",
  "priority": 10,
  "match": "^http://egotastic\\.com[/]+full-size-image/[0-9]+",
  "static": true,
  "finder": "src=['\"](http://cdn[0-9]+\\.cdn\\.egotastic\\.com/wp-content/uploads/[0-9]+/[0-9]+/.*?)['\"] class=\"attachment-large\"",
  "builder": "{1}",
  "debug": true
}

This is SUPPOSED to get the bottom images from source pages such as: http://egotastic.com/2011/11/reader-finds-kelly-kelly-covered-topless-geri-halliwell-teen-naughty-taylor-swift-bikini-top-olivia-wilde-private-pics-and-much-more/ but for the life of me I can't get it to work. All I get is the "Failed to extract from container" error. I have verified that it is getting the correct page (HTTP result 200), that the regex is correct (using a regex tester) and that no errors are thrown (by turning on the debug logging).

I am now out of places to look for the cause of the failure. It would be awesome if we could have something that would give us a lot more information during the development process for the plugin. Then once it was working we could turn it off. I noticed in the code the following block in the manager.js:

let m = obj.finder.exec(this.responseText);
if (obj.debug) {
alert(obj.finder)
alert(this.responseText);
alert("m:" + m);
}

So, I added the debug option to my JSON above but didn't get anything. Could this be added? And if you have any suggestions for my plugin, that would be great too.

AC does not work in FF 8 Beta

DownthemAll 2.0.8 works OK in FF 8 Beta but the AntiContainer component does not. It installs or stays installed, but will not execute, show, or import any plugins including the builtins. When I attempted to create a plugin, I believe I got a dialog box with a blank titlebar, a blank content area equal to the titlebar, and an X button. The plugin was not created.

imagetwist.com filter possible?

I'm afraid the filter-writing is far over my head, but would it be possible to add a filter for imagetwist.com? Great plugin; thank you in advance!

Myspace.com

Hello.

Could you denvelop a plugin for Myspace.com?

Thanks

Some new sites to plugins support

Filepap.com
upsimple.com
imgbox.com
dumparump.com
photobucket.com
4pics.org
sharenxs.com
picsplash.com
imagetwist.com
suxorz.com
ompldr.org
imageupload.org
suxorz.com
bildr.no
clip2net.com
imgchili.com
imgur.com
gyazo.com
imageshack.us (outdated)
urlgalleries.com
imageporter.com

Thanks!

ieeexplore.ieee.org plugin

IEEE Xplore offers free downloads of "Classic" titles for members. However, each book is broken up into chapters that have to be downloaded separately.

This plugin takes care of that. (All that's required after is to merge the PDFs into a single one.)

The Writing Plugins wiki page states that to share a plugin, one can either create a pull (which I can't figure out how to do) or to post an issue.

So here goes.

{
  "type": "redirector",
  "ns": "nonymous",
  "author": "go2null",
  "prefix": "ieeexplore.ieee.org",
  "match": "^http://ieeexplore.ieee.org/xpl/ebooks/bookPdfWithBanner.jsp\\?fileName=([0-9]+).pdf&bkn=([0-9]+)$",
  "static": true,
  "pattern": "^.*fileName.([0-9]+).*bkn.([0-9]+)$",
  "replacement": "http://ieeexplore.ieee.org/ebooks/$2/$1.pdf?bkn=$2"
}

All comments welcome.

new anticontainer script for www.bobx.com/dark

{
"type": "redirector",
"ns": "www.bobx.com",
"author": "Ian Clark",
"prefix": "www.bobx.com",
"match": "bobx.com/[a-zA-Z-]idol/[0-9a-zA-Z-//]large",
"static": true,
"pattern": "idol/([0-9a-zA-Z-]
)/large-[a-zA-Z-]
([0-9]*)/",
"replacement": "idol/$1/$1-00$2.jpg"
}

Simple page examiner: "Failed to extract URL from container *" despite correct URL in DtA

Since an initial lesson in JSON escapes, I've made dozens of successful page expanders. In the last few months, I've been having trouble with "Failed to extract URL" but the problems have all been complicated so I assumed I was writing bad regex. This case seems as simple as possible, and I can't make it work. Either I'm making a fool of myself again or something's wrong.

I want to patch some holes in my 8-Bit Theater run.
Code:

{
    "type": "resolver",
    "ns": "downthemall.net",
    "author": "Hypocee",
    "prefix": "8-Bit Theater",
    "match": "nuklearpower.com",
    "static": true,
    "finder": "img src=\"(http://.\\.cdn\\.nuklearpower\\.com/.*?)\"",
    "builder": "{1}"
}

The regex is a little sloppy, yes, but it finds the right thing and only the right thing.

Used on pages like:
http://www.nuklearpower.com/8-bit-theater-archive/?archive_year=2001

AC processes the container page properly. The target images appear in the DtA manager with their proper filenames, but all downloads fail with the "Failed to extract URL" error.
If I get "Download Information" on any download in DtA and copy-paste that URL into Firefox, I go directly to the desired image.
Save directory was created from the DtA filepicker, is empty and remains empty.
DtA 2.0.8, AC 20010913 nightly
WinXP Pro 32 SP3
FF 7.0.1

Creating XMLHttpRequest in sandbox throws error

When calling new XMLHttpRequest from within a sandbox plugin, the following exception is raised:

Error: [Exception... "Failure"
    nsresult: "0x80004005 (NS_ERROR_FAILURE)"
    location: "JS frame :: resource://dtaac/sandboxfactories.jsm :: XMLHttpRequest_WRAP :: line 55"
    data: no]
Source File: resource://dtaac/sandboxfactories.jsm
Line: 55

The line in question is within the constructor of the wrapped XHR, where the inner XHR object is instantiated. Apparently the constructor throws an exception:

this._xhr = new XMLHttpRequest();

I tried to figure out why it happens, but I’m a bit lost now. The constructor XMLHttpRequest itself is available; and many related problems on the web with that error code say it’s cross-site-related, but by the time the line gets executed there’s no information about any URL yet.

Bug on FlickR

Hello everybody

I have discovered AntiContainer several weeks ago, and it was the perfect add-on for mass-downloading on FlickR.

But since I have upgraded to FF8 with to AntiContainer 1.2, FlickR plugin doesn't work.
When I add a new link with right-click, the download is blocked on "Starting" and it never starts.
On another computer, I have tried with FF7 and AC1.1 and I have the same problem.

I don't know if it happens only to me, or if FlickR website has changed, but if someone could take a look on it, it would be great, because writing a script is just impossible for me.

Thanks in advance =)

imdb.com and last.fm

Hi,
Sorry if this is not the best place to request this, but I was wondering if someone might create a filter for imdb.com galleries, and also last.fm galleries?

For example, there are 884 photos of Angelina Jolie on imdb.com, each on an individual page.
http://www.imdb.com/name/nm0001401/mediaindex

Or on last.fm, each artist has hundreds of photos also. Here's an example:
http://www.last.fm/music/Florence%2B%252B%2Bthe%2BMachine/+images

It would be great to be able to easily save some of these photos, with downthemall + anticontainer, but I'm not smart enough to create a filter :(
Can anyone help?

Sarah.

Request.send() with paramaters?!

I was writing a plugin and with new request i needed to send request with method 'POST"
(i needed this to submit form and the form uses method "POST")

anyway, according to this : https://developer.mozilla.org/en/XMLHttpRequest
send can take optional parameter represent the body of the message (only in case of "POST")

I wrote the plugin and it didn't work ,so i checked the source code and i found this
in XMLHttpRequest.prototype in sandboxfactories module line 99

the send function always sends null whatever parameters she get

and in sandboxscripts.js line 69 in Request.Prototype also the send function
does't take parameters

so i changed that and it worked
i was able to send the request and submit the form and the plugin worked successfully

so i wanted to point you guys to that issue so that it can be fixed

thank you for the great plugin.

Show plugin used.

Would it be possible to include somewhere on the download information popup what plugin is being used to grab an image? I just had an issue where the wrong plugin was getting called and I couldn't figure out why. I finally noticed that the wrong plugin name flashed briefly in the download window. But, it is gone in less than a second and there is nowhere to see it afterwards.

iwiw.hu

Hello.

Should you denvelop a filter for iwiw.hu?

Thanks

Make compatible with restartless dta-3

Do not make AC restartless at this point. Right now it is enough to make it compatible with the new module system, in particular the new internal module system that already landed.

ImgChill plugin broken

avidone:

"Failed to extract URL" error message on ImgChilli galleries now
Previously Downthemall with AntiContainer was successful at downloading galleries from ImgChilli. Now the "failed to extract..." error message is displayed. Can it be made to work again?

Migrated from https://bugs.downthemall.net/ticket/2204

Make generator expression syntax accept nested expressions

Expand the generator expression syntax, used in both the generator and builder properties, to accept nested expressions within or and replace expressions. The following use cases are of interest:

  • {or:{url:1},2} – to use url-matches instead of the normal finder-matches.
  • {replace:{url:1},regexp,replacement} – similar, to run a replacement on an url-match.
  • {or:1,{replace:2,regexp,replacement}} – to run a replacement on the match first.
  • {replace:{or:1,2},regexp,{3}} – and other really crazy combinations.

To support this, the expression functions would implicitely translate single numbers in parameters automatically to {num:N} (or {N}), providing full backwards compatibility.

Alternative would be to use a sandbox for this, but I feel that adds a lot more complexity than necessary.

Merged filter expression is incompatible with the JS version

As already announced in #60, there some bug which is why I had to disable the filter generation/merging again in 58cb117.

It is mere coincidence what pref()s are parsed last. It relies on the enumeration of the "directory", may it be an OS enumeration or ZipReader enumeration. My guess is that the ZipReader returns dtaac.js, filters.js while the OS returns it the other way round (by coincidence).

As it turns out, the enumeration actually seems consistent, but my observation was simply wrong. When I install a blank AntiContainer XPI, the default filter is actually empty. It’s just that (usually) the filter generation runs directly so it does not make a difference. When looking at about:config and resetting that value however, it is empty. So it seems that the generated and merged filter expression is never actually used, hence this issue never occuring before.

With my build process changes the preferences are now only set once, so nothing can overwrite another, so the filter expression definitely makes it into the running extension. And there the following issue happens:

As soon as you open dTa, either the download dialog, the manager or the preferences, it wants to load the filter definition and fails with the following error:

Error: invalid quantifier
Source File: resource://dta/support/filtermanager.jsm
Line: 97

I’ve already tried debugging a bit, and the error happens when the merged expression is converted to a RegExp object. Apparently some quantifier ({ }, *, + or ?) is misplaced or not escaped correctly, but I don’t know what exactly happens (or should happen) there.

As that problem blocks the plugin completely, I disabled the filter generation temporarily, which basically results in the same as it was before (as the actually written filter was never read).

jCarousel images

A number of the sites I grab images from have started using the jCarousel library. This library gives you a horizontal strip with thumnails below a zoomed image. The problem with this is that it keeps only a certain quantity of thumbnails active. As you scroll left or right, new thumbnails are brought in and old ones discarded. If the gallery has say 60 images then only 18 maybe loaded. If all the filenames are basically the same except for an incremental sequence number then I can use the batch download to get the images. But if the file names are all different, it becomes much more difficult. Do you have any idea on the best way to handle sites using this library?

Plugin Help

I have a site that uses the following convention:
Gallery Page: http://hq-celebrity.com/super-sexy-irina-shayk-on-the-runway-in-mexico/
Picture Pages: http://hq-celebrity.com/photos/irina-shayk-2011-11-29/irina-shayk-6, http://hq-celebrity.com/photos/irina-shayk-2011-11-29/irina-shayk-7,http://hq-celebrity.com/photos/irina-shayk-2011-11-29/irina-shayk-1, etc.
Image Link: http://hq-celebrity.com/photos/irina-shayk-2011-11-29/irina-shayk-6.jpg

So the picture page and the actual image link are almost the same save that the image has the proper extension on it. I have been trying to create a redirector plugin that just adds ".jpg" to the end of the URL but I can't seem to get it working. I suspect that because the 2 URLs are basically the same that AC is re-matching it. Is there someway to do this?

Here's my plugin:

{ "type": "redirector", "ns": "krohn.ky", "author": "kmon", "prefix": "hq-celebrity.com", "match": "^http://hq-celebrity\\.com/photos/", "static": true, "pattern": "(.*)", "replacement": "http://$1\.jpg" }

Facebook hi-res plugin

http://www.luminaria.cc/en/2011/02/firefox-plugin-to-download-high-resolution-albums/

{
"type": "sandbox",
"useDefaultClean": false,
"prefix": "Luminaria.cc - Facebook Hi-Res",
"static": false,
"match": "^http://(www\\.)?facebook\\.com/photo\\.php\\?",
"ns": "Luminaria.cc",
"author": "Francesco Luminaria",
"date": 1298242799000,
"resolve":"var hd = responseText.match(\"]+href=\\\"([^\\\"]+?jpg)\\\"[^>]?\"); if (hd == null) hd = responseText.match(\"]+src=\\\"([^\\\"]+?)\\\"[^>]+id=\\\"myphoto\\\"[^>]*/>\"); setURL(hd[1]); finish();"
}

Body-rockin.com

Hello.

Could you denvelop a plugin for Body-rockin.com?

Thanks

Help with Plugin for Egotastic

I have the following plugin which grabs images from Egotastic.com (for example: http://egotastic.com/2011/09/go-nuts-preview-of-the-sexiest-2012-glam-model-calendars/). But I keep getting the error "Failed to extract url from container"? I have used a regex tester and confirmed that the proper URL to the image is being pulled from the page by my finder.

{
  "type": "resolver",
  "ns": "krohn.ky",
  "author": "kmon",
  "priority": 1,
  "prefix": "egotastic.com-rs1",
  "match": "^http://egotastic\\.com[/]+full-size-image/[0-9]+",
  "static": true,
  "finder": "src=\"(http://cdn[0-9]+\\.cdn\\.egotastic\\.com/wp-content/uploads/[0-9]+/[0-9]+/.*?)\" class=\"attachment-large\"",
  "builder": "{1}"
}

Plugin for - http://forums.ozcelebs.net/ - phpBB

Hi,
Just thought i share a plug-in for Anti-container that i wrote. someone with more knowledge of phpBB may be able to modify it so that it might work as for all phpBB forum attachment plugin.

Test URL: http://forums.ozcelebs.net/viewtopic.php?f=88&t=4979&sid=96a6c6f97f6fcbb55901392b12535915&start=1350

{
"type": "redirector",
"ns": "nonymous",
"author": "Anti-Container User #1",
"prefix": "http://forums.ozcelebs.net",
"match": "http://forums\.ozcelebs\.net/fileSystem/displayImage\.php\?id=(.+)",
"pattern": "http://forums\.ozcelebs\.net/fileSystem/(.+)Image\.php\?id=",
"replacement": "showImage.php?id="
}

Facebook photos

Doesn't seem to work any more - error message:
Failed to extract URL from container

Expander Usage

I have a site that uses page #s to link to the individual image pages. For example. the blog will have some text story and then at the bottom will have 1 2 3 4 5 6 7 8 9 10 11 12... etc. Each of the numbers will link to a page with 1 or more images (full size, not linked). Could I create an expander that would create a new job for each number and then each new job would download the images on it's page? Thanks!

khinsider (migrated)

AMurphy6091:

Anti-Container plugin Request
There is a domain (downloads.khinsider.com) which contains individual direct download links for songs from a long list of video game soundtracks. Recently. I have tried using DownThemAll to acquire all these songs at once but end up with ~27kb "htm" files. I have Anti-Container but have no idea how to write a plugin to circumvent this. If you could either write it or include it in an update, it would be much appreciated.

Migrated from https://bugs.downthemall.net/ticket/2207

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.