i want to create a timeline to illustrate the journey of Huggingface-hub library:
Browse filesThe Story Behind the Library
Every major library has an origin story. For `huggingface_hub`, it began with a simple idea: **what if sharing machine learning models could be as easy as sharing code on GitHub?**
In the early days of the Hugging Face Hub, researchers and practitioners faced a common frustration. Training a state-of-the-art model required significant compute resources and expertise. Once trained, these models often lived in isolation, stored on local machines and shared via (broken) Google Drive links. The AI community was duplicating work, wasting resources, and missing opportunities for collaboration.
The Hugging Face Hub emerged as the answer to this challenge. Initially, it was primarily used to share checkpoints compatible with the `transformers` library. All the Python code for interacting with the Hub lived within this library, making it inaccessible for other libraries to reuse.
In late 2020, we shipped `huggingface_hub` [v0.0.1](https://github.com/huggingface/huggingface_hub/releases/tag/v0.0.1) with a simple mission: extract the internal logic from `transformers` and create a dedicated library that would unify how to access and share machine learning models and datasets on the Hugging Face Hub. Initially, the library was as straightforward as a Git wrapper for downloading files and managing repositories. Five years and 35+ releases later, `huggingface_hub` has evolved far beyond its origins.
Let's trace that journey.
### The Foundation Years (2020-2021)
The early releases established the basics. Version [0.0.8](https://github.com/huggingface/huggingface_hub/releases/tag/v0.0.8) introduced our first APIs, wrapping Git commands to interact with repositories. Version [0.0.17](https://github.com/huggingface/huggingface_hub/releases/tag/v0.0.17) brought token-based authentication, enabling secure access to private repositories and uploads. These were humble beginnings, but they laid the groundwork for everything that followed.
### The Great Shift: Git to HTTP (2022)
In June 2022, version [0.8.1](https://github.com/huggingface/huggingface_hub/releases/tag/v0.8.1) marked a pivotal moment: we introduced the HTTP Commit API. Instead of requiring Git and Git LFS installations, users could now upload files directly through HTTP requests. The new `create_commit()` API simplified workflows dramatically, especially for large model files that had been cumbersome with Git LFS. In parallel of the commit API, a git-aware cache file layout was introduced. All libraries would now share the same cache, with explicit versioning and file deduplication.
This wasn't just a technical improvement. It was a philosophical shift. We were no longer building a Git wrapper; we were building purpose-built infrastructure for machine learning artifacts.
### An Expanding API Surface (2022–2024)
As the Hub grew from a model repository into a full platform, `huggingface_hub` kept pace with an expanding API surface. Core repository primitives matured: listing trees, browsing refs and commits, reading files or syncing folders, and managing tags, branches, and release cycles. Repository metadata and webhooks rounded out the offering so teams could react to changes in real time.
[Spaces](https://huggingface.co/docs/huggingface_hub/guides/manage-spaces) gained full programmatic control to deploy and manage ML apps (hardware requests, secrets, environment configuration, uploads). To deploy models on production-scale infrastructure, [Inference Endpoints](https://huggingface.co/docs/huggingface_hub/guides/inference_endpoints) were integrated as well. The [Jobs API](https://huggingface.co/docs/huggingface_hub/guides/jobs) came later (Q3 2025) to complete our compute offering.
The social and community layers became first-class: APIs for [pull requests and comments](https://huggingface.co/docs/huggingface_hub/guides/community), user and organization info, repository likes, following and followers, plus [Collections](https://huggingface.co/docs/huggingface_hub/guides/collections) to curate and share sets across the Hub. Everyday ergonomics improved too: seamless authentication in Colab, resumable downloads, reliable uploads of large-scale folders, and more.
Then came version [0.28.0](https://github.com/huggingface/huggingface_hub/releases/tag/v0.28.0) and the [Inference Providers](https://huggingface.co/docs/huggingface_hub/guides/inference) ecosystem. Instead of a single inference backend, we partnered with multiple serverless providers (Together AI, SambaNova, Replicate, Cerebras, Groq, and more) to serve one API with transparent routing. The pay-per-request architecture finally matched how people actually wanted to work.
### Ready. Xet. Go! (2024-2025)
Version [0.30.0](https://github.com/huggingface/huggingface_hub/releases/tag/v0.30.0) introduced Xet, a groundbreaking new protocol for storing large objects in Git repositories. Unlike Git LFS, which deduplicates at the file level, Xet operates at the chunk level (64KB chunks). When you modify a large model file, only the changed chunks are uploaded or downloaded, not the entire file.
[The migration was massive](https://huggingface.co/spaces/jsulz/ready-xet-go), starting with 20 petabytes across over 500,000 repositories. Yet it happened transparently, with full backward compatibility. One year later, all **77PB+** over **6,000,000 repositories** have been migrated seamlessly to the Xet backend, allowing for much faster (and smarter!) uploads and downloads.

i want a nice modern visualization that i can download as a png to insert in a blogpost. make it horizontally. I also want it as a gif.
- README.md +8 -5
- components/footer.js +86 -0
- components/navbar.js +89 -0
- index.html +122 -19
- script.js +144 -0
- style.css +32 -19
|
@@ -1,10 +1,13 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: HuggingFace Timeline Voyager 🚀
|
| 3 |
+
colorFrom: red
|
| 4 |
+
colorTo: purple
|
| 5 |
+
emoji: 🐳
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
tags:
|
| 9 |
+
- deepsite-v3
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Welcome to your new DeepSite project!
|
| 13 |
+
This project was created with [DeepSite](https://deepsite.hf.co).
|
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomFooter extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
footer {
|
| 7 |
+
background: #1e1b4b;
|
| 8 |
+
color: white;
|
| 9 |
+
padding: 2rem 1rem;
|
| 10 |
+
text-align: center;
|
| 11 |
+
margin-top: 4rem;
|
| 12 |
+
}
|
| 13 |
+
.footer-content {
|
| 14 |
+
max-width: 1200px;
|
| 15 |
+
margin: 0 auto;
|
| 16 |
+
display: flex;
|
| 17 |
+
flex-direction: column;
|
| 18 |
+
gap: 1.5rem;
|
| 19 |
+
}
|
| 20 |
+
.footer-links {
|
| 21 |
+
display: flex;
|
| 22 |
+
justify-content: center;
|
| 23 |
+
gap: 1.5rem;
|
| 24 |
+
flex-wrap: wrap;
|
| 25 |
+
}
|
| 26 |
+
.footer-links a {
|
| 27 |
+
color: #a5b4fc;
|
| 28 |
+
text-decoration: none;
|
| 29 |
+
transition: color 0.2s;
|
| 30 |
+
}
|
| 31 |
+
.footer-links a:hover {
|
| 32 |
+
color: white;
|
| 33 |
+
}
|
| 34 |
+
.social-links {
|
| 35 |
+
display: flex;
|
| 36 |
+
justify-content: center;
|
| 37 |
+
gap: 1rem;
|
| 38 |
+
}
|
| 39 |
+
.social-links a {
|
| 40 |
+
color: white;
|
| 41 |
+
display: flex;
|
| 42 |
+
align-items: center;
|
| 43 |
+
justify-content: center;
|
| 44 |
+
width: 36px;
|
| 45 |
+
height: 36px;
|
| 46 |
+
background: rgba(255, 255, 255, 0.1);
|
| 47 |
+
border-radius: 50%;
|
| 48 |
+
transition: background 0.2s;
|
| 49 |
+
}
|
| 50 |
+
.social-links a:hover {
|
| 51 |
+
background: rgba(255, 255, 255, 0.2);
|
| 52 |
+
}
|
| 53 |
+
.copyright {
|
| 54 |
+
font-size: 0.875rem;
|
| 55 |
+
color: #a5b4fc;
|
| 56 |
+
}
|
| 57 |
+
</style>
|
| 58 |
+
<footer>
|
| 59 |
+
<div class="footer-content">
|
| 60 |
+
<div class="footer-links">
|
| 61 |
+
<a href="https://huggingface.co/" target="_blank">HuggingFace</a>
|
| 62 |
+
<a href="https://huggingface.co/docs" target="_blank">Docs</a>
|
| 63 |
+
<a href="https://huggingface.co/models" target="_blank">Models</a>
|
| 64 |
+
<a href="https://huggingface.co/datasets" target="_blank">Datasets</a>
|
| 65 |
+
<a href="https://huggingface.co/spaces" target="_blank">Spaces</a>
|
| 66 |
+
</div>
|
| 67 |
+
<div class="social-links">
|
| 68 |
+
<a href="https://twitter.com/huggingface" target="_blank" aria-label="Twitter">
|
| 69 |
+
<i data-feather="twitter"></i>
|
| 70 |
+
</a>
|
| 71 |
+
<a href="https://github.com/huggingface" target="_blank" aria-label="GitHub">
|
| 72 |
+
<i data-feather="github"></i>
|
| 73 |
+
</a>
|
| 74 |
+
<a href="https://www.linkedin.com/company/huggingface" target="_blank" aria-label="LinkedIn">
|
| 75 |
+
<i data-feather="linkedin"></i>
|
| 76 |
+
</a>
|
| 77 |
+
</div>
|
| 78 |
+
<div class="copyright">
|
| 79 |
+
© ${new Date().getFullYear()} HuggingFace Hub Timeline. Not affiliated with HuggingFace Inc.
|
| 80 |
+
</div>
|
| 81 |
+
</div>
|
| 82 |
+
</footer>
|
| 83 |
+
`;
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
customElements.define('custom-footer', CustomFooter);
|
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomNavbar extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
nav {
|
| 7 |
+
background: white;
|
| 8 |
+
padding: 1rem 2rem;
|
| 9 |
+
display: flex;
|
| 10 |
+
justify-content: space-between;
|
| 11 |
+
align-items: center;
|
| 12 |
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
| 13 |
+
position: sticky;
|
| 14 |
+
top: 0;
|
| 15 |
+
z-index: 50;
|
| 16 |
+
}
|
| 17 |
+
.logo {
|
| 18 |
+
display: flex;
|
| 19 |
+
align-items: center;
|
| 20 |
+
gap: 0.5rem;
|
| 21 |
+
font-weight: bold;
|
| 22 |
+
color: #4f46e5;
|
| 23 |
+
font-size: 1.25rem;
|
| 24 |
+
}
|
| 25 |
+
.logo-icon {
|
| 26 |
+
width: 32px;
|
| 27 |
+
height: 32px;
|
| 28 |
+
}
|
| 29 |
+
ul {
|
| 30 |
+
display: flex;
|
| 31 |
+
gap: 1.5rem;
|
| 32 |
+
list-style: none;
|
| 33 |
+
margin: 0;
|
| 34 |
+
padding: 0;
|
| 35 |
+
}
|
| 36 |
+
a {
|
| 37 |
+
color: #4b5563;
|
| 38 |
+
text-decoration: none;
|
| 39 |
+
font-weight: 500;
|
| 40 |
+
transition: color 0.2s;
|
| 41 |
+
}
|
| 42 |
+
a:hover {
|
| 43 |
+
color: #4f46e5;
|
| 44 |
+
}
|
| 45 |
+
.active {
|
| 46 |
+
color: #4f46e5;
|
| 47 |
+
position: relative;
|
| 48 |
+
}
|
| 49 |
+
.active::after {
|
| 50 |
+
content: '';
|
| 51 |
+
position: absolute;
|
| 52 |
+
bottom: -4px;
|
| 53 |
+
left: 0;
|
| 54 |
+
width: 100%;
|
| 55 |
+
height: 2px;
|
| 56 |
+
background: #4f46e5;
|
| 57 |
+
border-radius: 2px;
|
| 58 |
+
}
|
| 59 |
+
@media (max-width: 768px) {
|
| 60 |
+
nav {
|
| 61 |
+
flex-direction: column;
|
| 62 |
+
gap: 1rem;
|
| 63 |
+
padding: 1rem;
|
| 64 |
+
}
|
| 65 |
+
ul {
|
| 66 |
+
width: 100%;
|
| 67 |
+
justify-content: space-between;
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
</style>
|
| 71 |
+
<nav>
|
| 72 |
+
<a href="/" class="logo">
|
| 73 |
+
<svg class="logo-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
| 74 |
+
<path d="M12 2L2 7L12 12L22 7L12 2Z" fill="#4f46e5"/>
|
| 75 |
+
<path d="M2 17L12 22L22 17" stroke="#4f46e5" stroke-width="2" stroke-linecap="round"/>
|
| 76 |
+
<path d="M2 12L12 17L22 12" stroke="#4f46e5" stroke-width="2" stroke-linecap="round"/>
|
| 77 |
+
</svg>
|
| 78 |
+
<span>HF Hub Timeline</span>
|
| 79 |
+
</a>
|
| 80 |
+
<ul>
|
| 81 |
+
<li><a href="/" class="active">Timeline</a></li>
|
| 82 |
+
<li><a href="https://huggingface.co/docs/huggingface_hub" target="_blank">Documentation</a></li>
|
| 83 |
+
<li><a href="https://github.com/huggingface/huggingface_hub" target="_blank">GitHub</a></li>
|
| 84 |
+
</ul>
|
| 85 |
+
</nav>
|
| 86 |
+
`;
|
| 87 |
+
}
|
| 88 |
+
}
|
| 89 |
+
customElements.define('custom-navbar', CustomNavbar);
|
|
@@ -1,19 +1,122 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
</
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>HuggingFace Hub Timeline</title>
|
| 7 |
+
<link rel="stylesheet" href="style.css">
|
| 8 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 10 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 11 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
|
| 12 |
+
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
|
| 13 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/gif.js/0.2.0/gif.js"></script>
|
| 14 |
+
</head>
|
| 15 |
+
<body class="bg-gray-50">
|
| 16 |
+
<div class="container mx-auto px-4 py-12">
|
| 17 |
+
<div class="text-center mb-12">
|
| 18 |
+
<h1 class="text-4xl font-bold text-indigo-900 mb-4">The Evolution of HuggingFace Hub</h1>
|
| 19 |
+
<p class="text-xl text-gray-600 max-w-3xl mx-auto">A visual journey through key milestones of the huggingface_hub library</p>
|
| 20 |
+
</div>
|
| 21 |
+
|
| 22 |
+
<div class="relative">
|
| 23 |
+
<!-- Timeline -->
|
| 24 |
+
<div class="overflow-x-auto pb-12">
|
| 25 |
+
<div id="timeline-container" class="min-w-[1200px]">
|
| 26 |
+
<div class="flex flex-col">
|
| 27 |
+
<!-- Timeline line -->
|
| 28 |
+
<div class="relative h-2 bg-gradient-to-r from-purple-500 to-indigo-600 rounded-full mx-16 mb-16"></div>
|
| 29 |
+
|
| 30 |
+
<!-- Timeline items -->
|
| 31 |
+
<div class="flex justify-between px-16">
|
| 32 |
+
<!-- 2020-2021 -->
|
| 33 |
+
<div class="timeline-item relative w-64">
|
| 34 |
+
<div class="absolute -top-10 left-1/2 transform -translate-x-1/2 w-6 h-6 bg-indigo-600 rounded-full border-4 border-white shadow-lg"></div>
|
| 35 |
+
<div class="bg-white p-6 rounded-xl shadow-lg mt-4">
|
| 36 |
+
<h3 class="font-bold text-indigo-800">Foundation Years</h3>
|
| 37 |
+
<p class="text-sm text-gray-600">2020-2021</p>
|
| 38 |
+
<ul class="mt-2 space-y-1 text-sm text-gray-700">
|
| 39 |
+
<li>• v0.0.1: First release</li>
|
| 40 |
+
<li>• Git wrapper for ML models</li>
|
| 41 |
+
<li>• Token-based auth</li>
|
| 42 |
+
</ul>
|
| 43 |
+
</div>
|
| 44 |
+
</div>
|
| 45 |
+
|
| 46 |
+
<!-- 2022 -->
|
| 47 |
+
<div class="timeline-item relative w-64">
|
| 48 |
+
<div class="absolute -top-10 left-1/2 transform -translate-x-1/2 w-6 h-6 bg-indigo-600 rounded-full border-4 border-white shadow-lg"></div>
|
| 49 |
+
<div class="bg-white p-6 rounded-xl shadow-lg mt-4">
|
| 50 |
+
<h3 class="font-bold text-indigo-800">Git to HTTP</h3>
|
| 51 |
+
<p class="text-sm text-gray-600">2022</p>
|
| 52 |
+
<ul class="mt-2 space-y-1 text-sm text-gray-700">
|
| 53 |
+
<li>• HTTP Commit API</li>
|
| 54 |
+
<li>• Git-aware cache</li>
|
| 55 |
+
<li>• Spaces integration</li>
|
| 56 |
+
</ul>
|
| 57 |
+
</div>
|
| 58 |
+
</div>
|
| 59 |
+
|
| 60 |
+
<!-- 2022-2024 -->
|
| 61 |
+
<div class="timeline-item relative w-64">
|
| 62 |
+
<div class="absolute -top-10 left-1/2 transform -translate-x-1/2 w-6 h-6 bg-indigo-600 rounded-full border-4 border-white shadow-lg"></div>
|
| 63 |
+
<div class="bg-white p-6 rounded-xl shadow-lg mt-4">
|
| 64 |
+
<h3 class="font-bold text-indigo-800">API Expansion</h3>
|
| 65 |
+
<p class="text-sm text-gray-600">2022-2024</p>
|
| 66 |
+
<ul class="mt-2 space-y-1 text-sm text-gray-700">
|
| 67 |
+
<li>• Inference Endpoints</li>
|
| 68 |
+
<li>• Community APIs</li>
|
| 69 |
+
<li>• Collections</li>
|
| 70 |
+
</ul>
|
| 71 |
+
</div>
|
| 72 |
+
</div>
|
| 73 |
+
|
| 74 |
+
<!-- 2024-2025 -->
|
| 75 |
+
<div class="timeline-item relative w-64">
|
| 76 |
+
<div class="absolute -top-10 left-1/2 transform -translate-x-1/2 w-6 h-6 bg-indigo-600 rounded-full border-4 border-white shadow-lg"></div>
|
| 77 |
+
<div class="bg-white p-6 rounded-xl shadow-lg mt-4">
|
| 78 |
+
<h3 class="font-bold text-indigo-800">Xet Protocol</h3>
|
| 79 |
+
<p class="text-sm text-gray-600">2024-2025</p>
|
| 80 |
+
<ul class="mt-2 space-y-1 text-sm text-gray-700">
|
| 81 |
+
<li>• Chunk-level storage</li>
|
| 82 |
+
<li>• 77PB+ migrated</li>
|
| 83 |
+
<li>• Faster transfers</li>
|
| 84 |
+
</ul>
|
| 85 |
+
</div>
|
| 86 |
+
</div>
|
| 87 |
+
</div>
|
| 88 |
+
</div>
|
| 89 |
+
</div>
|
| 90 |
+
</div>
|
| 91 |
+
|
| 92 |
+
<!-- Stats Chart -->
|
| 93 |
+
<div class="mt-16 bg-white rounded-xl shadow-lg p-6">
|
| 94 |
+
<canvas id="growthChart" height="300"></canvas>
|
| 95 |
+
</div>
|
| 96 |
+
</div>
|
| 97 |
+
|
| 98 |
+
<div class="mt-12 flex justify-center space-x-4">
|
| 99 |
+
<button id="downloadPng" class="bg-indigo-600 hover:bg-indigo-700 text-white px-6 py-2 rounded-lg flex items-center">
|
| 100 |
+
<i data-feather="download" class="mr-2"></i> Download as PNG
|
| 101 |
+
</button>
|
| 102 |
+
<button id="generateGif" class="bg-purple-600 hover:bg-purple-700 text-white px-6 py-2 rounded-lg flex items-center">
|
| 103 |
+
<i data-feather="film" class="mr-2"></i> Generate GIF
|
| 104 |
+
</button>
|
| 105 |
+
</div>
|
| 106 |
+
|
| 107 |
+
<div id="gif-preview" class="mt-8 hidden text-center">
|
| 108 |
+
<h3 class="text-lg font-semibold mb-4">GIF Preview</h3>
|
| 109 |
+
<div class="flex justify-center">
|
| 110 |
+
<img id="gif-result" class="max-w-full rounded-lg border border-gray-200 shadow">
|
| 111 |
+
</div>
|
| 112 |
+
<button id="downloadGif" class="mt-4 bg-green-600 hover:bg-green-700 text-white px-6 py-2 rounded-lg flex items-center mx-auto">
|
| 113 |
+
<i data-feather="download" class="mr-2"></i> Download GIF
|
| 114 |
+
</button>
|
| 115 |
+
</div>
|
| 116 |
+
</div>
|
| 117 |
+
|
| 118 |
+
<script src="script.js"></script>
|
| 119 |
+
<script>feather.replace();</script>
|
| 120 |
+
<script src="https://deepsite.hf.co/deepsite-badge.js"></script>
|
| 121 |
+
</body>
|
| 122 |
+
</html>
|
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 2 |
+
// Initialize Chart.js
|
| 3 |
+
const ctx = document.getElementById('growthChart').getContext('2d');
|
| 4 |
+
const growthChart = new Chart(ctx, {
|
| 5 |
+
type: 'line',
|
| 6 |
+
data: {
|
| 7 |
+
labels: ['2020', '2021', '2022', '2023', '2024', '2025'],
|
| 8 |
+
datasets: [{
|
| 9 |
+
label: 'Repositories',
|
| 10 |
+
data: [1000, 15000, 100000, 500000, 3000000, 6000000],
|
| 11 |
+
borderColor: '#6366F1',
|
| 12 |
+
backgroundColor: 'rgba(99, 102, 241, 0.1)',
|
| 13 |
+
tension: 0.3,
|
| 14 |
+
fill: true
|
| 15 |
+
}, {
|
| 16 |
+
label: 'Storage (PB)',
|
| 17 |
+
data: [0.1, 1, 5, 20, 50, 77],
|
| 18 |
+
borderColor: '#8B5CF6',
|
| 19 |
+
backgroundColor: 'rgba(139, 92, 246, 0.1)',
|
| 20 |
+
tension: 0.3,
|
| 21 |
+
fill: true
|
| 22 |
+
}]
|
| 23 |
+
},
|
| 24 |
+
options: {
|
| 25 |
+
responsive: true,
|
| 26 |
+
plugins: {
|
| 27 |
+
title: {
|
| 28 |
+
display: true,
|
| 29 |
+
text: 'HuggingFace Hub Growth Metrics',
|
| 30 |
+
font: {
|
| 31 |
+
size: 18
|
| 32 |
+
}
|
| 33 |
+
},
|
| 34 |
+
legend: {
|
| 35 |
+
position: 'top',
|
| 36 |
+
}
|
| 37 |
+
},
|
| 38 |
+
scales: {
|
| 39 |
+
y: {
|
| 40 |
+
beginAtZero: true
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
});
|
| 45 |
+
|
| 46 |
+
// Animate timeline items on scroll
|
| 47 |
+
const timelineItems = document.querySelectorAll('.timeline-item');
|
| 48 |
+
const observer = new IntersectionObserver((entries) => {
|
| 49 |
+
entries.forEach(entry => {
|
| 50 |
+
if (entry.isIntersecting) {
|
| 51 |
+
entry.target.classList.add('visible');
|
| 52 |
+
}
|
| 53 |
+
});
|
| 54 |
+
}, { threshold: 0.1 });
|
| 55 |
+
|
| 56 |
+
timelineItems.forEach(item => {
|
| 57 |
+
observer.observe(item);
|
| 58 |
+
});
|
| 59 |
+
|
| 60 |
+
// Download as PNG
|
| 61 |
+
document.getElementById('downloadPng').addEventListener('click', function() {
|
| 62 |
+
const container = document.getElementById('timeline-container');
|
| 63 |
+
|
| 64 |
+
html2canvas(container, {
|
| 65 |
+
scale: 2,
|
| 66 |
+
backgroundColor: '#F9FAFB',
|
| 67 |
+
logging: false,
|
| 68 |
+
useCORS: true
|
| 69 |
+
}).then(canvas => {
|
| 70 |
+
const link = document.createElement('a');
|
| 71 |
+
link.download = 'huggingface-timeline.png';
|
| 72 |
+
link.href = canvas.toDataURL('image/png');
|
| 73 |
+
link.click();
|
| 74 |
+
});
|
| 75 |
+
});
|
| 76 |
+
|
| 77 |
+
// Generate GIF
|
| 78 |
+
document.getElementById('generateGif').addEventListener('click', function() {
|
| 79 |
+
const preview = document.getElementById('gif-preview');
|
| 80 |
+
const gifResult = document.getElementById('gif-result');
|
| 81 |
+
const downloadGif = document.getElementById('downloadGif');
|
| 82 |
+
const button = this;
|
| 83 |
+
|
| 84 |
+
button.disabled = true;
|
| 85 |
+
button.innerHTML = '<i data-feather="loader" class="animate-spin mr-2"></i> Generating...';
|
| 86 |
+
feather.replace();
|
| 87 |
+
|
| 88 |
+
// Initialize GIF.js
|
| 89 |
+
const gif = new GIF({
|
| 90 |
+
workers: 2,
|
| 91 |
+
quality: 10,
|
| 92 |
+
width: 1200,
|
| 93 |
+
height: 500,
|
| 94 |
+
workerScript: 'https://cdnjs.cloudflare.com/ajax/libs/gif.js/0.2.0/gif.worker.js'
|
| 95 |
+
});
|
| 96 |
+
|
| 97 |
+
// Capture frames for the GIF
|
| 98 |
+
const timelineContainer = document.getElementById('timeline-container');
|
| 99 |
+
const items = timelineContainer.querySelectorAll('.timeline-item');
|
| 100 |
+
|
| 101 |
+
// Reset animation
|
| 102 |
+
items.forEach(item => item.classList.remove('visible'));
|
| 103 |
+
|
| 104 |
+
// Capture each frame as items appear
|
| 105 |
+
items.forEach((item, index) => {
|
| 106 |
+
setTimeout(() => {
|
| 107 |
+
item.classList.add('visible');
|
| 108 |
+
|
| 109 |
+
setTimeout(() => {
|
| 110 |
+
html2canvas(timelineContainer, {
|
| 111 |
+
scale: 1,
|
| 112 |
+
backgroundColor: '#F9FAFB',
|
| 113 |
+
logging: false,
|
| 114 |
+
useCORS: true
|
| 115 |
+
}).then(canvas => {
|
| 116 |
+
gif.addFrame(canvas, {delay: 500});
|
| 117 |
+
|
| 118 |
+
// If last frame, render the GIF
|
| 119 |
+
if (index === items.length - 1) {
|
| 120 |
+
gif.on('finished', function(blob) {
|
| 121 |
+
const url = URL.createObjectURL(blob);
|
| 122 |
+
gifResult.src = url;
|
| 123 |
+
preview.classList.remove('hidden');
|
| 124 |
+
|
| 125 |
+
downloadGif.onclick = function() {
|
| 126 |
+
const a = document.createElement('a');
|
| 127 |
+
a.href = url;
|
| 128 |
+
a.download = 'huggingface-timeline.gif';
|
| 129 |
+
a.click();
|
| 130 |
+
};
|
| 131 |
+
|
| 132 |
+
button.disabled = false;
|
| 133 |
+
button.innerHTML = '<i data-feather="film" class="mr-2"></i> Generate GIF';
|
| 134 |
+
feather.replace();
|
| 135 |
+
});
|
| 136 |
+
|
| 137 |
+
gif.render();
|
| 138 |
+
}
|
| 139 |
+
});
|
| 140 |
+
}, 600); // Wait for animation to complete
|
| 141 |
+
}, index * 1000);
|
| 142 |
+
});
|
| 143 |
+
});
|
| 144 |
+
});
|
|
@@ -1,28 +1,41 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
| 4 |
}
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
}
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
margin-bottom: 10px;
|
| 15 |
-
margin-top: 5px;
|
| 16 |
}
|
| 17 |
|
| 18 |
-
.
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
padding: 16px;
|
| 22 |
-
border: 1px solid lightgray;
|
| 23 |
-
border-radius: 16px;
|
| 24 |
}
|
| 25 |
|
| 26 |
-
.
|
| 27 |
-
|
|
|
|
| 28 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Animation for timeline items */
|
| 2 |
+
.timeline-item {
|
| 3 |
+
opacity: 0;
|
| 4 |
+
transform: translateY(20px);
|
| 5 |
+
transition: all 0.6s ease-out;
|
| 6 |
}
|
| 7 |
|
| 8 |
+
.timeline-item.visible {
|
| 9 |
+
opacity: 1;
|
| 10 |
+
transform: translateY(0);
|
| 11 |
}
|
| 12 |
|
| 13 |
+
/* Custom scrollbar for horizontal timeline */
|
| 14 |
+
.overflow-x-auto::-webkit-scrollbar {
|
| 15 |
+
height: 8px;
|
|
|
|
|
|
|
| 16 |
}
|
| 17 |
|
| 18 |
+
.overflow-x-auto::-webkit-scrollbar-track {
|
| 19 |
+
background: #f1f1f1;
|
| 20 |
+
border-radius: 10px;
|
|
|
|
|
|
|
|
|
|
| 21 |
}
|
| 22 |
|
| 23 |
+
.overflow-x-auto::-webkit-scrollbar-thumb {
|
| 24 |
+
background: #888;
|
| 25 |
+
border-radius: 10px;
|
| 26 |
}
|
| 27 |
+
|
| 28 |
+
.overflow-x-auto::-webkit-scrollbar-thumb:hover {
|
| 29 |
+
background: #555;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
/* Pulse animation for download buttons */
|
| 33 |
+
@keyframes pulse {
|
| 34 |
+
0% { transform: scale(1); }
|
| 35 |
+
50% { transform: scale(1.05); }
|
| 36 |
+
100% { transform: scale(1); }
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
#downloadPng:hover, #generateGif:hover, #downloadGif:hover {
|
| 40 |
+
animation: pulse 1.5s infinite;
|
| 41 |
+
}
|