Git Product home page Git Product logo

hyperspace's Introduction

Hyperspace Desktop icon

Hyperspace Desktop

The new beautiful, fluffy client for the fediverse written in TypeScript and React

Hyperspace Desktop on a MacBook Pro

Matrix room Discord server Build Status GitHub release (latest SemVer including pre-releases) License: NPLv4+ Hyperspace

Socialize and communicate with your friends in the fediverse (ActivityPub-powered social networks like Mastodon and Pleroma) with Hyperspace Desktop. Browse your timelines, check in with friends, and share your experiences across the fediverse in a beautiful, clean, and customizable way.

What Hyperspace Desktop offers:

  • A clean, responsive, and streamlined design that fits in with your Mac
  • Support for switching between accounts to access the accounts you use the most
  • Customization support, ranging from several beautiful themes to masonry layout and infinite scrolling
  • Powerful toot composer with media uploads, emojis, and polls
  • Activity and recommended views that give you insight on the community/instance you reside in

Get started

Hyperspace Desktop is available for the major desktop platforms via our downloads page, GitHub, and other store platforms where applicable.

Download from our website ›

Download from a store

Get on the Snap Store Get on the Mac App Store

via WinGet:

winget install HyperspaceDesktop

Build from source

To build Hyperspace Desktop, you'll need the following tools and packages:

  • Node.js v10 or later
  • (macOS-only) Xcode 10 or higher

Installing dependencies

First, clone the repository from GitHub:

git clone https://github.com/hyperspacedev/hyperspace

Then, in the app directory, run the following command to install all of the package dependencies:

npm install

Testing changes

Run any of the following scripts to test:

  • npm start - Starts a local server hosted at https://localhost:3000.
  • npm run electron:build - Builds a copy of the source code and then runs the app through Electron. Ensure that the location key in config.json points to "desktop" before running this.
  • npm run electron:prebuilt - Similar to electron:build but doesn't build the project before running.

The location key in config.json can take the following values during testing:

  • https://localhost:3000: Most suitable for running npm start or running via react-scripts.
  • desktop: Most suitable for when testing the desktop application.

Note: Hyperspace Desktop v1.1.0-beta3 and older versions require the location field to be changed to "https://localhost:3000" before running.

Building a release

To build a release, run the following command:

npm run build

The built files will be available under build as static files that can be hosted on a web server. If you plan to release these files alongside the desktop apps, compress these files in a ZIP.

Building desktop apps

You can run any of the following commands to build a release for the desktop:

  • npm run build:desktop-all: Builds the desktop apps for all platforms (eg. Windows, macOS, Linux). Will run npm run build before building.
  • npm run build:win: Builds the desktop app for Windows without running npm run build.
  • npm run build:mac: Builds the desktop apps for macOS without running npm run build. See the details below for more information on building for macOS.
  • npm run build:mas: Builds the desktop apps for the Mac App Store without running npm run build. See the details below for more information on building for macOS.
  • npm run build:linux: Builds the desktop apps for Linux (eg. Debian package, AppImage, and Snap) without running npm run build.
  • npm run build:linux-select-targets: Builds the desktop app for Linux without running npm run build. Targets are required as parameters.

The built files will be available under dist that can be uploaded to your app distributor or website.

Extra steps for macOS

The macOS builds of Hyperspace Desktop require a bit more effort and resources to build and distribute accordingly. The following is a quick guide to building Hyperspace Desktop for macOS and for the Mac App Store.

Gather your tools

To create a code-signed and notarized version of Hyperspace Desktop, you'll need to acquire some provisioning profiles and certificates from a valid Apple Developer account.

For certificates, make sure your Mac has the following certificates installed:

  • 3rd Party Mac Developer Application
  • 3rd Party Mac Developer Installer
  • Developer ID Application
  • Developer ID Installer
  • Mac Developer

The easiest way to handle this is by opening Xcode and going to Preferences › Accounts and create the certificates from "Manage Certificates".

You'll also need to create a provisioning profile for Mac App Store distribution and save it to the desktop folder as embedded.provisonprofile.

Create your entitlements files

You'll also need to create the entitlements files in the desktop directory that declares the permissions for Hyperspace Desktop. Replace TEAM_ID with the appropriate Apple Developer information and BUNDLE_ID with the bundle ID of your app.

entitlements.mac.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>com.apple.security.network.client</key>
    <true/>
    <key>com.apple.security.files.user-selected.read-write</key>
    <true/>
  </dict>
</plist>
entitlements.mas.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.cs.allow-jit</key>
	<true/>
	<key>com.apple.security.network.client</key>
	<true/>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
	<true/>
	<key>com.apple.security.application-groups</key>
	<array>
		<string>TEAM_ID.BUNDLE_ID</string>
	</array>
	<key>com.apple.security.files.user-selected.read-only</key>
	<true/>
	<key>com.apple.security.files.user-selected.read-write</key>
	<true/>
</dict>
</plist>
entitlements.mas.inherit.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.inherit</key>
	<true/>
	<key>com.apple.security.cs.allow-jit</key>
	<true/>
	<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
	<true/>
	</dict>
</plist>
entitlements.mas.loginhelper.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
  </dict>
</plist>
info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>ElectronTeamID</key>
	<string>TEAM_ID</string>
	<key>com.apple.developer.team-identifier</key>
	<string>TEAM_ID</string>
	<key>com.apple.application-identifier</key>
	<string>TEAM_ID.BUNDLE_ID</string>
</dict>
</plist>
Edit notarize.js

You'll also need to edit notarize.js in the desktop directory. Replace <TEAM_ID>, <BUNDLE_ID>, and <APPLE_DEVELOPER_EMAIL> with the appropriate information from the app and your account from Apple Developer.

// notarize.js
// Script to notarize Hyperspace for macOS
// © 2019 Hyperspace developers. Licensed under Apache 2.0.

const { notarize } = require("electron-notarize");

// This is pulled from the Apple Keychain. To set this up,
// follow the instructions provided here:
// https://github.com/electron/electron-notarize#safety-when-using-appleidpassword
const password = `@keychain:AC_PASSWORD`;

exports.default = async function notarizing(context) {
    const { electronPlatformName, appOutDir } = context;
    if (electronPlatformName !== "darwin") {
        return;
    }

    console.log("Notarizing Hyperspace...");

    const appName = context.packager.appInfo.productFilename;

    return await notarize({
        appBundleId: "<BUNDLE_ID>",
        appPath: `${appOutDir}/${appName}.app`,
        appleId: "<APPLE_DEVELOPER_EMAIL>",
        appleIdPassword: password,
        ascProvider: "<TEAM_ID>"
    });
};

Note that the password is pulled from your keychain. You'll need to create an app password and store it in your keychain as AC_PASSWORD.

Build the apps

Run any of the following commands to build Hyperspace Desktop for the Mac:

  • npm run build:mac - Builds the macOS app in a DMG container.
  • npm run build:mac-unsigned - Similar to build:mac, but skips code signing and notarization. Use only for CI or in situations where code signing and notarization is not available.
  • npm run build:mas - Builds the Mac App Store package.

Licensing and Credits

Hyperspace Desktop is licensed under the Non-violent Public License v4+, a permissive license under the conditions that you do not use this for any unethical purposes and to file patent claims. Please read what your rights are as a Hyperspace Desktop user/developer in the license for more information.

Hyperspace Desktop has been made possible by the React, TypeScript, Megalodon, and Material-UI projects as well our Patrons and our contributors on GitHub.

Contribute

Contribution guidelines are available in the contributing file and when you make an issue/pull request. Additionally, you can access our Code of Conduct.

If you want to aid the project in other ways, consider supporting the project on Patreon.

hyperspace's People

Contributors

alicerunsonfedora avatar ariasuni avatar audmaxwell avatar bleonard252 avatar dependabot[bot] avatar travisk-codes 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

hyperspace's Issues

[Bug] Well-known login check is failing because of different timeline endpoint

Describe the bug
The well-known instance login check to ensure the instance is a valid Mastodon instance is failing because it tries to go to /api/v1/public but returns a 404, causing validation to fail. It should be pinging /api/v1/timelines/public instead.

To Reproduce
Steps to reproduce the behavior:

  1. Open Hyperspace.
  2. Try to login to an instance like m.g3l.org.

Expected behavior
The validation should succeed and continue as normal.

Screenshots
Screen Shot 2019-10-12 at 12 18 09

App Information (please complete the following information):

  • OS: Arch Linux
  • Version: 1.0.0

Additional context
This might have been caused due to a change in Mastodon's API when moving to v3.0.0. This will need to be checked again.

[Bug] Mac App Store version doesn't load its window

Describe the bug
The main window disappears when the app is launched.

To Reproduce
Steps to reproduce the behavior:

  1. Open Hyperspace

Expected behavior
The main window should appear.

App Information (please complete the following information):

  • OS: macOS 10.15
  • Version: 1.0.0

Additional context
It appears there's an "out of memory" error somewhere...

Log from Terminal:

Error: Error: ENOENT: no such file or directory, open '/Applications/Hyperspace.app/Contents/Resources/app-update.yml'
(node:6521) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open '/Applications/Hyperspace.app/Contents/Resources/app-update.yml'
(node:6521) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open '/Applications/Hyperspace.app/Contents/Resources/app-update.yml'
(node:6521) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:6521) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:6521) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:6521) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

#
# Fatal process OOM in CodeRange setup: allocate virtual memory
#

[Bug] Buffer prevents loading snaps/AppImages

This might be the emulation machine or an spading problem with AppImage/snap, but I've found that Electron seems to crash due to some issue with Buffer. More specifically:

if (encoding == 'utf8') return buf.utf8Slice(start, end);

RangeError: Index out of range

Timeline streaming fails on Pleroma

Hello

I want to read every toot I receive. So I would like to have an option for hyperspace to load the new messages without auto-scrolling to the newest.

Thanks

[Bug] Vibrancy effect on MacOS Catalina broken

In the beta versions of macOS Catalina, the vibrancy effects goes berserk when working with auto mode. This might be due to an issue with the current implementation of switching from light to dark mode and will need some further refinements.

[Enhancement request] Multi-account support

We currently have hidden UI for account switching, though we haven't successfully implemented the logic to do this. I'm guessing we'll need a way to either switch the local storages around or store settings as JSON objects per user.

To do

  • Devise logic to support multiple accounts
  • Design UI for more than one login on Welcome page
  • Make easy method to switch between accounts with access tokens

Search function breaks on desktop app

The search function in the desktop version breaks when performing a search, claiming that the app got an undefined instead of a string. This might be due to the way the protocol is implemented.

image

Note: clicking on a tag doesn't result in this issue either.

[Enhancement request] Possible instance card redesign

Instance information contains much more than its URL and owner. Furthermore, it'd be nice to view terms of service and invite someone to an instance (if allowed) from the interface without going to the actual web frontend to do so (eg. "Configure on Mastodon").

I think I might have some UI for this. Thoughts?
Hyperspace Instance Card Redesign

[Enhancement request] Granular control for notification badge

Currently, the notification badge forcibly shows new notifications when the app receives a new one without accounting for any existing ones that the user might not have seen before. I often find myself opening the notifications panel time and time again because I don't see anything for new notifications.

There should be a new setting that dictates what the badge will display:

  • The total notifications on the server
  • Only new notifications

This might be toggled as a user string under the setting displayOnNotificationBadge with either a string or the type "all" | "new". In theory, this could probably be done as a bool so that it works with setUserDefaultBool and getUserDefaultBool.

[Bug] Private API Rejection on Hyperspace 1.0.2 (MAS)

Describe the bug
This is just a reminder on the issue regarding a private API rejection:

Your app includes a version of an SDK from Electron that violates the App Store Review Guidelines. The version of the Electron SDK you are using in your app attempts to hide the use of private APIs. This is a violation Section 2.5.1 of the App Store Review Guidelines.

Found private class usage:
CAContext
CALayerHost
NSAccessibilityRemoteUIElement
NSNextStepFrame
NSThemeFrame
NSURLFileTypeMappings

As well as a crash:

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes:       0x0000000000000001, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Illegal instruction: 4
Termination Reason:    Namespace SIGNAL, Code 0x4
Terminating Process:   exc handler [3221]

Application Specific Information:
dyld: launch, running initializers
/usr/lib/libSystem.B.dylib
Could not set sandbox profile data: Operation not permitted (1)

App Information (please complete the following information):

  • OS: macOS 10.15
  • Version 1.0.2

Additional context
Issue reported on electron/electron#20027

[Design bug] Posts have varying sizes on mobile screens, clips visibility icon

Posts in different sections of Hyperspace have different padding rules when compared to the timeline. As such, some parts of posts get clipped inside and thus cause problems.

There are a few things that should be done to prevent this and possibly remove visual clutter on smaller devices:

  • Fix the padding so it matches the timelines
  • Hide the 'Open in Web'/'Show thread' buttons and move them to the overflow menu.

[Request] Adopt a masonry layout on wider screens

Currently, Hyperspace forces a one-column view of posts that scales across devices. However, it might be better to implement something that can fold out into a grid of posts like Google+ did (masonry layout):

Google+ homepage

Image from Wiktor Olejniczak's Design Overview — Google+

  • credit to Azazer via email for this request

Possible challenges

  • Computation of post sizes in grid might slow down app
  • Existing NPM packages might not have TypeScript/Material-UI support
  • <Grid> element in Material-UI is not masonry-responsive

Error dialog about systemPreferences.subscribeNotifications() on Linux

When opening the app, I get this message:

A JavaScript error occurred in the main process

Uncaught Exception:
TypeError: systemPreferences.subscribeNotification is not a function
  at createWindow (/opt/Hyperspace/resources/app.asar/build/- electron.js:149:23)
  at App.<anonymous> (/opt/Hyperspace/resources/app.asar/build/- electron.js:293:5)
  at App.emit (events.js:199:15)

Screenshot_20190730_235133

[Bug] Search bar reloads page instead of searching on desktop apps

Describe the bug
When trying to perform a search on the desktop versions of Hyperspace, the page reloads instead of navigating to the page.

To Reproduce
Steps to reproduce the behavior:

  1. Open the Hyperspace desktop app.
  2. Try searching for anything.

Expected behavior
The search page should load with search results.

App Information (please complete the following information):

  • OS: macOS 10.15
  • Version 1.0.0beta7

Additional context
This might be an issue within Electron itself and the code might need to be rewritten.

Implement keyboard shortcuts

Hyperspace 0.7 introduced keyboard shortcuts for the compose window and in other parts of the app, besides the Ctrl/Cmd + Enter functionality. They aren't present in the beta just yet, so we should work on adding them back in.

AppImage and snap sandboxes not configured

When I try to execute appimage on Manjaro I am presented with this console output
[5591:0619/213110.898717:FATAL:setuid_sandbox_host.cc(157)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /tmp/.mount_HypersgkUaW5/chrome-sandbox is owned by root and has mode 4755. Trace/breakpoint trap (core dumped)

[Bug] "Enable push notifications" setting always defaults to false

The 'enable push notifications' setting in the Settings pane will always reset to false on a browser reload or re-navigation. It doesn't affect page navigation.

Possible causes

  • createUserDefaults keeps resetting the preference due to an error
  • Disabling user notifications the first time when asked causes setting reset

[Bug] Client authentication malformed errors

In some cases and on certain installations of Hyperspace, the authentication process fails, reporting the following error:

Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.

This has been noticed with gopherdonapp/app (though this might be a different issue) and also with Hyperspace 1.0.0beta1u1 by @[email protected] at the hyperspaceapp-next URL.

Possible causes

  • Dynamic redirect URL methods in deployment don't work correctly in Megalodon.
  • HTTPS authentication conflicts

Possible solutions

  • Add a parameter in config.json that explicitly states the URL to which Hyperspace will be hosted.
  • Reserve dynamic redirects for the desktop app and/or as a fallback to the parameter.
  • Use hyperspaceapp:// protocol for desktop app redirection

"build-desktop" command appears not to exist

Instructions tell you "build-desktop" should create a deployable .deb of the application. I tried build-desktop, npm build-desktop and npm build desktop and none of those work.

jtd@Volans:~/hyperspace$ npm version
npm WARN npm npm does not support Node.js v10.15.2
npm WARN npm You should probably upgrade to a newer version of node as we
npm WARN npm can't make any promises that npm will work with this version.
npm WARN npm Supported releases of Node.js are the latest release of 4, 6, 7, 8, 9.
npm WARN npm You can find the latest version at https://nodejs.org/
{ hyperspace: '1.0.0-beta5',
  npm: '5.8.0',
  ares: '1.14.0',
  cldr: '34.0',
  http_parser: '2.8.0',
  icu: '63.1',
  modules: '64',
  napi: '3',
  nghttp2: '1.36.0',
  node: '10.15.2',
  openssl: '1.1.1b',
  tz: '2018e',
  unicode: '11.0',
  uv: '1.24.1',
  v8: '6.8.275.32-node.12',
  zlib: '1.2.11' }
jtd@Volans:~/hyperspace$ npm --version
5.8.0
jtd@Volans:~/hyperspace$ nodejs --version
v10.15.2

[Bug] Boosted/reblogged post menu has blue outline when focused in Chrome

Description
Title mostly explains it. Chrome will place a blue outline around focused buttons. Because non-boosted posts do not have this outline, I assume it is unwanted behavior (and I personally find it unattractive)

To Reproduce
Steps to reproduce the behavior:

  1. Open app in Chrome (version below)
  2. Find a boosted post and click the "more" menu button
  3. Should see menu items with the "focused" blue outline (see screenshot)

Expected behavior
Match styles of non-boosted post menu (no outline)

Screenshots
Screenshot 2019-10-18 at 22 38 42

App Information

  • OS: Chrome OS version 77.0.3865.105
  • Browser: Chrome (help/about redirects to Chrome OS version when using Chrome on Chrome OS?)

Additional Context
I have a fix ready (basically just adding an "outline: none" style), but I hear it's good etiquette to submit an issue first :)

[Bug] Performance hit on Pleroma instance

Hi,

When I startup Hyperspace it hits my Pleroma instance pla.social hard. CPU utilization goest 100%. Here is the thread I started about it. There is a video of the dev console that may give a clue as to what is happening. Let me know if I can provide any more data.

Thanks, PLA

[Proposal] Profile page redesign

Currently, this is our profile page design:

image

As nice as this layout might be, there might be better ways to design this page. From my understanding, there are some notable issues (thanks to @Martmists for pointing some of these out):

  • Not everything is properly aligned in the center of the page
  • Not all information is displayed (tables)
  • Technically has "two" toolbars (buttons at bottom and the one icon in the top right on the user's own profile)
  • Not really Material Design friendly

We should probably work on making a better-designed profile page that is as beautiful as it is functional.

About page blanks in Pleroma instances

Initially from #65 . Details as follows from @bleonard252:

My Pleroma instance seems to run very well on Hyperspace. The number one bug I'm running into is the About page-- it flashes a "Loading" screen then the whole page blanks. The Firefox Inspector shows an empty div.root element.

Re-review licensing

This issues falls in-tandem with #71 and #86.

As per a suggestion from [REDACTED]:

@alicerunsonfedora as you've got a rather small number of contributors, please consider switching to [REDACTED] NPL license so that gab users can't just fork it and use it for hate anyway without being in violation of the license

consider her CNPL license as well, it includes additional restrictions on hierarchical commercial usage

If we merge these changes, we'll need to update our license. We need to keep in mind of the following things:

  • The OSS license should still give us the proper permissions to submit apps to the Mac App Store (licenses like GPL are MAS-incompatible).
  • The license should also fall in line with the aforementioned suggestion so that Hyperspace isn't misused or re-written to be misused.

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.