GithubHelp home page GithubHelp logo

image_picker_web's Introduction

ImagePickerWeb

Issues Stars Pub Version Flutter Web CI

This Web-Plugin allows Flutter Web to pick images (as File, Widget or Uint8List) and videos (as File or Uint8List). Many thanks goes to AlvaroVasconcelos for the implementation of picking images in his plugin: flutter_web_image_picker

ExampleGif

Disclaimer for Videos

  • Till now [Mar. 2020] it's not possible (due to security reasons) to play a local video file (see also video_player_web). But you can retreive the file and upload them somewhere and play it as a network source.

Getting Started

Add image_picker_web to your pubspec.yaml:

image_picker_web: any

Picking Images

Pick an image

Load image as Image.memory Widget:

Image? fromPicker = await ImagePickerWeb.getImageAsWidget();

Load image as bytes:

Uint8List? bytesFromPicker = await ImagePickerWeb.getImageAsBytes();

Load image as and html.File object :

html.File? imageFile = (await ImagePickerWeb.getMultiImagesAsFile())?[0];

Pick multiple images

Load images as a List<Image> :

List<Image>? fromPicker = await ImagePickerWeb.getMultiImagesAsWidget();

Load images as bytes :

List<Uint8List>? bytesFromPicker = await ImagePickerWeb.getMultiImagesAsBytes();

Load images as List<html.File> objects :

List<html.File> imageFiles = await ImagePickerWeb.getMultiImagesAsFile();

How do I get all Informations out of my Image/Video (e.g. Image AND File in one run)?

Besides the standard getImage() or getVideo() methods you can use the getters:

  • getImageInfo or
  • getVideoInfo to acheive this.

Full Example

import 'dart:html' as html;
 
import 'package:mime_type/mime_type.dart';
import 'package:path/path.dart' as Path;
import 'package:image_picker_web/image_picker_web.dart';
import 'package:flutter/material.dart';

 html.File _cloudFile;
 var _fileBytes;
 Image _imageWidget;
 
 Future<void> getMultipleImageInfos() async {
    var mediaData = await ImagePickerWeb.getImageInfo;
    String mimeType = mime(Path.basename(mediaData.fileName));
    html.File mediaFile =
        new html.File(mediaData.data, mediaData.fileName, {'type': mimeType});

    if (mediaFile != null) {
      setState(() {
        _cloudFile = mediaFile;
        _fileBytes = mediaData.data;
        _imageWidget = Image.memory(mediaData.data);
      });
    }
  }

With getMultipleImageInfos() you can get all three available types in one call.

Picking Videos

To load a video as html.File do:

html.File? videoFile = await ImagePickerWeb.getVideoAsFile();

To load a video as Uint8List do:

Uint8List? videoData = await ImagePickerWeb.getVideoAsBytes();

Reminder: Don't use Uint8List retreivement for big video files! Flutter can't handle that. Pick bigger sized videos and high-resolution videos as html.File !

After you uploaded your video somewhere hosted, you can retreive the network url to play it.

MediaInfos

  • The methods getVideoInfo and getImageInfo are also available and you can use them to retreive further informations about your picked source.

Pick multiple images

Load videos as bytes:

List<Uint8List>? videos = ImagePickerWeb.getMultiVideosAsBytes();

Load videos as List<html.File> objects :

List<html.File>? videoFiles = await ImagePickerWeb.getMultiVideosAsFile();

Migration Guide

From 3.0.0 to 4.0.0

  • The WebImagePicker class has been removed. Use methods from ImagePickerWeb class instead.
  • getImageInfo and getVideoInfo are now methods and not getters. Use them like ImagePickerWeb.getImageInfo() and ImagePickerWeb.getVideoInfo().

image_picker_web's People

Contributors

ashwinkey04 avatar bymoye avatar davidlepilote avatar sethkitchen avatar testeurmaniak 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

Watchers

 avatar  avatar

image_picker_web's Issues

Resizing images picked

Hi
The picker is working fine, but before uploading images I'm wanting to resize them.

I'm trying the following

var bytes = await ImagePickerWeb.getImage(outputType: ImageType.bytes, );
img.Image imageTemp = img.decodeImage(bytes);
img.Image resizedImg = img.copyResize(imageTemp, width: size) ;
Uint8List newBytes = resizedImg.getBytes(format: img.Format.rgb);

but the list I get back seems to be in a different format to the original "bytes" returned as I can't then load them into a preview image.

Do you know of an effective way to resize the images returned from the picker. I'm happy to use any ImageType return type as I've been trying several methods to resize.

File Type

Have you got plans to have the image to be as file type File?

The mobile version does this, and Firebase Storage Upload requires a File, not an Image.

The App Frequently Crashes When Taking Photos with the Camera on Android

  1. Implement the following code.
  2. Deploy it as a web application.
  3. Access it using a low-spec Android smartphone and take a photo.
class ImagePickerTest extends StatelessWidget {
  const ImagePickerTest({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: IconButton(
        onPressed: () async {
          await ImagePicker().pickImage(
            source: ImageSource.camera,
            imageQuality: 10,
          );
        },
        icon: const Icon(Icons.camera_alt_sharp),
      )),
    );
  }
}

Expectation:
I suspect it is due to memory shortage causing other activities to be killed.

Remarks:

  • It happens frequently on Chrome, but as of now, it has not occurred on Brave.
  • I Only have a low-spec smartphone.

Not Working on Microsoft Edge

Unable to pick image on Microsoft Edge 44.18362.449.0
It opens image picker but nothing happens once I select any image...

Working fine on Chrome and Mozilla...
Any suggestions?

Thanks

WASM Support

Any eta for flutter version 3.22.1 compatibility with wasm support

Not working in safari in mobile browser

Flie picker dialog not always opening in safari browser of mobile device, it's completely fine in chrome and safari browser of mac. But in mobile devices it is not working as expected.
Only facing issue for image picker dialog not showing every time like choose File

Platform

Web (Mobile Web Safari browser issue )
Platform OS version
Safari os version 15.2

on button tap fetching image
Here is code snippet

Future<void> pickImage() async {
   final fromPicker = await ImagePickerWeb.getImageAsWidget();
   if (fromPicker != null) {
     setState(() {
       _pickedImages.clear();
       _pickedImages.add(fromPicker);
     });
   }
 }

Issue is not opening image picker dialog with options choose image, photo library every time.

To reproduce please verify in mobile safari browser

original-567CAA51-319C-4D63-A364-37ECCD8FE991.mp4

Flutter version
Flutter (Channel stable, 2.8.1, on macOS 12.1 21C52 darwin-x64, locale en-GB)

Compiler error in Android/iOS(DartVM)

I want to use both image_picker and image_picker_web.
It work in flutter web.
But native platform error.

Compiler message:
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/image_picker_web.dart:6:8: Error: Not found: 'dart:html'
import 'dart:html' as html;
       ^

../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/src/web_image_picker.dart:2:8: Error: Not found: 'dart:html'

import 'dart:html' as html;

       ^

../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.1/lib/src/browser_client.dart:6:8: Error: Not found: 'dart:html'

import 'dart:html';

       ^

../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/image_picker_web.dart:32:10: Error: Type 'html.File' not found.

  Future<html.File> _pickFile(String type) async {

         ^^^^^^^^^

../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.1/lib/src/browser_client.dart:34:18: Error: 'HttpRequest' isn't a type.

  final _xhrs = <HttpRequest>{};

                 ^^^^^^^^^^^
Running pod install...                                              2.8s
Building macOS application...
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/image_picker_web.dart:33:16: Error: 'FileUploadInputElement' isn't a type.
    final html.FileUploadInputElement input = html.FileUploadInputElement();
               ^^^^^^^^^^^^^^^^^^^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/image_picker_web.dart:33:47: Error: Method not found: 'FileUploadInputElement'.
    final html.FileUploadInputElement input = html.FileUploadInputElement();
                                              ^^^^^^^^^^^^^^^^^^^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/src/web_image_picker.dart:7:16: Error: 'FileUploadInputElement' isn't a type.
    final html.FileUploadInputElement input = html.FileUploadInputElement();
               ^^^^^^^^^^^^^^^^^^^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/src/web_image_picker.dart:7:47: Error: Method not found: 'FileUploadInputElement'.
    final html.FileUploadInputElement input = html.FileUploadInputElement();
                                              ^^^^^^^^^^^^^^^^^^^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/src/web_image_picker.dart:12:20: Error: Method not found: 'FileReader'.
    final reader = html.FileReader();
                   ^^^^^^^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/src/web_image_picker.dart:28:16: Error: 'FileUploadInputElement' isn't a type.
    final html.FileUploadInputElement input = html.FileUploadInputElement();
               ^^^^^^^^^^^^^^^^^^^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/src/web_image_picker.dart:28:47: Error: Method not found: 'FileUploadInputElement'.
    final html.FileUploadInputElement input = html.FileUploadInputElement();
                                              ^^^^^^^^^^^^^^^^^^^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_web-1.0.8/lib/src/web_image_picker.dart:33:20: Error: Method not found: 'FileReader'.
    final reader = html.FileReader();
                   ^^^^^^^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.1/lib/src/browser_client.dart:58:34: Error: 'Blob' isn't a type.
      var blob = xhr.response as Blob ?? Blob([]);
                                 ^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.1/lib/src/browser_client.dart:46:15: Error: The method 'HttpRequest' isn't defined for the class 'BrowserClient'.
 - 'BrowserClient' is from 'package:http/src/browser_client.dart' ('../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.1/lib/src/browser_client.dart').
Try correcting the name to the name of an existing method, or defining a method named 'HttpRequest'.
    var xhr = HttpRequest();
              ^^^^^^^^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.1/lib/src/browser_client.dart:58:42: Error: The method 'Blob' isn't defined for the class 'BrowserClient'.
 - 'BrowserClient' is from 'package:http/src/browser_client.dart' ('../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.1/lib/src/browser_client.dart').
Try correcting the name to the name of an existing method, or defining a method named 'Blob'.
      var blob = xhr.response as Blob ?? Blob([]);
                                         ^^^^
../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.1/lib/src/browser_client.dart:59:20: Error: The method 'FileReader' isn't defined for the class 'BrowserClient'.
 - 'BrowserClient' is from 'package:http/src/browser_client.dart' ('../../../development/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.1/lib/src/browser_client.dart').
Try correcting the name to the name of an existing method, or defining a method named 'FileReader'.
      var reader = FileReader();
                   ^^^^^^^^^^
../../../development/flutter/packages/flutter_web_plugins/lib/src/plugin_registry.dart:29:5: Error: Method not found: 'webOnlySetPluginHandler'.
    ui.webOnlySetPluginHandler(_binaryMessenger.handlePlatformMessage);
    ^^^^^^^^^^^^^^^^^^^^^^^

Can you make an universal version?

On the android,the program use this library can't get through the compiling.
Can you make it does nothing on Android but can pass the Android compiling?

Meta data path returns blank

When attempting to use the metadata path, all I ever get is blank

  Image fromPicker = await ImagePickerWeb.getImage(outputType: ImageType.widget);
  var meta = await ImagePickerWeb.getImageInfo;
  print('meta.path = ' + meta.filePath); // prints 'meta.path = '

Am I missing something?

EDIT: flutter information:

>flutter doctor -v
[√] Flutter (Channel beta, v1.17.0, on Microsoft Windows [Version 10.0.18362.778], locale en-CA)
    • Flutter version 1.17.0 at C:\development\flutter
    • Framework revision d3ed9ec945 (2 weeks ago), 2020-04-06 14:07:34 -0700
    • Engine revision c9506cb8e9
    • Dart version 2.8.0 (build 2.8.0-dev.18.0 eea9717938)

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at C:\Users\danbm\AppData\Local\Android\sdk
    • Platform android-29, build-tools 28.0.3
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[√] Android Studio (version 3.5)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin version 42.0.1
    • Dart plugin version 191.8593
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)

[√] Connected device (2 available)
    • Chrome     • chrome     • web-javascript • Google Chrome 80.0.3987.163
    • Web Server • web-server • web-javascript • Flutter Tools

• No issues found!

Not working on Safari (iOS)

The popup for browsing the gallery doesn’t show on Safari. Is this a known issue or am I doing something wrong?

iOS build issue which image_picker_web in pubspec.yaml

First, thanks so much for the plugin. This will become more popular as flutter web becomes more common.

Currently I have:
image_picker_web: ^1.0.9 in my pubspec.yaml file.

When building for iOS, I get the following error:

[ios/.symlinks/plugins/image_picker_web/example] flutter pub get
Running "flutter pub get" in example...                         
Cannot open file, path = '/Users/username/.pub-cache/global_packages/image_picker_web_example/pubspec.lock' (OS Error: No such file or directory, errno = 2)
pub get failed (66; Cannot open file, path = '/Users/username/.pub-cache/global_packages/image_picker_web_example/pubspec.lock' (OS Error: No such file or directory, errno = 2))
exit code 66

Since iOS isn't supported by this plugin, I took out all references in my code to the image_picker_web package, but I still get the error. The only way to avoid it is to comment out image_picker_web: ^1.0.9 in my pubspec.yaml and run 'flutter pub get'

I was hoping to use the kIsWeb boolean to decide whether or not to use image_picker or image_picker_web package... but it looks like when image_picker_web is in the pubspec.yaml file, the project can't be built for iOS.

Just to be clear, I'm not looking for any functionality for ios... I'm just hoping to be able to build with the package in the pubspec file. (and then, avoid that code with the kIsWeb boolean.

Any help would be appreciated.

Choose FIle Button

image

How can I remove it? It pop up when i pick an image.

Example code:

Uint8List? imageBytes = await ImagePickerWeb.getImageAsBytes();

Multi videos picker

I didnt upload multiple videos please update it for also multi videos

Uint8List? videoData = await ImagePickerWeb.getVideoAsBytes();

Thank you so much for amazing packge

Is it possible to get Image and File?

Hi, I am using this library on a form, I would like to show the Image widget when the user selects the image (I've accomplished this), but when I submit the form I need the File info to send it to Firebase and it seems the only way to get both is requesting the image twice to the user, which is kind of annoying.

Thanks in advance,

Cannot run / build for web

[🔴] × flutter build web

💪 Building with sound null safety 💪

Target dart2js failed: Exception: /home/praharshb/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_for_web-2.1.4/lib/image_picker_for_web.dart:246:23:
Error: 'is' can't be used as an identifier because it's a keyword.
      if (!_completer.is Completed && files != null) {
                      ^^
/home/praharshb/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_for_web-2.1.4/lib/image_picker_for_web.dart:246:26:
Error: Expected ')' before this.
      if (!_completer.is Completed && files != null) {
                         ^^^^^^^^^
/home/praharshb/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_for_web-2.1.4/lib/image_picker_for_web.dart:246:23:
Error: The getter 'is' isn't defined for the class 'Completer<PickedFile>'.
 - 'Completer' is from 'dart:async'.
 - 'PickedFile' is from 'package:image_picker_platform_interface/src/types/picked_file/html.dart'
 ('/home/praharshb/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_platform_interface-2.4.1/lib/src/types/picked_file/html.dart').
      if (!_completer.is Completed && files != null) {
                      ^^
/home/praharshb/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_for_web-2.1.4/lib/image_picker_for_web.dart:248:42:
Error: Property 'first' cannot be accessed on 'List<File>?' because it is potentially null.
 - 'List' is from 'dart:core'.
 - 'File' is from 'dart:html'.
          html.Url.createObjectUrl(files.first),
                                         ^^^^^
Error: Compilation failed.


Compiling lib/main.dart for the Web...                             10.6s
Exception: Failed to compile application for the Web.

Not Working On Android

I installed the package in my project but the packet worked on the web but didn't work on android. I couldn't run the project.

[Suggestion] Make it type safe

Since method getImage accepts enum, the return value is of Object?. This is a bit confusing.

I suggest to leverage types and create three different methods, example:

Future<Uint8List> getImageAsBytes();

Future<File> getImageAsFile();

Future<Widget> getImageAsWidget();

What do you think?

Not receiving return after upload file window closed

Hi,

After calling await ImagePickerWeb.getImage(outputType: ImageType.widget); and closing the file upload window, or pressing back on the smartphone, there is not a return from this call. I believe that a null was expected, so that I can dismiss a loadbar or anything like this on the page.

Tested on chrome and firefox.

Thanks,

Picking and uploading videos

The README for this package states:

Don't use Uint8List retreivement for big video files! Flutter can't handle that. Pick bigger sized videos and high-resolution videos as html.File !

So that indicates we need to use html.File? videoFile = await ImagePickerWeb.getVideoAsFile();.

However, in Flutter Web we can't use MultipartFile.fromPath() to upload (because there is no path available) since we can't use dart.io. So we have to use MultipartFile.fromBytes() to upload. So this means for larger files (or any video file?) we have to convert html.File back to Uint8List, correct? So how do we do that?

Please correct any of these points if I'm wrong. Thanks!

dart.html error while build apk

dart.html is not supported in Android & iOS, Can universal_html be used instead since app will not build with dart.html?

when importing image_picker_web in a cross platform app I get this error during build:

/.pub-cache/hosted/pub.dev/image_picker_web-3.1.1/lib/src/extensions/file_extensions.dart:2:8: Error: Dart library 'dart:html' is not available on this platform. import 'dart:html' as html;

To fix it I replaced the import 'dart:html' as html; to import "package:universal_html/html.dart" as html;

LRV

the ImagePickerWeb.getMultiVideosAsFile doesn't allow picking LRV files. Is it possible?

getImage with 2 types at the same time

Hello

I'd like to getImage

    Image fromPicker = await ImagePickerWeb.getImage(outputType: ImageType.widget);

and

    Uint8List bytesFromPicker =
        await ImagePickerWeb.getImage(outputType: ImageType.bytes);

at the same time

is is possible?

Because, I wrote both of them. it open dialogs 2times.

Target crashed

As part of a Flutter web application, I allow authenticated users to pick multiple large (~4Gb) mp4 files and upload them to Google storage.

I first picked the file:

List<html.File>? picked =
                      await ImagePickerWeb.getMultiVideosAsFile();

And then upload them though via putFile.
In some cases, the upload crashed with the message "Debugger: Target crashed!!!"

I opened a issue to Firebase/Flutterfire firebase/flutterfire#11341 initially believing it was their problem.

But following their instructions, we made some tests which seems to point image_web_picker as responsible for the issue.
Please refer to the link provided above for the details.

I would be thankful if you could assist to solve this problem

ImagePickerWeb.getImage(outputType: ImageType.file);

Sorry man I try to use you lib but when I try to get file name from picked file I got a problem.
The result html.File contains "name" property but this contain only the filename and not the full path, also the "relativePath" is always empty.

After clicking the image picker, the dialog appears, but when clicking on cancel, the loader is not dismissing

Below is the code for selecting a video for the web. However, when the dialog appears and the user clicks cancel, the CustomLoader is not getting dismissed. The line of code "await ImagePickerWeb.getImageInfo;" is not getting executed.
imagePicker() async {
try {
final fromPicker = await ImagePickerWeb.getImageInfo;
CustomLoader.show();
if (fromPicker!.fileName!.isNotEmpty) {
int imageCount = 0;
//Count the number of image files in the list
final kb = await ((await fromPicker!.data!.lengthInBytes) / 1024);
final mb = kb / 1024;
if (mb > 10) {
errorSnackBar(content: 'For image maximum limit is 10mb.');
CustomLoader.dismiss();
} else if (mb == 0) {
errorSnackBar(content: 'For image maximum limit is 10mb.');
CustomLoader.dismiss();
} else {
for (var item in filePathTypeList) {
if (item.type == 'image') {
imageCount++;
}
}
if (imageCount >= 4) {
errorSnackBar(content: 'Maximum 4 images can be uploaded');
} else {
filePathTypeList.add(FileWebDetails(
path: Rx(fromPicker!.data!),
type: 'image',
originalPath: fromPicker.fileName!));
}
}
} else {
CustomLoader.dismiss();
}
CustomLoader.dismiss();
logger(
message: e.toString(),
);
} catch (e) {
CustomLoader.dismiss();
logger(
title: "Video Picker error",
message: e.toString(),
);
}
}

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.