Giter Site home page Giter Site logo

acgtools / hanime-hunter Goto Github PK

View Code? Open in Web Editor NEW
98.0 2.0 7.0 993 KB

A CLI app to download HAnime. 用于下载里番的 CLI 工具

License: GNU General Public License v3.0

Go 100.00%
anime cli cli-app go golang hanime open-source opensource hentai downloader

hanime-hunter's Introduction

hanime-hunter

English | 简体中文

A CLI app to download HAnime.

If you like this repo, please consider giving it a star (o゜▽゜)o☆ . Thank you OwO.

Random Wink OvO


Choose your faction

Check here and chooes a reaction: Pure Love Knight ❤️, NTR Warrior:🚀

Installation

Using go

$ go install -ldflags "-s -w" github.com/acgtools/hanime-hunter@latest

Download from releases

release page

Supported Site

NSFW Warning, the following site may contain sensitive content.

Site Language Episode Series Playlist Status
hanime1.me Chinese Available
hanime.tv English Available

Community

Discord

Quick Start

Prerequisites

Ensure that your terminal charset is UTF-8

Windows

> chcp
Active code page: 65001

# if code page is not 65001(utf-8), change it temporarily
> chcp 65001

If you want to set the default charset, follow the steps:

  1. Start -> Run -> regedit
  2. Go to [HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\Autorun]
  3. Change the value to @chcp 65001>nul

If Autorun is not present, you can add a New String.

This approach will auto-execute @chcp 65001>nul when cmd starts.

Linux

$ echo $LANG
en_US.UTF-8

FFmpeg

Command Help

$ hani -h
HAnime downloader. Repo: https://github.com/acgtools/hanime-hunter

Usage:
  hani [command]

Available Commands:
  dl          download
  help        Help about any command
  version     Print version info

Flags:
  -h, --help               help for hani
      --log-level string   log level, options: debug, info, warn, error, fatal (default "info")

Use "hani [command] --help" for more information about a command.

Download

$ hani help dl
download

Usage:
  hani dl [flags]

Flags:
  -h, --help                help for dl
  -i, --info                get anime info only
      --low-quality         download the lowest quality video
  -o, --output-dir string   output directory
  -q, --quality string      specify video quality. e.g. 1080p, 720p, 480p ...
      --retry uint8         number of retries, max 255 (default 10)
  -s, --series              download full series

Global Flags:
      --log-level string   log level, options: debug, info, warn, error, fatal (default "info")

Hanime1me

Only one episode

The default quality will be the highest quality.

# Download from the watch page
# The anime will be saved in ./anime_series_title/
$ hani dl https://hanime1.me/watch?v=xxxx

Full series based on the specified episode

# Download the full series
# E.g. If you provide the link of the Anime_Foo_02
# then the full series of Anime_Foo will be downloaded (Anime_Foo_01, Anime_Foo_02, ...)
$ hani dl -s https://hanime1.me/watch?v=xxxx

Skip downloaded files

If some files get stuck during downloading, stop the program and then restart the download.

It will skip the files that have already been downloaded.

Download playlist

$ hani dl https://hanime1.me/playlist?list=xxxx

Specify the output directory

# The anime will be saved in output_dir/anime_series_title/
$ hani dl -o <output_dir>

Specify the quality

# You can specify the quality of video
# if it is not exist, the default (highest quality) will be downloaded
$ hani dl -q "720p" https://hanime1.me/watch?v=xxxx

Get info only

# Get only the downloadable video info:
# title, quality, file extension
$ hani dl -i https://hanime1.me/watch?v=xxxx

Hanimetv

Only one episode

The default quality will be the highest quality.

# Download from the watch page
# The anime will be saved in ./anime_series_title/
$ hani dl https://hanime.tv/videos/hentai/xxx

Full series based on the specified episode

# Download the full series
# E.g. If you provide the link of the Anime_Foo_02
# then the full series of Anime_Foo will be downloaded (Anime_Foo_01, Anime_Foo_02, ...)
$ hani dl -s https://hanime.tv/videos/hentai/xxx

Skip downloaded files

If some files get stuck during downloading, stop the program and then restart the download.

It will skip the files that have already been downloaded.

Download playlist

$ hani dl https://hanime.tv/playlists/xxxx

Specify the output directory

# The anime will be saved in output_dir/anime_series_title/
$ hani dl -o <output_dir>

Specify the quality

# You can specify the quality of video
# if it is not exists, the default (highest quality) will be downloaded
$ hani dl -q "720p" https://hanime.tv/videos/hentai/xxx

Get info only

# Get only the downloadable video info:
# title, quality, file extension
$ hani dl -i https://hanime.tv/videos/hentai/xxx

Issue

Feel free to create issues to report bugs or request new features.

Star History

Star History Chart

hanime-hunter's People

Stargazers

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

Watchers

 avatar  avatar

hanime-hunter's Issues

[FEAT] Support resumable downloads

Is your feature request related to a problem?

The users have to download the videos that failed to download from beginning.

用户需要从头开始下载未完成的视频。

Describe the solution you'd like

Resume from the last download.

从上次已完成的部分开始。

Why is the feature needed?

Save the users' time.

节省用户时间。

Example

$ hani dl xxx
# xxx 80% 
# terminate the program 

$ hani dl xxx
# start from 80%

[FEAT] Auto-retry when the video failed to download

Is your feature request related to a problem?

When some videos failed to download, hani just canceled the download and star from beginning next time.

当某些文件下载错误时,hani 会直接取消下载。

Describe the solution you'd like

Add a flag like retry to define the number of retries for video downloading.

添加例如 retry 的 flag 用于为视频下载设置重试次数。

Why is the feature needed?

The users will not need to re-execute hani to download the videos that failed to download.

用户将无需重新执行 hani 来重新下载。

Example

$ hani dl -s xxx
xxx1 error  -> xxx1 downloading -> xxx1 complete
xxx2 downloading 

Discussion: All in one tool or Split into multiple tools / 讨论:全能工具还是拆分成多个

I have an idea to create some downloaders for collecting Animes, Comics and Games.

Now I'm facing two choices:

  1. ❤️ Create a all-in-one tool
  2. 🚀 Split them into multiple tools, each tool only needs to focus on one type of content.

I hope to gather some opinions. You can choose a reaction above.

If you have your ideas, please feel free to comment here.

我有个想法就是做些工具来下载动画,漫画和游戏。

我现在面临两个选择:

  1. ❤️ 做一个全能的工具
  2. 🚀 将它拆分成单一工具,每个工具专注于单一内容.

我希望收集一些意见,大家可以选择一个表情来投票。

也欢迎在此处提出你的想法。

Thank you~

[BUG] wsarecv: An existing connection was forcibly closed by the remote host.

描述出现的问题

Windows电脑 Powershell下无法正常下载。

如何复现

Site:
Video: https://hanime1.me/watch?v=88165

步骤:

PowerShell/github/hanime-hunter
❯ $env:https_proxy = "http://127.0.0.1:7890"

PowerShell/github/hanime-hunter
❯ $env:http_proxy = "http://127.0.0.1:7890"

PowerShell/github/hanime-hunter
❯ .\hani.exe dl -s https://hanime1.me/watch?v=88165
INFO Site: hanime1.me
INFO Anime found: Peh-koi, Searching episodes, Please wait a moment...
Error: get download info of "85711": get dl info from "https://vdownload-41.sb-cd.com/1/4/14784560-720p.mp4?secure=g2K26xErrKjdlnMTb67y-A,1705342299&m=41&d=1&_tid=14784560": send req to "https://vdownload-41.sb-cd.com/1/4/14784560-720p.mp4?secure=g2K26xErrKjdlnMTb67y-A,1705342299&m=41&d=1&_tid=14784560": Get "https://vdownload-41.sb-cd.com/1/4/14784560-720p.mp4?secure=g2K26xErrKjdlnMTb67y-A,1705342299&m=41&d=1&_tid=14784560": read tcp 127.0.0.1:63243->127.0.0.1:7890: wsarecv: An existing connection was forcibly closed by the remote host.

期望的结果

如何和clash代理环境结合

实际的结果

无法下载

截图 (可选)

见上面代码

运行环境

PowerShell/github/hanime-hunter
❯ .\hani version
Version: 0.3.1, Go: go1.21.5, Platform: windows/amd64

Error in download

Describe the bug

hani dl https://hanime.tv/videos/hentai/bikyaku-seido-kaichou-ai
INFO Site: hanime.tv
INFO Anime found: Bikyaku Seido Kaichou Ai, Searching episodes, Please wait a moment...
INFO Episodes found: [bikyaku-seido-kaichou-ai]
INFO Start downloading ...

Press ctrl+c to quit

Caught panic:

runtime error: invalid memory address or nil pointer dereference

Restoring terminal...

goroutine 1 [running]:
runtime/debug.Stack()
/opt/hostedtoolcache/go/1.21.7/x64/src/runtime/debug/stack.go:24 +0x5e
runtime/debug.PrintStack()
/opt/hostedtoolcache/go/1.21.7/x64/src/runtime/debug/stack.go:16 +0x13
github.com/charmbracelet/bubbletea.(*Program).Run.func1()
/home/runner/go/pkg/mod/github.com/charmbracelet/[email protected]/tea.go:440 +0x91
panic({0xaf02a0?, 0xf53c90?})
/opt/hostedtoolcache/go/1.21.7/x64/src/runtime/panic.go:920 +0x270
github.com/acgtools/hanime-hunter/internal/tui/progressbar.(*Model).Update(0xc0000a8700, {0xb2c020?, 0xc0001e6f90?})
/home/runner/work/hanime-hunter/hanime-hunter/internal/tui/progressbar/update.go:58 +0x165
github.com/charmbracelet/bubbletea.(*Program).eventLoop(0xc0001e80c0, {0xc3df90?, 0xc0000a8700?}, 0xc00007d958?)
/home/runner/go/pkg/mod/github.com/charmbracelet/[email protected]/tea.go:373 +0x637
github.com/charmbracelet/bubbletea.(*Program).Run(0xc0001e80c0)
/home/runner/go/pkg/mod/github.com/charmbracelet/[email protected]/tea.go:503 +0x85c
github.com/acgtools/hanime-hunter/cmd.download({0xc00001e140, 0x38}, 0xc00009e078)
/home/runner/work/hanime-hunter/hanime-hunter/cmd/download.go:99 +0x450
github.com/acgtools/hanime-hunter/cmd.glob..func1(0xc000174200?, {0xc00008e0b0, 0x1, 0xb65d68?})
/home/runner/work/hanime-hunter/hanime-hunter/cmd/download.go:40 +0xc5
github.com/spf13/cobra.(*Command).execute(0xf68000, {0xc00008e080, 0x1, 0x1})
/home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:983 +0xabc
github.com/spf13/cobra.(*Command).ExecuteC(0xf682e0)
/home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:1115 +0x3ff
github.com/spf13/cobra.(*Command).Execute(...)
/home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:1039
github.com/acgtools/hanime-hunter/cmd.Execute()
/home/runner/work/hanime-hunter/hanime-hunter/cmd/root.go:19 +0x28
main.main()
/home/runner/work/hanime-hunter/hanime-hunter/main.go:6 +0xf

How To Reproduce

Just download anything.

 - Platform:   <!-- e.g. windows 11-->
 - Version:    <!-- - v0.3.2 -->

### Additional context (Optional) 
<!-- Add any other context about the problem here. -->
Already changed chcp to 65001

[FEAT] Replace old low-quality video with higher quality video when batch downloading

你的建议/新功能需要解决什么问题?

hanime1.me 网站的视频,会随时间更新画质(比如 720p -> 1080p)。我在使用batch下载功能时,会默认下载最高画质(这很好)。但是之前下载的原本低画质视频还在,导致有两个画质的视频。

描述你的解决方案

增加一个下载时,检查低画质视频,然后默认删除已下载的低画质视频,用高画质视频替换的功能

为什么需要?

大家肯定是追求高画质的

[FEAT] Display all error info when some videos failed to download

Is your feature request related to a problem?

Only the error for the first video that failed to download will be displayed in terminal after downloading.

只有第一个出现的下载错误会显示出来。

Describe the solution you'd like

Add Err field for HAnime struct.

HAnime 结构添加 Err 字段。

Why is the feature needed?

For the current version, only the error info for the first video that failed to download will be displayed in terminal, making it difficult to obtain more information for bug reporting.

现版本只有第一个下载失败的视频的错误信息会被显示来,不利于获取信息用于排查 BUG。

Example

$ hani dl -s xxx
xxx1 error
xxx2 complete
xxx3 error

error info 1: ...
error info 3: ... 

Feat: support downloading the playlist of hanime1me

Is your feature request related to a problem? Please describe.
Current version of hani cannot download the playlist of hanime1.me

Describe the solution you'd like
Resolve playlist URL and download the animes

Why is the feature needed?
this is a planned feature

Example

$ hani dl xx.xx/playlist?list=xxxx

Bug: some video ids may not include quality info that will cause a panic

Describe the bug
If the vieo id dose not contain the quality, it will cause a panic

How To Reproduce
The video info: videos/FC51EFE.mp4

Expected behavior
Download the video without quality info

Actual behavior
panic

Screenshots
N/A

Environment (please complete the following information):

  • Platform: windows/amd64
  • Version: v0.1.0

New Feature: Adding Search and Download Based on Search Results

Describe the solution you'd like
Adding Search and Download Based on Search Results

Why is the feature needed?
Through the search function, users can quickly find the content they want to download without manually browsing through the entire library or directory. This allows users to efficiently locate the files, resources, or information they need and swiftly initiate the download process, enhancing the overall user experience. The search feature significantly streamlines the navigation and operational flow for users within the downloader, making it more convenient and intuitive.

Example
I can search based on tags or video names and then download the searched videos. It would be great if I could specify a download limit (for example, if I find 100 videos, but I only need to download 10 of them).

下载时会报错并卡住

下载一短时间后会报错:
context deadline exceeded (Client.Timeout or context cancellation while reading body)

[BUG]: The '/' symbol in the video name will result in an error in the download path.

描述出现的问题

视频名称里出现的/符号, 会导致下载路径生成错误

如何复现

example 1

S:/x18/hanime took 45s
❯ hani.exe dl https://hanime1.me/watch?v=89745
INFO Site: hanime1.me
INFO Anime found: Shinshi No.52, Searching episodes, Please wait a moment...
INFO Episodes found: "[Shinshi No.52] ルアンメェイ・生命の探究 / Ruan Mei: research of life"
INFO Start downloading ...

  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░   0%  0.00 MiB/68.65 MiB  [Shinshi No.52] ルアンメェイ・生命の探究 / Ruan Mei: research of life


Press ctrl+c to quit

ERRO dl: download file "[Shinshi No.52] ルアンメェイ・生命の探究 / Ruan Mei: research of life": create file "Shinshi No.52\\[Shinshi No.52] ルアンメェイ・生命の探究 \\ Ruan Mei: research of life 1080p.octet-stream": open Shinshi No.52\[Shinshi No.52] ルアンメェイ・生命の探究 \ Ruan Mei: research of life 1080p.octet-stream: The system cannot find the path specified.

example 2

S:/x18/hanime
❯ $env:https_proxy = "http://127.0.0.1:7890"

S:/x18/hanime
❯ hani.exe dl -s https://hanime1.me/watch?v=89744
INFO Site: hanime1.me
INFO Anime found: Tir_Al, Searching episodes, Please wait a moment...
INFO Episodes found [`[Tir_Al] 2024. 01. Arlecchino [All scene/4k]`]
INFO Start downloading ...

  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░   0%  0.00 MiB/34.92 MiB  [Tir_Al] 2024. 01. Arlecchino [All scene/4k] 1080p.mp4  Error


Press ctrl+c to quit

ERRO dl: download file "[Tir_Al] 2024. 01. Arlecchino [All scene/4k]": create file "Tir_Al\\[Tir_Al] 2024. 01. Arlecchino [All scene\\4k] 1080p.mp4": open Tir_Al\[Tir_Al] 2024. 01. Arlecchino [All scene\4k] 1080p.mp4: The system cannot find the path specified.

运行环境

S:/x18/hanime took 3s
❯ hani.exe version
Version: 0.3.1, Go: go1.21.5, Platform: windows/amd64

[FEAT] addtional download nfo info & anime poster for jellyfin-like tools

你的建议/新功能需要解决什么问题?

影视资料的下载和管理是密不可分的,既然hunter是个下载器,被下载的网站上视频已经是刮削好的,如果能顺便添加下载nfo和封面图的视频刮削功能。想必对于jellyfin等用户来说会吸引力大增。

[FEAT] Auto-quit program when all downloads are completed

Is your feature request related to a problem?

The users have to input ctrl+c to quit when all downloads are completed。

在下载完成后用户需要输入 ctrl+c 才能退出程序。

Describe the solution you'd like

Auto-quit after downloading.

下载完成后自动退出。

Why is the feature needed?

The feature makes it more convenient for users to use hani in shell script.

使得用户在 shell 脚本中使用更方便。

Example

$ hani dl xxx
xxx 100% complete
# auto-quit

文件保存位置需要优化

需求: 1. 加入一个默认的保存目录,比如~/hani_downloads/
2. 加入可以下载完成后执行命令的配置

我是在服务器上使用这个项目的,我不想在根目录直接使用命令并下载,因为这样的话会直接在根目录创建文件夹,每次使用时都需要先切到 ~/downloads/ 文件夹,下载后使用rclone命令进行上传该文件夹下的所有内容.所以可不可以加入一个固定的输出路径,或者有 config 之类的文件可以自行配置.
如果可以加入下载完成后执行命令这个功能就可以在下载完成后自动执行 rclone 的上传命令.我现在是使用crontab命令每天00:00执行rclone的上传命令

命令如下 : 0 0 * * * /usr/bin/rclone move ~/本地地址/ yundabei:/远程文件夹名称 --delete-empty-src-dirs

[FEAT] Download basic metrics: Average download speed & Estimated download time

Is your feature request related to a problem?

  1. 预估下载时间
  2. 平均下载速度

Describe the solution you'd like

简单计算和平均每一项的下载速度

Why is the feature needed?

因为大部分国人都用vpn,有平均下载速度,会让用户对当前vpn连接hanime服务器的速度有个直观的感知。

加油加油!!! 我作为学计算机的,知道开源不易,给星星

Feat: support downloading from hanimetv

Is your feature request related to a problem? Please describe.
Download from hanimetv

Describe the solution you'd like
Download from link

Why is the feature needed?
It is a planned feature

Example

$ hani dl xxx

[FEAT] Avoid repeat downloading using a similarity evaluation module

你的建议/新功能需要解决什么问题?

image

如图,由于网站会重命名文件,导致会下载其实是同一个视频的不同名称的文件。

描述你的解决方案

在下载前需要一个函数来判断,已经存在的视频和将要下载视频的相似度。
这个函数可以通过比较文件的大小是否相同/相近(99%以内),或者文件名的前缀/关键词相同来判断

为什么需要?

因为这个项目是个自动化下载的项目,自动避免重复的下载还是十分必要的

[BUG] Cannot download a few videos

Describe the bug

There are some videos that cannot be downloaded. For example, https://hanime.tv/videos/hentai/imaizumin-chi-wa-douyara-gal-no-tamariba-ni-natteru-rashii-1.

How To Reproduce

just download https://hanime.tv/videos/hentai/imaizumin-chi-wa-douyara-gal-no-tamariba-ni-natteru-rashii-1

Expected behavior

https://hanime.tv/videos/hentai/imaizumin-chi-wa-douyara-gal-no-tamariba-ni-natteru-rashii-1
Episode 2, 3 and 4 can be downloaded.

Actual behavior

It gives an error.

Screenshots (Optional)

Environment

# Get the version info
$ hani version
  • Platform:
  • Version:

Additional context (Optional)

panic: crypto/cipher: input not full blocks

                                       goroutine 87 [running]:
                                                              crypto/cipher.(*cbcDecrypter).CryptBlocks(0xfdd790?, {0xc00057e160?, 0xc0001e6200?, 0x10?}, {0xc000378000?, 0xc00045bcd8?, 0x0?})
                                                                            /opt/hostedtoolcache/go/1.21.5/x64/src/crypto/cipher/cbc.go:145 +0x411
                          github.com/acgtools/hanime-hunter/pkg/util.AESDecrypt({0xc000378000, 0xa2, 0x200}, {0xc0001e6200?, 0xc0000f3d10?, 0xadc953?}, {0xc0001e6200, 0x6c?, 0x200})
                                                                    /home/runner/work/hanime-hunter/hanime-hunter/pkg/util/crypto.go:18 +0xe2
                     github.com/acgtools/hanime-hunter/internal/downloader.saveTS({0xc00038a000, 0x6c}, {0xc00031d540, 0x39}, {0xc0001e6200, 0x10, 0x200}, {0xc0001e6200, 0x10, 0x200})
                                                                    /home/runner/work/hanime-hunter/hanime-hunter/internal/downloader/downloader.go:319 +0x2de
                                      github.com/acgtools/hanime-hunter/internal/downloader.(*Downloader).saveM3U8.(*Downloader).saveM3U8.func1.func2()
                                    /home/runner/work/hanime-hunter/hanime-hunter/internal/downloader/downloader.go:219 +0x290
      golang.org/x/sync/errgroup.(*Group).Go.func1()
                                                            /home/runner/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:75 +0x56
                  created by golang.org/x/sync/errgroup.(*Group).Go in goroutine 18
                                                                                    /home/runner/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:72 +0x96

[FEAT] tampermonkey script maybe next good choice

你的建议/新功能需要解决什么问题?

CLI 的还是需要输入视频id的,在浏览相关网站时,大家其实会想一键下载多个感兴趣的视频。这时候就需要一个个点击进入详情页面获取URL或者id,然后输入终端下载,然后退出来。还是有一点点麻烦

描述你的解决方案

iwara有个类似的项目,可以实现勾选视频,一键下载。我觉得作者有空可以考虑类似的hanime项目。

image

为什么需要?

降低使用门槛,优化使用体验,是吸引小白的新用户最好的办法。

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.