Spaces:
No application file
No application file
Bundle D3 + GSAP locally, move inline script to app.js
#3
by Reubencf - opened
- app.js +940 -0
- index.html +435 -1376
- vendor/d3-voronoi-map.js +1 -0
- vendor/d3-voronoi-treemap.js +1 -0
- vendor/d3-weighted-voronoi.js +1 -0
- vendor/d3.min.js +0 -0
- vendor/gsap.min.js +11 -0
app.js
ADDED
|
@@ -0,0 +1,940 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// ===========================================================================
|
| 2 |
+
// PALETTE — pulled from CSS variables so tokens stay single-source-of-truth
|
| 3 |
+
// ===========================================================================
|
| 4 |
+
const CSS = getComputedStyle(document.documentElement);
|
| 5 |
+
const PALETTE = [
|
| 6 |
+
CSS.getPropertyValue('--palette-1').trim(),
|
| 7 |
+
CSS.getPropertyValue('--palette-2').trim(),
|
| 8 |
+
CSS.getPropertyValue('--palette-3').trim(),
|
| 9 |
+
CSS.getPropertyValue('--palette-4').trim(),
|
| 10 |
+
CSS.getPropertyValue('--palette-5').trim(),
|
| 11 |
+
CSS.getPropertyValue('--palette-6').trim(),
|
| 12 |
+
CSS.getPropertyValue('--palette-7').trim(),
|
| 13 |
+
CSS.getPropertyValue('--palette-8').trim(),
|
| 14 |
+
CSS.getPropertyValue('--palette-9').trim(),
|
| 15 |
+
CSS.getPropertyValue('--palette-10').trim(),
|
| 16 |
+
CSS.getPropertyValue('--palette-11').trim(),
|
| 17 |
+
CSS.getPropertyValue('--palette-12').trim(),
|
| 18 |
+
];
|
| 19 |
+
|
| 20 |
+
/** Brighten an HSL-mapped color for the inner tick mark (and voronoi hovers). */
|
| 21 |
+
function luminousVariant(hex, lightnessBoost = 0.4, saturationBoost = 0.12) {
|
| 22 |
+
const c = d3.hsl(hex);
|
| 23 |
+
c.l = Math.min(0.9, c.l + lightnessBoost);
|
| 24 |
+
c.s = Math.min(1, c.s + saturationBoost);
|
| 25 |
+
return c.formatHex();
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
/** Format a number as an integer + <span class="decimal">.Mk</span>. */
|
| 29 |
+
function formatRows(n) {
|
| 30 |
+
if (n >= 1_000_000) {
|
| 31 |
+
const v = n / 1_000_000;
|
| 32 |
+
const [whole, frac] = v.toFixed(1).split('.');
|
| 33 |
+
return `${whole}<span class="decimal">.${frac}M</span>`;
|
| 34 |
+
}
|
| 35 |
+
if (n >= 1_000) {
|
| 36 |
+
const v = n / 1_000;
|
| 37 |
+
const [whole, frac] = v.toFixed(1).split('.');
|
| 38 |
+
return `${whole}<span class="decimal">.${frac}k</span>`;
|
| 39 |
+
}
|
| 40 |
+
return String(n);
|
| 41 |
+
}
|
| 42 |
+
function formatShort(n) {
|
| 43 |
+
if (n >= 1_000_000) return (n / 1_000_000).toFixed(1).replace(/\.0$/, '') + 'M';
|
| 44 |
+
if (n >= 1_000) return (n / 1_000).toFixed(1).replace(/\.0$/, '') + 'k';
|
| 45 |
+
return String(n);
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
// Upgrade hero stat numbers to support a decimal span
|
| 49 |
+
document.querySelectorAll('.stat .num').forEach(el => {
|
| 50 |
+
const raw = el.getAttribute('data-value');
|
| 51 |
+
const m = raw && raw.match(/^([~≈]?[\d,]+)(\.[\d]+)?([A-Za-z+]+)?$/);
|
| 52 |
+
if (!m) { el.textContent = raw || ''; return; }
|
| 53 |
+
const [, whole, frac = '', suffix = ''] = m;
|
| 54 |
+
el.innerHTML = frac || suffix
|
| 55 |
+
? `${whole}<span class="decimal">${frac}${suffix}</span>`
|
| 56 |
+
: whole;
|
| 57 |
+
});
|
| 58 |
+
|
| 59 |
+
// ===========================================================================
|
| 60 |
+
// DATASET CATALOG
|
| 61 |
+
// ===========================================================================
|
| 62 |
+
const DATASETS = [
|
| 63 |
+
{
|
| 64 |
+
key: "speech",
|
| 65 |
+
title: "Multilingual Synthetic Speech",
|
| 66 |
+
tagline: "Zero-shot voice cloning with Qwen3-TTS across 9 languages",
|
| 67 |
+
raw: { repo: "Reubencf/multilingual-synthetic-tts", rows: 68677 },
|
| 68 |
+
adaption: { repo: "Reubencf/Adaption-multilingual-speech", rows: 10274 },
|
| 69 |
+
languages: "en, ja, zh, ko, de, es, fr, ru, pt",
|
| 70 |
+
modality: "audio + text",
|
| 71 |
+
license: "open / synthetic",
|
| 72 |
+
schema: ["audio", "text", "language", "language_name", "style", "voice", "sample_rate"],
|
| 73 |
+
model: "Qwen3-TTS-12Hz-1.7B-Base",
|
| 74 |
+
group: "paired"
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
key: "sentences",
|
| 78 |
+
title: "Multilingual Sentences (text-only)",
|
| 79 |
+
tagline: "Text projection of the TTS corpus — ready for Adaption",
|
| 80 |
+
raw: null,
|
| 81 |
+
adaption: { repo: "Reubencf/Adaption-multilingual-sentences", rows: 10000 },
|
| 82 |
+
languages: "ja, ru, ko, de, es, pt, zh, en, fr + 114 more",
|
| 83 |
+
modality: "text",
|
| 84 |
+
license: "open",
|
| 85 |
+
schema: ["text", "enhanced_prompt", "enhanced_completion", "language", "voice", "style"],
|
| 86 |
+
group: "paired"
|
| 87 |
+
},
|
| 88 |
+
{
|
| 89 |
+
key: "music",
|
| 90 |
+
title: "Music — FMA Labeled",
|
| 91 |
+
tagline: "Creative-Commons music tracks with lyrics, genre, mood, BPM, key",
|
| 92 |
+
raw: { repo: "Reubencf/fma-labeled", rows: 29000 },
|
| 93 |
+
adaption: { repo: "Reubencf/adaption-music-style-prompts", rows: 9950 },
|
| 94 |
+
languages: "en",
|
| 95 |
+
modality: "audio + text",
|
| 96 |
+
license: "CC-BY / CC0 (source-dependent)",
|
| 97 |
+
schema: ["audio", "lyrics", "genre", "sub_genres", "mood", "instruments", "bpm", "key", "vocal_type", "energy", "era", "quality"],
|
| 98 |
+
model: "gemini-flash-latest",
|
| 99 |
+
group: "paired"
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
key: "street",
|
| 103 |
+
title: "StreetView Global",
|
| 104 |
+
tagline: "Globally-sampled Mapillary street images with scene classification",
|
| 105 |
+
raw: { repo: "Reubencf/streetview-global", rows: 30000 },
|
| 106 |
+
adaption: { repo: "Reubencf/adaption-street-scene-descriptions", rows: 10100 },
|
| 107 |
+
languages: "en",
|
| 108 |
+
modality: "image + text",
|
| 109 |
+
license: "CC-BY-SA-4.0",
|
| 110 |
+
schema: ["image", "scene_description", "setting", "weather", "time_of_day", "road_type", "infrastructure", "lat", "lon", "compass"],
|
| 111 |
+
group: "paired"
|
| 112 |
+
},
|
| 113 |
+
{
|
| 114 |
+
key: "magazines",
|
| 115 |
+
title: "Magazines Multilingual VQA",
|
| 116 |
+
tagline: "Public-domain magazine OCR in 40+ source languages (including low-resource)",
|
| 117 |
+
raw: { repo: "Reubencf/magazines-multilingual-vqa", rows: 29039 },
|
| 118 |
+
adaption: { repo: "Reubencf/adaption-multilingual-doc-qa", rows: 8800 },
|
| 119 |
+
languages: "ar, de, en, es, fr, hi, it, ja, pt, zh + 35 more (Afrikaans, Amharic, Yoruba, Yiddish, Bengali, Santali, Somali, Vietnamese, Russian, Maithili, Tibetan, …)",
|
| 120 |
+
modality: "image + text",
|
| 121 |
+
license: "CC-BY-4.0",
|
| 122 |
+
schema: ["image", "ocr_text", "english_description", "question", "answer", "target_language", "page_type"],
|
| 123 |
+
model: "Gemma 4 31B via vLLM",
|
| 124 |
+
group: "paired"
|
| 125 |
+
},
|
| 126 |
+
{
|
| 127 |
+
key: "lowresource",
|
| 128 |
+
title: "Low-Resource Doc Q/A",
|
| 129 |
+
tagline: "Low-resource-language slice of the magazines corpus",
|
| 130 |
+
raw: null,
|
| 131 |
+
adaption: { repo: "Reubencf/Adaption-low-resource-doc-qa", rows: 10200 },
|
| 132 |
+
languages: "Afrikaans, Amharic, Yoruba, Yiddish, Bengali, Santali, Somali, Vietnamese, Maithili, Tigrinya, Meitei, Lao, …",
|
| 133 |
+
modality: "image + text",
|
| 134 |
+
license: "CC-BY-4.0",
|
| 135 |
+
schema: ["image", "ocr_text", "question", "answer", "source_language"],
|
| 136 |
+
group: "paired"
|
| 137 |
+
},
|
| 138 |
+
{
|
| 139 |
+
key: "captions",
|
| 140 |
+
title: "Multilingual Image Captions",
|
| 141 |
+
tagline: "English + multilingual captions with bounding-box visualizations",
|
| 142 |
+
raw: { repo: "Reubencf/multilingual-image-annotations", rows: 464 },
|
| 143 |
+
adaption: { repo: "Reubencf/adaption-multilingual-image-captions", rows: 462 },
|
| 144 |
+
languages: "en, es, fr, hi, zh, ar, pt",
|
| 145 |
+
modality: "image + text",
|
| 146 |
+
license: "CC-BY-4.0",
|
| 147 |
+
schema: ["image", "boxed_image", "description_en", "descriptions", "vqa", "detections"],
|
| 148 |
+
model: "Gemma 4 31B",
|
| 149 |
+
group: "paired"
|
| 150 |
+
},
|
| 151 |
+
{
|
| 152 |
+
key: "frontend",
|
| 153 |
+
title: "Frontend Coding",
|
| 154 |
+
tagline: "Hand-curated HTML / Tailwind / JS prompts and completions",
|
| 155 |
+
raw: { repo: "Reubencf/frontend-coding", rows: 500 },
|
| 156 |
+
adaption: { repo: "Reubencf/frontend-html-tailwind-js", rows: 145 },
|
| 157 |
+
languages: "en",
|
| 158 |
+
modality: "text (code)",
|
| 159 |
+
license: "MIT",
|
| 160 |
+
schema: ["prompt", "previous_code", "code", "reasoning"],
|
| 161 |
+
group: "paired"
|
| 162 |
+
},
|
| 163 |
+
{
|
| 164 |
+
key: "news2026",
|
| 165 |
+
title: "Current Affairs 2026",
|
| 166 |
+
tagline: "2026 Wikipedia current-events Q/A with RAG grounding (through Apr 9, 2026)",
|
| 167 |
+
raw: { repo: "Reubencf/future-news-events-2026", rows: 5447 },
|
| 168 |
+
adaption: { repo: "Reubencf/current-affairs-2026", rows: 5339 },
|
| 169 |
+
languages: "en",
|
| 170 |
+
modality: "text",
|
| 171 |
+
license: "open",
|
| 172 |
+
schema: ["question", "answer", "enhanced_prompt", "enhanced_completion", "reasoning_trace", "date", "event_id", "section", "source"],
|
| 173 |
+
model: "Cohere Command R + RAG",
|
| 174 |
+
group: "paired"
|
| 175 |
+
},
|
| 176 |
+
{
|
| 177 |
+
key: "news2025",
|
| 178 |
+
title: "Current Affairs 2025",
|
| 179 |
+
tagline: "2025 global events Q/A",
|
| 180 |
+
raw: { repo: "Reubencf/2025_events", rows: 5390 },
|
| 181 |
+
adaption: { repo: "Reubencf/current-affairs-2025", rows: 5390 },
|
| 182 |
+
languages: "en",
|
| 183 |
+
modality: "text",
|
| 184 |
+
license: "open",
|
| 185 |
+
schema: ["question", "answer", "enhanced_prompt", "enhanced_completion"],
|
| 186 |
+
group: "paired"
|
| 187 |
+
},
|
| 188 |
+
{
|
| 189 |
+
key: "news2024",
|
| 190 |
+
title: "Current Affairs 2024",
|
| 191 |
+
tagline: "2024 global events Q/A",
|
| 192 |
+
raw: { repo: "Reubencf/2024_events", rows: 5190 },
|
| 193 |
+
adaption: { repo: "Reubencf/current-affairs-2024", rows: 5190 },
|
| 194 |
+
languages: "en",
|
| 195 |
+
modality: "text",
|
| 196 |
+
license: "open",
|
| 197 |
+
schema: ["question", "answer", "enhanced_prompt", "enhanced_completion"],
|
| 198 |
+
group: "paired"
|
| 199 |
+
},
|
| 200 |
+
{
|
| 201 |
+
key: "news2023",
|
| 202 |
+
title: "Current Affairs 2023",
|
| 203 |
+
tagline: "2023 global events Q/A",
|
| 204 |
+
raw: { repo: "Reubencf/2023_events", rows: 4667 },
|
| 205 |
+
adaption: { repo: "Reubencf/current-affairs-2023", rows: 4667 },
|
| 206 |
+
languages: "en",
|
| 207 |
+
modality: "text",
|
| 208 |
+
license: "open",
|
| 209 |
+
schema: ["question", "answer", "enhanced_prompt", "enhanced_completion"],
|
| 210 |
+
group: "paired"
|
| 211 |
+
},
|
| 212 |
+
// Pre-training pools — now included in the raw donut too.
|
| 213 |
+
{
|
| 214 |
+
key: "polyaudio",
|
| 215 |
+
title: "PolyglotAudio",
|
| 216 |
+
tagline: "Broad multilingual audio pre-training pool",
|
| 217 |
+
raw: { repo: "Reubencf/PolyglotAudio", rows: 1200000 },
|
| 218 |
+
adaption: null,
|
| 219 |
+
languages: "multilingual",
|
| 220 |
+
modality: "audio + text",
|
| 221 |
+
license: "open",
|
| 222 |
+
schema: ["audio", "text", "language"],
|
| 223 |
+
group: "paired"
|
| 224 |
+
},
|
| 225 |
+
{
|
| 226 |
+
key: "polytext",
|
| 227 |
+
title: "PolyglotText",
|
| 228 |
+
tagline: "Large multilingual text pre-training pool",
|
| 229 |
+
raw: { repo: "Reubencf/PolyglotText", rows: 13400000 },
|
| 230 |
+
adaption: null,
|
| 231 |
+
languages: "multilingual",
|
| 232 |
+
modality: "text",
|
| 233 |
+
license: "open",
|
| 234 |
+
schema: ["text", "language"],
|
| 235 |
+
group: "paired"
|
| 236 |
+
},
|
| 237 |
+
];
|
| 238 |
+
|
| 239 |
+
// Stable color per dataset key — cycles through PALETTE
|
| 240 |
+
const datasetColor = d3.scaleOrdinal(PALETTE).domain(DATASETS.map(d => d.key));
|
| 241 |
+
DATASETS.forEach(d => { d.color = datasetColor(d.key); });
|
| 242 |
+
|
| 243 |
+
// ===========================================================================
|
| 244 |
+
// DONUT CHART (D3 — used for both Raw/Adaption donuts and the modality donut)
|
| 245 |
+
// ===========================================================================
|
| 246 |
+
const tooltipEl = document.getElementById('donut-tooltip');
|
| 247 |
+
|
| 248 |
+
// Per-SVG selection state for drill-down (scale-up selected, dim others).
|
| 249 |
+
const donutState = new Map(); // svgId -> { selectedKey, paths, arcGen }
|
| 250 |
+
|
| 251 |
+
function renderDonut({ svgId, centerId, field, datasets, getValue, getKey, getTitle, getColor, getMeta, colorScale, topLabel, bottomLabel, topIcon, bottomIcon, sizing = 'linear' }) {
|
| 252 |
+
const svg = d3.select('#' + svgId);
|
| 253 |
+
svg.selectAll('*').remove();
|
| 254 |
+
|
| 255 |
+
const bbox = svg.node().getBoundingClientRect();
|
| 256 |
+
const size = Math.min(bbox.width, bbox.height);
|
| 257 |
+
const outerR = size / 2 - 6;
|
| 258 |
+
const innerR = outerR * 0.62;
|
| 259 |
+
svg.attr('viewBox', `${-size / 2} ${-size / 2} ${size} ${size}`);
|
| 260 |
+
|
| 261 |
+
const filtered = datasets.filter(d => getValue(d) > 0);
|
| 262 |
+
const total = d3.sum(filtered, getValue);
|
| 263 |
+
const count = filtered.length;
|
| 264 |
+
|
| 265 |
+
// Sizing strategy for the arc:
|
| 266 |
+
// "linear" — true proportions (small slices can vanish)
|
| 267 |
+
// "log" — power-compressed so tiny datasets stay visible while the
|
| 268 |
+
// big ones (PolyglotText 13M+, PolyglotAudio 1M+) still read
|
| 269 |
+
// as clearly the largest slices
|
| 270 |
+
// "sqrt" — lighter square-root compression
|
| 271 |
+
// Tooltip + center numbers always show real values.
|
| 272 |
+
const sizeValue = d => {
|
| 273 |
+
const v = getValue(d);
|
| 274 |
+
if (sizing === 'log') return Math.pow(v + 1, 0.38);
|
| 275 |
+
if (sizing === 'sqrt') return Math.sqrt(v + 1);
|
| 276 |
+
return v;
|
| 277 |
+
};
|
| 278 |
+
|
| 279 |
+
const pie = d3.pie().value(sizeValue).sort(null).padAngle(0.022);
|
| 280 |
+
const arcs = pie(filtered);
|
| 281 |
+
const arcGen = d3.arc().innerRadius(innerR).outerRadius(outerR).cornerRadius(3);
|
| 282 |
+
const resolveColor = getColor || (x => datasetColor(getKey(x)));
|
| 283 |
+
|
| 284 |
+
const g = svg.append('g');
|
| 285 |
+
|
| 286 |
+
// Slice paths
|
| 287 |
+
const paths = g.selectAll('path')
|
| 288 |
+
.data(arcs)
|
| 289 |
+
.join('path')
|
| 290 |
+
.attr('class', 'donut-slice')
|
| 291 |
+
.attr('fill', d => resolveColor(d.data))
|
| 292 |
+
.attr('stroke', '#000000')
|
| 293 |
+
.attr('stroke-width', 2)
|
| 294 |
+
.attr('stroke-linejoin', 'round');
|
| 295 |
+
|
| 296 |
+
// Radial sweep: interpolate endAngle from startAngle → target, so arcs
|
| 297 |
+
// literally grow around the ring from 0° of arc to their full sweep.
|
| 298 |
+
paths.each(function (d) {
|
| 299 |
+
const [cx, cy] = arcGen.centroid(d);
|
| 300 |
+
this._centroid = [cx, cy];
|
| 301 |
+
this._current = { startAngle: d.startAngle, endAngle: d.startAngle, padAngle: d.padAngle };
|
| 302 |
+
});
|
| 303 |
+
paths.transition()
|
| 304 |
+
.delay((d, i) => i * 80)
|
| 305 |
+
.duration(1100)
|
| 306 |
+
.ease(d3.easeCubicOut)
|
| 307 |
+
.attrTween('d', function (d) {
|
| 308 |
+
const interp = d3.interpolate(this._current, d);
|
| 309 |
+
this._current = interp(1);
|
| 310 |
+
return t => arcGen(interp(t));
|
| 311 |
+
});
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
|
| 315 |
+
// Hover tooltip + click drill-down
|
| 316 |
+
paths
|
| 317 |
+
.on('mouseenter', function (ev, d) {
|
| 318 |
+
const nm = getTitle(d.data);
|
| 319 |
+
const v = getValue(d.data);
|
| 320 |
+
const meta = getMeta ? getMeta(d.data) : '';
|
| 321 |
+
tooltipEl.innerHTML =
|
| 322 |
+
`<div class="t-name">${nm}</div>` +
|
| 323 |
+
`<div class="t-meta">${v.toLocaleString()} rows` +
|
| 324 |
+
(meta ? ` · ${meta}` : '') + `</div>`;
|
| 325 |
+
gsap.to(tooltipEl, { opacity: 1, duration: 0.15, overwrite: true });
|
| 326 |
+
})
|
| 327 |
+
.on('mousemove', function (ev) {
|
| 328 |
+
tooltipEl.style.left = (ev.clientX + 14) + 'px';
|
| 329 |
+
tooltipEl.style.top = (ev.clientY + 14) + 'px';
|
| 330 |
+
})
|
| 331 |
+
.on('mouseleave', function () {
|
| 332 |
+
gsap.to(tooltipEl, { opacity: 0, duration: 0.12, overwrite: true });
|
| 333 |
+
})
|
| 334 |
+
.on('click', function (ev, d) {
|
| 335 |
+
const key = getKey(d.data);
|
| 336 |
+
focusDonutSlice(svgId, this, key);
|
| 337 |
+
if (typeof showDetails === 'function') showDetails(key);
|
| 338 |
+
});
|
| 339 |
+
|
| 340 |
+
// Cache for drill-down reset logic.
|
| 341 |
+
donutState.set(svgId, { paths, arcGen, resolveColor });
|
| 342 |
+
|
| 343 |
+
// Center content — start at 0 and count up with GSAP.
|
| 344 |
+
if (centerId) {
|
| 345 |
+
const centerEl = document.getElementById(centerId);
|
| 346 |
+
const topIconHtml = topIcon ? `<span class="icon">${topIcon}</span>` : '';
|
| 347 |
+
const bottomIconHtml = bottomIcon ? `<span class="icon">${bottomIcon}</span>` : '';
|
| 348 |
+
centerEl.innerHTML =
|
| 349 |
+
`<div class="center-item top">
|
| 350 |
+
<div class="center-label">${topIconHtml}${topLabel}</div>
|
| 351 |
+
<div class="center-number js-count-top">0</div>
|
| 352 |
+
</div>
|
| 353 |
+
<div class="center-item bottom">
|
| 354 |
+
<div class="center-number js-count-bottom">0</div>
|
| 355 |
+
<div class="center-label">${bottomLabel}${bottomIconHtml}</div>
|
| 356 |
+
</div>`;
|
| 357 |
+
|
| 358 |
+
const topEl = centerEl.querySelector('.js-count-top');
|
| 359 |
+
const bottomEl = centerEl.querySelector('.js-count-bottom');
|
| 360 |
+
|
| 361 |
+
const topObj = { v: 0 };
|
| 362 |
+
gsap.to(topObj, {
|
| 363 |
+
v: count,
|
| 364 |
+
duration: 1.0,
|
| 365 |
+
ease: 'power2.out',
|
| 366 |
+
delay: 0.55,
|
| 367 |
+
onUpdate: () => { topEl.textContent = Math.floor(topObj.v); },
|
| 368 |
+
onComplete: () => { topEl.textContent = count; }
|
| 369 |
+
});
|
| 370 |
+
|
| 371 |
+
const bottomObj = { v: 0 };
|
| 372 |
+
gsap.to(bottomObj, {
|
| 373 |
+
v: total,
|
| 374 |
+
duration: 1.6,
|
| 375 |
+
ease: 'power2.out',
|
| 376 |
+
delay: 0.65,
|
| 377 |
+
onUpdate: () => { bottomEl.innerHTML = formatRows(Math.floor(bottomObj.v)); },
|
| 378 |
+
onComplete: () => { bottomEl.innerHTML = formatRows(total); }
|
| 379 |
+
});
|
| 380 |
+
|
| 381 |
+
gsap.from(`#${centerId} .center-label`, { y: 14, opacity: 0, duration: 0.55, ease: 'power3.out', delay: 0.45, stagger: 0.15 });
|
| 382 |
+
gsap.from(`#${centerId} .center-number`, { y: 10, opacity: 0, duration: 0.55, ease: 'power3.out', delay: 0.55, stagger: 0.15 });
|
| 383 |
+
|
| 384 |
+
// Space out the top/bottom blocks since the divider is gone.
|
| 385 |
+
centerEl.querySelector('.center-item.bottom').style.marginTop = '14px';
|
| 386 |
+
}
|
| 387 |
+
|
| 388 |
+
return paths;
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
/** Click drill-down: scale up clicked slice, dim the rest, toggle on re-click. */
|
| 392 |
+
function focusDonutSlice(svgId, clickedEl, clickedKey) {
|
| 393 |
+
const state = donutState.get(svgId);
|
| 394 |
+
if (!state) return;
|
| 395 |
+
const { paths, arcGen } = state;
|
| 396 |
+
|
| 397 |
+
// Toggle off if clicking the already-selected slice
|
| 398 |
+
if (state.selectedKey === clickedKey) {
|
| 399 |
+
resetDonutFocus(svgId);
|
| 400 |
+
return;
|
| 401 |
+
}
|
| 402 |
+
state.selectedKey = clickedKey;
|
| 403 |
+
|
| 404 |
+
paths.nodes().forEach((node, i) => {
|
| 405 |
+
const d = paths.data()[i];
|
| 406 |
+
const isSelected = node === clickedEl;
|
| 407 |
+
if (isSelected) {
|
| 408 |
+
const [cx, cy] = node._centroid || arcGen.centroid(d);
|
| 409 |
+
gsap.to(node, {
|
| 410 |
+
scale: 1.08,
|
| 411 |
+
opacity: 1,
|
| 412 |
+
svgOrigin: `${cx} ${cy}`,
|
| 413 |
+
filter: 'drop-shadow(0 0 14px rgba(255,255,255,0.35)) brightness(1.15)',
|
| 414 |
+
duration: 0.45,
|
| 415 |
+
ease: 'power2.out',
|
| 416 |
+
overwrite: 'auto'
|
| 417 |
+
});
|
| 418 |
+
} else {
|
| 419 |
+
gsap.to(node, {
|
| 420 |
+
scale: 1,
|
| 421 |
+
opacity: 0.3,
|
| 422 |
+
filter: 'none',
|
| 423 |
+
duration: 0.35,
|
| 424 |
+
ease: 'power2.out',
|
| 425 |
+
overwrite: 'auto'
|
| 426 |
+
});
|
| 427 |
+
}
|
| 428 |
+
});
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
+
function resetDonutFocus(svgId) {
|
| 432 |
+
const state = donutState.get(svgId);
|
| 433 |
+
if (!state) return;
|
| 434 |
+
state.selectedKey = null;
|
| 435 |
+
state.paths.nodes().forEach(node => {
|
| 436 |
+
gsap.to(node, {
|
| 437 |
+
scale: 1, opacity: 1, filter: 'none',
|
| 438 |
+
duration: 0.35, ease: 'power2.out', overwrite: 'auto'
|
| 439 |
+
});
|
| 440 |
+
});
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
+
// ---- Raw vs Adaption donuts ----
|
| 444 |
+
// The Raw donut shows every dataset that has a raw repo (including the
|
| 445 |
+
// PolyglotText / PolyglotAudio pre-training pools). The Adaption donut shows
|
| 446 |
+
// every dataset with an Adaption-remastered version. renderDonut() filters
|
| 447 |
+
// out zero-value entries automatically.
|
| 448 |
+
renderDonut({
|
| 449 |
+
svgId: 'chart-raw',
|
| 450 |
+
centerId: 'center-raw',
|
| 451 |
+
field: 'raw',
|
| 452 |
+
datasets: DATASETS,
|
| 453 |
+
getValue: d => (d.raw && d.raw.rows) || 0,
|
| 454 |
+
getKey: d => d.key,
|
| 455 |
+
getTitle: d => d.title,
|
| 456 |
+
getMeta: d => d.raw ? d.raw.repo : '',
|
| 457 |
+
topLabel: 'RAW DATASETS',
|
| 458 |
+
bottomLabel: 'ROWS',
|
| 459 |
+
topIcon: '',
|
| 460 |
+
bottomIcon: '',
|
| 461 |
+
sizing: 'log', // compress so tiny datasets still get a visible slice
|
| 462 |
+
});
|
| 463 |
+
|
| 464 |
+
renderDonut({
|
| 465 |
+
svgId: 'chart-adaption',
|
| 466 |
+
centerId: 'center-adaption',
|
| 467 |
+
field: 'adaption',
|
| 468 |
+
datasets: DATASETS,
|
| 469 |
+
getValue: d => (d.adaption && d.adaption.rows) || 0,
|
| 470 |
+
getKey: d => d.key,
|
| 471 |
+
getTitle: d => d.title,
|
| 472 |
+
getMeta: d => d.adaption ? d.adaption.repo : '',
|
| 473 |
+
topLabel: 'ADAPTION SETS',
|
| 474 |
+
bottomLabel: 'ROWS',
|
| 475 |
+
topIcon: '',
|
| 476 |
+
bottomIcon: '',
|
| 477 |
+
});
|
| 478 |
+
|
| 479 |
+
// ---- Modality donut ----
|
| 480 |
+
const MODALITIES = [
|
| 481 |
+
{ key: 'text', name: 'Text', count: 5 },
|
| 482 |
+
{ key: 'audio', name: 'Audio', count: 3 },
|
| 483 |
+
{ key: 'image', name: 'Image', count: 3 },
|
| 484 |
+
{ key: 'code', name: 'Code', count: 1 },
|
| 485 |
+
];
|
| 486 |
+
const modalityColor = d3.scaleOrdinal(PALETTE).domain(MODALITIES.map(m => m.key));
|
| 487 |
+
|
| 488 |
+
renderDonut({
|
| 489 |
+
svgId: 'chart-modality',
|
| 490 |
+
centerId: 'center-modality',
|
| 491 |
+
field: 'count',
|
| 492 |
+
datasets: MODALITIES,
|
| 493 |
+
getValue: d => d.count,
|
| 494 |
+
getKey: d => d.key,
|
| 495 |
+
getTitle: d => d.name,
|
| 496 |
+
getColor: d => modalityColor(d.key),
|
| 497 |
+
getMeta: d => `${d.count} datasets`,
|
| 498 |
+
topLabel: 'MODALITIES',
|
| 499 |
+
bottomLabel: 'DATASETS',
|
| 500 |
+
topIcon: '',
|
| 501 |
+
bottomIcon: '',
|
| 502 |
+
});
|
| 503 |
+
|
| 504 |
+
// ===========================================================================
|
| 505 |
+
// DETAILS CARD — rendered on slice click with GSAP reveal
|
| 506 |
+
// ===========================================================================
|
| 507 |
+
function hideLanguageDetails() {
|
| 508 |
+
// No-op placeholder — currently we share the single details card; click-
|
| 509 |
+
// another to switch. Kept as an explicit symbol for future extension.
|
| 510 |
+
}
|
| 511 |
+
|
| 512 |
+
function showLanguageDetails(langData, color) {
|
| 513 |
+
const card = document.getElementById('details-card');
|
| 514 |
+
card.style.display = '';
|
| 515 |
+
|
| 516 |
+
// Per-dataset breakdown for this language.
|
| 517 |
+
const breakdown = DATASET_LANGS
|
| 518 |
+
.map(d => ({ dataset: d.name, key: d.key, rows: d.langs[langData.code] || 0 }))
|
| 519 |
+
.filter(d => d.rows > 0)
|
| 520 |
+
.sort((a, b) => b.rows - a.rows);
|
| 521 |
+
|
| 522 |
+
const rows = breakdown.map(b =>
|
| 523 |
+
`<div class="kv"><div class="k">${b.dataset}</div><div class="v"><strong>${formatShort(b.rows)}</strong>
|
| 524 |
+
<span style="color:var(--muted);font-size:0.85em">(${b.rows.toLocaleString()})</span></div></div>`
|
| 525 |
+
).join('');
|
| 526 |
+
|
| 527 |
+
card.innerHTML = `
|
| 528 |
+
<h3>
|
| 529 |
+
<span class="swatch" style="background:${color}"></span>
|
| 530 |
+
${langData.name} <span style="color:var(--muted);font-weight:400;font-size:0.9rem">(${langData.code})</span>
|
| 531 |
+
</h3>
|
| 532 |
+
<p class="tagline">Total across the raw corpus: <strong>${langData.value.toLocaleString()}</strong> rows.</p>
|
| 533 |
+
<div class="kv-grid">${rows}</div>
|
| 534 |
+
`;
|
| 535 |
+
|
| 536 |
+
gsap.fromTo(card,
|
| 537 |
+
{ y: 80, opacity: 0 },
|
| 538 |
+
{ y: 0, opacity: 1, duration: 0.75, ease: 'power4.out' }
|
| 539 |
+
);
|
| 540 |
+
gsap.from(card.querySelectorAll('.kv'), {
|
| 541 |
+
y: 18, opacity: 0, duration: 0.45, ease: 'power3.out',
|
| 542 |
+
stagger: 0.05, delay: 0.2
|
| 543 |
+
});
|
| 544 |
+
|
| 545 |
+
card.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
| 546 |
+
}
|
| 547 |
+
|
| 548 |
+
function showDetails(key) {
|
| 549 |
+
const d = DATASETS.find(x => x.key === key);
|
| 550 |
+
if (!d) return;
|
| 551 |
+
const card = document.getElementById('details-card');
|
| 552 |
+
card.style.display = '';
|
| 553 |
+
|
| 554 |
+
const repoLink = info => info
|
| 555 |
+
? `<a href="https://huggingface.co/datasets/${info.repo}" target="_blank">${info.repo}</a>`
|
| 556 |
+
: `<span style="color:var(--muted);">—</span>`;
|
| 557 |
+
const rowsCell = info => info
|
| 558 |
+
? `<strong>${formatShort(info.rows)}</strong> <span style="color:var(--muted);font-size:0.85em">(${info.rows.toLocaleString()})</span>`
|
| 559 |
+
: `<span style="color:var(--muted);">—</span>`;
|
| 560 |
+
|
| 561 |
+
card.innerHTML = `
|
| 562 |
+
<h3>
|
| 563 |
+
<span class="swatch" style="background:${d.color}"></span>
|
| 564 |
+
${d.title}
|
| 565 |
+
</h3>
|
| 566 |
+
<p class="tagline">${d.tagline}</p>
|
| 567 |
+
<div class="kv-grid">
|
| 568 |
+
<div class="kv"><div class="k">Raw repo</div><div class="v">${repoLink(d.raw)}</div></div>
|
| 569 |
+
<div class="kv"><div class="k">Raw rows</div><div class="v">${rowsCell(d.raw)}</div></div>
|
| 570 |
+
<div class="kv"><div class="k">Adaption repo</div><div class="v">${repoLink(d.adaption)}</div></div>
|
| 571 |
+
<div class="kv"><div class="k">Adaption rows</div><div class="v">${rowsCell(d.adaption)}</div></div>
|
| 572 |
+
<div class="kv"><div class="k">Modality</div><div class="v">${d.modality}</div></div>
|
| 573 |
+
<div class="kv"><div class="k">License</div><div class="v">${d.license}</div></div>
|
| 574 |
+
${d.model ? `<div class="kv"><div class="k">Annotator</div><div class="v">${d.model}</div></div>` : ''}
|
| 575 |
+
<div class="kv"><div class="k">Languages</div><div class="v">${d.languages}</div></div>
|
| 576 |
+
</div>
|
| 577 |
+
<div class="kv" style="margin-top:18px;">
|
| 578 |
+
<div class="k">Schema</div>
|
| 579 |
+
<div class="schema-list">${d.schema.map(c => `<code>${c}</code>`).join('')}</div>
|
| 580 |
+
</div>
|
| 581 |
+
`;
|
| 582 |
+
|
| 583 |
+
// Elegant slide-in from the bottom with power4.out.
|
| 584 |
+
gsap.fromTo(card,
|
| 585 |
+
{ y: 80, opacity: 0 },
|
| 586 |
+
{ y: 0, opacity: 1, duration: 0.75, ease: 'power4.out' }
|
| 587 |
+
);
|
| 588 |
+
gsap.from(card.querySelectorAll('.kv'), {
|
| 589 |
+
y: 18, opacity: 0, duration: 0.45, ease: 'power3.out',
|
| 590 |
+
stagger: 0.05, delay: 0.2
|
| 591 |
+
});
|
| 592 |
+
|
| 593 |
+
card.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
| 594 |
+
}
|
| 595 |
+
|
| 596 |
+
// ===========================================================================
|
| 597 |
+
// INITIAL PAGE LOAD — hero image → hero stats → chart cards, staggered.
|
| 598 |
+
// ===========================================================================
|
| 599 |
+
const loadTl = gsap.timeline();
|
| 600 |
+
loadTl
|
| 601 |
+
.from('.hero-img', { y: 20, opacity: 0, duration: 0.9, ease: 'power3.out' })
|
| 602 |
+
.from('.stat', { y: 20, opacity: 0, duration: 0.7, ease: 'power3.out', stagger: 0.15 }, '-=0.5')
|
| 603 |
+
.from('.chart-card', { y: 20, opacity: 0, duration: 0.8, ease: 'power3.out', stagger: 0.15 }, '-=0.3');
|
| 604 |
+
|
| 605 |
+
// ===========================================================================
|
| 606 |
+
// LANGUAGE DATA (for the Voronoi treemap)
|
| 607 |
+
// ===========================================================================
|
| 608 |
+
const LANG_NAMES = {
|
| 609 |
+
tr: "Turkish", ru: "Russian", it: "Italian", en: "English", eo: "Esperanto",
|
| 610 |
+
hu: "Hungarian", de: "German", fr: "French", pt: "Portuguese", mk: "Macedonian",
|
| 611 |
+
es: "Spanish", he: "Hebrew", fi: "Finnish", ber: "Berber", nl: "Dutch",
|
| 612 |
+
pl: "Polish", sr: "Serbian", mr: "Marathi", el: "Greek", da: "Danish",
|
| 613 |
+
cs: "Czech", sv: "Swedish", bg: "Bulgarian", la: "Latin", zh: "Mandarin",
|
| 614 |
+
ro: "Romanian", ia: "Interlingua", ja: "Japanese", tok: "Toki Pona",
|
| 615 |
+
lfn: "Lingua Franca Nova", uk: "Ukrainian", tt: "Tatar", tl: "Tagalog",
|
| 616 |
+
id: "Indonesian", nb: "Norwegian B.", lt: "Lithuanian", az: "Azerbaijani",
|
| 617 |
+
ie: "Interlingue", tlh: "Klingon", jbo: "Lojban", mhr: "Meadow Mari",
|
| 618 |
+
bn: "Bengali", fa: "Persian", br: "Breton", ilo: "Ilocano", ar: "Arabic",
|
| 619 |
+
ceb: "Cebuano", hi: "Hindi", vi: "Vietnamese", pam: "Kapampangan",
|
| 620 |
+
hy: "Armenian", be: "Belarusian", ko: "Korean", yue: "Cantonese",
|
| 621 |
+
ca: "Catalan", kab: "Kabyle", af: "Afrikaans", am: "Amharic", yi: "Yiddish",
|
| 622 |
+
sat: "Santali", so: "Somali", te: "Telugu", ne: "Nepali", pa: "Punjabi",
|
| 623 |
+
ur: "Urdu", ta: "Tamil", ml: "Malayalam", th: "Thai", or: "Odia",
|
| 624 |
+
sd: "Sindhi", gu: "Gujarati", kn: "Kannada", my: "Burmese", bo: "Tibetan",
|
| 625 |
+
lo: "Lao", mni: "Meitei", kk: "Kazakh", oc: "Occitan", hr: "Croatian",
|
| 626 |
+
sk: "Slovak", et: "Estonian", sl: "Slovenian", is: "Icelandic", ms: "Malay",
|
| 627 |
+
sq: "Albanian", hsb: "Upper Sorbian", dsb: "Lower Sorbian", mai: "Maithili",
|
| 628 |
+
kha: "Khasi", dtp: "Kadazan", yo: "Yoruba", sw: "Swahili", cy: "Welsh",
|
| 629 |
+
ga: "Irish", gd: "Scottish Gaelic", ti: "Tigrinya", os: "Ossetian",
|
| 630 |
+
sa: "Sanskrit", ug: "Uyghur", uz: "Uzbek", ka: "Georgian", eu: "Basque",
|
| 631 |
+
vo: "Volapük", ido: "Ido", nov: "Novial", avk: "Kotava", ldn: "Láadan",
|
| 632 |
+
afh: "Afrihili", lzh: "Classical Chinese", non: "Old Norse", ang: "Old English",
|
| 633 |
+
grc: "Ancient Greek", sux: "Sumerian", fro: "Old French", cbk: "Chavacano",
|
| 634 |
+
zsm: "Standard Malay", war: "Waray", kw: "Cornish", nah: "Nahuatl",
|
| 635 |
+
kek: "Q'eqchi'", hif: "Fiji Hindi", crh: "Crimean Tatar", sah: "Sakha",
|
| 636 |
+
ext: "Extremaduran", csb: "Kashubian", sgs: "Samogitian", cha: "Chamorro",
|
| 637 |
+
tvl: "Tuvaluan", mi: "Maori", lin: "Lingala", arq: "Algerian Arabic",
|
| 638 |
+
arz: "Egyptian Arabic", orv: "Old East Slavic", prg: "Old Prussian",
|
| 639 |
+
chv: "Chuvash", bar: "Bavarian", pms: "Piedmontese", egl: "Emilian",
|
| 640 |
+
jav: "Javanese", sun: "Sundanese", hoc: "Ho", zza: "Zaza",
|
| 641 |
+
rif: "Riffian Berber", nog: "Nogai", km: "Khmer",
|
| 642 |
+
};
|
| 643 |
+
|
| 644 |
+
const DATASET_LANGS = [
|
| 645 |
+
{
|
| 646 |
+
key: "polytext", name: "PolyglotText",
|
| 647 |
+
langs: {
|
| 648 |
+
tr: 1767000, ru: 1695000, it: 1588000, en: 1337000, eo: 1171000,
|
| 649 |
+
hu: 817000, de: 675000, fr: 520000, pt: 470000, mk: 398000,
|
| 650 |
+
es: 358000, he: 272000, fi: 263000, ber: 180000, nl: 125000,
|
| 651 |
+
pl: 118000, sr: 106000, mr: 96000, el: 94000, da: 90000,
|
| 652 |
+
cs: 72000, sv: 71000, bg: 70000, la: 66000, zh: 58000, ro: 56000,
|
| 653 |
+
ia: 54000, ja: 43000, tok: 39000, lfn: 38000, uk: 38000, tt: 33000,
|
| 654 |
+
tl: 31000, id: 31000, nb: 31000, lt: 29000, az: 25000, ie: 24000,
|
| 655 |
+
tlh: 23000, jbo: 21000, mhr: 19000, bn: 19000, fa: 17000, br: 17000,
|
| 656 |
+
ilo: 17000, ar: 16000, ceb: 15000, hi: 13000, vi: 11000, pam: 11000,
|
| 657 |
+
hy: 9000, be: 9000, ko: 9000,
|
| 658 |
+
cbk: 19000, sk: 8000, vo: 8000, oc: 8000, et: 8000,
|
| 659 |
+
war: 6700, ms: 6700, hr: 6700, eu: 6700, yi: 5400, af: 5400,
|
| 660 |
+
km: 4000, ca: 4000, kha: 4000, dtp: 4000, zza: 4000, is: 4000,
|
| 661 |
+
avk: 4000, ga: 4000, hoc: 4000, sl: 4000, sq: 4000, chv: 4000,
|
| 662 |
+
kw: 4000, sux: 2700, ang: 2700, pms: 2700, prg: 2700, ug: 2700,
|
| 663 |
+
lzh: 2700, egl: 2700, ur: 2700, sah: 2700, nds: 2700, mi: 2700,
|
| 664 |
+
tvl: 1400, cha: 1400, th: 1400, cy: 1400, non: 1400, yo: 1400,
|
| 665 |
+
lin: 1400, grc: 1400, arq: 1400, orv: 1400, sw: 1400, rif: 1400,
|
| 666 |
+
crh: 1400, hif: 1400, jav: 1400, sun: 1400, hsb: 1400, dsb: 1400,
|
| 667 |
+
amh: 1400, csb: 1400, sgs: 1400, ext: 1400, nov: 1400, nog: 1400,
|
| 668 |
+
arz: 1400, nah: 1400, ido: 1400, afh: 1400, kk: 1400,
|
| 669 |
+
}
|
| 670 |
+
},
|
| 671 |
+
{
|
| 672 |
+
key: "polyaudio", name: "PolyglotAudio",
|
| 673 |
+
langs: {
|
| 674 |
+
en: 698000, es: 261000, eo: 105000, de: 32000, fr: 16000,
|
| 675 |
+
ru: 9200, pl: 8800, ber: 6600, nl: 5900, it: 5900,
|
| 676 |
+
yue: 4300, pt: 3300, ja: 1400, mr: 1200, ca: 505,
|
| 677 |
+
cs: 410, zh: 110, fi: 93, hu: 87, uk: 38,
|
| 678 |
+
he: 16, tok: 5, kab: 5,
|
| 679 |
+
}
|
| 680 |
+
},
|
| 681 |
+
{
|
| 682 |
+
key: "tts", name: "multilingual-synthetic-tts",
|
| 683 |
+
langs: {
|
| 684 |
+
ja: 13951, ru: 9105, de: 8972, ko: 8129, es: 7917,
|
| 685 |
+
pt: 5438, zh: 5417, en: 5157, fr: 4551,
|
| 686 |
+
}
|
| 687 |
+
},
|
| 688 |
+
{
|
| 689 |
+
key: "magazines", name: "magazines-multilingual-vqa",
|
| 690 |
+
langs: {
|
| 691 |
+
de: 4412, fr: 3279, ru: 2762, pt: 2047, vi: 1637, bn: 1598,
|
| 692 |
+
en: 1004, af: 826, ar: 156, it: 136, fa: 132, te: 132,
|
| 693 |
+
ja: 130, ne: 108, pa: 100, ur: 98, nl: 95, tr: 85, zh: 83,
|
| 694 |
+
ta: 68, ml: 64, id: 43, th: 47, am: 123, yi: 108, sat: 85,
|
| 695 |
+
so: 25, hi: 15, es: 10, mr: 9, kn: 8, or: 17, sd: 3,
|
| 696 |
+
mai: 1021, la: 146, bo: 25, be: 8, da: 6, ko: 4, bg: 4,
|
| 697 |
+
os: 3, sa: 3, my: 3, oc: 1, gd: 1, ti: 1, hy: 1, pl: 1,
|
| 698 |
+
mni: 1, uk: 1, lo: 1, kk: 1,
|
| 699 |
+
}
|
| 700 |
+
},
|
| 701 |
+
{ key: "fma", name: "fma-labeled", langs: { en: 29000 } },
|
| 702 |
+
{ key: "streetview", name: "streetview-global", langs: { en: 30000 } },
|
| 703 |
+
{ key: "current_affairs", name: "current-affairs (raw, 2023-26)", langs: { en: 20694 } },
|
| 704 |
+
{ key: "frontend", name: "frontend-coding", langs: { en: 500 } },
|
| 705 |
+
{
|
| 706 |
+
key: "image_ann", name: "multilingual-image-annotations",
|
| 707 |
+
langs: { en: 464, es: 464, fr: 464, hi: 464, zh: 464, ar: 464, pt: 464 }
|
| 708 |
+
},
|
| 709 |
+
];
|
| 710 |
+
|
| 711 |
+
// Aggregate totals across the raw corpus
|
| 712 |
+
const langTotals = {};
|
| 713 |
+
for (const d of DATASET_LANGS) {
|
| 714 |
+
for (const [lang, n] of Object.entries(d.langs)) {
|
| 715 |
+
langTotals[lang] = (langTotals[lang] || 0) + n;
|
| 716 |
+
}
|
| 717 |
+
}
|
| 718 |
+
const langEntries = Object.entries(langTotals)
|
| 719 |
+
.sort((a, b) => b[1] - a[1])
|
| 720 |
+
.map(([code, n]) => ({
|
| 721 |
+
code,
|
| 722 |
+
name: LANG_NAMES[code] || code,
|
| 723 |
+
value: n,
|
| 724 |
+
sizeValue: Math.log10(n + 10),
|
| 725 |
+
}));
|
| 726 |
+
|
| 727 |
+
// ===========================================================================
|
| 728 |
+
// VORONOI TREEMAP (D3) — palette quantile coloring, black strokes
|
| 729 |
+
// ===========================================================================
|
| 730 |
+
(function renderVoronoi() {
|
| 731 |
+
const container = document.getElementById('chart-treemap');
|
| 732 |
+
const tooltip = document.getElementById('voronoi-tooltip');
|
| 733 |
+
|
| 734 |
+
if (typeof d3 === 'undefined' || !d3.voronoiTreemap) {
|
| 735 |
+
container.insertAdjacentHTML('beforeend',
|
| 736 |
+
`<div style="color:#ff8a8a;padding:24px;text-align:center;font-size:0.9rem">
|
| 737 |
+
Voronoi treemap libraries failed to load. Check your network / CSP.
|
| 738 |
+
</div>`);
|
| 739 |
+
return;
|
| 740 |
+
}
|
| 741 |
+
|
| 742 |
+
// Map language size buckets onto PALETTE via quantiles, so cells naturally
|
| 743 |
+
// cluster by tonal groups.
|
| 744 |
+
const colorScale = d3.scaleQuantile()
|
| 745 |
+
.domain(langEntries.map(e => e.sizeValue))
|
| 746 |
+
.range(PALETTE);
|
| 747 |
+
|
| 748 |
+
function draw() {
|
| 749 |
+
container.querySelectorAll('svg').forEach(s => s.remove());
|
| 750 |
+
|
| 751 |
+
const rect = container.getBoundingClientRect();
|
| 752 |
+
const width = Math.max(320, rect.width);
|
| 753 |
+
const height = Math.max(320, rect.height);
|
| 754 |
+
|
| 755 |
+
// Circular clip polygon
|
| 756 |
+
const clipPad = 6;
|
| 757 |
+
const cx = width / 2, cy = height / 2;
|
| 758 |
+
const r = Math.min(width, height) / 2 - clipPad;
|
| 759 |
+
const N = 96;
|
| 760 |
+
const clipPolygon = d3.range(N).map(i => [
|
| 761 |
+
cx + r * Math.cos((i / N) * 2 * Math.PI),
|
| 762 |
+
cy + r * Math.sin((i / N) * 2 * Math.PI),
|
| 763 |
+
]);
|
| 764 |
+
|
| 765 |
+
const root = d3.hierarchy({ name: 'root', children: langEntries })
|
| 766 |
+
.sum(d => d.sizeValue);
|
| 767 |
+
|
| 768 |
+
const treemap = d3.voronoiTreemap()
|
| 769 |
+
.clip(clipPolygon)
|
| 770 |
+
.convergenceRatio(0.005)
|
| 771 |
+
.maxIterationCount(120)
|
| 772 |
+
.minWeightRatio(0.01);
|
| 773 |
+
treemap(root);
|
| 774 |
+
|
| 775 |
+
const svg = d3.select(container).append('svg')
|
| 776 |
+
.attr('viewBox', `0 0 ${width} ${height}`)
|
| 777 |
+
.attr('preserveAspectRatio', 'xMidYMid meet');
|
| 778 |
+
const g = svg.append('g');
|
| 779 |
+
|
| 780 |
+
// Outer circle outline
|
| 781 |
+
g.append('circle')
|
| 782 |
+
.attr('cx', cx).attr('cy', cy).attr('r', r + 1)
|
| 783 |
+
.attr('fill', 'none')
|
| 784 |
+
.attr('stroke', '#1f1f1f')
|
| 785 |
+
.attr('stroke-width', 1);
|
| 786 |
+
|
| 787 |
+
const leaves = root.leaves();
|
| 788 |
+
|
| 789 |
+
const cells = g.selectAll('path.voronoi-cell')
|
| 790 |
+
.data(leaves)
|
| 791 |
+
.join('path')
|
| 792 |
+
.attr('class', 'voronoi-cell')
|
| 793 |
+
.attr('d', d => 'M' + d.polygon.map(p => p.join(',')).join('L') + 'Z')
|
| 794 |
+
.attr('fill', d => colorScale(d.data.sizeValue))
|
| 795 |
+
.attr('stroke', '#000000')
|
| 796 |
+
.attr('stroke-width', 1.2)
|
| 797 |
+
.attr('stroke-linejoin', 'round');
|
| 798 |
+
|
| 799 |
+
// Record centroid per cell so we can scale from the cell's own center.
|
| 800 |
+
cells.each(function (leaf) {
|
| 801 |
+
const [cx, cy] = leaf.site || d3.polygonCentroid(leaf.polygon);
|
| 802 |
+
this._centroid = [cx, cy];
|
| 803 |
+
});
|
| 804 |
+
|
| 805 |
+
// Mosaic build: fade + scale up from each cell's own centroid, staggered.
|
| 806 |
+
cells.nodes().forEach((node, i) => {
|
| 807 |
+
const [cx, cy] = node._centroid;
|
| 808 |
+
gsap.fromTo(node,
|
| 809 |
+
{ scale: 0, opacity: 0, svgOrigin: `${cx} ${cy}` },
|
| 810 |
+
{ scale: 1, opacity: 1, svgOrigin: `${cx} ${cy}`,
|
| 811 |
+
duration: 0.55, ease: 'power3.out', delay: i * 0.012 }
|
| 812 |
+
);
|
| 813 |
+
});
|
| 814 |
+
|
| 815 |
+
// Labels — sized by cell area; smaller cells hide the name, tiny ones only show on hover.
|
| 816 |
+
function polyArea(pts) {
|
| 817 |
+
let a = 0;
|
| 818 |
+
for (let i = 0, n = pts.length; i < n; i++) {
|
| 819 |
+
const [x1, y1] = pts[i], [x2, y2] = pts[(i + 1) % n];
|
| 820 |
+
a += x1 * y2 - x2 * y1;
|
| 821 |
+
}
|
| 822 |
+
return Math.abs(a) / 2;
|
| 823 |
+
}
|
| 824 |
+
|
| 825 |
+
leaves.forEach(leaf => {
|
| 826 |
+
const area = polyArea(leaf.polygon);
|
| 827 |
+
const side = Math.sqrt(area);
|
| 828 |
+
const [x, y] = leaf.site || d3.polygonCentroid(leaf.polygon);
|
| 829 |
+
const d = leaf.data;
|
| 830 |
+
|
| 831 |
+
if (side >= 44) {
|
| 832 |
+
const nameSize = Math.max(10, Math.min(18, side / 6));
|
| 833 |
+
const codeSize = Math.max(9, Math.min(13, side / 9));
|
| 834 |
+
const text = g.append('text')
|
| 835 |
+
.datum(leaf.data)
|
| 836 |
+
.attr('class', 'voronoi-label')
|
| 837 |
+
.attr('x', x).attr('y', y - 2)
|
| 838 |
+
.attr('font-size', nameSize);
|
| 839 |
+
text.append('tspan').text(d.name);
|
| 840 |
+
text.append('tspan')
|
| 841 |
+
.attr('class', 'code')
|
| 842 |
+
.attr('x', x).attr('dy', nameSize * 0.95)
|
| 843 |
+
.attr('font-size', codeSize)
|
| 844 |
+
.text(`${d.code} · ${formatShort(d.value)}`);
|
| 845 |
+
} else if (side >= 22) {
|
| 846 |
+
const sz = Math.max(8, Math.min(11, side / 3));
|
| 847 |
+
g.append('text')
|
| 848 |
+
.datum(leaf.data)
|
| 849 |
+
.attr('class', 'voronoi-label')
|
| 850 |
+
.attr('x', x).attr('y', y + sz / 3)
|
| 851 |
+
.attr('font-size', sz)
|
| 852 |
+
.text(d.code);
|
| 853 |
+
}
|
| 854 |
+
});
|
| 855 |
+
|
| 856 |
+
// Hover tooltip
|
| 857 |
+
cells
|
| 858 |
+
.on('mouseenter', (ev, d) => {
|
| 859 |
+
tooltip.innerHTML =
|
| 860 |
+
`<span class="t-name">${d.data.name}</span>` +
|
| 861 |
+
`<span class="t-code">(${d.data.code})</span>` +
|
| 862 |
+
`<div class="t-rows">${d.data.value.toLocaleString()} rows</div>`;
|
| 863 |
+
gsap.to(tooltip, { opacity: 1, duration: 0.12, overwrite: true });
|
| 864 |
+
})
|
| 865 |
+
.on('mousemove', (ev) => {
|
| 866 |
+
const bb = container.getBoundingClientRect();
|
| 867 |
+
tooltip.style.left = (ev.clientX - bb.left + 12) + 'px';
|
| 868 |
+
tooltip.style.top = (ev.clientY - bb.top + 12) + 'px';
|
| 869 |
+
})
|
| 870 |
+
.on('mouseleave', () => {
|
| 871 |
+
gsap.to(tooltip, { opacity: 0, duration: 0.1, overwrite: true });
|
| 872 |
+
});
|
| 873 |
+
|
| 874 |
+
// Click drill-down: highlight the clicked cell, dim the rest, surface a
|
| 875 |
+
// language detail card below the treemap.
|
| 876 |
+
let selectedCell = null;
|
| 877 |
+
cells.on('click', function (ev, d) {
|
| 878 |
+
const [cx, cy] = this._centroid;
|
| 879 |
+
const sameAgain = selectedCell === this;
|
| 880 |
+
if (sameAgain) {
|
| 881 |
+
// reset
|
| 882 |
+
selectedCell = null;
|
| 883 |
+
cells.nodes().forEach(node => {
|
| 884 |
+
const [ncx, ncy] = node._centroid;
|
| 885 |
+
gsap.to(node, {
|
| 886 |
+
scale: 1, opacity: 1,
|
| 887 |
+
svgOrigin: `${ncx} ${ncy}`,
|
| 888 |
+
filter: 'none',
|
| 889 |
+
duration: 0.35, ease: 'power2.out', overwrite: 'auto',
|
| 890 |
+
});
|
| 891 |
+
});
|
| 892 |
+
g.selectAll('.voronoi-label').each(function() {
|
| 893 |
+
gsap.to(this, { opacity: 1, duration: 0.35, overwrite: 'auto' });
|
| 894 |
+
});
|
| 895 |
+
hideLanguageDetails();
|
| 896 |
+
return;
|
| 897 |
+
}
|
| 898 |
+
selectedCell = this;
|
| 899 |
+
cells.nodes().forEach(node => {
|
| 900 |
+
const [ncx, ncy] = node._centroid;
|
| 901 |
+
if (node === this) {
|
| 902 |
+
gsap.to(node, {
|
| 903 |
+
scale: 1.1, opacity: 1,
|
| 904 |
+
svgOrigin: `${ncx} ${ncy}`,
|
| 905 |
+
filter: 'drop-shadow(0 0 10px rgba(255,255,255,0.45)) brightness(1.35)',
|
| 906 |
+
duration: 0.45, ease: 'power2.out', overwrite: 'auto',
|
| 907 |
+
});
|
| 908 |
+
} else {
|
| 909 |
+
gsap.to(node, {
|
| 910 |
+
scale: 1, opacity: 0,
|
| 911 |
+
svgOrigin: `${ncx} ${ncy}`,
|
| 912 |
+
filter: 'none',
|
| 913 |
+
duration: 0.35, ease: 'power2.out', overwrite: 'auto',
|
| 914 |
+
});
|
| 915 |
+
}
|
| 916 |
+
});
|
| 917 |
+
g.selectAll('.voronoi-label').each(function(ld) {
|
| 918 |
+
if (ld && ld.code === d.data.code) {
|
| 919 |
+
gsap.to(this, { opacity: 1, duration: 0.45, overwrite: 'auto' });
|
| 920 |
+
} else {
|
| 921 |
+
gsap.to(this, { opacity: 0, duration: 0.35, overwrite: 'auto' });
|
| 922 |
+
}
|
| 923 |
+
});
|
| 924 |
+
showLanguageDetails(d.data, colorScale(d.data.sizeValue));
|
| 925 |
+
|
| 926 |
+
// Also emit the custom event so external code can react.
|
| 927 |
+
container.dispatchEvent(new CustomEvent('voronoi-drilldown', {
|
| 928 |
+
detail: { code: d.data.code, name: d.data.name, rows: d.data.value }
|
| 929 |
+
}));
|
| 930 |
+
});
|
| 931 |
+
}
|
| 932 |
+
|
| 933 |
+
draw();
|
| 934 |
+
|
| 935 |
+
let t;
|
| 936 |
+
window.addEventListener('resize', () => {
|
| 937 |
+
clearTimeout(t);
|
| 938 |
+
t = setTimeout(draw, 200);
|
| 939 |
+
});
|
| 940 |
+
})();
|
index.html
CHANGED
|
@@ -1,1376 +1,435 @@
|
|
| 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>ReubenDataLab · Dataset Explorer</title>
|
| 7 |
-
|
| 8 |
-
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 9 |
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 10 |
-
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Google+Sans:ital,opsz,wght@0,17..18,400..700;1,17..18,400..700&display=swap" rel="stylesheet">
|
| 11 |
-
|
| 12 |
-
<script src="
|
| 13 |
-
<script src="
|
| 14 |
-
<script src="
|
| 15 |
-
<script src="
|
| 16 |
-
<script src="
|
| 17 |
-
|
| 18 |
-
<style>
|
| 19 |
-
:root {
|
| 20 |
-
--bg: #000000;
|
| 21 |
-
--fg: #ffffff;
|
| 22 |
-
--muted: #8a8a94;
|
| 23 |
-
--card: #141414;
|
| 24 |
-
--card-alt: #1c1c1e;
|
| 25 |
-
--border: #262626;
|
| 26 |
-
--divider: #2e2e2e;
|
| 27 |
-
--tooltip-bg: rgba(20, 20, 20, 0.96);
|
| 28 |
-
|
| 29 |
-
--palette-1: #3b82f6;
|
| 30 |
-
--palette-2: #10b981;
|
| 31 |
-
--palette-3: #ef4444;
|
| 32 |
-
--palette-4: #f59e0b;
|
| 33 |
-
--palette-5: #8b5cf6;
|
| 34 |
-
--palette-6: #ec4899;
|
| 35 |
-
--palette-7: #06b6d4;
|
| 36 |
-
--palette-8: #84cc16;
|
| 37 |
-
--palette-9: #f97316;
|
| 38 |
-
--palette-10: #14b8a6;
|
| 39 |
-
--palette-11: #a855f7;
|
| 40 |
-
--palette-12: #eab308;
|
| 41 |
-
}
|
| 42 |
-
|
| 43 |
-
* { box-sizing: border-box; }
|
| 44 |
-
html, body {
|
| 45 |
-
margin: 0; padding: 0;
|
| 46 |
-
background: var(--bg);
|
| 47 |
-
color: var(--fg);
|
| 48 |
-
font-family: "Geist", "Google Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
| 49 |
-
font-weight: 400;
|
| 50 |
-
min-height: 100vh;
|
| 51 |
-
-webkit-font-smoothing: antialiased;
|
| 52 |
-
letter-spacing: 0.005em;
|
| 53 |
-
}
|
| 54 |
-
|
| 55 |
-
a { color: var(--fg); text-decoration: none; }
|
| 56 |
-
a:hover { opacity: 0.7; }
|
| 57 |
-
|
| 58 |
-
/* Header / hero image */
|
| 59 |
-
header {
|
| 60 |
-
max-width: 1440px;
|
| 61 |
-
margin: 0 auto;
|
| 62 |
-
padding: 32px 24px 8px 24px;
|
| 63 |
-
text-align: center;
|
| 64 |
-
}
|
| 65 |
-
.hero-img {
|
| 66 |
-
display: block;
|
| 67 |
-
max-width: 900px;
|
| 68 |
-
width: 100%;
|
| 69 |
-
height: auto;
|
| 70 |
-
margin: 0 auto;
|
| 71 |
-
border-radius: 14px;
|
| 72 |
-
}
|
| 73 |
-
|
| 74 |
-
/* Hero stats banner */
|
| 75 |
-
.hero-stats {
|
| 76 |
-
max-width: 1440px;
|
| 77 |
-
margin: 24px auto 0 auto;
|
| 78 |
-
padding: 0 24px;
|
| 79 |
-
display: grid;
|
| 80 |
-
grid-template-columns: repeat(5, 1fr);
|
| 81 |
-
gap: 14px;
|
| 82 |
-
}
|
| 83 |
-
.stat {
|
| 84 |
-
background: var(--card);
|
| 85 |
-
border: 1px solid var(--border);
|
| 86 |
-
border-radius: 16px;
|
| 87 |
-
padding: 18px 14px;
|
| 88 |
-
text-align: center;
|
| 89 |
-
}
|
| 90 |
-
.stat .num {
|
| 91 |
-
display: block;
|
| 92 |
-
font-size: 1.75rem;
|
| 93 |
-
font-weight: 700;
|
| 94 |
-
color: var(--fg);
|
| 95 |
-
letter-spacing: -0.015em;
|
| 96 |
-
line-height: 1.05;
|
| 97 |
-
}
|
| 98 |
-
.stat .num .decimal { font-size: 0.55em; font-weight: 500; opacity: 0.75; margin-left: 1px; }
|
| 99 |
-
.stat .lbl {
|
| 100 |
-
display: block;
|
| 101 |
-
font-size: 0.68rem;
|
| 102 |
-
color: var(--muted);
|
| 103 |
-
text-transform: uppercase;
|
| 104 |
-
letter-spacing: 0.13em;
|
| 105 |
-
margin-top: 8px;
|
| 106 |
-
font-weight: 500;
|
| 107 |
-
}
|
| 108 |
-
.stat .sub {
|
| 109 |
-
display: block;
|
| 110 |
-
font-size: 0.6rem;
|
| 111 |
-
color: var(--muted);
|
| 112 |
-
font-weight: 400;
|
| 113 |
-
letter-spacing: 0.04em;
|
| 114 |
-
margin-top: 4px;
|
| 115 |
-
opacity: 0.65;
|
| 116 |
-
text-transform: none;
|
| 117 |
-
}
|
| 118 |
-
|
| 119 |
-
/* Chart sections */
|
| 120 |
-
.charts {
|
| 121 |
-
max-width: 1440px;
|
| 122 |
-
margin: 0 auto;
|
| 123 |
-
display: grid;
|
| 124 |
-
grid-template-columns: 1fr 1fr;
|
| 125 |
-
gap: 24px;
|
| 126 |
-
padding: 24px;
|
| 127 |
-
}
|
| 128 |
-
.chart-card {
|
| 129 |
-
background: var(--card);
|
| 130 |
-
border: 1px solid var(--border);
|
| 131 |
-
border-radius: 20px;
|
| 132 |
-
padding: 24px 20px 16px 20px;
|
| 133 |
-
}
|
| 134 |
-
.chart-card h2 {
|
| 135 |
-
text-align: center;
|
| 136 |
-
margin: 0 0 4px 0;
|
| 137 |
-
font-size: 1.1rem;
|
| 138 |
-
font-weight: 600;
|
| 139 |
-
color: var(--fg);
|
| 140 |
-
letter-spacing: -0.005em;
|
| 141 |
-
}
|
| 142 |
-
.chart-card .subtitle {
|
| 143 |
-
text-align: center;
|
| 144 |
-
margin: 0 0 14px 0;
|
| 145 |
-
font-size: 0.82rem;
|
| 146 |
-
color: var(--muted);
|
| 147 |
-
font-weight: 400;
|
| 148 |
-
}
|
| 149 |
-
|
| 150 |
-
/* Donut */
|
| 151 |
-
.donut-wrap {
|
| 152 |
-
position: relative;
|
| 153 |
-
width: 100%;
|
| 154 |
-
max-width: 560px;
|
| 155 |
-
aspect-ratio: 1;
|
| 156 |
-
margin: 0 auto;
|
| 157 |
-
}
|
| 158 |
-
.donut-wrap.small { max-width: 400px; }
|
| 159 |
-
.donut-svg {
|
| 160 |
-
width: 100%;
|
| 161 |
-
height: 100%;
|
| 162 |
-
display: block;
|
| 163 |
-
overflow: visible;
|
| 164 |
-
}
|
| 165 |
-
.donut-slice { cursor: pointer; transition: filter 0.2s ease; }
|
| 166 |
-
.donut-slice:hover { filter: brightness(1.25) drop-shadow(0 0 10px rgba(255,255,255,0.15)); }
|
| 167 |
-
|
| 168 |
-
.donut-center {
|
| 169 |
-
position: absolute;
|
| 170 |
-
inset: 0;
|
| 171 |
-
display: flex;
|
| 172 |
-
flex-direction: column;
|
| 173 |
-
align-items: center;
|
| 174 |
-
justify-content: center;
|
| 175 |
-
pointer-events: none;
|
| 176 |
-
padding: 18%;
|
| 177 |
-
text-align: center;
|
| 178 |
-
}
|
| 179 |
-
.donut-center.small { padding: 22%; }
|
| 180 |
-
.center-item { width: 100%; }
|
| 181 |
-
.center-label {
|
| 182 |
-
font-size: 0.65rem;
|
| 183 |
-
font-weight: 500;
|
| 184 |
-
color: var(--muted);
|
| 185 |
-
letter-spacing: 0.18em;
|
| 186 |
-
text-transform: uppercase;
|
| 187 |
-
display: flex;
|
| 188 |
-
align-items: center;
|
| 189 |
-
justify-content: center;
|
| 190 |
-
gap: 6px;
|
| 191 |
-
}
|
| 192 |
-
.center-label .icon { font-size: 0.85rem; opacity: 0.9; }
|
| 193 |
-
.center-number {
|
| 194 |
-
font-size: clamp(1.8rem, 4.5vw, 2.75rem);
|
| 195 |
-
font-weight: 700;
|
| 196 |
-
color: var(--fg);
|
| 197 |
-
line-height: 1;
|
| 198 |
-
letter-spacing: -0.03em;
|
| 199 |
-
margin: 4px 0;
|
| 200 |
-
}
|
| 201 |
-
.center-number .decimal {
|
| 202 |
-
font-size: 0.55em;
|
| 203 |
-
font-weight: 500;
|
| 204 |
-
color: var(--fg);
|
| 205 |
-
opacity: 0.72;
|
| 206 |
-
margin-left: 1px;
|
| 207 |
-
}
|
| 208 |
-
.center-divider {
|
| 209 |
-
width: 42%;
|
| 210 |
-
border: none;
|
| 211 |
-
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
| 212 |
-
margin: 10px auto;
|
| 213 |
-
}
|
| 214 |
-
|
| 215 |
-
/* Details card */
|
| 216 |
-
.details {
|
| 217 |
-
max-width: 1440px;
|
| 218 |
-
margin: 0 auto 32px auto;
|
| 219 |
-
padding: 0 24px;
|
| 220 |
-
}
|
| 221 |
-
.details-card {
|
| 222 |
-
background: var(--card);
|
| 223 |
-
border: 1px solid var(--border);
|
| 224 |
-
border-radius: 20px;
|
| 225 |
-
padding: 26px 28px;
|
| 226 |
-
min-height: 140px;
|
| 227 |
-
}
|
| 228 |
-
.details-card h3 {
|
| 229 |
-
margin: 0 0 8px 0;
|
| 230 |
-
font-size: 1.35rem;
|
| 231 |
-
color: var(--fg);
|
| 232 |
-
display: flex;
|
| 233 |
-
align-items: center;
|
| 234 |
-
gap: 12px;
|
| 235 |
-
font-weight: 600;
|
| 236 |
-
letter-spacing: -0.01em;
|
| 237 |
-
}
|
| 238 |
-
.details-card h3 .swatch { display: inline-block; width: 14px; height: 14px; border-radius: 50%; }
|
| 239 |
-
.details-card h3 a { color: var(--fg); font-size: 1.05rem; opacity: 0.85; }
|
| 240 |
-
.details-card h3 a:hover { opacity: 1; text-decoration: underline; }
|
| 241 |
-
.details-card .tagline { color: var(--muted); font-size: 0.95rem; margin: 0 0 18px 0; }
|
| 242 |
-
.kv-grid {
|
| 243 |
-
display: grid;
|
| 244 |
-
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
| 245 |
-
gap: 12px 24px;
|
| 246 |
-
}
|
| 247 |
-
.kv .k { color: var(--muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 4px; font-weight: 500; }
|
| 248 |
-
.kv .v { color: var(--fg); font-size: 0.9rem; }
|
| 249 |
-
.kv .v a { border-bottom: 1px dashed var(--muted); }
|
| 250 |
-
.kv .v strong { font-weight: 600; }
|
| 251 |
-
.schema-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
|
| 252 |
-
.schema-list code {
|
| 253 |
-
background: var(--card-alt);
|
| 254 |
-
color: var(--fg);
|
| 255 |
-
padding: 3px 8px;
|
| 256 |
-
border-radius: 6px;
|
| 257 |
-
font-size: 0.78rem;
|
| 258 |
-
font-family: "SF Mono", Consolas, monospace;
|
| 259 |
-
border: 1px solid var(--border);
|
| 260 |
-
}
|
| 261 |
-
|
| 262 |
-
/* Extras (modality + treemap) */
|
| 263 |
-
.extras {
|
| 264 |
-
max-width: 1440px;
|
| 265 |
-
margin: 8px auto 0 auto;
|
| 266 |
-
padding: 0 24px 24px 24px;
|
| 267 |
-
display: grid;
|
| 268 |
-
grid-template-columns: 1fr 2fr;
|
| 269 |
-
gap: 24px;
|
| 270 |
-
}
|
| 271 |
-
.plot-treemap { width: 100%; height: 900px; position: relative; }
|
| 272 |
-
.plot-treemap svg { width: 100%; height: 100%; display: block; }
|
| 273 |
-
|
| 274 |
-
/* Voronoi */
|
| 275 |
-
.voronoi-cell {
|
| 276 |
-
cursor: pointer;
|
| 277 |
-
transition: filter 0.18s ease, opacity 0.18s ease;
|
| 278 |
-
}
|
| 279 |
-
.voronoi-cell:hover { filter: brightness(1.35) drop-shadow(0 0 8px rgba(255,255,255,0.35)); }
|
| 280 |
-
.voronoi-label {
|
| 281 |
-
font-family: "Geist", "Google Sans", sans-serif;
|
| 282 |
-
font-weight: 600;
|
| 283 |
-
fill: #ffffff;
|
| 284 |
-
pointer-events: none;
|
| 285 |
-
text-anchor: middle;
|
| 286 |
-
user-select: none;
|
| 287 |
-
}
|
| 288 |
-
.voronoi-label .code { font-weight: 400; opacity: 0.8; fill: #ffffff; }
|
| 289 |
-
.voronoi-tooltip {
|
| 290 |
-
position: absolute;
|
| 291 |
-
pointer-events: none;
|
| 292 |
-
background: var(--tooltip-bg);
|
| 293 |
-
border: 1px solid var(--border);
|
| 294 |
-
border-radius: 10px;
|
| 295 |
-
padding: 10px 14px;
|
| 296 |
-
font-size: 0.85rem;
|
| 297 |
-
color: var(--fg);
|
| 298 |
-
box-shadow: 0 12px 32px rgba(0,0,0,0.7);
|
| 299 |
-
opacity: 0;
|
| 300 |
-
transition: opacity 0.12s ease;
|
| 301 |
-
white-space: nowrap;
|
| 302 |
-
z-index: 20;
|
| 303 |
-
font-family: "Geist", sans-serif;
|
| 304 |
-
}
|
| 305 |
-
.voronoi-tooltip .t-name { font-weight: 700; color: var(--fg); font-size: 0.95rem; }
|
| 306 |
-
.voronoi-tooltip .t-code { color: var(--muted); font-size: 0.72rem; margin-left: 4px; }
|
| 307 |
-
.voronoi-tooltip .t-rows { color: var(--fg); font-weight: 600; margin-top: 4px; opacity: 0.9; }
|
| 308 |
-
|
| 309 |
-
/* Donut tooltip (shared style) */
|
| 310 |
-
.donut-tooltip {
|
| 311 |
-
position: fixed;
|
| 312 |
-
pointer-events: none;
|
| 313 |
-
background: var(--tooltip-bg);
|
| 314 |
-
border: 1px solid var(--border);
|
| 315 |
-
border-radius: 10px;
|
| 316 |
-
padding: 10px 14px;
|
| 317 |
-
font-size: 0.85rem;
|
| 318 |
-
color: var(--fg);
|
| 319 |
-
box-shadow: 0 12px 32px rgba(0,0,0,0.7);
|
| 320 |
-
opacity: 0;
|
| 321 |
-
transition: opacity 0.12s ease;
|
| 322 |
-
white-space: nowrap;
|
| 323 |
-
z-index: 50;
|
| 324 |
-
font-family: "Geist", sans-serif;
|
| 325 |
-
}
|
| 326 |
-
.donut-tooltip .t-name { font-weight: 700; font-size: 0.95rem; }
|
| 327 |
-
.donut-tooltip .t-meta { color: var(--muted); font-size: 0.78rem; margin-top: 4px; }
|
| 328 |
-
|
| 329 |
-
footer {
|
| 330 |
-
max-width: 1440px;
|
| 331 |
-
margin: 0 auto 32px auto;
|
| 332 |
-
padding: 0 24px;
|
| 333 |
-
text-align: center;
|
| 334 |
-
color: var(--muted);
|
| 335 |
-
font-size: 0.8rem;
|
| 336 |
-
font-weight: 400;
|
| 337 |
-
}
|
| 338 |
-
footer a { border-bottom: 1px dashed var(--muted); }
|
| 339 |
-
|
| 340 |
-
@media (max-width: 900px) {
|
| 341 |
-
.hero-stats { grid-template-columns: repeat(2, 1fr); }
|
| 342 |
-
.extras { grid-template-columns: 1fr; }
|
| 343 |
-
}
|
| 344 |
-
@media (max-width: 780px) {
|
| 345 |
-
.charts { grid-template-columns: 1fr; }
|
| 346 |
-
}
|
| 347 |
-
</style>
|
| 348 |
-
</head>
|
| 349 |
-
<body>
|
| 350 |
-
|
| 351 |
-
<header>
|
| 352 |
-
<img src="Reubensdataset.png" alt="Reuben's Data Lab" class="hero-img" />
|
| 353 |
-
</header>
|
| 354 |
-
|
| 355 |
-
<section class="hero-stats">
|
| 356 |
-
<div class="stat">
|
| 357 |
-
<span class="num" data-value="12"></span>
|
| 358 |
-
<span class="lbl">Raw datasets</span>
|
| 359 |
-
<span class="sub">in four HF collections</span>
|
| 360 |
-
</div>
|
| 361 |
-
<div class="stat">
|
| 362 |
-
<span class="num" data-value="14.8M"></span>
|
| 363 |
-
<span class="lbl">Total rows</span>
|
| 364 |
-
<span class="sub">every row, every dataset</span>
|
| 365 |
-
</div>
|
| 366 |
-
<div class="stat">
|
| 367 |
-
<span class="num" data-value="130+"></span>
|
| 368 |
-
<span class="lbl">Languages</span>
|
| 369 |
-
<span class="sub">many rarely seen online</span>
|
| 370 |
-
</div>
|
| 371 |
-
<div class="stat">
|
| 372 |
-
<span class="num" data-value="4"></span>
|
| 373 |
-
<span class="lbl">Modalities</span>
|
| 374 |
-
<span class="sub">audio, text, images, code</span>
|
| 375 |
-
</div>
|
| 376 |
-
<div class="stat">
|
| 377 |
-
<span class="num" data-value="17"></span>
|
| 378 |
-
<span class="lbl">Days to build</span>
|
| 379 |
-
<span class="sub">April 8 to April 24, 2026</span>
|
| 380 |
-
</div>
|
| 381 |
-
</section>
|
| 382 |
-
|
| 383 |
-
<section class="charts">
|
| 384 |
-
<div class="chart-card">
|
| 385 |
-
<h2>Raw corpus</h2>
|
| 386 |
-
<div class="subtitle">Every dataset I've created in the <a href="https://huggingface.co/ReubenDataLab/collections" target="_blank" rel="noopener">ReubenDataLab collections</a></div>
|
| 387 |
-
<div class="donut-wrap">
|
| 388 |
-
<svg id="chart-raw" class="donut-svg"></svg>
|
| 389 |
-
<div class="donut-center" id="center-raw"></div>
|
| 390 |
-
</div>
|
| 391 |
-
</div>
|
| 392 |
-
<div class="chart-card">
|
| 393 |
-
<h2>Adaption-remastered</h2>
|
| 394 |
-
<div class="subtitle">Improved datasets after running them through <a href="https://adaptionlabs.ai" target="_blank" rel="noopener">adaptionlabs.ai</a></div>
|
| 395 |
-
<div class="donut-wrap">
|
| 396 |
-
<svg id="chart-adaption" class="donut-svg"></svg>
|
| 397 |
-
<div class="donut-center" id="center-adaption"></div>
|
| 398 |
-
</div>
|
| 399 |
-
</div>
|
| 400 |
-
</section>
|
| 401 |
-
|
| 402 |
-
<div class="details">
|
| 403 |
-
<div id="details-card" class="details-card" style="display: none;"></div>
|
| 404 |
-
</div>
|
| 405 |
-
|
| 406 |
-
<section class="extras">
|
| 407 |
-
<div class="chart-card">
|
| 408 |
-
<h2>Modality split</h2>
|
| 409 |
-
<div class="subtitle">Share of the corpus by data type</div>
|
| 410 |
-
<div class="donut-wrap small">
|
| 411 |
-
<svg id="chart-modality" class="donut-svg"></svg>
|
| 412 |
-
<div class="donut-center small" id="center-modality"></div>
|
| 413 |
-
</div>
|
| 414 |
-
</div>
|
| 415 |
-
<div class="chart-card">
|
| 416 |
-
<h2>Languages across the corpus</h2>
|
| 417 |
-
<div class="subtitle">Every language that appears in any raw dataset, sized (log-scale) by total row count. Hover for exact numbers.</div>
|
| 418 |
-
<div id="chart-treemap" class="plot-treemap">
|
| 419 |
-
<div id="voronoi-tooltip" class="voronoi-tooltip"></div>
|
| 420 |
-
</div>
|
| 421 |
-
</div>
|
| 422 |
-
</section>
|
| 423 |
-
|
| 424 |
-
<div id="donut-tooltip" class="donut-tooltip"></div>
|
| 425 |
-
|
| 426 |
-
<footer>
|
| 427 |
-
Data self-reported from HF dataset pages · Built for the
|
| 428 |
-
<a href="https://www.adaptionlabs.ai/blog/the-uncharted-data-challenge" target="_blank">Uncharted Data Challenge</a>
|
| 429 |
-
· Author <a href="https://huggingface.co/Reubencf" target="_blank">@Reubencf</a>
|
| 430 |
-
</footer>
|
| 431 |
-
|
| 432 |
-
<script>
|
| 433 |
-
|
| 434 |
-
/
|
| 435 |
-
/
|
| 436 |
-
const CSS = getComputedStyle(document.documentElement);
|
| 437 |
-
const PALETTE = [
|
| 438 |
-
CSS.getPropertyValue('--palette-1').trim(),
|
| 439 |
-
CSS.getPropertyValue('--palette-2').trim(),
|
| 440 |
-
CSS.getPropertyValue('--palette-3').trim(),
|
| 441 |
-
CSS.getPropertyValue('--palette-4').trim(),
|
| 442 |
-
CSS.getPropertyValue('--palette-5').trim(),
|
| 443 |
-
CSS.getPropertyValue('--palette-6').trim(),
|
| 444 |
-
CSS.getPropertyValue('--palette-7').trim(),
|
| 445 |
-
CSS.getPropertyValue('--palette-8').trim(),
|
| 446 |
-
CSS.getPropertyValue('--palette-9').trim(),
|
| 447 |
-
CSS.getPropertyValue('--palette-10').trim(),
|
| 448 |
-
CSS.getPropertyValue('--palette-11').trim(),
|
| 449 |
-
CSS.getPropertyValue('--palette-12').trim(),
|
| 450 |
-
];
|
| 451 |
-
|
| 452 |
-
/** Brighten an HSL-mapped color for the inner tick mark (and voronoi hovers). */
|
| 453 |
-
function luminousVariant(hex, lightnessBoost = 0.4, saturationBoost = 0.12) {
|
| 454 |
-
const c = d3.hsl(hex);
|
| 455 |
-
c.l = Math.min(0.9, c.l + lightnessBoost);
|
| 456 |
-
c.s = Math.min(1, c.s + saturationBoost);
|
| 457 |
-
return c.formatHex();
|
| 458 |
-
}
|
| 459 |
-
|
| 460 |
-
/** Format a number as an integer + <span class="decimal">.Mk</span>. */
|
| 461 |
-
function formatRows(n) {
|
| 462 |
-
if (n >= 1_000_000) {
|
| 463 |
-
const v = n / 1_000_000;
|
| 464 |
-
const [whole, frac] = v.toFixed(1).split('.');
|
| 465 |
-
return `${whole}<span class="decimal">.${frac}M</span>`;
|
| 466 |
-
}
|
| 467 |
-
if (n >= 1_000) {
|
| 468 |
-
const v = n / 1_000;
|
| 469 |
-
const [whole, frac] = v.toFixed(1).split('.');
|
| 470 |
-
return `${whole}<span class="decimal">.${frac}k</span>`;
|
| 471 |
-
}
|
| 472 |
-
return String(n);
|
| 473 |
-
}
|
| 474 |
-
function formatShort(n) {
|
| 475 |
-
if (n >= 1_000_000) return (n / 1_000_000).toFixed(1).replace(/\.0$/, '') + 'M';
|
| 476 |
-
if (n >= 1_000) return (n / 1_000).toFixed(1).replace(/\.0$/, '') + 'k';
|
| 477 |
-
return String(n);
|
| 478 |
-
}
|
| 479 |
-
|
| 480 |
-
// Upgrade hero stat numbers to support a decimal span
|
| 481 |
-
document.querySelectorAll('.stat .num').forEach(el => {
|
| 482 |
-
const raw = el.getAttribute('data-value');
|
| 483 |
-
const m = raw && raw.match(/^([~≈]?[\d,]+)(\.[\d]+)?([A-Za-z+]+)?$/);
|
| 484 |
-
if (!m) { el.textContent = raw || ''; return; }
|
| 485 |
-
const [, whole, frac = '', suffix = ''] = m;
|
| 486 |
-
el.innerHTML = frac || suffix
|
| 487 |
-
? `${whole}<span class="decimal">${frac}${suffix}</span>`
|
| 488 |
-
: whole;
|
| 489 |
-
});
|
| 490 |
-
|
| 491 |
-
// ===========================================================================
|
| 492 |
-
// DATASET CATALOG
|
| 493 |
-
// ===========================================================================
|
| 494 |
-
const DATASETS = [
|
| 495 |
-
{
|
| 496 |
-
key: "speech",
|
| 497 |
-
title: "Multilingual Synthetic Speech",
|
| 498 |
-
tagline: "Zero-shot voice cloning with Qwen3-TTS across 9 languages",
|
| 499 |
-
raw: { repo: "Reubencf/multilingual-synthetic-tts", rows: 68677 },
|
| 500 |
-
adaption: { repo: "Reubencf/Adaption-multilingual-speech", rows: 10274 },
|
| 501 |
-
languages: "en, ja, zh, ko, de, es, fr, ru, pt",
|
| 502 |
-
modality: "audio + text",
|
| 503 |
-
license: "open / synthetic",
|
| 504 |
-
schema: ["audio", "text", "language", "language_name", "style", "voice", "sample_rate"],
|
| 505 |
-
model: "Qwen3-TTS-12Hz-1.7B-Base",
|
| 506 |
-
group: "paired"
|
| 507 |
-
},
|
| 508 |
-
{
|
| 509 |
-
key: "sentences",
|
| 510 |
-
title: "Multilingual Sentences (text-only)",
|
| 511 |
-
tagline: "Text projection of the TTS corpus — ready for Adaption",
|
| 512 |
-
raw: null,
|
| 513 |
-
adaption: { repo: "Reubencf/Adaption-multilingual-sentences", rows: 10000 },
|
| 514 |
-
languages: "ja, ru, ko, de, es, pt, zh, en, fr + 114 more",
|
| 515 |
-
modality: "text",
|
| 516 |
-
license: "open",
|
| 517 |
-
schema: ["text", "enhanced_prompt", "enhanced_completion", "language", "voice", "style"],
|
| 518 |
-
group: "paired"
|
| 519 |
-
},
|
| 520 |
-
{
|
| 521 |
-
key: "music",
|
| 522 |
-
title: "Music — FMA Labeled",
|
| 523 |
-
tagline: "Creative-Commons music tracks with lyrics, genre, mood, BPM, key",
|
| 524 |
-
raw: { repo: "Reubencf/fma-labeled", rows: 29000 },
|
| 525 |
-
adaption: { repo: "Reubencf/adaption-music-style-prompts", rows: 9950 },
|
| 526 |
-
languages: "en",
|
| 527 |
-
modality: "audio + text",
|
| 528 |
-
license: "CC-BY / CC0 (source-dependent)",
|
| 529 |
-
schema: ["audio", "lyrics", "genre", "sub_genres", "mood", "instruments", "bpm", "key", "vocal_type", "energy", "era", "quality"],
|
| 530 |
-
model: "gemini-flash-latest",
|
| 531 |
-
group: "paired"
|
| 532 |
-
},
|
| 533 |
-
{
|
| 534 |
-
key: "street",
|
| 535 |
-
title: "StreetView Global",
|
| 536 |
-
tagline: "Globally-sampled Mapillary street images with scene classification",
|
| 537 |
-
raw: { repo: "Reubencf/streetview-global", rows: 30000 },
|
| 538 |
-
adaption: { repo: "Reubencf/adaption-street-scene-descriptions", rows: 10100 },
|
| 539 |
-
languages: "en",
|
| 540 |
-
modality: "image + text",
|
| 541 |
-
license: "CC-BY-SA-4.0",
|
| 542 |
-
schema: ["image", "scene_description", "setting", "weather", "time_of_day", "road_type", "infrastructure", "lat", "lon", "compass"],
|
| 543 |
-
group: "paired"
|
| 544 |
-
},
|
| 545 |
-
{
|
| 546 |
-
key: "magazines",
|
| 547 |
-
title: "Magazines Multilingual VQA",
|
| 548 |
-
tagline: "Public-domain magazine OCR in 40+ source languages (including low-resource)",
|
| 549 |
-
raw: { repo: "Reubencf/magazines-multilingual-vqa", rows: 29039 },
|
| 550 |
-
adaption: { repo: "Reubencf/adaption-multilingual-doc-qa", rows: 8800 },
|
| 551 |
-
languages: "ar, de, en, es, fr, hi, it, ja, pt, zh + 35 more (Afrikaans, Amharic, Yoruba, Yiddish, Bengali, Santali, Somali, Vietnamese, Russian, Maithili, Tibetan, …)",
|
| 552 |
-
modality: "image + text",
|
| 553 |
-
license: "CC-BY-4.0",
|
| 554 |
-
schema: ["image", "ocr_text", "english_description", "question", "answer", "target_language", "page_type"],
|
| 555 |
-
model: "Gemma 4 31B via vLLM",
|
| 556 |
-
group: "paired"
|
| 557 |
-
},
|
| 558 |
-
{
|
| 559 |
-
key: "lowresource",
|
| 560 |
-
title: "Low-Resource Doc Q/A",
|
| 561 |
-
tagline: "Low-resource-language slice of the magazines corpus",
|
| 562 |
-
raw: null,
|
| 563 |
-
adaption: { repo: "Reubencf/Adaption-low-resource-doc-qa", rows: 10200 },
|
| 564 |
-
languages: "Afrikaans, Amharic, Yoruba, Yiddish, Bengali, Santali, Somali, Vietnamese, Maithili, Tigrinya, Meitei, Lao, …",
|
| 565 |
-
modality: "image + text",
|
| 566 |
-
license: "CC-BY-4.0",
|
| 567 |
-
schema: ["image", "ocr_text", "question", "answer", "source_language"],
|
| 568 |
-
group: "paired"
|
| 569 |
-
},
|
| 570 |
-
{
|
| 571 |
-
key: "captions",
|
| 572 |
-
title: "Multilingual Image Captions",
|
| 573 |
-
tagline: "English + multilingual captions with bounding-box visualizations",
|
| 574 |
-
raw: { repo: "Reubencf/multilingual-image-annotations", rows: 464 },
|
| 575 |
-
adaption: { repo: "Reubencf/adaption-multilingual-image-captions", rows: 462 },
|
| 576 |
-
languages: "en, es, fr, hi, zh, ar, pt",
|
| 577 |
-
modality: "image + text",
|
| 578 |
-
license: "CC-BY-4.0",
|
| 579 |
-
schema: ["image", "boxed_image", "description_en", "descriptions", "vqa", "detections"],
|
| 580 |
-
model: "Gemma 4 31B",
|
| 581 |
-
group: "paired"
|
| 582 |
-
},
|
| 583 |
-
{
|
| 584 |
-
key: "frontend",
|
| 585 |
-
title: "Frontend Coding",
|
| 586 |
-
tagline: "Hand-curated HTML / Tailwind / JS prompts and completions",
|
| 587 |
-
raw: { repo: "Reubencf/frontend-coding", rows: 500 },
|
| 588 |
-
adaption: { repo: "Reubencf/frontend-html-tailwind-js", rows: 145 },
|
| 589 |
-
languages: "en",
|
| 590 |
-
modality: "text (code)",
|
| 591 |
-
license: "MIT",
|
| 592 |
-
schema: ["prompt", "previous_code", "code", "reasoning"],
|
| 593 |
-
group: "paired"
|
| 594 |
-
},
|
| 595 |
-
{
|
| 596 |
-
key: "news2026",
|
| 597 |
-
title: "Current Affairs 2026",
|
| 598 |
-
tagline: "2026 Wikipedia current-events Q/A with RAG grounding (through Apr 9, 2026)",
|
| 599 |
-
raw: { repo: "Reubencf/future-news-events-2026", rows: 5447 },
|
| 600 |
-
adaption: { repo: "Reubencf/current-affairs-2026", rows: 5339 },
|
| 601 |
-
languages: "en",
|
| 602 |
-
modality: "text",
|
| 603 |
-
license: "open",
|
| 604 |
-
schema: ["question", "answer", "enhanced_prompt", "enhanced_completion", "reasoning_trace", "date", "event_id", "section", "source"],
|
| 605 |
-
model: "Cohere Command R + RAG",
|
| 606 |
-
group: "paired"
|
| 607 |
-
},
|
| 608 |
-
{
|
| 609 |
-
key: "news2025",
|
| 610 |
-
title: "Current Affairs 2025",
|
| 611 |
-
tagline: "2025 global events Q/A",
|
| 612 |
-
raw: { repo: "Reubencf/2025_events", rows: 5390 },
|
| 613 |
-
adaption: { repo: "Reubencf/current-affairs-2025", rows: 5390 },
|
| 614 |
-
languages: "en",
|
| 615 |
-
modality: "text",
|
| 616 |
-
license: "open",
|
| 617 |
-
schema: ["question", "answer", "enhanced_prompt", "enhanced_completion"],
|
| 618 |
-
group: "paired"
|
| 619 |
-
},
|
| 620 |
-
{
|
| 621 |
-
key: "news2024",
|
| 622 |
-
title: "Current Affairs 2024",
|
| 623 |
-
tagline: "2024 global events Q/A",
|
| 624 |
-
raw: { repo: "Reubencf/2024_events", rows: 5190 },
|
| 625 |
-
adaption: { repo: "Reubencf/current-affairs-2024", rows: 5190 },
|
| 626 |
-
languages: "en",
|
| 627 |
-
modality: "text",
|
| 628 |
-
license: "open",
|
| 629 |
-
schema: ["question", "answer", "enhanced_prompt", "enhanced_completion"],
|
| 630 |
-
group: "paired"
|
| 631 |
-
},
|
| 632 |
-
{
|
| 633 |
-
key: "news2023",
|
| 634 |
-
title: "Current Affairs 2023",
|
| 635 |
-
tagline: "2023 global events Q/A",
|
| 636 |
-
raw: { repo: "Reubencf/2023_events", rows: 4667 },
|
| 637 |
-
adaption: { repo: "Reubencf/current-affairs-2023", rows: 4667 },
|
| 638 |
-
languages: "en",
|
| 639 |
-
modality: "text",
|
| 640 |
-
license: "open",
|
| 641 |
-
schema: ["question", "answer", "enhanced_prompt", "enhanced_completion"],
|
| 642 |
-
group: "paired"
|
| 643 |
-
},
|
| 644 |
-
// Pre-training pools — now included in the raw donut too.
|
| 645 |
-
{
|
| 646 |
-
key: "polyaudio",
|
| 647 |
-
title: "PolyglotAudio",
|
| 648 |
-
tagline: "Broad multilingual audio pre-training pool",
|
| 649 |
-
raw: { repo: "Reubencf/PolyglotAudio", rows: 1200000 },
|
| 650 |
-
adaption: null,
|
| 651 |
-
languages: "multilingual",
|
| 652 |
-
modality: "audio + text",
|
| 653 |
-
license: "open",
|
| 654 |
-
schema: ["audio", "text", "language"],
|
| 655 |
-
group: "paired"
|
| 656 |
-
},
|
| 657 |
-
{
|
| 658 |
-
key: "polytext",
|
| 659 |
-
title: "PolyglotText",
|
| 660 |
-
tagline: "Large multilingual text pre-training pool",
|
| 661 |
-
raw: { repo: "Reubencf/PolyglotText", rows: 13400000 },
|
| 662 |
-
adaption: null,
|
| 663 |
-
languages: "multilingual",
|
| 664 |
-
modality: "text",
|
| 665 |
-
license: "open",
|
| 666 |
-
schema: ["text", "language"],
|
| 667 |
-
group: "paired"
|
| 668 |
-
},
|
| 669 |
-
];
|
| 670 |
-
|
| 671 |
-
// Stable color per dataset key — cycles through PALETTE
|
| 672 |
-
const datasetColor = d3.scaleOrdinal(PALETTE).domain(DATASETS.map(d => d.key));
|
| 673 |
-
DATASETS.forEach(d => { d.color = datasetColor(d.key); });
|
| 674 |
-
|
| 675 |
-
// ===========================================================================
|
| 676 |
-
// DONUT CHART (D3 — used for both Raw/Adaption donuts and the modality donut)
|
| 677 |
-
// ===========================================================================
|
| 678 |
-
const tooltipEl = document.getElementById('donut-tooltip');
|
| 679 |
-
|
| 680 |
-
// Per-SVG selection state for drill-down (scale-up selected, dim others).
|
| 681 |
-
const donutState = new Map(); // svgId -> { selectedKey, paths, arcGen }
|
| 682 |
-
|
| 683 |
-
function renderDonut({ svgId, centerId, field, datasets, getValue, getKey, getTitle, getColor, getMeta, colorScale, topLabel, bottomLabel, topIcon, bottomIcon, sizing = 'linear' }) {
|
| 684 |
-
const svg = d3.select('#' + svgId);
|
| 685 |
-
svg.selectAll('*').remove();
|
| 686 |
-
|
| 687 |
-
const bbox = svg.node().getBoundingClientRect();
|
| 688 |
-
const size = Math.min(bbox.width, bbox.height);
|
| 689 |
-
const outerR = size / 2 - 6;
|
| 690 |
-
const innerR = outerR * 0.62;
|
| 691 |
-
svg.attr('viewBox', `${-size / 2} ${-size / 2} ${size} ${size}`);
|
| 692 |
-
|
| 693 |
-
const filtered = datasets.filter(d => getValue(d) > 0);
|
| 694 |
-
const total = d3.sum(filtered, getValue);
|
| 695 |
-
const count = filtered.length;
|
| 696 |
-
|
| 697 |
-
// Sizing strategy for the arc:
|
| 698 |
-
// "linear" — true proportions (small slices can vanish)
|
| 699 |
-
// "log" — power-compressed so tiny datasets stay visible while the
|
| 700 |
-
// big ones (PolyglotText 13M+, PolyglotAudio 1M+) still read
|
| 701 |
-
// as clearly the largest slices
|
| 702 |
-
// "sqrt" — lighter square-root compression
|
| 703 |
-
// Tooltip + center numbers always show real values.
|
| 704 |
-
const sizeValue = d => {
|
| 705 |
-
const v = getValue(d);
|
| 706 |
-
if (sizing === 'log') return Math.pow(v + 1, 0.38);
|
| 707 |
-
if (sizing === 'sqrt') return Math.sqrt(v + 1);
|
| 708 |
-
return v;
|
| 709 |
-
};
|
| 710 |
-
|
| 711 |
-
const pie = d3.pie().value(sizeValue).sort(null).padAngle(0.022);
|
| 712 |
-
const arcs = pie(filtered);
|
| 713 |
-
const arcGen = d3.arc().innerRadius(innerR).outerRadius(outerR).cornerRadius(3);
|
| 714 |
-
const resolveColor = getColor || (x => datasetColor(getKey(x)));
|
| 715 |
-
|
| 716 |
-
const g = svg.append('g');
|
| 717 |
-
|
| 718 |
-
// Slice paths
|
| 719 |
-
const paths = g.selectAll('path')
|
| 720 |
-
.data(arcs)
|
| 721 |
-
.join('path')
|
| 722 |
-
.attr('class', 'donut-slice')
|
| 723 |
-
.attr('fill', d => resolveColor(d.data))
|
| 724 |
-
.attr('stroke', '#000000')
|
| 725 |
-
.attr('stroke-width', 2)
|
| 726 |
-
.attr('stroke-linejoin', 'round');
|
| 727 |
-
|
| 728 |
-
// Radial sweep: interpolate endAngle from startAngle → target, so arcs
|
| 729 |
-
// literally grow around the ring from 0° of arc to their full sweep.
|
| 730 |
-
paths.each(function (d) {
|
| 731 |
-
const [cx, cy] = arcGen.centroid(d);
|
| 732 |
-
this._centroid = [cx, cy];
|
| 733 |
-
this._current = { startAngle: d.startAngle, endAngle: d.startAngle, padAngle: d.padAngle };
|
| 734 |
-
});
|
| 735 |
-
paths.transition()
|
| 736 |
-
.delay((d, i) => i * 80)
|
| 737 |
-
.duration(1100)
|
| 738 |
-
.ease(d3.easeCubicOut)
|
| 739 |
-
.attrTween('d', function (d) {
|
| 740 |
-
const interp = d3.interpolate(this._current, d);
|
| 741 |
-
this._current = interp(1);
|
| 742 |
-
return t => arcGen(interp(t));
|
| 743 |
-
});
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
// Hover tooltip + click drill-down
|
| 748 |
-
paths
|
| 749 |
-
.on('mouseenter', function (ev, d) {
|
| 750 |
-
const nm = getTitle(d.data);
|
| 751 |
-
const v = getValue(d.data);
|
| 752 |
-
const meta = getMeta ? getMeta(d.data) : '';
|
| 753 |
-
tooltipEl.innerHTML =
|
| 754 |
-
`<div class="t-name">${nm}</div>` +
|
| 755 |
-
`<div class="t-meta">${v.toLocaleString()} rows` +
|
| 756 |
-
(meta ? ` · ${meta}` : '') + `</div>`;
|
| 757 |
-
gsap.to(tooltipEl, { opacity: 1, duration: 0.15, overwrite: true });
|
| 758 |
-
})
|
| 759 |
-
.on('mousemove', function (ev) {
|
| 760 |
-
tooltipEl.style.left = (ev.clientX + 14) + 'px';
|
| 761 |
-
tooltipEl.style.top = (ev.clientY + 14) + 'px';
|
| 762 |
-
})
|
| 763 |
-
.on('mouseleave', function () {
|
| 764 |
-
gsap.to(tooltipEl, { opacity: 0, duration: 0.12, overwrite: true });
|
| 765 |
-
})
|
| 766 |
-
.on('click', function (ev, d) {
|
| 767 |
-
const key = getKey(d.data);
|
| 768 |
-
focusDonutSlice(svgId, this, key);
|
| 769 |
-
if (typeof showDetails === 'function') showDetails(key);
|
| 770 |
-
});
|
| 771 |
-
|
| 772 |
-
// Cache for drill-down reset logic.
|
| 773 |
-
donutState.set(svgId, { paths, arcGen, resolveColor });
|
| 774 |
-
|
| 775 |
-
// Center content — start at 0 and count up with GSAP.
|
| 776 |
-
if (centerId) {
|
| 777 |
-
const centerEl = document.getElementById(centerId);
|
| 778 |
-
const topIconHtml = topIcon ? `<span class="icon">${topIcon}</span>` : '';
|
| 779 |
-
const bottomIconHtml = bottomIcon ? `<span class="icon">${bottomIcon}</span>` : '';
|
| 780 |
-
centerEl.innerHTML =
|
| 781 |
-
`<div class="center-item top">
|
| 782 |
-
<div class="center-label">${topIconHtml}${topLabel}</div>
|
| 783 |
-
<div class="center-number js-count-top">0</div>
|
| 784 |
-
</div>
|
| 785 |
-
<div class="center-item bottom">
|
| 786 |
-
<div class="center-number js-count-bottom">0</div>
|
| 787 |
-
<div class="center-label">${bottomLabel}${bottomIconHtml}</div>
|
| 788 |
-
</div>`;
|
| 789 |
-
|
| 790 |
-
const topEl = centerEl.querySelector('.js-count-top');
|
| 791 |
-
const bottomEl = centerEl.querySelector('.js-count-bottom');
|
| 792 |
-
|
| 793 |
-
const topObj = { v: 0 };
|
| 794 |
-
gsap.to(topObj, {
|
| 795 |
-
v: count,
|
| 796 |
-
duration: 1.0,
|
| 797 |
-
ease: 'power2.out',
|
| 798 |
-
delay: 0.55,
|
| 799 |
-
onUpdate: () => { topEl.textContent = Math.floor(topObj.v); },
|
| 800 |
-
onComplete: () => { topEl.textContent = count; }
|
| 801 |
-
});
|
| 802 |
-
|
| 803 |
-
const bottomObj = { v: 0 };
|
| 804 |
-
gsap.to(bottomObj, {
|
| 805 |
-
v: total,
|
| 806 |
-
duration: 1.6,
|
| 807 |
-
ease: 'power2.out',
|
| 808 |
-
delay: 0.65,
|
| 809 |
-
onUpdate: () => { bottomEl.innerHTML = formatRows(Math.floor(bottomObj.v)); },
|
| 810 |
-
onComplete: () => { bottomEl.innerHTML = formatRows(total); }
|
| 811 |
-
});
|
| 812 |
-
|
| 813 |
-
gsap.from(`#${centerId} .center-label`, { y: 14, opacity: 0, duration: 0.55, ease: 'power3.out', delay: 0.45, stagger: 0.15 });
|
| 814 |
-
gsap.from(`#${centerId} .center-number`, { y: 10, opacity: 0, duration: 0.55, ease: 'power3.out', delay: 0.55, stagger: 0.15 });
|
| 815 |
-
|
| 816 |
-
// Space out the top/bottom blocks since the divider is gone.
|
| 817 |
-
centerEl.querySelector('.center-item.bottom').style.marginTop = '14px';
|
| 818 |
-
}
|
| 819 |
-
|
| 820 |
-
return paths;
|
| 821 |
-
}
|
| 822 |
-
|
| 823 |
-
/** Click drill-down: scale up clicked slice, dim the rest, toggle on re-click. */
|
| 824 |
-
function focusDonutSlice(svgId, clickedEl, clickedKey) {
|
| 825 |
-
const state = donutState.get(svgId);
|
| 826 |
-
if (!state) return;
|
| 827 |
-
const { paths, arcGen } = state;
|
| 828 |
-
|
| 829 |
-
// Toggle off if clicking the already-selected slice
|
| 830 |
-
if (state.selectedKey === clickedKey) {
|
| 831 |
-
resetDonutFocus(svgId);
|
| 832 |
-
return;
|
| 833 |
-
}
|
| 834 |
-
state.selectedKey = clickedKey;
|
| 835 |
-
|
| 836 |
-
paths.nodes().forEach((node, i) => {
|
| 837 |
-
const d = paths.data()[i];
|
| 838 |
-
const isSelected = node === clickedEl;
|
| 839 |
-
if (isSelected) {
|
| 840 |
-
const [cx, cy] = node._centroid || arcGen.centroid(d);
|
| 841 |
-
gsap.to(node, {
|
| 842 |
-
scale: 1.08,
|
| 843 |
-
opacity: 1,
|
| 844 |
-
svgOrigin: `${cx} ${cy}`,
|
| 845 |
-
filter: 'drop-shadow(0 0 14px rgba(255,255,255,0.35)) brightness(1.15)',
|
| 846 |
-
duration: 0.45,
|
| 847 |
-
ease: 'power2.out',
|
| 848 |
-
overwrite: 'auto'
|
| 849 |
-
});
|
| 850 |
-
} else {
|
| 851 |
-
gsap.to(node, {
|
| 852 |
-
scale: 1,
|
| 853 |
-
opacity: 0.3,
|
| 854 |
-
filter: 'none',
|
| 855 |
-
duration: 0.35,
|
| 856 |
-
ease: 'power2.out',
|
| 857 |
-
overwrite: 'auto'
|
| 858 |
-
});
|
| 859 |
-
}
|
| 860 |
-
});
|
| 861 |
-
}
|
| 862 |
-
|
| 863 |
-
function resetDonutFocus(svgId) {
|
| 864 |
-
const state = donutState.get(svgId);
|
| 865 |
-
if (!state) return;
|
| 866 |
-
state.selectedKey = null;
|
| 867 |
-
state.paths.nodes().forEach(node => {
|
| 868 |
-
gsap.to(node, {
|
| 869 |
-
scale: 1, opacity: 1, filter: 'none',
|
| 870 |
-
duration: 0.35, ease: 'power2.out', overwrite: 'auto'
|
| 871 |
-
});
|
| 872 |
-
});
|
| 873 |
-
}
|
| 874 |
-
|
| 875 |
-
// ---- Raw vs Adaption donuts ----
|
| 876 |
-
// The Raw donut shows every dataset that has a raw repo (including the
|
| 877 |
-
// PolyglotText / PolyglotAudio pre-training pools). The Adaption donut shows
|
| 878 |
-
// every dataset with an Adaption-remastered version. renderDonut() filters
|
| 879 |
-
// out zero-value entries automatically.
|
| 880 |
-
renderDonut({
|
| 881 |
-
svgId: 'chart-raw',
|
| 882 |
-
centerId: 'center-raw',
|
| 883 |
-
field: 'raw',
|
| 884 |
-
datasets: DATASETS,
|
| 885 |
-
getValue: d => (d.raw && d.raw.rows) || 0,
|
| 886 |
-
getKey: d => d.key,
|
| 887 |
-
getTitle: d => d.title,
|
| 888 |
-
getMeta: d => d.raw ? d.raw.repo : '',
|
| 889 |
-
topLabel: 'RAW DATASETS',
|
| 890 |
-
bottomLabel: 'ROWS',
|
| 891 |
-
topIcon: '',
|
| 892 |
-
bottomIcon: '',
|
| 893 |
-
sizing: 'log', // compress so tiny datasets still get a visible slice
|
| 894 |
-
});
|
| 895 |
-
|
| 896 |
-
renderDonut({
|
| 897 |
-
svgId: 'chart-adaption',
|
| 898 |
-
centerId: 'center-adaption',
|
| 899 |
-
field: 'adaption',
|
| 900 |
-
datasets: DATASETS,
|
| 901 |
-
getValue: d => (d.adaption && d.adaption.rows) || 0,
|
| 902 |
-
getKey: d => d.key,
|
| 903 |
-
getTitle: d => d.title,
|
| 904 |
-
getMeta: d => d.adaption ? d.adaption.repo : '',
|
| 905 |
-
topLabel: 'ADAPTION SETS',
|
| 906 |
-
bottomLabel: 'ROWS',
|
| 907 |
-
topIcon: '',
|
| 908 |
-
bottomIcon: '',
|
| 909 |
-
});
|
| 910 |
-
|
| 911 |
-
// ---- Modality donut ----
|
| 912 |
-
const MODALITIES = [
|
| 913 |
-
{ key: 'text', name: 'Text', count: 5 },
|
| 914 |
-
{ key: 'audio', name: 'Audio', count: 3 },
|
| 915 |
-
{ key: 'image', name: 'Image', count: 3 },
|
| 916 |
-
{ key: 'code', name: 'Code', count: 1 },
|
| 917 |
-
];
|
| 918 |
-
const modalityColor = d3.scaleOrdinal(PALETTE).domain(MODALITIES.map(m => m.key));
|
| 919 |
-
|
| 920 |
-
renderDonut({
|
| 921 |
-
svgId: 'chart-modality',
|
| 922 |
-
centerId: 'center-modality',
|
| 923 |
-
field: 'count',
|
| 924 |
-
datasets: MODALITIES,
|
| 925 |
-
getValue: d => d.count,
|
| 926 |
-
getKey: d => d.key,
|
| 927 |
-
getTitle: d => d.name,
|
| 928 |
-
getColor: d => modalityColor(d.key),
|
| 929 |
-
getMeta: d => `${d.count} datasets`,
|
| 930 |
-
topLabel: 'MODALITIES',
|
| 931 |
-
bottomLabel: 'DATASETS',
|
| 932 |
-
topIcon: '',
|
| 933 |
-
bottomIcon: '',
|
| 934 |
-
});
|
| 935 |
-
|
| 936 |
-
// ===========================================================================
|
| 937 |
-
// DETAILS CARD — rendered on slice click with GSAP reveal
|
| 938 |
-
// ===========================================================================
|
| 939 |
-
function hideLanguageDetails() {
|
| 940 |
-
// No-op placeholder — currently we share the single details card; click-
|
| 941 |
-
// another to switch. Kept as an explicit symbol for future extension.
|
| 942 |
-
}
|
| 943 |
-
|
| 944 |
-
function showLanguageDetails(langData, color) {
|
| 945 |
-
const card = document.getElementById('details-card');
|
| 946 |
-
card.style.display = '';
|
| 947 |
-
|
| 948 |
-
// Per-dataset breakdown for this language.
|
| 949 |
-
const breakdown = DATASET_LANGS
|
| 950 |
-
.map(d => ({ dataset: d.name, key: d.key, rows: d.langs[langData.code] || 0 }))
|
| 951 |
-
.filter(d => d.rows > 0)
|
| 952 |
-
.sort((a, b) => b.rows - a.rows);
|
| 953 |
-
|
| 954 |
-
const rows = breakdown.map(b =>
|
| 955 |
-
`<div class="kv"><div class="k">${b.dataset}</div><div class="v"><strong>${formatShort(b.rows)}</strong>
|
| 956 |
-
<span style="color:var(--muted);font-size:0.85em">(${b.rows.toLocaleString()})</span></div></div>`
|
| 957 |
-
).join('');
|
| 958 |
-
|
| 959 |
-
card.innerHTML = `
|
| 960 |
-
<h3>
|
| 961 |
-
<span class="swatch" style="background:${color}"></span>
|
| 962 |
-
${langData.name} <span style="color:var(--muted);font-weight:400;font-size:0.9rem">(${langData.code})</span>
|
| 963 |
-
</h3>
|
| 964 |
-
<p class="tagline">Total across the raw corpus: <strong>${langData.value.toLocaleString()}</strong> rows.</p>
|
| 965 |
-
<div class="kv-grid">${rows}</div>
|
| 966 |
-
`;
|
| 967 |
-
|
| 968 |
-
gsap.fromTo(card,
|
| 969 |
-
{ y: 80, opacity: 0 },
|
| 970 |
-
{ y: 0, opacity: 1, duration: 0.75, ease: 'power4.out' }
|
| 971 |
-
);
|
| 972 |
-
gsap.from(card.querySelectorAll('.kv'), {
|
| 973 |
-
y: 18, opacity: 0, duration: 0.45, ease: 'power3.out',
|
| 974 |
-
stagger: 0.05, delay: 0.2
|
| 975 |
-
});
|
| 976 |
-
|
| 977 |
-
card.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
| 978 |
-
}
|
| 979 |
-
|
| 980 |
-
function showDetails(key) {
|
| 981 |
-
const d = DATASETS.find(x => x.key === key);
|
| 982 |
-
if (!d) return;
|
| 983 |
-
const card = document.getElementById('details-card');
|
| 984 |
-
card.style.display = '';
|
| 985 |
-
|
| 986 |
-
const repoLink = info => info
|
| 987 |
-
? `<a href="https://huggingface.co/datasets/${info.repo}" target="_blank">${info.repo}</a>`
|
| 988 |
-
: `<span style="color:var(--muted);">—</span>`;
|
| 989 |
-
const rowsCell = info => info
|
| 990 |
-
? `<strong>${formatShort(info.rows)}</strong> <span style="color:var(--muted);font-size:0.85em">(${info.rows.toLocaleString()})</span>`
|
| 991 |
-
: `<span style="color:var(--muted);">—</span>`;
|
| 992 |
-
|
| 993 |
-
card.innerHTML = `
|
| 994 |
-
<h3>
|
| 995 |
-
<span class="swatch" style="background:${d.color}"></span>
|
| 996 |
-
${d.title}
|
| 997 |
-
</h3>
|
| 998 |
-
<p class="tagline">${d.tagline}</p>
|
| 999 |
-
<div class="kv-grid">
|
| 1000 |
-
<div class="kv"><div class="k">Raw repo</div><div class="v">${repoLink(d.raw)}</div></div>
|
| 1001 |
-
<div class="kv"><div class="k">Raw rows</div><div class="v">${rowsCell(d.raw)}</div></div>
|
| 1002 |
-
<div class="kv"><div class="k">Adaption repo</div><div class="v">${repoLink(d.adaption)}</div></div>
|
| 1003 |
-
<div class="kv"><div class="k">Adaption rows</div><div class="v">${rowsCell(d.adaption)}</div></div>
|
| 1004 |
-
<div class="kv"><div class="k">Modality</div><div class="v">${d.modality}</div></div>
|
| 1005 |
-
<div class="kv"><div class="k">License</div><div class="v">${d.license}</div></div>
|
| 1006 |
-
${d.model ? `<div class="kv"><div class="k">Annotator</div><div class="v">${d.model}</div></div>` : ''}
|
| 1007 |
-
<div class="kv"><div class="k">Languages</div><div class="v">${d.languages}</div></div>
|
| 1008 |
-
</div>
|
| 1009 |
-
<div class="kv" style="margin-top:18px;">
|
| 1010 |
-
<div class="k">Schema</div>
|
| 1011 |
-
<div class="schema-list">${d.schema.map(c => `<code>${c}</code>`).join('')}</div>
|
| 1012 |
-
</div>
|
| 1013 |
-
`;
|
| 1014 |
-
|
| 1015 |
-
// Elegant slide-in from the bottom with power4.out.
|
| 1016 |
-
gsap.fromTo(card,
|
| 1017 |
-
{ y: 80, opacity: 0 },
|
| 1018 |
-
{ y: 0, opacity: 1, duration: 0.75, ease: 'power4.out' }
|
| 1019 |
-
);
|
| 1020 |
-
gsap.from(card.querySelectorAll('.kv'), {
|
| 1021 |
-
y: 18, opacity: 0, duration: 0.45, ease: 'power3.out',
|
| 1022 |
-
stagger: 0.05, delay: 0.2
|
| 1023 |
-
});
|
| 1024 |
-
|
| 1025 |
-
card.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
| 1026 |
-
}
|
| 1027 |
-
|
| 1028 |
-
// ===========================================================================
|
| 1029 |
-
// INITIAL PAGE LOAD — hero image → hero stats → chart cards, staggered.
|
| 1030 |
-
// ===========================================================================
|
| 1031 |
-
const loadTl = gsap.timeline();
|
| 1032 |
-
loadTl
|
| 1033 |
-
.from('.hero-img', { y: 20, opacity: 0, duration: 0.9, ease: 'power3.out' })
|
| 1034 |
-
.from('.stat', { y: 20, opacity: 0, duration: 0.7, ease: 'power3.out', stagger: 0.15 }, '-=0.5')
|
| 1035 |
-
.from('.chart-card', { y: 20, opacity: 0, duration: 0.8, ease: 'power3.out', stagger: 0.15 }, '-=0.3');
|
| 1036 |
-
|
| 1037 |
-
// ===========================================================================
|
| 1038 |
-
// LANGUAGE DATA (for the Voronoi treemap)
|
| 1039 |
-
// ===========================================================================
|
| 1040 |
-
const LANG_NAMES = {
|
| 1041 |
-
tr: "Turkish", ru: "Russian", it: "Italian", en: "English", eo: "Esperanto",
|
| 1042 |
-
hu: "Hungarian", de: "German", fr: "French", pt: "Portuguese", mk: "Macedonian",
|
| 1043 |
-
es: "Spanish", he: "Hebrew", fi: "Finnish", ber: "Berber", nl: "Dutch",
|
| 1044 |
-
pl: "Polish", sr: "Serbian", mr: "Marathi", el: "Greek", da: "Danish",
|
| 1045 |
-
cs: "Czech", sv: "Swedish", bg: "Bulgarian", la: "Latin", zh: "Mandarin",
|
| 1046 |
-
ro: "Romanian", ia: "Interlingua", ja: "Japanese", tok: "Toki Pona",
|
| 1047 |
-
lfn: "Lingua Franca Nova", uk: "Ukrainian", tt: "Tatar", tl: "Tagalog",
|
| 1048 |
-
id: "Indonesian", nb: "Norwegian B.", lt: "Lithuanian", az: "Azerbaijani",
|
| 1049 |
-
ie: "Interlingue", tlh: "Klingon", jbo: "Lojban", mhr: "Meadow Mari",
|
| 1050 |
-
bn: "Bengali", fa: "Persian", br: "Breton", ilo: "Ilocano", ar: "Arabic",
|
| 1051 |
-
ceb: "Cebuano", hi: "Hindi", vi: "Vietnamese", pam: "Kapampangan",
|
| 1052 |
-
hy: "Armenian", be: "Belarusian", ko: "Korean", yue: "Cantonese",
|
| 1053 |
-
ca: "Catalan", kab: "Kabyle", af: "Afrikaans", am: "Amharic", yi: "Yiddish",
|
| 1054 |
-
sat: "Santali", so: "Somali", te: "Telugu", ne: "Nepali", pa: "Punjabi",
|
| 1055 |
-
ur: "Urdu", ta: "Tamil", ml: "Malayalam", th: "Thai", or: "Odia",
|
| 1056 |
-
sd: "Sindhi", gu: "Gujarati", kn: "Kannada", my: "Burmese", bo: "Tibetan",
|
| 1057 |
-
lo: "Lao", mni: "Meitei", kk: "Kazakh", oc: "Occitan", hr: "Croatian",
|
| 1058 |
-
sk: "Slovak", et: "Estonian", sl: "Slovenian", is: "Icelandic", ms: "Malay",
|
| 1059 |
-
sq: "Albanian", hsb: "Upper Sorbian", dsb: "Lower Sorbian", mai: "Maithili",
|
| 1060 |
-
kha: "Khasi", dtp: "Kadazan", yo: "Yoruba", sw: "Swahili", cy: "Welsh",
|
| 1061 |
-
ga: "Irish", gd: "Scottish Gaelic", ti: "Tigrinya", os: "Ossetian",
|
| 1062 |
-
sa: "Sanskrit", ug: "Uyghur", uz: "Uzbek", ka: "Georgian", eu: "Basque",
|
| 1063 |
-
vo: "Volapük", ido: "Ido", nov: "Novial", avk: "Kotava", ldn: "Láadan",
|
| 1064 |
-
afh: "Afrihili", lzh: "Classical Chinese", non: "Old Norse", ang: "Old English",
|
| 1065 |
-
grc: "Ancient Greek", sux: "Sumerian", fro: "Old French", cbk: "Chavacano",
|
| 1066 |
-
zsm: "Standard Malay", war: "Waray", kw: "Cornish", nah: "Nahuatl",
|
| 1067 |
-
kek: "Q'eqchi'", hif: "Fiji Hindi", crh: "Crimean Tatar", sah: "Sakha",
|
| 1068 |
-
ext: "Extremaduran", csb: "Kashubian", sgs: "Samogitian", cha: "Chamorro",
|
| 1069 |
-
tvl: "Tuvaluan", mi: "Maori", lin: "Lingala", arq: "Algerian Arabic",
|
| 1070 |
-
arz: "Egyptian Arabic", orv: "Old East Slavic", prg: "Old Prussian",
|
| 1071 |
-
chv: "Chuvash", bar: "Bavarian", pms: "Piedmontese", egl: "Emilian",
|
| 1072 |
-
jav: "Javanese", sun: "Sundanese", hoc: "Ho", zza: "Zaza",
|
| 1073 |
-
rif: "Riffian Berber", nog: "Nogai", km: "Khmer",
|
| 1074 |
-
};
|
| 1075 |
-
|
| 1076 |
-
const DATASET_LANGS = [
|
| 1077 |
-
{
|
| 1078 |
-
key: "polytext", name: "PolyglotText",
|
| 1079 |
-
langs: {
|
| 1080 |
-
tr: 1767000, ru: 1695000, it: 1588000, en: 1337000, eo: 1171000,
|
| 1081 |
-
hu: 817000, de: 675000, fr: 520000, pt: 470000, mk: 398000,
|
| 1082 |
-
es: 358000, he: 272000, fi: 263000, ber: 180000, nl: 125000,
|
| 1083 |
-
pl: 118000, sr: 106000, mr: 96000, el: 94000, da: 90000,
|
| 1084 |
-
cs: 72000, sv: 71000, bg: 70000, la: 66000, zh: 58000, ro: 56000,
|
| 1085 |
-
ia: 54000, ja: 43000, tok: 39000, lfn: 38000, uk: 38000, tt: 33000,
|
| 1086 |
-
tl: 31000, id: 31000, nb: 31000, lt: 29000, az: 25000, ie: 24000,
|
| 1087 |
-
tlh: 23000, jbo: 21000, mhr: 19000, bn: 19000, fa: 17000, br: 17000,
|
| 1088 |
-
ilo: 17000, ar: 16000, ceb: 15000, hi: 13000, vi: 11000, pam: 11000,
|
| 1089 |
-
hy: 9000, be: 9000, ko: 9000,
|
| 1090 |
-
cbk: 19000, sk: 8000, vo: 8000, oc: 8000, et: 8000,
|
| 1091 |
-
war: 6700, ms: 6700, hr: 6700, eu: 6700, yi: 5400, af: 5400,
|
| 1092 |
-
km: 4000, ca: 4000, kha: 4000, dtp: 4000, zza: 4000, is: 4000,
|
| 1093 |
-
avk: 4000, ga: 4000, hoc: 4000, sl: 4000, sq: 4000, chv: 4000,
|
| 1094 |
-
kw: 4000, sux: 2700, ang: 2700, pms: 2700, prg: 2700, ug: 2700,
|
| 1095 |
-
lzh: 2700, egl: 2700, ur: 2700, sah: 2700, nds: 2700, mi: 2700,
|
| 1096 |
-
tvl: 1400, cha: 1400, th: 1400, cy: 1400, non: 1400, yo: 1400,
|
| 1097 |
-
lin: 1400, grc: 1400, arq: 1400, orv: 1400, sw: 1400, rif: 1400,
|
| 1098 |
-
crh: 1400, hif: 1400, jav: 1400, sun: 1400, hsb: 1400, dsb: 1400,
|
| 1099 |
-
amh: 1400, csb: 1400, sgs: 1400, ext: 1400, nov: 1400, nog: 1400,
|
| 1100 |
-
arz: 1400, nah: 1400, ido: 1400, afh: 1400, kk: 1400,
|
| 1101 |
-
}
|
| 1102 |
-
},
|
| 1103 |
-
{
|
| 1104 |
-
key: "polyaudio", name: "PolyglotAudio",
|
| 1105 |
-
langs: {
|
| 1106 |
-
en: 698000, es: 261000, eo: 105000, de: 32000, fr: 16000,
|
| 1107 |
-
ru: 9200, pl: 8800, ber: 6600, nl: 5900, it: 5900,
|
| 1108 |
-
yue: 4300, pt: 3300, ja: 1400, mr: 1200, ca: 505,
|
| 1109 |
-
cs: 410, zh: 110, fi: 93, hu: 87, uk: 38,
|
| 1110 |
-
he: 16, tok: 5, kab: 5,
|
| 1111 |
-
}
|
| 1112 |
-
},
|
| 1113 |
-
{
|
| 1114 |
-
key: "tts", name: "multilingual-synthetic-tts",
|
| 1115 |
-
langs: {
|
| 1116 |
-
ja: 13951, ru: 9105, de: 8972, ko: 8129, es: 7917,
|
| 1117 |
-
pt: 5438, zh: 5417, en: 5157, fr: 4551,
|
| 1118 |
-
}
|
| 1119 |
-
},
|
| 1120 |
-
{
|
| 1121 |
-
key: "magazines", name: "magazines-multilingual-vqa",
|
| 1122 |
-
langs: {
|
| 1123 |
-
de: 4412, fr: 3279, ru: 2762, pt: 2047, vi: 1637, bn: 1598,
|
| 1124 |
-
en: 1004, af: 826, ar: 156, it: 136, fa: 132, te: 132,
|
| 1125 |
-
ja: 130, ne: 108, pa: 100, ur: 98, nl: 95, tr: 85, zh: 83,
|
| 1126 |
-
ta: 68, ml: 64, id: 43, th: 47, am: 123, yi: 108, sat: 85,
|
| 1127 |
-
so: 25, hi: 15, es: 10, mr: 9, kn: 8, or: 17, sd: 3,
|
| 1128 |
-
mai: 1021, la: 146, bo: 25, be: 8, da: 6, ko: 4, bg: 4,
|
| 1129 |
-
os: 3, sa: 3, my: 3, oc: 1, gd: 1, ti: 1, hy: 1, pl: 1,
|
| 1130 |
-
mni: 1, uk: 1, lo: 1, kk: 1,
|
| 1131 |
-
}
|
| 1132 |
-
},
|
| 1133 |
-
{ key: "fma", name: "fma-labeled", langs: { en: 29000 } },
|
| 1134 |
-
{ key: "streetview", name: "streetview-global", langs: { en: 30000 } },
|
| 1135 |
-
{ key: "current_affairs", name: "current-affairs (raw, 2023-26)", langs: { en: 20694 } },
|
| 1136 |
-
{ key: "frontend", name: "frontend-coding", langs: { en: 500 } },
|
| 1137 |
-
{
|
| 1138 |
-
key: "image_ann", name: "multilingual-image-annotations",
|
| 1139 |
-
langs: { en: 464, es: 464, fr: 464, hi: 464, zh: 464, ar: 464, pt: 464 }
|
| 1140 |
-
},
|
| 1141 |
-
];
|
| 1142 |
-
|
| 1143 |
-
// Aggregate totals across the raw corpus
|
| 1144 |
-
const langTotals = {};
|
| 1145 |
-
for (const d of DATASET_LANGS) {
|
| 1146 |
-
for (const [lang, n] of Object.entries(d.langs)) {
|
| 1147 |
-
langTotals[lang] = (langTotals[lang] || 0) + n;
|
| 1148 |
-
}
|
| 1149 |
-
}
|
| 1150 |
-
const langEntries = Object.entries(langTotals)
|
| 1151 |
-
.sort((a, b) => b[1] - a[1])
|
| 1152 |
-
.map(([code, n]) => ({
|
| 1153 |
-
code,
|
| 1154 |
-
name: LANG_NAMES[code] || code,
|
| 1155 |
-
value: n,
|
| 1156 |
-
sizeValue: Math.log10(n + 10),
|
| 1157 |
-
}));
|
| 1158 |
-
|
| 1159 |
-
// ===========================================================================
|
| 1160 |
-
// VORONOI TREEMAP (D3) — palette quantile coloring, black strokes
|
| 1161 |
-
// ===========================================================================
|
| 1162 |
-
(function renderVoronoi() {
|
| 1163 |
-
const container = document.getElementById('chart-treemap');
|
| 1164 |
-
const tooltip = document.getElementById('voronoi-tooltip');
|
| 1165 |
-
|
| 1166 |
-
if (typeof d3 === 'undefined' || !d3.voronoiTreemap) {
|
| 1167 |
-
container.insertAdjacentHTML('beforeend',
|
| 1168 |
-
`<div style="color:#ff8a8a;padding:24px;text-align:center;font-size:0.9rem">
|
| 1169 |
-
Voronoi treemap libraries failed to load. Check your network / CSP.
|
| 1170 |
-
</div>`);
|
| 1171 |
-
return;
|
| 1172 |
-
}
|
| 1173 |
-
|
| 1174 |
-
// Map language size buckets onto PALETTE via quantiles, so cells naturally
|
| 1175 |
-
// cluster by tonal groups.
|
| 1176 |
-
const colorScale = d3.scaleQuantile()
|
| 1177 |
-
.domain(langEntries.map(e => e.sizeValue))
|
| 1178 |
-
.range(PALETTE);
|
| 1179 |
-
|
| 1180 |
-
function draw() {
|
| 1181 |
-
container.querySelectorAll('svg').forEach(s => s.remove());
|
| 1182 |
-
|
| 1183 |
-
const rect = container.getBoundingClientRect();
|
| 1184 |
-
const width = Math.max(320, rect.width);
|
| 1185 |
-
const height = Math.max(320, rect.height);
|
| 1186 |
-
|
| 1187 |
-
// Circular clip polygon
|
| 1188 |
-
const clipPad = 6;
|
| 1189 |
-
const cx = width / 2, cy = height / 2;
|
| 1190 |
-
const r = Math.min(width, height) / 2 - clipPad;
|
| 1191 |
-
const N = 96;
|
| 1192 |
-
const clipPolygon = d3.range(N).map(i => [
|
| 1193 |
-
cx + r * Math.cos((i / N) * 2 * Math.PI),
|
| 1194 |
-
cy + r * Math.sin((i / N) * 2 * Math.PI),
|
| 1195 |
-
]);
|
| 1196 |
-
|
| 1197 |
-
const root = d3.hierarchy({ name: 'root', children: langEntries })
|
| 1198 |
-
.sum(d => d.sizeValue);
|
| 1199 |
-
|
| 1200 |
-
const treemap = d3.voronoiTreemap()
|
| 1201 |
-
.clip(clipPolygon)
|
| 1202 |
-
.convergenceRatio(0.005)
|
| 1203 |
-
.maxIterationCount(120)
|
| 1204 |
-
.minWeightRatio(0.01);
|
| 1205 |
-
treemap(root);
|
| 1206 |
-
|
| 1207 |
-
const svg = d3.select(container).append('svg')
|
| 1208 |
-
.attr('viewBox', `0 0 ${width} ${height}`)
|
| 1209 |
-
.attr('preserveAspectRatio', 'xMidYMid meet');
|
| 1210 |
-
const g = svg.append('g');
|
| 1211 |
-
|
| 1212 |
-
// Outer circle outline
|
| 1213 |
-
g.append('circle')
|
| 1214 |
-
.attr('cx', cx).attr('cy', cy).attr('r', r + 1)
|
| 1215 |
-
.attr('fill', 'none')
|
| 1216 |
-
.attr('stroke', '#1f1f1f')
|
| 1217 |
-
.attr('stroke-width', 1);
|
| 1218 |
-
|
| 1219 |
-
const leaves = root.leaves();
|
| 1220 |
-
|
| 1221 |
-
const cells = g.selectAll('path.voronoi-cell')
|
| 1222 |
-
.data(leaves)
|
| 1223 |
-
.join('path')
|
| 1224 |
-
.attr('class', 'voronoi-cell')
|
| 1225 |
-
.attr('d', d => 'M' + d.polygon.map(p => p.join(',')).join('L') + 'Z')
|
| 1226 |
-
.attr('fill', d => colorScale(d.data.sizeValue))
|
| 1227 |
-
.attr('stroke', '#000000')
|
| 1228 |
-
.attr('stroke-width', 1.2)
|
| 1229 |
-
.attr('stroke-linejoin', 'round');
|
| 1230 |
-
|
| 1231 |
-
// Record centroid per cell so we can scale from the cell's own center.
|
| 1232 |
-
cells.each(function (leaf) {
|
| 1233 |
-
const [cx, cy] = leaf.site || d3.polygonCentroid(leaf.polygon);
|
| 1234 |
-
this._centroid = [cx, cy];
|
| 1235 |
-
});
|
| 1236 |
-
|
| 1237 |
-
// Mosaic build: fade + scale up from each cell's own centroid, staggered.
|
| 1238 |
-
cells.nodes().forEach((node, i) => {
|
| 1239 |
-
const [cx, cy] = node._centroid;
|
| 1240 |
-
gsap.fromTo(node,
|
| 1241 |
-
{ scale: 0, opacity: 0, svgOrigin: `${cx} ${cy}` },
|
| 1242 |
-
{ scale: 1, opacity: 1, svgOrigin: `${cx} ${cy}`,
|
| 1243 |
-
duration: 0.55, ease: 'power3.out', delay: i * 0.012 }
|
| 1244 |
-
);
|
| 1245 |
-
});
|
| 1246 |
-
|
| 1247 |
-
// Labels — sized by cell area; smaller cells hide the name, tiny ones only show on hover.
|
| 1248 |
-
function polyArea(pts) {
|
| 1249 |
-
let a = 0;
|
| 1250 |
-
for (let i = 0, n = pts.length; i < n; i++) {
|
| 1251 |
-
const [x1, y1] = pts[i], [x2, y2] = pts[(i + 1) % n];
|
| 1252 |
-
a += x1 * y2 - x2 * y1;
|
| 1253 |
-
}
|
| 1254 |
-
return Math.abs(a) / 2;
|
| 1255 |
-
}
|
| 1256 |
-
|
| 1257 |
-
leaves.forEach(leaf => {
|
| 1258 |
-
const area = polyArea(leaf.polygon);
|
| 1259 |
-
const side = Math.sqrt(area);
|
| 1260 |
-
const [x, y] = leaf.site || d3.polygonCentroid(leaf.polygon);
|
| 1261 |
-
const d = leaf.data;
|
| 1262 |
-
|
| 1263 |
-
if (side >= 44) {
|
| 1264 |
-
const nameSize = Math.max(10, Math.min(18, side / 6));
|
| 1265 |
-
const codeSize = Math.max(9, Math.min(13, side / 9));
|
| 1266 |
-
const text = g.append('text')
|
| 1267 |
-
.datum(leaf.data)
|
| 1268 |
-
.attr('class', 'voronoi-label')
|
| 1269 |
-
.attr('x', x).attr('y', y - 2)
|
| 1270 |
-
.attr('font-size', nameSize);
|
| 1271 |
-
text.append('tspan').text(d.name);
|
| 1272 |
-
text.append('tspan')
|
| 1273 |
-
.attr('class', 'code')
|
| 1274 |
-
.attr('x', x).attr('dy', nameSize * 0.95)
|
| 1275 |
-
.attr('font-size', codeSize)
|
| 1276 |
-
.text(`${d.code} · ${formatShort(d.value)}`);
|
| 1277 |
-
} else if (side >= 22) {
|
| 1278 |
-
const sz = Math.max(8, Math.min(11, side / 3));
|
| 1279 |
-
g.append('text')
|
| 1280 |
-
.datum(leaf.data)
|
| 1281 |
-
.attr('class', 'voronoi-label')
|
| 1282 |
-
.attr('x', x).attr('y', y + sz / 3)
|
| 1283 |
-
.attr('font-size', sz)
|
| 1284 |
-
.text(d.code);
|
| 1285 |
-
}
|
| 1286 |
-
});
|
| 1287 |
-
|
| 1288 |
-
// Hover tooltip
|
| 1289 |
-
cells
|
| 1290 |
-
.on('mouseenter', (ev, d) => {
|
| 1291 |
-
tooltip.innerHTML =
|
| 1292 |
-
`<span class="t-name">${d.data.name}</span>` +
|
| 1293 |
-
`<span class="t-code">(${d.data.code})</span>` +
|
| 1294 |
-
`<div class="t-rows">${d.data.value.toLocaleString()} rows</div>`;
|
| 1295 |
-
gsap.to(tooltip, { opacity: 1, duration: 0.12, overwrite: true });
|
| 1296 |
-
})
|
| 1297 |
-
.on('mousemove', (ev) => {
|
| 1298 |
-
const bb = container.getBoundingClientRect();
|
| 1299 |
-
tooltip.style.left = (ev.clientX - bb.left + 12) + 'px';
|
| 1300 |
-
tooltip.style.top = (ev.clientY - bb.top + 12) + 'px';
|
| 1301 |
-
})
|
| 1302 |
-
.on('mouseleave', () => {
|
| 1303 |
-
gsap.to(tooltip, { opacity: 0, duration: 0.1, overwrite: true });
|
| 1304 |
-
});
|
| 1305 |
-
|
| 1306 |
-
// Click drill-down: highlight the clicked cell, dim the rest, surface a
|
| 1307 |
-
// language detail card below the treemap.
|
| 1308 |
-
let selectedCell = null;
|
| 1309 |
-
cells.on('click', function (ev, d) {
|
| 1310 |
-
const [cx, cy] = this._centroid;
|
| 1311 |
-
const sameAgain = selectedCell === this;
|
| 1312 |
-
if (sameAgain) {
|
| 1313 |
-
// reset
|
| 1314 |
-
selectedCell = null;
|
| 1315 |
-
cells.nodes().forEach(node => {
|
| 1316 |
-
const [ncx, ncy] = node._centroid;
|
| 1317 |
-
gsap.to(node, {
|
| 1318 |
-
scale: 1, opacity: 1,
|
| 1319 |
-
svgOrigin: `${ncx} ${ncy}`,
|
| 1320 |
-
filter: 'none',
|
| 1321 |
-
duration: 0.35, ease: 'power2.out', overwrite: 'auto',
|
| 1322 |
-
});
|
| 1323 |
-
});
|
| 1324 |
-
g.selectAll('.voronoi-label').each(function() {
|
| 1325 |
-
gsap.to(this, { opacity: 1, duration: 0.35, overwrite: 'auto' });
|
| 1326 |
-
});
|
| 1327 |
-
hideLanguageDetails();
|
| 1328 |
-
return;
|
| 1329 |
-
}
|
| 1330 |
-
selectedCell = this;
|
| 1331 |
-
cells.nodes().forEach(node => {
|
| 1332 |
-
const [ncx, ncy] = node._centroid;
|
| 1333 |
-
if (node === this) {
|
| 1334 |
-
gsap.to(node, {
|
| 1335 |
-
scale: 1.1, opacity: 1,
|
| 1336 |
-
svgOrigin: `${ncx} ${ncy}`,
|
| 1337 |
-
filter: 'drop-shadow(0 0 10px rgba(255,255,255,0.45)) brightness(1.35)',
|
| 1338 |
-
duration: 0.45, ease: 'power2.out', overwrite: 'auto',
|
| 1339 |
-
});
|
| 1340 |
-
} else {
|
| 1341 |
-
gsap.to(node, {
|
| 1342 |
-
scale: 1, opacity: 0,
|
| 1343 |
-
svgOrigin: `${ncx} ${ncy}`,
|
| 1344 |
-
filter: 'none',
|
| 1345 |
-
duration: 0.35, ease: 'power2.out', overwrite: 'auto',
|
| 1346 |
-
});
|
| 1347 |
-
}
|
| 1348 |
-
});
|
| 1349 |
-
g.selectAll('.voronoi-label').each(function(ld) {
|
| 1350 |
-
if (ld && ld.code === d.data.code) {
|
| 1351 |
-
gsap.to(this, { opacity: 1, duration: 0.45, overwrite: 'auto' });
|
| 1352 |
-
} else {
|
| 1353 |
-
gsap.to(this, { opacity: 0, duration: 0.35, overwrite: 'auto' });
|
| 1354 |
-
}
|
| 1355 |
-
});
|
| 1356 |
-
showLanguageDetails(d.data, colorScale(d.data.sizeValue));
|
| 1357 |
-
|
| 1358 |
-
// Also emit the custom event so external code can react.
|
| 1359 |
-
container.dispatchEvent(new CustomEvent('voronoi-drilldown', {
|
| 1360 |
-
detail: { code: d.data.code, name: d.data.name, rows: d.data.value }
|
| 1361 |
-
}));
|
| 1362 |
-
});
|
| 1363 |
-
}
|
| 1364 |
-
|
| 1365 |
-
draw();
|
| 1366 |
-
|
| 1367 |
-
let t;
|
| 1368 |
-
window.addEventListener('resize', () => {
|
| 1369 |
-
clearTimeout(t);
|
| 1370 |
-
t = setTimeout(draw, 200);
|
| 1371 |
-
});
|
| 1372 |
-
})();
|
| 1373 |
-
</script>
|
| 1374 |
-
|
| 1375 |
-
</body>
|
| 1376 |
-
</html>
|
|
|
|
| 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>ReubenDataLab · Dataset Explorer</title>
|
| 7 |
+
|
| 8 |
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 9 |
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 10 |
+
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Google+Sans:ital,opsz,wght@0,17..18,400..700;1,17..18,400..700&display=swap" rel="stylesheet">
|
| 11 |
+
|
| 12 |
+
<script src="vendor/d3.min.js" defer></script>
|
| 13 |
+
<script src="vendor/d3-weighted-voronoi.js" defer></script>
|
| 14 |
+
<script src="vendor/d3-voronoi-map.js" defer></script>
|
| 15 |
+
<script src="vendor/d3-voronoi-treemap.js" defer></script>
|
| 16 |
+
<script src="vendor/gsap.min.js" defer></script>
|
| 17 |
+
|
| 18 |
+
<style>
|
| 19 |
+
:root {
|
| 20 |
+
--bg: #000000;
|
| 21 |
+
--fg: #ffffff;
|
| 22 |
+
--muted: #8a8a94;
|
| 23 |
+
--card: #141414;
|
| 24 |
+
--card-alt: #1c1c1e;
|
| 25 |
+
--border: #262626;
|
| 26 |
+
--divider: #2e2e2e;
|
| 27 |
+
--tooltip-bg: rgba(20, 20, 20, 0.96);
|
| 28 |
+
|
| 29 |
+
--palette-1: #3b82f6;
|
| 30 |
+
--palette-2: #10b981;
|
| 31 |
+
--palette-3: #ef4444;
|
| 32 |
+
--palette-4: #f59e0b;
|
| 33 |
+
--palette-5: #8b5cf6;
|
| 34 |
+
--palette-6: #ec4899;
|
| 35 |
+
--palette-7: #06b6d4;
|
| 36 |
+
--palette-8: #84cc16;
|
| 37 |
+
--palette-9: #f97316;
|
| 38 |
+
--palette-10: #14b8a6;
|
| 39 |
+
--palette-11: #a855f7;
|
| 40 |
+
--palette-12: #eab308;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
* { box-sizing: border-box; }
|
| 44 |
+
html, body {
|
| 45 |
+
margin: 0; padding: 0;
|
| 46 |
+
background: var(--bg);
|
| 47 |
+
color: var(--fg);
|
| 48 |
+
font-family: "Geist", "Google Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
| 49 |
+
font-weight: 400;
|
| 50 |
+
min-height: 100vh;
|
| 51 |
+
-webkit-font-smoothing: antialiased;
|
| 52 |
+
letter-spacing: 0.005em;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
a { color: var(--fg); text-decoration: none; }
|
| 56 |
+
a:hover { opacity: 0.7; }
|
| 57 |
+
|
| 58 |
+
/* Header / hero image */
|
| 59 |
+
header {
|
| 60 |
+
max-width: 1440px;
|
| 61 |
+
margin: 0 auto;
|
| 62 |
+
padding: 32px 24px 8px 24px;
|
| 63 |
+
text-align: center;
|
| 64 |
+
}
|
| 65 |
+
.hero-img {
|
| 66 |
+
display: block;
|
| 67 |
+
max-width: 900px;
|
| 68 |
+
width: 100%;
|
| 69 |
+
height: auto;
|
| 70 |
+
margin: 0 auto;
|
| 71 |
+
border-radius: 14px;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
/* Hero stats banner */
|
| 75 |
+
.hero-stats {
|
| 76 |
+
max-width: 1440px;
|
| 77 |
+
margin: 24px auto 0 auto;
|
| 78 |
+
padding: 0 24px;
|
| 79 |
+
display: grid;
|
| 80 |
+
grid-template-columns: repeat(5, 1fr);
|
| 81 |
+
gap: 14px;
|
| 82 |
+
}
|
| 83 |
+
.stat {
|
| 84 |
+
background: var(--card);
|
| 85 |
+
border: 1px solid var(--border);
|
| 86 |
+
border-radius: 16px;
|
| 87 |
+
padding: 18px 14px;
|
| 88 |
+
text-align: center;
|
| 89 |
+
}
|
| 90 |
+
.stat .num {
|
| 91 |
+
display: block;
|
| 92 |
+
font-size: 1.75rem;
|
| 93 |
+
font-weight: 700;
|
| 94 |
+
color: var(--fg);
|
| 95 |
+
letter-spacing: -0.015em;
|
| 96 |
+
line-height: 1.05;
|
| 97 |
+
}
|
| 98 |
+
.stat .num .decimal { font-size: 0.55em; font-weight: 500; opacity: 0.75; margin-left: 1px; }
|
| 99 |
+
.stat .lbl {
|
| 100 |
+
display: block;
|
| 101 |
+
font-size: 0.68rem;
|
| 102 |
+
color: var(--muted);
|
| 103 |
+
text-transform: uppercase;
|
| 104 |
+
letter-spacing: 0.13em;
|
| 105 |
+
margin-top: 8px;
|
| 106 |
+
font-weight: 500;
|
| 107 |
+
}
|
| 108 |
+
.stat .sub {
|
| 109 |
+
display: block;
|
| 110 |
+
font-size: 0.6rem;
|
| 111 |
+
color: var(--muted);
|
| 112 |
+
font-weight: 400;
|
| 113 |
+
letter-spacing: 0.04em;
|
| 114 |
+
margin-top: 4px;
|
| 115 |
+
opacity: 0.65;
|
| 116 |
+
text-transform: none;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
/* Chart sections */
|
| 120 |
+
.charts {
|
| 121 |
+
max-width: 1440px;
|
| 122 |
+
margin: 0 auto;
|
| 123 |
+
display: grid;
|
| 124 |
+
grid-template-columns: 1fr 1fr;
|
| 125 |
+
gap: 24px;
|
| 126 |
+
padding: 24px;
|
| 127 |
+
}
|
| 128 |
+
.chart-card {
|
| 129 |
+
background: var(--card);
|
| 130 |
+
border: 1px solid var(--border);
|
| 131 |
+
border-radius: 20px;
|
| 132 |
+
padding: 24px 20px 16px 20px;
|
| 133 |
+
}
|
| 134 |
+
.chart-card h2 {
|
| 135 |
+
text-align: center;
|
| 136 |
+
margin: 0 0 4px 0;
|
| 137 |
+
font-size: 1.1rem;
|
| 138 |
+
font-weight: 600;
|
| 139 |
+
color: var(--fg);
|
| 140 |
+
letter-spacing: -0.005em;
|
| 141 |
+
}
|
| 142 |
+
.chart-card .subtitle {
|
| 143 |
+
text-align: center;
|
| 144 |
+
margin: 0 0 14px 0;
|
| 145 |
+
font-size: 0.82rem;
|
| 146 |
+
color: var(--muted);
|
| 147 |
+
font-weight: 400;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
/* Donut */
|
| 151 |
+
.donut-wrap {
|
| 152 |
+
position: relative;
|
| 153 |
+
width: 100%;
|
| 154 |
+
max-width: 560px;
|
| 155 |
+
aspect-ratio: 1;
|
| 156 |
+
margin: 0 auto;
|
| 157 |
+
}
|
| 158 |
+
.donut-wrap.small { max-width: 400px; }
|
| 159 |
+
.donut-svg {
|
| 160 |
+
width: 100%;
|
| 161 |
+
height: 100%;
|
| 162 |
+
display: block;
|
| 163 |
+
overflow: visible;
|
| 164 |
+
}
|
| 165 |
+
.donut-slice { cursor: pointer; transition: filter 0.2s ease; }
|
| 166 |
+
.donut-slice:hover { filter: brightness(1.25) drop-shadow(0 0 10px rgba(255,255,255,0.15)); }
|
| 167 |
+
|
| 168 |
+
.donut-center {
|
| 169 |
+
position: absolute;
|
| 170 |
+
inset: 0;
|
| 171 |
+
display: flex;
|
| 172 |
+
flex-direction: column;
|
| 173 |
+
align-items: center;
|
| 174 |
+
justify-content: center;
|
| 175 |
+
pointer-events: none;
|
| 176 |
+
padding: 18%;
|
| 177 |
+
text-align: center;
|
| 178 |
+
}
|
| 179 |
+
.donut-center.small { padding: 22%; }
|
| 180 |
+
.center-item { width: 100%; }
|
| 181 |
+
.center-label {
|
| 182 |
+
font-size: 0.65rem;
|
| 183 |
+
font-weight: 500;
|
| 184 |
+
color: var(--muted);
|
| 185 |
+
letter-spacing: 0.18em;
|
| 186 |
+
text-transform: uppercase;
|
| 187 |
+
display: flex;
|
| 188 |
+
align-items: center;
|
| 189 |
+
justify-content: center;
|
| 190 |
+
gap: 6px;
|
| 191 |
+
}
|
| 192 |
+
.center-label .icon { font-size: 0.85rem; opacity: 0.9; }
|
| 193 |
+
.center-number {
|
| 194 |
+
font-size: clamp(1.8rem, 4.5vw, 2.75rem);
|
| 195 |
+
font-weight: 700;
|
| 196 |
+
color: var(--fg);
|
| 197 |
+
line-height: 1;
|
| 198 |
+
letter-spacing: -0.03em;
|
| 199 |
+
margin: 4px 0;
|
| 200 |
+
}
|
| 201 |
+
.center-number .decimal {
|
| 202 |
+
font-size: 0.55em;
|
| 203 |
+
font-weight: 500;
|
| 204 |
+
color: var(--fg);
|
| 205 |
+
opacity: 0.72;
|
| 206 |
+
margin-left: 1px;
|
| 207 |
+
}
|
| 208 |
+
.center-divider {
|
| 209 |
+
width: 42%;
|
| 210 |
+
border: none;
|
| 211 |
+
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
| 212 |
+
margin: 10px auto;
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
/* Details card */
|
| 216 |
+
.details {
|
| 217 |
+
max-width: 1440px;
|
| 218 |
+
margin: 0 auto 32px auto;
|
| 219 |
+
padding: 0 24px;
|
| 220 |
+
}
|
| 221 |
+
.details-card {
|
| 222 |
+
background: var(--card);
|
| 223 |
+
border: 1px solid var(--border);
|
| 224 |
+
border-radius: 20px;
|
| 225 |
+
padding: 26px 28px;
|
| 226 |
+
min-height: 140px;
|
| 227 |
+
}
|
| 228 |
+
.details-card h3 {
|
| 229 |
+
margin: 0 0 8px 0;
|
| 230 |
+
font-size: 1.35rem;
|
| 231 |
+
color: var(--fg);
|
| 232 |
+
display: flex;
|
| 233 |
+
align-items: center;
|
| 234 |
+
gap: 12px;
|
| 235 |
+
font-weight: 600;
|
| 236 |
+
letter-spacing: -0.01em;
|
| 237 |
+
}
|
| 238 |
+
.details-card h3 .swatch { display: inline-block; width: 14px; height: 14px; border-radius: 50%; }
|
| 239 |
+
.details-card h3 a { color: var(--fg); font-size: 1.05rem; opacity: 0.85; }
|
| 240 |
+
.details-card h3 a:hover { opacity: 1; text-decoration: underline; }
|
| 241 |
+
.details-card .tagline { color: var(--muted); font-size: 0.95rem; margin: 0 0 18px 0; }
|
| 242 |
+
.kv-grid {
|
| 243 |
+
display: grid;
|
| 244 |
+
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
| 245 |
+
gap: 12px 24px;
|
| 246 |
+
}
|
| 247 |
+
.kv .k { color: var(--muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: 4px; font-weight: 500; }
|
| 248 |
+
.kv .v { color: var(--fg); font-size: 0.9rem; }
|
| 249 |
+
.kv .v a { border-bottom: 1px dashed var(--muted); }
|
| 250 |
+
.kv .v strong { font-weight: 600; }
|
| 251 |
+
.schema-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
|
| 252 |
+
.schema-list code {
|
| 253 |
+
background: var(--card-alt);
|
| 254 |
+
color: var(--fg);
|
| 255 |
+
padding: 3px 8px;
|
| 256 |
+
border-radius: 6px;
|
| 257 |
+
font-size: 0.78rem;
|
| 258 |
+
font-family: "SF Mono", Consolas, monospace;
|
| 259 |
+
border: 1px solid var(--border);
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
/* Extras (modality + treemap) */
|
| 263 |
+
.extras {
|
| 264 |
+
max-width: 1440px;
|
| 265 |
+
margin: 8px auto 0 auto;
|
| 266 |
+
padding: 0 24px 24px 24px;
|
| 267 |
+
display: grid;
|
| 268 |
+
grid-template-columns: 1fr 2fr;
|
| 269 |
+
gap: 24px;
|
| 270 |
+
}
|
| 271 |
+
.plot-treemap { width: 100%; height: 900px; position: relative; }
|
| 272 |
+
.plot-treemap svg { width: 100%; height: 100%; display: block; }
|
| 273 |
+
|
| 274 |
+
/* Voronoi */
|
| 275 |
+
.voronoi-cell {
|
| 276 |
+
cursor: pointer;
|
| 277 |
+
transition: filter 0.18s ease, opacity 0.18s ease;
|
| 278 |
+
}
|
| 279 |
+
.voronoi-cell:hover { filter: brightness(1.35) drop-shadow(0 0 8px rgba(255,255,255,0.35)); }
|
| 280 |
+
.voronoi-label {
|
| 281 |
+
font-family: "Geist", "Google Sans", sans-serif;
|
| 282 |
+
font-weight: 600;
|
| 283 |
+
fill: #ffffff;
|
| 284 |
+
pointer-events: none;
|
| 285 |
+
text-anchor: middle;
|
| 286 |
+
user-select: none;
|
| 287 |
+
}
|
| 288 |
+
.voronoi-label .code { font-weight: 400; opacity: 0.8; fill: #ffffff; }
|
| 289 |
+
.voronoi-tooltip {
|
| 290 |
+
position: absolute;
|
| 291 |
+
pointer-events: none;
|
| 292 |
+
background: var(--tooltip-bg);
|
| 293 |
+
border: 1px solid var(--border);
|
| 294 |
+
border-radius: 10px;
|
| 295 |
+
padding: 10px 14px;
|
| 296 |
+
font-size: 0.85rem;
|
| 297 |
+
color: var(--fg);
|
| 298 |
+
box-shadow: 0 12px 32px rgba(0,0,0,0.7);
|
| 299 |
+
opacity: 0;
|
| 300 |
+
transition: opacity 0.12s ease;
|
| 301 |
+
white-space: nowrap;
|
| 302 |
+
z-index: 20;
|
| 303 |
+
font-family: "Geist", sans-serif;
|
| 304 |
+
}
|
| 305 |
+
.voronoi-tooltip .t-name { font-weight: 700; color: var(--fg); font-size: 0.95rem; }
|
| 306 |
+
.voronoi-tooltip .t-code { color: var(--muted); font-size: 0.72rem; margin-left: 4px; }
|
| 307 |
+
.voronoi-tooltip .t-rows { color: var(--fg); font-weight: 600; margin-top: 4px; opacity: 0.9; }
|
| 308 |
+
|
| 309 |
+
/* Donut tooltip (shared style) */
|
| 310 |
+
.donut-tooltip {
|
| 311 |
+
position: fixed;
|
| 312 |
+
pointer-events: none;
|
| 313 |
+
background: var(--tooltip-bg);
|
| 314 |
+
border: 1px solid var(--border);
|
| 315 |
+
border-radius: 10px;
|
| 316 |
+
padding: 10px 14px;
|
| 317 |
+
font-size: 0.85rem;
|
| 318 |
+
color: var(--fg);
|
| 319 |
+
box-shadow: 0 12px 32px rgba(0,0,0,0.7);
|
| 320 |
+
opacity: 0;
|
| 321 |
+
transition: opacity 0.12s ease;
|
| 322 |
+
white-space: nowrap;
|
| 323 |
+
z-index: 50;
|
| 324 |
+
font-family: "Geist", sans-serif;
|
| 325 |
+
}
|
| 326 |
+
.donut-tooltip .t-name { font-weight: 700; font-size: 0.95rem; }
|
| 327 |
+
.donut-tooltip .t-meta { color: var(--muted); font-size: 0.78rem; margin-top: 4px; }
|
| 328 |
+
|
| 329 |
+
footer {
|
| 330 |
+
max-width: 1440px;
|
| 331 |
+
margin: 0 auto 32px auto;
|
| 332 |
+
padding: 0 24px;
|
| 333 |
+
text-align: center;
|
| 334 |
+
color: var(--muted);
|
| 335 |
+
font-size: 0.8rem;
|
| 336 |
+
font-weight: 400;
|
| 337 |
+
}
|
| 338 |
+
footer a { border-bottom: 1px dashed var(--muted); }
|
| 339 |
+
|
| 340 |
+
@media (max-width: 900px) {
|
| 341 |
+
.hero-stats { grid-template-columns: repeat(2, 1fr); }
|
| 342 |
+
.extras { grid-template-columns: 1fr; }
|
| 343 |
+
}
|
| 344 |
+
@media (max-width: 780px) {
|
| 345 |
+
.charts { grid-template-columns: 1fr; }
|
| 346 |
+
}
|
| 347 |
+
</style>
|
| 348 |
+
</head>
|
| 349 |
+
<body>
|
| 350 |
+
|
| 351 |
+
<header>
|
| 352 |
+
<img src="Reubensdataset.png" alt="Reuben's Data Lab" class="hero-img" />
|
| 353 |
+
</header>
|
| 354 |
+
|
| 355 |
+
<section class="hero-stats">
|
| 356 |
+
<div class="stat">
|
| 357 |
+
<span class="num" data-value="12"></span>
|
| 358 |
+
<span class="lbl">Raw datasets</span>
|
| 359 |
+
<span class="sub">in four HF collections</span>
|
| 360 |
+
</div>
|
| 361 |
+
<div class="stat">
|
| 362 |
+
<span class="num" data-value="14.8M"></span>
|
| 363 |
+
<span class="lbl">Total rows</span>
|
| 364 |
+
<span class="sub">every row, every dataset</span>
|
| 365 |
+
</div>
|
| 366 |
+
<div class="stat">
|
| 367 |
+
<span class="num" data-value="130+"></span>
|
| 368 |
+
<span class="lbl">Languages</span>
|
| 369 |
+
<span class="sub">many rarely seen online</span>
|
| 370 |
+
</div>
|
| 371 |
+
<div class="stat">
|
| 372 |
+
<span class="num" data-value="4"></span>
|
| 373 |
+
<span class="lbl">Modalities</span>
|
| 374 |
+
<span class="sub">audio, text, images, code</span>
|
| 375 |
+
</div>
|
| 376 |
+
<div class="stat">
|
| 377 |
+
<span class="num" data-value="17"></span>
|
| 378 |
+
<span class="lbl">Days to build</span>
|
| 379 |
+
<span class="sub">April 8 to April 24, 2026</span>
|
| 380 |
+
</div>
|
| 381 |
+
</section>
|
| 382 |
+
|
| 383 |
+
<section class="charts">
|
| 384 |
+
<div class="chart-card">
|
| 385 |
+
<h2>Raw corpus</h2>
|
| 386 |
+
<div class="subtitle">Every dataset I've created in the <a href="https://huggingface.co/ReubenDataLab/collections" target="_blank" rel="noopener">ReubenDataLab collections</a></div>
|
| 387 |
+
<div class="donut-wrap">
|
| 388 |
+
<svg id="chart-raw" class="donut-svg"></svg>
|
| 389 |
+
<div class="donut-center" id="center-raw"></div>
|
| 390 |
+
</div>
|
| 391 |
+
</div>
|
| 392 |
+
<div class="chart-card">
|
| 393 |
+
<h2>Adaption-remastered</h2>
|
| 394 |
+
<div class="subtitle">Improved datasets after running them through <a href="https://adaptionlabs.ai" target="_blank" rel="noopener">adaptionlabs.ai</a></div>
|
| 395 |
+
<div class="donut-wrap">
|
| 396 |
+
<svg id="chart-adaption" class="donut-svg"></svg>
|
| 397 |
+
<div class="donut-center" id="center-adaption"></div>
|
| 398 |
+
</div>
|
| 399 |
+
</div>
|
| 400 |
+
</section>
|
| 401 |
+
|
| 402 |
+
<div class="details">
|
| 403 |
+
<div id="details-card" class="details-card" style="display: none;"></div>
|
| 404 |
+
</div>
|
| 405 |
+
|
| 406 |
+
<section class="extras">
|
| 407 |
+
<div class="chart-card">
|
| 408 |
+
<h2>Modality split</h2>
|
| 409 |
+
<div class="subtitle">Share of the corpus by data type</div>
|
| 410 |
+
<div class="donut-wrap small">
|
| 411 |
+
<svg id="chart-modality" class="donut-svg"></svg>
|
| 412 |
+
<div class="donut-center small" id="center-modality"></div>
|
| 413 |
+
</div>
|
| 414 |
+
</div>
|
| 415 |
+
<div class="chart-card">
|
| 416 |
+
<h2>Languages across the corpus</h2>
|
| 417 |
+
<div class="subtitle">Every language that appears in any raw dataset, sized (log-scale) by total row count. Hover for exact numbers.</div>
|
| 418 |
+
<div id="chart-treemap" class="plot-treemap">
|
| 419 |
+
<div id="voronoi-tooltip" class="voronoi-tooltip"></div>
|
| 420 |
+
</div>
|
| 421 |
+
</div>
|
| 422 |
+
</section>
|
| 423 |
+
|
| 424 |
+
<div id="donut-tooltip" class="donut-tooltip"></div>
|
| 425 |
+
|
| 426 |
+
<footer>
|
| 427 |
+
Data self-reported from HF dataset pages · Built for the
|
| 428 |
+
<a href="https://www.adaptionlabs.ai/blog/the-uncharted-data-challenge" target="_blank">Uncharted Data Challenge</a>
|
| 429 |
+
· Author <a href="https://huggingface.co/Reubencf" target="_blank">@Reubencf</a>
|
| 430 |
+
</footer>
|
| 431 |
+
|
| 432 |
+
<script src="app.js" defer></script>
|
| 433 |
+
|
| 434 |
+
</body>
|
| 435 |
+
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/d3-voronoi-map.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("d3-polygon"),require("d3-timer"),require("d3-dispatch"),require("d3-weighted-voronoi")):"function"==typeof define&&define.amd?define(["exports","d3-polygon","d3-timer","d3-dispatch","d3-weighted-voronoi"],n):n(t.d3=t.d3||{},t.d3,t.d3,t.d3,t.d3)}(this,function(t,n,e,r,i){"use strict";function o(){this.growthChangesLength=p,this.totalAvailableArea=NaN,this.lastAreaError=NaN,this.lastGrowth=NaN,this.growthChanges=[],this.growthChangeWeights=h(this.growthChangesLength),this.growthChangeWeightsSum=s(this.growthChangeWeights)}function a(t,n){return t>=n?1:-1}function h(t){for(var n=3,e=1,r=1,i=n,o=[],a=0;a<t;a++)o.push(i),i-=e,i<r&&(i=r);return o}function s(t){for(var n=0,e=0;e<t.length;e++)n+=t[e];return n}function g(){function t(t,a,s,l){var c,f,p=!1;for(r!==l.clip()&&(r=l.clip(),i=l.extent(),p=!0),p&&e(),c=o+g*l.prng()(),f=h+u*l.prng()();!n.polygonContains(r,[c,f]);)c=o+g*l.prng()(),f=h+u*l.prng()();return[c,f]}function e(){o=i[0][0],a=i[1][0],h=i[0][1],s=i[1][1],g=a-o,u=s-h}var r,i,o,a,h,s,g,u;return t}function u(){function t(t,n,r,i){var h=!1;return o!==i.clip()&&(o=i.clip(),h|=!0),a!==r&&(a=r,h|=!0),h&&e(),[s[0]+Math.cos(l+n*u)*g+.001*(i.prng()()-.5),s[1]+Math.sin(l+n*u)*g+.001*(i.prng()()-.5)]}function e(){s=n.polygonCentroid(o),g=r(s,o)/2,h=a.length,u=2*Math.PI/h}function r(t,n){for(var e,r=1/0,o=0,a=n[n.length-1],h=n[o];o<n.length;)e=i(t,a,h),e<r&&(r=e),o++,a=h,h=n[o];return r}function i(t,n,e){var r=t[0],i=t[1],o=n[0],a=n[1],h=e[0],s=e[1],g=r-o,u=i-a,l=h-o,c=s-a,f=g*l+u*c,p=l*l+c*c,w=-1;0!=p&&(w=f/p);var d,v;w<0?(d=o,v=a):w>1?(d=h,v=s):(d=o+w*l,v=a+w*c);var C=r-d,y=i-v;return Math.sqrt(C*C+y*y)}var o,a,h,s,g,u,l=0;return t.startAngle=function(n){return arguments.length?(l=n,t):l},t}function l(){function t(t,n,o,a){var s=!1;return r!==a.clip()&&(r=a.clip(),s|=!0),i!==o&&(i=o,s|=!0),s&&e(),h}function e(){o=i.length,a=n.polygonArea(r),h=a/o/2}var r,i,o,a,h;return t}function c(t){this.message=t,this.stack=(new Error).stack}function f(t){function a(t){return Math.pow(t,2)}function h(t,n){return a(n.x-t.x)+a(n.y-t.y)}function s(){u(),U.call("tick",P),k&&(T.stop(),U.call("end",P))}function u(){k||(Q&&f(),W=d(W,K.ratio()),b++,E=A(W),K.add(E),L=E<N,k=L||b>=V)}function f(){m(),M=t.length,x=Math.abs(n.polygonArea(J.clip())),N=z*x,K.clear().totalArea(x),b=0,L=!1,W=p(t,P),k=!1,Q=!1}function p(t,n){var e,r,i=t.reduce(function(t,n){return Math.max(t,R(n))},-(1/0)),o=i*_;return e=t.map(function(t,e,r){return{index:e,weight:Math.max(R(t),o),initialPosition:B(t,e,r,n),initialWeight:H(t,e,r,n),originalData:t}}),r=w(e,n),Y(r),J(r)}function w(t,e){var r,i=t.reduce(function(t,n){return t+=n.weight},0);return t.map(function(t,o,a){return r=t.initialPosition,n.polygonContains(J.clip(),r)||(r=q(t,o,a,e)),{index:t.index,targetedArea:x*t.weight/i,data:t,x:r[0],y:r[1],weight:t.initialWeight}})}function d(t,n){var e;if(v(t,n),e=t.map(function(t){return t.site.originalObject}),t=J(e),t.length<M)throw new c("at least 1 site has no area, which is not supposed to arise");if(C(t,n),e=t.map(function(t){return t.site.originalObject}),t=J(e),t.length<M)throw new c("at least 1 site has no area, which is not supposed to arise");return t}function v(t,e){var r,i,o,a,h,s,g,u=[],l=.5;r=l*e,i=1-r;for(var c=0;c<M;c++)o=t[c],a=o.site.originalObject,h=n.polygonCentroid(o),s=h[0]-a.x,g=h[1]-a.y,s*=i,g*=i,a.x+=s,a.y+=g,u.push(a);Y(u)}function C(t,e){var r,i,o,a,h,s,g=[],u=.1;r=u*e;for(var l=0;l<M;l++)i=t[l],o=i.site.originalObject,a=n.polygonArea(i),h=o.targetedArea/a,h=Math.max(h,1-u+r),h=Math.min(h,1+u-r),s=o.weight*h,s=Math.max(s,F),o.weight=s,g.push(o);Y(g)}function y(t){var n,e,r,i,o,a,s,g=0;do{if(g>X)throw new c("handleOverweighted1 is looping too much");n=!1;for(var u=0;u<M;u++){e=t[u];for(var l=u+1;l<M;l++)if(r=t[l],e.weight>r.weight?(i=e,o=r):(i=r,o=e),a=h(e,r),a<i.weight-o.weight){s=i.weight-o.weight-a,o.weight+=s+F,n=!0,g++;break}if(n)break}}while(n)}function A(t){for(var e,r,i,o=0,a=0;a<M;a++)e=t[a],r=e.site.originalObject,i=n.polygonArea(e),o+=Math.abs(r.targetedArea-i);return o}function m(){Y=y}var M,x,N,b,W,E,L,k,P,j=.01,O=50,G=.01,I=Math.random,q=g(),S=l(),F=(g(),1e-10),R=function(t){return t.weight},z=j,V=O,_=G,D=I,B=q,H=S,J=i.weightedVoronoi(),K=new o,Q=!0,T=e.timer(s),U=r.dispatch("tick","end");const X=1e3;var Y;return P={tick:u,restart:function(){return T.restart(s),P},stop:function(){return T.stop(),P},weight:function(t){return arguments.length?(R=t,Q=!0,P):R},convergenceRatio:function(t){return arguments.length?(z=t,Q=!0,P):z},maxIterationCount:function(t){return arguments.length?(V=t,P):V},minWeightRatio:function(t){return arguments.length?(_=t,Q=!0,P):_},clip:function(t){return arguments.length?(J.clip(t),Q=!0,P):J.clip()},extent:function(t){return arguments.length?(J.extent(t),Q=!0,P):J.extent()},size:function(t){return arguments.length?(J.size(t),Q=!0,P):J.size()},prng:function(t){return arguments.length?(D=t,Q=!0,P):D},initialPosition:function(t){return arguments.length?(B=t,Q=!0,P):B},initialWeight:function(t){return arguments.length?(H=t,Q=!0,P):H},state:function(){return Q&&f(),{ended:k,iterationCount:b,convergenceRatio:E/x,polygons:W}},on:function(t,n){return 1===arguments.length?U.on(t):(U.on(t,n),P)}}}var p=10;o.prototype.reset=function(){return this.lastAreaError=NaN,this.lastGrowth=NaN,this.growthChanges=[],this.growthChangesLength=p,this.growthChangeWeights=h(this.growthChangesLength),this.growthChangeWeightsSum=s(this.growthChangeWeights),this.totalAvailableArea=NaN,this},o.prototype.clear=function(){return this.lastAreaError=NaN,this.lastGrowth=NaN,this.growthChanges=[],this},o.prototype.length=function(t){return arguments.length?(parseInt(t)>0?(this.growthChangesLength=Math.floor(parseInt(t)),this.growthChangeWeights=h(this.growthChangesLength),this.growthChangeWeightsSum=s(this.growthChangeWeights)):console.warn("FlickeringMitigation.length() accepts only positive integers; unable to handle "+t),this):this.growthChangesLength},o.prototype.totalArea=function(t){return arguments.length?(parseFloat(t)>0?this.totalAvailableArea=parseFloat(t):console.warn("FlickeringMitigation.totalArea() accepts only positive numbers; unable to handle "+t),this):this.totalAvailableArea},o.prototype.add=function(t){var n,e;return n=this.lastAreaError,this.lastAreaError=t,isNaN(n)||(e=this.lastGrowth,this.lastGrowth=a(this.lastAreaError,n)),isNaN(e)||this.growthChanges.unshift(this.lastGrowth!=e),this.growthChanges.length>this.growthChangesLength&&this.growthChanges.pop(),this},o.prototype.ratio=function(){var t,n=0;if(this.growthChanges.length<this.growthChangesLength)return 0;if(this.lastAreaError>this.totalAvailableArea/10)return 0;for(var e=0;e<this.growthChangesLength;e++)this.growthChanges[e]&&(n+=this.growthChangeWeights[e]);return t=n/this.growthChangeWeightsSum},c.prototype.name="d3VoronoiMapError",c.prototype=new Error,t.voronoiMapSimulation=f,t.voronoiMapInitialPositionRandom=g,t.voronoiMapInitialPositionPie=u,t.d3VoronoiMapError=c,Object.defineProperty(t,"__esModule",{value:!0})});
|
vendor/d3-voronoi-treemap.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-voronoi-map")):"function"==typeof define&&define.amd?define(["exports","d3-voronoi-map"],t):t(n.d3=n.d3||{},n.d3)}(this,function(n,t){"use strict";function e(){function n(n){e(a,n)}function e(n,i){var o;if(i.polygon=n,0!=i.height){o=t.voronoiMapSimulation(i.children).clip(n).weight(function(n){return n.value}).convergenceRatio(l).maxIterationCount(p).minWeightRatio(g).prng(d).stop();for(var r=o.state();!r.ended;)o.tick(),r=o.state();r.polygons.forEach(function(n){e(n,n.site.originalObject.data.originalData)})}}var i=.01,o=50,r=.01,u=Math.random,a=[[0,0],[0,1],[1,1],[1,0]],c=[[0,0],[1,1]],f=[1,1],l=i,p=o,g=r,d=u,h=[{weight:1},{weight:1}],s=t.voronoiMapSimulation(h).stop();return n.convergenceRatio=function(t){return arguments.length?(l=t,n):l},n.maxIterationCount=function(t){return arguments.length?(p=t,n):p},n.minWeightRatio=function(t){return arguments.length?(g=t,n):g},n.clip=function(t){return arguments.length?(s.clip(t),a=s.clip(),c=s.extent(),f=s.size(),n):a},n.extent=function(t){return arguments.length?(s.extent(t),a=s.clip(),c=s.extent(),f=s.size(),n):c},n.size=function(t){return arguments.length?(s.size(t),a=s.clip(),c=s.extent(),f=s.size(),n):f},n.prng=function(t){return arguments.length?(d=t,n):d},n}n.voronoiTreemap=e,Object.defineProperty(n,"__esModule",{value:!0})});
|
vendor/d3-weighted-voronoi.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports,require("d3-array"),require("d3-polygon")):"function"==typeof define&&define.amd?define(["exports","d3-array","d3-polygon"],i):i(t.d3=t.d3||{},t.d3,t.d3)}(this,function(t,i,n){"use strict";function e(t){return t<=C&&t>=-C}function s(t,i){return t.x*i.x+t.y*i.y+t.z*i.z}function o(t,i){return e(t.x*i.y-t.y*i.x)&&e(t.y*i.z-t.z*i.y)&&e(t.z*i.x-t.x*i.z)}function r(t){var i,n,e,s,o,r,u,c;if(e=t[t.length-2],s=t[t.length-1],o=t[0],r=h(e,s),u=h(s,o),n=l(r,u),i=Math.sign(n),e=s,s=o,o=t[1],r=u,u=h(s,o),n=l(r,u),Math.sign(n)===i){for(c=2;c<t.length-1;c++)if(e=s,s=o,o=t[c],r=u,u=h(s,o),n=l(r,u),Math.sign(n)!==i)return;return i}}function h(t,i){return[i[0]-t[0],i[1]-t[1]]}function l(t,i){return t[0]*i[1]-t[1]*i[0]}function u(t,i){this.face=t,this.vert=i,this.nextf=null,this.prevf=null,this.nextv=null,this.prevv=null}function c(t){this.forFace=t,this.head=null}function a(t,i,n,e,s,o){this.x=t,this.y=i,this.weight=C,this.index=0,this.conflicts=new c((!1)),this.neighbours=null,this.nonClippedPolygon=null,this.polygon=null,this.originalObject=null,this.isDummy=!1,void 0!==s&&(this.originalObject=s),void 0!=o&&(this.isDummy=o),null!=e&&(this.weight=e),null!=n?this.z=n:this.z=this.projectZ(this.x,this.y,this.weight)}function f(t){var i=t.verts[0],n=t.verts[1],e=t.verts[2];this.a=i.y*(n.z-e.z)+n.y*(e.z-i.z)+e.y*(i.z-n.z),this.b=i.z*(n.x-e.x)+n.z*(e.x-i.x)+e.z*(i.x-n.x),this.c=i.x*(n.y-e.y)+n.x*(e.y-i.y)+e.x*(i.y-n.y),this.d=-1*(i.x*(n.y*e.z-e.y*n.z)+n.x*(e.y*i.z-i.y*e.z)+e.x*(i.y*n.z-n.y*i.z))}function p(t,i){this.x=t,this.y=i}function d(t,i,n){this.x=t,this.y=i,this.z=n}function v(t,i,n){this.next=null,this.prev=null,this.twin=null,this.orig=t,this.dest=i,this.iFace=n}function g(t){this.message=t,this.stack=(new Error).stack}function y(t,i,n,e){this.conflicts=new c((!0)),this.verts=[t,i,n],this.marked=!1;var s=t.subtract(i).crossproduct(i.subtract(n));this.normal=new d((-s.x),(-s.y),(-s.z)),this.normal.normalize(),this.createEdges(),this.dualPoint=null,void 0!=e&&this.orient(e)}function x(){this.points=[],this.facets=[],this.created=[],this.horizon=[],this.visible=[],this.current=0}function w(t,i){for(var n,e,s,o,r,h,l,u=b(i),c=-1,a=t.length-b(t),f=t[a-1];++c<a;){for(n=i.slice(),i.length=0,o=t[c],r=n[(s=n.length-u)-1],e=-1;++e<s;)h=n[e],z(h,f,o)?(z(r,f,o)||(l=m(r,h,f,o),isFinite(l[0])&&i.push(l)),i.push(h)):z(r,f,o)&&(l=m(r,h,f,o),isFinite(l[0])&&i.push(l)),r=h;u&&i.push(i[0]),f=o}return i}function z(t,i,n){return(n[0]-i[0])*(t[1]-i[1])<(n[1]-i[1])*(t[0]-i[0])}function m(t,i,n,e){var s=t[0],o=n[0],r=i[0]-s,h=e[0]-o,l=t[1],u=n[1],c=i[1]-l,a=e[1]-u,f=(h*(l-u)-a*(s-o))/(a*r-h*c);return[s+f*r,l+f*c]}function b(t){var i=t[0],n=t[t.length-1];return!(i[0]-n[0]||i[1]-n[1])}function k(t){var i=[],n=t,e=t.dest,s=e.originalObject,o=[];do{n=n.twin.prev;var r=n.orig.originalObject;r.isDummy||o.push(r);var h=n.iFace;h.isVisibleFromBelow()&&i.push(h)}while(n!==t);return s.neighbours=o,i}function F(t,i,e){var s=new x;s.clear(),s.init(i,t);for(var o=s.compute(t),r=[],h=[],l=o.length,u=0;u<l;u++){var c=o[u];if(c.isVisibleFromBelow())for(var a=0;a<3;a++){var f=c.edges[a],p=f.dest,d=p.originalObject;if(!h[p.index]){if(h[p.index]=!0,d.isDummy)continue;for(var v=k(f),g=[],y=null,z=null,m=1,b=1,F=0;F<v.length;F++){var P=v[F].getDualPoint(),E=P.x,j=P.y;null!==y&&(m=y-E,b=z-j,m<0&&(m=-m),b<0&&(b=-b)),(m>C||b>C)&&(g.push([E,j]),y=E,z=j)}if(d.nonClippedPolygon=g.reverse(),!d.isDummy&&n.polygonLength(d.nonClippedPolygon)>0){var q=w(e,d.nonClippedPolygon);d.polygon=q,q.site=d,q.length>0&&r.push(q)}}}}return r}function P(){function t(t){var i;return i=t.map(function(t){return new a(s(t),o(t),null,h(t),t,(!1))}),F(i,e(),l)}function e(){var t,i,n,e,s,o,r,h,l,c,f=[],p=[];t=u[0][0],i=u[1][0],n=u[0][1],e=u[1][1],s=i-t,o=e-n,r=t-s,h=i+s,l=n-o,c=e+o,f[0]=[r,l],f[1]=[r,c],f[2]=[h,c],f[3]=[h,l];for(var d=0;d<4;d++)p.push(new a(f[d][0],f[d][1],null,C,new a(f[d][0],f[d][1],null,C,null,(!0)),(!0)));return p}var s=function(t){return t.x},o=function(t){return t.y},h=function(t){return t.weight},l=[[0,0],[0,1],[1,1],[1,0]],u=[[0,0],[1,1]],c=[1,1];return t.x=function(i){return arguments.length?(s=i,t):s},t.y=function(i){return arguments.length?(o=i,t):o},t.weight=function(i){return arguments.length?(h=i,t):h},t.clip=function(e){var s,o,h;return arguments.length?(o=i.extent(e.map(function(t){return t[0]})),h=i.extent(e.map(function(t){return t[1]})),s=r(e),l=void 0===s?n.polygonHull(e):1===s?e.reverse():e,u=[[o[0],h[0]],[o[1],h[1]]],c=[o[1]-o[0],h[1]-h[0]],t):l},t.extent=function(i){return arguments.length?(l=[i[0],[i[0][0],i[1][1]],i[1],[i[1][0],i[0][1]]],u=i,c=[i[1][0]-i[0][0],i[1][1]-i[0][1]],t):u},t.size=function(i){return arguments.length?(l=[[0,0],[0,i[1]],[i[0],i[1]],[i[0],0]],u=[[0,0],i],c=i,t):c},t}var C=1e-10;c.prototype.add=function(t){null===this.head?this.head=t:this.forFace?(this.head.prevv=t,t.nextv=this.head,this.head=t):(this.head.prevf=t,t.nextf=this.head,this.head=t)},c.prototype.isEmpty=function(){return null===this.head},c.prototype.fill=function(t){if(!this.forFace){var i=this.head;do t.push(i.face),i.face.marked=!0,i=i.nextf;while(null!==i)}},c.prototype.removeAll=function(){if(this.forFace){var t=this.head;do null===t.prevf?null===t.nextf?t.vert.conflicts.head=null:(t.nextf.prevf=null,t.vert.conflicts.head=t.nextf):(null!=t.nextf&&(t.nextf.prevf=t.prevf),t.prevf.nextf=t.nextf),t=t.nextv,null!=t&&(t.prevv=null);while(null!=t)}else{var t=this.head;do null==t.prevv?null==t.nextv?t.face.conflicts.head=null:(t.nextv.prevv=null,t.face.conflicts.head=t.nextv):(null!=t.nextv&&(t.nextv.prevv=t.prevv),t.prevv.nextv=t.nextv),t=t.nextf,null!=t&&(t.prevf=null);while(null!=t)}},c.prototype.getVertices=function(){for(var t=[],i=this.head;null!==i;)t.push(i.vert),i=i.nextv;return t},a.prototype.projectZ=function(t,i,n){return t*t+i*i-n},a.prototype.setWeight=function(t){this.weight=t,this.z=this.projectZ(this.x,this.y,this.weight)},a.prototype.subtract=function(t){return new a(t.x-this.x,t.y-this.y,t.z-this.z)},a.prototype.crossproduct=function(t){return new a(this.y*t.z-this.z*t.y,this.z*t.x-this.x*t.z,this.x*t.y-this.y*t.x)},a.prototype.equals=function(t){return this.x===t.x&&this.y===t.y&&this.z===t.z},f.prototype.getNormZPlane=function(){return[-1*(this.a/this.c),-1*(this.b/this.c),-1*(this.d/this.c)]},f.prototype.getDualPointMappedToPlane=function(){var t=this.getNormZPlane(),i=new p(t[0]/2,t[1]/2);return i},d.prototype.negate=function(){this.x*=-1,this.y*=-1,this.z*=-1},d.prototype.normalize=function(){var t=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);t>0&&(this.x/=t,this.y/=t,this.z/=t)},v.prototype.isHorizon=function(){return null!==this.twin&&!this.iFace.marked&&this.twin.iFace.marked},v.prototype.findHorizon=function(t){if(this.isHorizon()){if(t.length>0&&this===t[0])return;t.push(this),this.next.findHorizon(t)}else null!==this.twin&&this.twin.next.findHorizon(t)},v.prototype.isEqual=function(t,i){return this.orig.equals(t)&&this.dest.equals(i)||this.orig.equals(i)&&this.dest.equals(t)},g.prototype.name="d3WeightedVoronoiError",g.prototype=new Error,y.prototype.getDualPoint=function(){if(null==this.dualPoint){var t=new f(this);this.dualPoint=t.getDualPointMappedToPlane()}return this.dualPoint},y.prototype.isVisibleFromBelow=function(){return this.normal.z<-1.4259414393190911e-9},y.prototype.createEdges=function(){this.edges=[],this.edges[0]=new v(this.verts[0],this.verts[1],this),this.edges[1]=new v(this.verts[1],this.verts[2],this),this.edges[2]=new v(this.verts[2],this.verts[0],this),this.edges[0].next=this.edges[1],this.edges[0].prev=this.edges[2],this.edges[1].next=this.edges[2],this.edges[1].prev=this.edges[0],this.edges[2].next=this.edges[0],this.edges[2].prev=this.edges[1]},y.prototype.orient=function(t){if(!(s(this.normal,t)<s(this.normal,this.verts[0]))){var i=this.verts[1];this.verts[1]=this.verts[2],this.verts[2]=i,this.normal.negate(),this.createEdges()}},y.prototype.getEdge=function(t,i){for(var n=0;n<3;n++)if(this.edges[n].isEqual(t,i))return this.edges[n];return null},y.prototype.link=function(t,i,n){if(t instanceof y){var e=t.getEdge(i,n);if(null===e)throw new g("when linking, twin is null");var s=this.getEdge(i,n);if(null===s)throw new g("when linking, twin is null");e.twin=s,s.twin=e}else{var e=t,s=this.getEdge(e.orig,e.dest);e.twin=s,s.twin=e}},y.prototype.conflict=function(t){return s(this.normal,t)>s(this.normal,this.verts[0])+C},y.prototype.getHorizon=function(){for(var t=0;t<3;t++)if(null!==this.edges[t].twin&&this.edges[t].twin.isHorizon())return this.edges[t];return null},y.prototype.removeConflict=function(){this.conflicts.removeAll()},x.prototype.init=function(t,i){this.points=[];for(var n=0;n<i.length;n++)this.points[n]=new a(i[n].x,i[n].y,i[n].z,null,i[n],(!1));this.points=this.points.concat(t)},x.prototype.permutate=function(){for(var t=this.points.length,i=t-1;i>0;i--){var n=Math.floor(Math.random()*i),e=this.points[n];e.index=i;var s=this.points[i];s.index=n,this.points.splice(n,1,s),this.points.splice(i,1,e)}},x.prototype.prep=function(){if(this.points.length<=3)throw new g("Less than 4 points");for(var t=0;t<this.points.length;t++)this.points[t].index=t;var i,n,r,h,l,u,c,a;i=this.points[0],n=this.points[1],r=h=null;for(var t=2;t<this.points.length;t++)if(!o(i,this.points[t])||!o(n,this.points[t])){r=this.points[t],r.index=2,this.points[2].index=t,this.points.splice(t,1,this.points[2]),this.points.splice(2,1,r);break}if(null===r)throw new g("Not enough non-planar Points (v2 is null)");a=new y(i,n,r);for(var t=3;t<this.points.length;t++)if(!e(s(a.normal,a.verts[0])-s(a.normal,this.points[t]))){h=this.points[t],h.index=3,this.points[3].index=t,this.points.splice(t,1,this.points[3]),this.points.splice(3,1,h);break}if(null===h)throw new g("Not enough non-planar Points (v3 is null)");a.orient(h),l=new y(i,r,h,n),u=new y(i,n,h,r),c=new y(n,r,h,i),this.addFacet(a),this.addFacet(l),this.addFacet(u),this.addFacet(c),a.link(l,i,r),a.link(u,i,n),a.link(c,n,r),l.link(u,i,h),l.link(c,r,h),u.link(c,h,n),this.current=4;for(var f,t=this.current;t<this.points.length;t++)f=this.points[t],a.conflict(f)&&this.addConflict(a,f),l.conflict(f)&&this.addConflict(l,f),u.conflict(f)&&this.addConflict(u,f),c.conflict(f)&&this.addConflict(c,f)},x.prototype.addConflicts=function(t,i,n){var e,s,o,r,h=t.conflicts.getVertices(),l=i.conflicts.getVertices(),u=[];for(o=r=0;o<h.length||r<l.length;)o<h.length&&r<l.length?(e=h[o],s=l[r],e.index===s.index?(u.push(e),o++,r++):e.index>s.index?(u.push(e),o++):(u.push(s),r++)):o<h.length?u.push(h[o++]):u.push(l[r++]);for(var o=u.length-1;o>=0;o--)e=u[o],n.conflict(e)&&this.addConflict(n,e)},x.prototype.addConflict=function(t,i){var n=new u(t,i);t.conflicts.add(n),i.conflicts.add(n)},x.prototype.removeConflict=function(t){t.removeConflict();var i=t.index;if(t.index=-1,i===this.facets.length-1)return void this.facets.splice(this.facets.length-1,1);if(!(i>=this.facets.length||i<0)){var n=this.facets.splice(this.facets.length-1,1);n[0].index=i,this.facets.splice(i,1,n[0])}},x.prototype.addFacet=function(t){t.index=this.facets.length,this.facets.push(t)},x.prototype.compute=function(){for(this.prep();this.current<this.points.length;){var t=this.points[this.current];if(t.conflicts.isEmpty())this.current++;else{this.created=[],this.horizon=[],this.visible=[],t.conflicts.fill(this.visible);for(var i,n=0;n<this.visible.length;n++)if(i=this.visible[n].getHorizon(),null!==i){i.findHorizon(this.horizon);break}for(var e=null,s=null,o=0;o<this.horizon.length;o++){var r=this.horizon[o],h=new y(t,r.orig,r.dest,r.twin.next.dest);h.conflicts=new c((!0)),this.addFacet(h),this.created.push(h),this.addConflicts(r.iFace,r.twin.iFace,h),h.link(r),null!==e&&h.link(e,t,r.orig),e=h,null===s&&(s=h)}if(null!==s&&null!==e&&e.link(s,t,this.horizon[0].orig),0!=this.created.length){for(var l=0;l<this.visible.length;l++)this.removeConflict(this.visible[l]);this.current++,this.created=[]}}}return this.facets},x.prototype.clear=function(){this.points=[],this.facets=[],this.created=[],this.horizon=[],this.visible=[],this.current=0},t.weightedVoronoi=P,t.d3WeightedVoronoiError=g,Object.defineProperty(t,"__esModule",{value:!0})});
|
vendor/d3.min.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
vendor/gsap.min.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*!
|
| 2 |
+
* GSAP 3.12.5
|
| 3 |
+
* https://gsap.com
|
| 4 |
+
*
|
| 5 |
+
* @license Copyright 2024, GreenSock. All rights reserved.
|
| 6 |
+
* Subject to the terms at https://gsap.com/standard-license or for Club GSAP members, the agreement issued with that membership.
|
| 7 |
+
* @author: Jack Doyle, jack@greensock.com
|
| 8 |
+
*/
|
| 9 |
+
|
| 10 |
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).window=t.window||{})}(this,function(e){"use strict";function _inheritsLoose(t,e){t.prototype=Object.create(e.prototype),(t.prototype.constructor=t).__proto__=e}function _assertThisInitialized(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function r(t){return"string"==typeof t}function s(t){return"function"==typeof t}function t(t){return"number"==typeof t}function u(t){return void 0===t}function v(t){return"object"==typeof t}function w(t){return!1!==t}function x(){return"undefined"!=typeof window}function y(t){return s(t)||r(t)}function P(t){return(i=yt(t,ot))&&ze}function Q(t,e){return console.warn("Invalid property",t,"set to",e,"Missing plugin? gsap.registerPlugin()")}function R(t,e){return!e&&console.warn(t)}function S(t,e){return t&&(ot[t]=e)&&i&&(i[t]=e)||ot}function T(){return 0}function ea(t){var e,r,i=t[0];if(v(i)||s(i)||(t=[t]),!(e=(i._gsap||{}).harness)){for(r=gt.length;r--&&!gt[r].targetTest(i););e=gt[r]}for(r=t.length;r--;)t[r]&&(t[r]._gsap||(t[r]._gsap=new Vt(t[r],e)))||t.splice(r,1);return t}function fa(t){return t._gsap||ea(Mt(t))[0]._gsap}function ga(t,e,r){return(r=t[e])&&s(r)?t[e]():u(r)&&t.getAttribute&&t.getAttribute(e)||r}function ha(t,e){return(t=t.split(",")).forEach(e)||t}function ia(t){return Math.round(1e5*t)/1e5||0}function ja(t){return Math.round(1e7*t)/1e7||0}function ka(t,e){var r=e.charAt(0),i=parseFloat(e.substr(2));return t=parseFloat(t),"+"===r?t+i:"-"===r?t-i:"*"===r?t*i:t/i}function la(t,e){for(var r=e.length,i=0;t.indexOf(e[i])<0&&++i<r;);return i<r}function ma(){var t,e,r=dt.length,i=dt.slice(0);for(ct={},t=dt.length=0;t<r;t++)(e=i[t])&&e._lazy&&(e.render(e._lazy[0],e._lazy[1],!0)._lazy=0)}function na(t,e,r,i){dt.length&&!L&&ma(),t.render(e,r,i||L&&e<0&&(t._initted||t._startAt)),dt.length&&!L&&ma()}function oa(t){var e=parseFloat(t);return(e||0===e)&&(t+"").match(at).length<2?e:r(t)?t.trim():t}function pa(t){return t}function qa(t,e){for(var r in e)r in t||(t[r]=e[r]);return t}function ta(t,e){for(var r in e)"__proto__"!==r&&"constructor"!==r&&"prototype"!==r&&(t[r]=v(e[r])?ta(t[r]||(t[r]={}),e[r]):e[r]);return t}function ua(t,e){var r,i={};for(r in t)r in e||(i[r]=t[r]);return i}function va(t){var e=t.parent||I,r=t.keyframes?function _setKeyframeDefaults(i){return function(t,e){for(var r in e)r in t||"duration"===r&&i||"ease"===r||(t[r]=e[r])}}(Z(t.keyframes)):qa;if(w(t.inherit))for(;e;)r(t,e.vars.defaults),e=e.parent||e._dp;return t}function xa(t,e,r,i,n){void 0===r&&(r="_first"),void 0===i&&(i="_last");var a,s=t[i];if(n)for(a=e[n];s&&s[n]>a;)s=s._prev;return s?(e._next=s._next,s._next=e):(e._next=t[r],t[r]=e),e._next?e._next._prev=e:t[i]=e,e._prev=s,e.parent=e._dp=t,e}function ya(t,e,r,i){void 0===r&&(r="_first"),void 0===i&&(i="_last");var n=e._prev,a=e._next;n?n._next=a:t[r]===e&&(t[r]=a),a?a._prev=n:t[i]===e&&(t[i]=n),e._next=e._prev=e.parent=null}function za(t,e){t.parent&&(!e||t.parent.autoRemoveChildren)&&t.parent.remove&&t.parent.remove(t),t._act=0}function Aa(t,e){if(t&&(!e||e._end>t._dur||e._start<0))for(var r=t;r;)r._dirty=1,r=r.parent;return t}function Ca(t,e,r,i){return t._startAt&&(L?t._startAt.revert(ht):t.vars.immediateRender&&!t.vars.autoRevert||t._startAt.render(e,!0,i))}function Ea(t){return t._repeat?Tt(t._tTime,t=t.duration()+t._rDelay)*t:0}function Ga(t,e){return(t-e._start)*e._ts+(0<=e._ts?0:e._dirty?e.totalDuration():e._tDur)}function Ha(t){return t._end=ja(t._start+(t._tDur/Math.abs(t._ts||t._rts||X)||0))}function Ia(t,e){var r=t._dp;return r&&r.smoothChildTiming&&t._ts&&(t._start=ja(r._time-(0<t._ts?e/t._ts:((t._dirty?t.totalDuration():t._tDur)-e)/-t._ts)),Ha(t),r._dirty||Aa(r,t)),t}function Ja(t,e){var r;if((e._time||!e._dur&&e._initted||e._start<t._time&&(e._dur||!e.add))&&(r=Ga(t.rawTime(),e),(!e._dur||Ot(0,e.totalDuration(),r)-e._tTime>X)&&e.render(r,!0)),Aa(t,e)._dp&&t._initted&&t._time>=t._dur&&t._ts){if(t._dur<t.duration())for(r=t;r._dp;)0<=r.rawTime()&&r.totalTime(r._tTime),r=r._dp;t._zTime=-X}}function Ka(e,r,i,n){return r.parent&&za(r),r._start=ja((t(i)?i:i||e!==I?xt(e,i,r):e._time)+r._delay),r._end=ja(r._start+(r.totalDuration()/Math.abs(r.timeScale())||0)),xa(e,r,"_first","_last",e._sort?"_start":0),bt(r)||(e._recent=r),n||Ja(e,r),e._ts<0&&Ia(e,e._tTime),e}function La(t,e){return(ot.ScrollTrigger||Q("scrollTrigger",e))&&ot.ScrollTrigger.create(e,t)}function Ma(t,e,r,i,n){return Qt(t,e,n),t._initted?!r&&t._pt&&!L&&(t._dur&&!1!==t.vars.lazy||!t._dur&&t.vars.lazy)&&f!==Rt.frame?(dt.push(t),t._lazy=[n,i],1):void 0:1}function Ra(t,e,r,i){var n=t._repeat,a=ja(e)||0,s=t._tTime/t._tDur;return s&&!i&&(t._time*=a/t._dur),t._dur=a,t._tDur=n?n<0?1e10:ja(a*(n+1)+t._rDelay*n):a,0<s&&!i&&Ia(t,t._tTime=t._tDur*s),t.parent&&Ha(t),r||Aa(t.parent,t),t}function Sa(t){return t instanceof Xt?Aa(t):Ra(t,t._dur)}function Va(e,r,i){var n,a,s=t(r[1]),o=(s?2:1)+(e<2?0:1),u=r[o];if(s&&(u.duration=r[1]),u.parent=i,e){for(n=u,a=i;a&&!("immediateRender"in n);)n=a.vars.defaults||{},a=w(a.vars.inherit)&&a.parent;u.immediateRender=w(n.immediateRender),e<2?u.runBackwards=1:u.startAt=r[o-1]}return new $t(r[0],u,r[1+o])}function Wa(t,e){return t||0===t?e(t):e}function Ya(t,e){return r(t)&&(e=st.exec(t))?e[1]:""}function _a(t,e){return t&&v(t)&&"length"in t&&(!e&&!t.length||t.length-1 in t&&v(t[0]))&&!t.nodeType&&t!==h}function cb(r){return r=Mt(r)[0]||R("Invalid scope")||{},function(t){var e=r.current||r.nativeElement||r;return Mt(t,e.querySelectorAll?e:e===r?R("Invalid scope")||a.createElement("div"):r)}}function db(t){return t.sort(function(){return.5-Math.random()})}function eb(t){if(s(t))return t;var p=v(t)?t:{each:t},_=jt(p.ease),m=p.from||0,g=parseFloat(p.base)||0,y={},e=0<m&&m<1,T=isNaN(m)||e,b=p.axis,w=m,x=m;return r(m)?w=x={center:.5,edges:.5,end:1}[m]||0:!e&&T&&(w=m[0],x=m[1]),function(t,e,r){var i,n,a,s,o,u,h,l,f,d=(r||p).length,c=y[d];if(!c){if(!(f="auto"===p.grid?0:(p.grid||[1,U])[1])){for(h=-U;h<(h=r[f++].getBoundingClientRect().left)&&f<d;);f<d&&f--}for(c=y[d]=[],i=T?Math.min(f,d)*w-.5:m%f,n=f===U?0:T?d*x/f-.5:m/f|0,l=U,u=h=0;u<d;u++)a=u%f-i,s=n-(u/f|0),c[u]=o=b?Math.abs("y"===b?s:a):K(a*a+s*s),h<o&&(h=o),o<l&&(l=o);"random"===m&&db(c),c.max=h-l,c.min=l,c.v=d=(parseFloat(p.amount)||parseFloat(p.each)*(d<f?d-1:b?"y"===b?d/f:f:Math.max(f,d/f))||0)*("edges"===m?-1:1),c.b=d<0?g-d:g,c.u=Ya(p.amount||p.each)||0,_=_&&d<0?Yt(_):_}return d=(c[t]-c.min)/c.max||0,ja(c.b+(_?_(d):d)*c.v)+c.u}}function fb(i){var n=Math.pow(10,((i+"").split(".")[1]||"").length);return function(e){var r=ja(Math.round(parseFloat(e)/i)*i*n);return(r-r%1)/n+(t(e)?0:Ya(e))}}function gb(h,e){var l,f,r=Z(h);return!r&&v(h)&&(l=r=h.radius||U,h.values?(h=Mt(h.values),(f=!t(h[0]))&&(l*=l)):h=fb(h.increment)),Wa(e,r?s(h)?function(t){return f=h(t),Math.abs(f-t)<=l?f:t}:function(e){for(var r,i,n=parseFloat(f?e.x:e),a=parseFloat(f?e.y:0),s=U,o=0,u=h.length;u--;)(r=f?(r=h[u].x-n)*r+(i=h[u].y-a)*i:Math.abs(h[u]-n))<s&&(s=r,o=u);return o=!l||s<=l?h[o]:e,f||o===e||t(e)?o:o+Ya(e)}:fb(h))}function hb(t,e,r,i){return Wa(Z(t)?!e:!0===r?!!(r=0):!i,function(){return Z(t)?t[~~(Math.random()*t.length)]:(r=r||1e-5)&&(i=r<1?Math.pow(10,(r+"").length-2):1)&&Math.floor(Math.round((t-r/2+Math.random()*(e-t+.99*r))/r)*r*i)/i})}function lb(e,r,t){return Wa(t,function(t){return e[~~r(t)]})}function ob(t){for(var e,r,i,n,a=0,s="";~(e=t.indexOf("random(",a));)i=t.indexOf(")",e),n="["===t.charAt(e+7),r=t.substr(e+7,i-e-7).match(n?at:tt),s+=t.substr(a,e-a)+hb(n?r:+r[0],n?0:+r[1],+r[2]||1e-5),a=i+1;return s+t.substr(a,t.length-a)}function rb(t,e,r){var i,n,a,s=t.labels,o=U;for(i in s)(n=s[i]-e)<0==!!r&&n&&o>(n=Math.abs(n))&&(a=i,o=n);return a}function tb(t){return za(t),t.scrollTrigger&&t.scrollTrigger.kill(!!L),t.progress()<1&&Ct(t,"onInterrupt"),t}function wb(t){if(t)if(t=!t.name&&t.default||t,x()||t.headless){var e=t.name,r=s(t),i=e&&!r&&t.init?function(){this._props=[]}:t,n={init:T,render:he,add:Wt,kill:ce,modifier:fe,rawVars:0},a={targetTest:0,get:0,getSetter:ne,aliases:{},register:0};if(Ft(),t!==i){if(pt[e])return;qa(i,qa(ua(t,n),a)),yt(i.prototype,yt(n,ua(t,a))),pt[i.prop=e]=i,t.targetTest&&(gt.push(i),ft[e]=1),e=("css"===e?"CSS":e.charAt(0).toUpperCase()+e.substr(1))+"Plugin"}S(e,i),t.register&&t.register(ze,i,_e)}else At.push(t)}function zb(t,e,r){return(6*(t+=t<0?1:1<t?-1:0)<1?e+(r-e)*t*6:t<.5?r:3*t<2?e+(r-e)*(2/3-t)*6:e)*St+.5|0}function Ab(e,r,i){var n,a,s,o,u,h,l,f,d,c,p=e?t(e)?[e>>16,e>>8&St,e&St]:0:zt.black;if(!p){if(","===e.substr(-1)&&(e=e.substr(0,e.length-1)),zt[e])p=zt[e];else if("#"===e.charAt(0)){if(e.length<6&&(e="#"+(n=e.charAt(1))+n+(a=e.charAt(2))+a+(s=e.charAt(3))+s+(5===e.length?e.charAt(4)+e.charAt(4):"")),9===e.length)return[(p=parseInt(e.substr(1,6),16))>>16,p>>8&St,p&St,parseInt(e.substr(7),16)/255];p=[(e=parseInt(e.substr(1),16))>>16,e>>8&St,e&St]}else if("hsl"===e.substr(0,3))if(p=c=e.match(tt),r){if(~e.indexOf("="))return p=e.match(et),i&&p.length<4&&(p[3]=1),p}else o=+p[0]%360/360,u=p[1]/100,n=2*(h=p[2]/100)-(a=h<=.5?h*(u+1):h+u-h*u),3<p.length&&(p[3]*=1),p[0]=zb(o+1/3,n,a),p[1]=zb(o,n,a),p[2]=zb(o-1/3,n,a);else p=e.match(tt)||zt.transparent;p=p.map(Number)}return r&&!c&&(n=p[0]/St,a=p[1]/St,s=p[2]/St,h=((l=Math.max(n,a,s))+(f=Math.min(n,a,s)))/2,l===f?o=u=0:(d=l-f,u=.5<h?d/(2-l-f):d/(l+f),o=l===n?(a-s)/d+(a<s?6:0):l===a?(s-n)/d+2:(n-a)/d+4,o*=60),p[0]=~~(o+.5),p[1]=~~(100*u+.5),p[2]=~~(100*h+.5)),i&&p.length<4&&(p[3]=1),p}function Bb(t){var r=[],i=[],n=-1;return t.split(Et).forEach(function(t){var e=t.match(rt)||[];r.push.apply(r,e),i.push(n+=e.length+1)}),r.c=i,r}function Cb(t,e,r){var i,n,a,s,o="",u=(t+o).match(Et),h=e?"hsla(":"rgba(",l=0;if(!u)return t;if(u=u.map(function(t){return(t=Ab(t,e,1))&&h+(e?t[0]+","+t[1]+"%,"+t[2]+"%,"+t[3]:t.join(","))+")"}),r&&(a=Bb(t),(i=r.c).join(o)!==a.c.join(o)))for(s=(n=t.replace(Et,"1").split(rt)).length-1;l<s;l++)o+=n[l]+(~i.indexOf(l)?u.shift()||h+"0,0,0,0)":(a.length?a:u.length?u:r).shift());if(!n)for(s=(n=t.split(Et)).length-1;l<s;l++)o+=n[l]+u[l];return o+n[s]}function Fb(t){var e,r=t.join(" ");if(Et.lastIndex=0,Et.test(r))return e=Dt.test(r),t[1]=Cb(t[1],e),t[0]=Cb(t[0],e,Bb(t[1])),!0}function Ob(t){var e=(t+"").split("("),r=Lt[e[0]];return r&&1<e.length&&r.config?r.config.apply(null,~t.indexOf("{")?[function _parseObjectInString(t){for(var e,r,i,n={},a=t.substr(1,t.length-3).split(":"),s=a[0],o=1,u=a.length;o<u;o++)r=a[o],e=o!==u-1?r.lastIndexOf(","):r.length,i=r.substr(0,e),n[s]=isNaN(i)?i.replace(Bt,"").trim():+i,s=r.substr(e+1).trim();return n}(e[1])]:function _valueInParentheses(t){var e=t.indexOf("(")+1,r=t.indexOf(")"),i=t.indexOf("(",e);return t.substring(e,~i&&i<r?t.indexOf(")",r+1):r)}(t).split(",").map(oa)):Lt._CE&&It.test(t)?Lt._CE("",t):r}function Qb(t,e){for(var r,i=t._first;i;)i instanceof Xt?Qb(i,e):!i.vars.yoyoEase||i._yoyo&&i._repeat||i._yoyo===e||(i.timeline?Qb(i.timeline,e):(r=i._ease,i._ease=i._yEase,i._yEase=r,i._yoyo=e)),i=i._next}function Sb(t,e,r,i){void 0===r&&(r=function easeOut(t){return 1-e(1-t)}),void 0===i&&(i=function easeInOut(t){return t<.5?e(2*t)/2:1-e(2*(1-t))/2});var n,a={easeIn:e,easeOut:r,easeInOut:i};return ha(t,function(t){for(var e in Lt[t]=ot[t]=a,Lt[n=t.toLowerCase()]=r,a)Lt[n+("easeIn"===e?".in":"easeOut"===e?".out":".inOut")]=Lt[t+"."+e]=a[e]}),a}function Tb(e){return function(t){return t<.5?(1-e(1-2*t))/2:.5+e(2*(t-.5))/2}}function Ub(r,t,e){function Jm(t){return 1===t?1:i*Math.pow(2,-10*t)*H((t-a)*n)+1}var i=1<=t?t:1,n=(e||(r?.3:.45))/(t<1?t:1),a=n/N*(Math.asin(1/i)||0),s="out"===r?Jm:"in"===r?function(t){return 1-Jm(1-t)}:Tb(Jm);return n=N/n,s.config=function(t,e){return Ub(r,t,e)},s}function Vb(e,r){function Rm(t){return t?--t*t*((r+1)*t+r)+1:0}void 0===r&&(r=1.70158);var t="out"===e?Rm:"in"===e?function(t){return 1-Rm(1-t)}:Tb(Rm);return t.config=function(t){return Vb(e,t)},t}var F,L,l,I,h,n,a,i,o,f,d,c,p,_,m,g,b,O,k,M,C,A,z,E,D,B,Y,j,q={autoSleep:120,force3D:"auto",nullTargetWarn:1,units:{lineHeight:""}},V={duration:.5,overwrite:!1,delay:0},U=1e8,X=1/U,N=2*Math.PI,G=N/4,W=0,K=Math.sqrt,J=Math.cos,H=Math.sin,$="function"==typeof ArrayBuffer&&ArrayBuffer.isView||function(){},Z=Array.isArray,tt=/(?:-?\.?\d|\.)+/gi,et=/[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g,rt=/[-+=.]*\d+[.e-]*\d*[a-z%]*/g,it=/[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi,nt=/[+-]=-?[.\d]+/,at=/[^,'"\[\]\s]+/gi,st=/^[+\-=e\s\d]*\d+[.\d]*([a-z]*|%)\s*$/i,ot={},ut={suppressEvents:!0,isStart:!0,kill:!1},ht={suppressEvents:!0,kill:!1},lt={suppressEvents:!0},ft={},dt=[],ct={},pt={},_t={},mt=30,gt=[],vt="",yt=function _merge(t,e){for(var r in e)t[r]=e[r];return t},Tt=function _animationCycle(t,e){var r=Math.floor(t/=e);return t&&r===t?r-1:r},bt=function _isFromOrFromStart(t){var e=t.data;return"isFromStart"===e||"isStart"===e},wt={_start:0,endTime:T,totalDuration:T},xt=function _parsePosition(t,e,i){var n,a,s,o=t.labels,u=t._recent||wt,h=t.duration()>=U?u.endTime(!1):t._dur;return r(e)&&(isNaN(e)||e in o)?(a=e.charAt(0),s="%"===e.substr(-1),n=e.indexOf("="),"<"===a||">"===a?(0<=n&&(e=e.replace(/=/,"")),("<"===a?u._start:u.endTime(0<=u._repeat))+(parseFloat(e.substr(1))||0)*(s?(n<0?u:i).totalDuration()/100:1)):n<0?(e in o||(o[e]=h),o[e]):(a=parseFloat(e.charAt(n-1)+e.substr(n+1)),s&&i&&(a=a/100*(Z(i)?i[0]:i).totalDuration()),1<n?_parsePosition(t,e.substr(0,n-1),i)+a:h+a)):null==e?h:+e},Ot=function _clamp(t,e,r){return r<t?t:e<r?e:r},kt=[].slice,Mt=function toArray(t,e,i){return l&&!e&&l.selector?l.selector(t):!r(t)||i||!n&&Ft()?Z(t)?function _flatten(t,e,i){return void 0===i&&(i=[]),t.forEach(function(t){return r(t)&&!e||_a(t,1)?i.push.apply(i,Mt(t)):i.push(t)})||i}(t,i):_a(t)?kt.call(t,0):t?[t]:[]:kt.call((e||a).querySelectorAll(t),0)},Pt=function mapRange(e,t,r,i,n){var a=t-e,s=i-r;return Wa(n,function(t){return r+((t-e)/a*s||0)})},Ct=function _callback(t,e,r){var i,n,a,s=t.vars,o=s[e],u=l,h=t._ctx;if(o)return i=s[e+"Params"],n=s.callbackScope||t,r&&dt.length&&ma(),h&&(l=h),a=i?o.apply(n,i):o.call(n),l=u,a},At=[],St=255,zt={aqua:[0,St,St],lime:[0,St,0],silver:[192,192,192],black:[0,0,0],maroon:[128,0,0],teal:[0,128,128],blue:[0,0,St],navy:[0,0,128],white:[St,St,St],olive:[128,128,0],yellow:[St,St,0],orange:[St,165,0],gray:[128,128,128],purple:[128,0,128],green:[0,128,0],red:[St,0,0],pink:[St,192,203],cyan:[0,St,St],transparent:[St,St,St,0]},Et=function(){var t,e="(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b";for(t in zt)e+="|"+t+"\\b";return new RegExp(e+")","gi")}(),Dt=/hsl[a]?\(/,Rt=(k=Date.now,M=500,C=33,A=k(),z=A,D=E=1e3/240,g={time:0,frame:0,tick:function tick(){yl(!0)},deltaRatio:function deltaRatio(t){return b/(1e3/(t||60))},wake:function wake(){o&&(!n&&x()&&(h=n=window,a=h.document||{},ot.gsap=ze,(h.gsapVersions||(h.gsapVersions=[])).push(ze.version),P(i||h.GreenSockGlobals||!h.gsap&&h||{}),At.forEach(wb)),m="undefined"!=typeof requestAnimationFrame&&requestAnimationFrame,p&&g.sleep(),_=m||function(t){return setTimeout(t,D-1e3*g.time+1|0)},c=1,yl(2))},sleep:function sleep(){(m?cancelAnimationFrame:clearTimeout)(p),c=0,_=T},lagSmoothing:function lagSmoothing(t,e){M=t||1/0,C=Math.min(e||33,M)},fps:function fps(t){E=1e3/(t||240),D=1e3*g.time+E},add:function add(n,t,e){var a=t?function(t,e,r,i){n(t,e,r,i),g.remove(a)}:n;return g.remove(n),B[e?"unshift":"push"](a),Ft(),a},remove:function remove(t,e){~(e=B.indexOf(t))&&B.splice(e,1)&&e<=O&&O--},_listeners:B=[]}),Ft=function _wake(){return!c&&Rt.wake()},Lt={},It=/^[\d.\-M][\d.\-,\s]/,Bt=/["']/g,Yt=function _invertEase(e){return function(t){return 1-e(1-t)}},jt=function _parseEase(t,e){return t&&(s(t)?t:Lt[t]||Ob(t))||e};function yl(t){var e,r,i,n,a=k()-z,s=!0===t;if((M<a||a<0)&&(A+=a-C),(0<(e=(i=(z+=a)-A)-D)||s)&&(n=++g.frame,b=i-1e3*g.time,g.time=i/=1e3,D+=e+(E<=e?4:E-e),r=1),s||(p=_(yl)),r)for(O=0;O<B.length;O++)B[O](i,b,n,t)}function gn(t){return t<j?Y*t*t:t<.7272727272727273?Y*Math.pow(t-1.5/2.75,2)+.75:t<.9090909090909092?Y*(t-=2.25/2.75)*t+.9375:Y*Math.pow(t-2.625/2.75,2)+.984375}ha("Linear,Quad,Cubic,Quart,Quint,Strong",function(t,e){var r=e<5?e+1:e;Sb(t+",Power"+(r-1),e?function(t){return Math.pow(t,r)}:function(t){return t},function(t){return 1-Math.pow(1-t,r)},function(t){return t<.5?Math.pow(2*t,r)/2:1-Math.pow(2*(1-t),r)/2})}),Lt.Linear.easeNone=Lt.none=Lt.Linear.easeIn,Sb("Elastic",Ub("in"),Ub("out"),Ub()),Y=7.5625,j=1/2.75,Sb("Bounce",function(t){return 1-gn(1-t)},gn),Sb("Expo",function(t){return t?Math.pow(2,10*(t-1)):0}),Sb("Circ",function(t){return-(K(1-t*t)-1)}),Sb("Sine",function(t){return 1===t?1:1-J(t*G)}),Sb("Back",Vb("in"),Vb("out"),Vb()),Lt.SteppedEase=Lt.steps=ot.SteppedEase={config:function config(t,e){void 0===t&&(t=1);var r=1/t,i=t+(e?0:1),n=e?1:0;return function(t){return((i*Ot(0,.99999999,t)|0)+n)*r}}},V.ease=Lt["quad.out"],ha("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt",function(t){return vt+=t+","+t+"Params,"});var qt,Vt=function GSCache(t,e){this.id=W++,(t._gsap=this).target=t,this.harness=e,this.get=e?e.get:ga,this.set=e?e.getSetter:ne},Ut=((qt=Animation.prototype).delay=function delay(t){return t||0===t?(this.parent&&this.parent.smoothChildTiming&&this.startTime(this._start+t-this._delay),this._delay=t,this):this._delay},qt.duration=function duration(t){return arguments.length?this.totalDuration(0<this._repeat?t+(t+this._rDelay)*this._repeat:t):this.totalDuration()&&this._dur},qt.totalDuration=function totalDuration(t){return arguments.length?(this._dirty=0,Ra(this,this._repeat<0?t:(t-this._repeat*this._rDelay)/(this._repeat+1))):this._tDur},qt.totalTime=function totalTime(t,e){if(Ft(),!arguments.length)return this._tTime;var r=this._dp;if(r&&r.smoothChildTiming&&this._ts){for(Ia(this,t),!r._dp||r.parent||Ja(r,this);r&&r.parent;)r.parent._time!==r._start+(0<=r._ts?r._tTime/r._ts:(r.totalDuration()-r._tTime)/-r._ts)&&r.totalTime(r._tTime,!0),r=r.parent;!this.parent&&this._dp.autoRemoveChildren&&(0<this._ts&&t<this._tDur||this._ts<0&&0<t||!this._tDur&&!t)&&Ka(this._dp,this,this._start-this._delay)}return(this._tTime!==t||!this._dur&&!e||this._initted&&Math.abs(this._zTime)===X||!t&&!this._initted&&(this.add||this._ptLookup))&&(this._ts||(this._pTime=t),na(this,t,e)),this},qt.time=function time(t,e){return arguments.length?this.totalTime(Math.min(this.totalDuration(),t+Ea(this))%(this._dur+this._rDelay)||(t?this._dur:0),e):this._time},qt.totalProgress=function totalProgress(t,e){return arguments.length?this.totalTime(this.totalDuration()*t,e):this.totalDuration()?Math.min(1,this._tTime/this._tDur):0<this.rawTime()?1:0},qt.progress=function progress(t,e){return arguments.length?this.totalTime(this.duration()*(!this._yoyo||1&this.iteration()?t:1-t)+Ea(this),e):this.duration()?Math.min(1,this._time/this._dur):0<this.rawTime()?1:0},qt.iteration=function iteration(t,e){var r=this.duration()+this._rDelay;return arguments.length?this.totalTime(this._time+(t-1)*r,e):this._repeat?Tt(this._tTime,r)+1:1},qt.timeScale=function timeScale(t,e){if(!arguments.length)return this._rts===-X?0:this._rts;if(this._rts===t)return this;var r=this.parent&&this._ts?Ga(this.parent._time,this):this._tTime;return this._rts=+t||0,this._ts=this._ps||t===-X?0:this._rts,this.totalTime(Ot(-Math.abs(this._delay),this._tDur,r),!1!==e),Ha(this),function _recacheAncestors(t){for(var e=t.parent;e&&e.parent;)e._dirty=1,e.totalDuration(),e=e.parent;return t}(this)},qt.paused=function paused(t){return arguments.length?(this._ps!==t&&((this._ps=t)?(this._pTime=this._tTime||Math.max(-this._delay,this.rawTime()),this._ts=this._act=0):(Ft(),this._ts=this._rts,this.totalTime(this.parent&&!this.parent.smoothChildTiming?this.rawTime():this._tTime||this._pTime,1===this.progress()&&Math.abs(this._zTime)!==X&&(this._tTime-=X)))),this):this._ps},qt.startTime=function startTime(t){if(arguments.length){this._start=t;var e=this.parent||this._dp;return!e||!e._sort&&this.parent||Ka(e,this,t-this._delay),this}return this._start},qt.endTime=function endTime(t){return this._start+(w(t)?this.totalDuration():this.duration())/Math.abs(this._ts||1)},qt.rawTime=function rawTime(t){var e=this.parent||this._dp;return e?t&&(!this._ts||this._repeat&&this._time&&this.totalProgress()<1)?this._tTime%(this._dur+this._rDelay):this._ts?Ga(e.rawTime(t),this):this._tTime:this._tTime},qt.revert=function revert(t){void 0===t&&(t=lt);var e=L;return L=t,(this._initted||this._startAt)&&(this.timeline&&this.timeline.revert(t),this.totalTime(-.01,t.suppressEvents)),"nested"!==this.data&&!1!==t.kill&&this.kill(),L=e,this},qt.globalTime=function globalTime(t){for(var e=this,r=arguments.length?t:e.rawTime();e;)r=e._start+r/(Math.abs(e._ts)||1),e=e._dp;return!this.parent&&this._sat?this._sat.globalTime(t):r},qt.repeat=function repeat(t){return arguments.length?(this._repeat=t===1/0?-2:t,Sa(this)):-2===this._repeat?1/0:this._repeat},qt.repeatDelay=function repeatDelay(t){if(arguments.length){var e=this._time;return this._rDelay=t,Sa(this),e?this.time(e):this}return this._rDelay},qt.yoyo=function yoyo(t){return arguments.length?(this._yoyo=t,this):this._yoyo},qt.seek=function seek(t,e){return this.totalTime(xt(this,t),w(e))},qt.restart=function restart(t,e){return this.play().totalTime(t?-this._delay:0,w(e))},qt.play=function play(t,e){return null!=t&&this.seek(t,e),this.reversed(!1).paused(!1)},qt.reverse=function reverse(t,e){return null!=t&&this.seek(t||this.totalDuration(),e),this.reversed(!0).paused(!1)},qt.pause=function pause(t,e){return null!=t&&this.seek(t,e),this.paused(!0)},qt.resume=function resume(){return this.paused(!1)},qt.reversed=function reversed(t){return arguments.length?(!!t!==this.reversed()&&this.timeScale(-this._rts||(t?-X:0)),this):this._rts<0},qt.invalidate=function invalidate(){return this._initted=this._act=0,this._zTime=-X,this},qt.isActive=function isActive(){var t,e=this.parent||this._dp,r=this._start;return!(e&&!(this._ts&&this._initted&&e.isActive()&&(t=e.rawTime(!0))>=r&&t<this.endTime(!0)-X))},qt.eventCallback=function eventCallback(t,e,r){var i=this.vars;return 1<arguments.length?(e?(i[t]=e,r&&(i[t+"Params"]=r),"onUpdate"===t&&(this._onUpdate=e)):delete i[t],this):i[t]},qt.then=function then(t){var i=this;return new Promise(function(e){function Co(){var t=i.then;i.then=null,s(r)&&(r=r(i))&&(r.then||r===i)&&(i.then=t),e(r),i.then=t}var r=s(t)?t:pa;i._initted&&1===i.totalProgress()&&0<=i._ts||!i._tTime&&i._ts<0?Co():i._prom=Co})},qt.kill=function kill(){tb(this)},Animation);function Animation(t){this.vars=t,this._delay=+t.delay||0,(this._repeat=t.repeat===1/0?-2:t.repeat||0)&&(this._rDelay=t.repeatDelay||0,this._yoyo=!!t.yoyo||!!t.yoyoEase),this._ts=1,Ra(this,+t.duration,1,1),this.data=t.data,l&&(this._ctx=l).data.push(this),c||Rt.wake()}qa(Ut.prototype,{_time:0,_start:0,_end:0,_tTime:0,_tDur:0,_dirty:0,_repeat:0,_yoyo:!1,parent:null,_initted:!1,_rDelay:0,_ts:1,_dp:0,ratio:0,_zTime:-X,_prom:0,_ps:!1,_rts:1});var Xt=function(i){function Timeline(t,e){var r;return void 0===t&&(t={}),(r=i.call(this,t)||this).labels={},r.smoothChildTiming=!!t.smoothChildTiming,r.autoRemoveChildren=!!t.autoRemoveChildren,r._sort=w(t.sortChildren),I&&Ka(t.parent||I,_assertThisInitialized(r),e),t.reversed&&r.reverse(),t.paused&&r.paused(!0),t.scrollTrigger&&La(_assertThisInitialized(r),t.scrollTrigger),r}_inheritsLoose(Timeline,i);var e=Timeline.prototype;return e.to=function to(t,e,r){return Va(0,arguments,this),this},e.from=function from(t,e,r){return Va(1,arguments,this),this},e.fromTo=function fromTo(t,e,r,i){return Va(2,arguments,this),this},e.set=function set(t,e,r){return e.duration=0,e.parent=this,va(e).repeatDelay||(e.repeat=0),e.immediateRender=!!e.immediateRender,new $t(t,e,xt(this,r),1),this},e.call=function call(t,e,r){return Ka(this,$t.delayedCall(0,t,e),r)},e.staggerTo=function staggerTo(t,e,r,i,n,a,s){return r.duration=e,r.stagger=r.stagger||i,r.onComplete=a,r.onCompleteParams=s,r.parent=this,new $t(t,r,xt(this,n)),this},e.staggerFrom=function staggerFrom(t,e,r,i,n,a,s){return r.runBackwards=1,va(r).immediateRender=w(r.immediateRender),this.staggerTo(t,e,r,i,n,a,s)},e.staggerFromTo=function staggerFromTo(t,e,r,i,n,a,s,o){return i.startAt=r,va(i).immediateRender=w(i.immediateRender),this.staggerTo(t,e,i,n,a,s,o)},e.render=function render(t,e,r){var i,n,a,s,o,u,h,l,f,d,c,p,_=this._time,m=this._dirty?this.totalDuration():this._tDur,g=this._dur,v=t<=0?0:ja(t),y=this._zTime<0!=t<0&&(this._initted||!g);if(this!==I&&m<v&&0<=t&&(v=m),v!==this._tTime||r||y){if(_!==this._time&&g&&(v+=this._time-_,t+=this._time-_),i=v,f=this._start,u=!(l=this._ts),y&&(g||(_=this._zTime),!t&&e||(this._zTime=t)),this._repeat){if(c=this._yoyo,o=g+this._rDelay,this._repeat<-1&&t<0)return this.totalTime(100*o+t,e,r);if(i=ja(v%o),v===m?(s=this._repeat,i=g):((s=~~(v/o))&&s===v/o&&(i=g,s--),g<i&&(i=g)),d=Tt(this._tTime,o),!_&&this._tTime&&d!==s&&this._tTime-d*o-this._dur<=0&&(d=s),c&&1&s&&(i=g-i,p=1),s!==d&&!this._lock){var T=c&&1&d,b=T===(c&&1&s);if(s<d&&(T=!T),_=T?0:v%g?g:v,this._lock=1,this.render(_||(p?0:ja(s*o)),e,!g)._lock=0,this._tTime=v,!e&&this.parent&&Ct(this,"onRepeat"),this.vars.repeatRefresh&&!p&&(this.invalidate()._lock=1),_&&_!==this._time||u!=!this._ts||this.vars.onRepeat&&!this.parent&&!this._act)return this;if(g=this._dur,m=this._tDur,b&&(this._lock=2,_=T?g:-1e-4,this.render(_,!0),this.vars.repeatRefresh&&!p&&this.invalidate()),this._lock=0,!this._ts&&!u)return this;Qb(this,p)}}if(this._hasPause&&!this._forcing&&this._lock<2&&(h=function _findNextPauseTween(t,e,r){var i;if(e<r)for(i=t._first;i&&i._start<=r;){if("isPause"===i.data&&i._start>e)return i;i=i._next}else for(i=t._last;i&&i._start>=r;){if("isPause"===i.data&&i._start<e)return i;i=i._prev}}(this,ja(_),ja(i)))&&(v-=i-(i=h._start)),this._tTime=v,this._time=i,this._act=!l,this._initted||(this._onUpdate=this.vars.onUpdate,this._initted=1,this._zTime=t,_=0),!_&&i&&!e&&!s&&(Ct(this,"onStart"),this._tTime!==v))return this;if(_<=i&&0<=t)for(n=this._first;n;){if(a=n._next,(n._act||i>=n._start)&&n._ts&&h!==n){if(n.parent!==this)return this.render(t,e,r);if(n.render(0<n._ts?(i-n._start)*n._ts:(n._dirty?n.totalDuration():n._tDur)+(i-n._start)*n._ts,e,r),i!==this._time||!this._ts&&!u){h=0,a&&(v+=this._zTime=-X);break}}n=a}else{n=this._last;for(var w=t<0?t:i;n;){if(a=n._prev,(n._act||w<=n._end)&&n._ts&&h!==n){if(n.parent!==this)return this.render(t,e,r);if(n.render(0<n._ts?(w-n._start)*n._ts:(n._dirty?n.totalDuration():n._tDur)+(w-n._start)*n._ts,e,r||L&&(n._initted||n._startAt)),i!==this._time||!this._ts&&!u){h=0,a&&(v+=this._zTime=w?-X:X);break}}n=a}}if(h&&!e&&(this.pause(),h.render(_<=i?0:-X)._zTime=_<=i?1:-1,this._ts))return this._start=f,Ha(this),this.render(t,e,r);this._onUpdate&&!e&&Ct(this,"onUpdate",!0),(v===m&&this._tTime>=this.totalDuration()||!v&&_)&&(f!==this._start&&Math.abs(l)===Math.abs(this._ts)||this._lock||(!t&&g||!(v===m&&0<this._ts||!v&&this._ts<0)||za(this,1),e||t<0&&!_||!v&&!_&&m||(Ct(this,v===m&&0<=t?"onComplete":"onReverseComplete",!0),!this._prom||v<m&&0<this.timeScale()||this._prom())))}return this},e.add=function add(e,i){var n=this;if(t(i)||(i=xt(this,i,e)),!(e instanceof Ut)){if(Z(e))return e.forEach(function(t){return n.add(t,i)}),this;if(r(e))return this.addLabel(e,i);if(!s(e))return this;e=$t.delayedCall(0,e)}return this!==e?Ka(this,e,i):this},e.getChildren=function getChildren(t,e,r,i){void 0===t&&(t=!0),void 0===e&&(e=!0),void 0===r&&(r=!0),void 0===i&&(i=-U);for(var n=[],a=this._first;a;)a._start>=i&&(a instanceof $t?e&&n.push(a):(r&&n.push(a),t&&n.push.apply(n,a.getChildren(!0,e,r)))),a=a._next;return n},e.getById=function getById(t){for(var e=this.getChildren(1,1,1),r=e.length;r--;)if(e[r].vars.id===t)return e[r]},e.remove=function remove(t){return r(t)?this.removeLabel(t):s(t)?this.killTweensOf(t):(ya(this,t),t===this._recent&&(this._recent=this._last),Aa(this))},e.totalTime=function totalTime(t,e){return arguments.length?(this._forcing=1,!this._dp&&this._ts&&(this._start=ja(Rt.time-(0<this._ts?t/this._ts:(this.totalDuration()-t)/-this._ts))),i.prototype.totalTime.call(this,t,e),this._forcing=0,this):this._tTime},e.addLabel=function addLabel(t,e){return this.labels[t]=xt(this,e),this},e.removeLabel=function removeLabel(t){return delete this.labels[t],this},e.addPause=function addPause(t,e,r){var i=$t.delayedCall(0,e||T,r);return i.data="isPause",this._hasPause=1,Ka(this,i,xt(this,t))},e.removePause=function removePause(t){var e=this._first;for(t=xt(this,t);e;)e._start===t&&"isPause"===e.data&&za(e),e=e._next},e.killTweensOf=function killTweensOf(t,e,r){for(var i=this.getTweensOf(t,r),n=i.length;n--;)Nt!==i[n]&&i[n].kill(t,e);return this},e.getTweensOf=function getTweensOf(e,r){for(var i,n=[],a=Mt(e),s=this._first,o=t(r);s;)s instanceof $t?la(s._targets,a)&&(o?(!Nt||s._initted&&s._ts)&&s.globalTime(0)<=r&&s.globalTime(s.totalDuration())>r:!r||s.isActive())&&n.push(s):(i=s.getTweensOf(a,r)).length&&n.push.apply(n,i),s=s._next;return n},e.tweenTo=function tweenTo(t,e){e=e||{};var r,i=this,n=xt(i,t),a=e.startAt,s=e.onStart,o=e.onStartParams,u=e.immediateRender,h=$t.to(i,qa({ease:e.ease||"none",lazy:!1,immediateRender:!1,time:n,overwrite:"auto",duration:e.duration||Math.abs((n-(a&&"time"in a?a.time:i._time))/i.timeScale())||X,onStart:function onStart(){if(i.pause(),!r){var t=e.duration||Math.abs((n-(a&&"time"in a?a.time:i._time))/i.timeScale());h._dur!==t&&Ra(h,t,0,1).render(h._time,!0,!0),r=1}s&&s.apply(h,o||[])}},e));return u?h.render(0):h},e.tweenFromTo=function tweenFromTo(t,e,r){return this.tweenTo(e,qa({startAt:{time:xt(this,t)}},r))},e.recent=function recent(){return this._recent},e.nextLabel=function nextLabel(t){return void 0===t&&(t=this._time),rb(this,xt(this,t))},e.previousLabel=function previousLabel(t){return void 0===t&&(t=this._time),rb(this,xt(this,t),1)},e.currentLabel=function currentLabel(t){return arguments.length?this.seek(t,!0):this.previousLabel(this._time+X)},e.shiftChildren=function shiftChildren(t,e,r){void 0===r&&(r=0);for(var i,n=this._first,a=this.labels;n;)n._start>=r&&(n._start+=t,n._end+=t),n=n._next;if(e)for(i in a)a[i]>=r&&(a[i]+=t);return Aa(this)},e.invalidate=function invalidate(t){var e=this._first;for(this._lock=0;e;)e.invalidate(t),e=e._next;return i.prototype.invalidate.call(this,t)},e.clear=function clear(t){void 0===t&&(t=!0);for(var e,r=this._first;r;)e=r._next,this.remove(r),r=e;return this._dp&&(this._time=this._tTime=this._pTime=0),t&&(this.labels={}),Aa(this)},e.totalDuration=function totalDuration(t){var e,r,i,n=0,a=this,s=a._last,o=U;if(arguments.length)return a.timeScale((a._repeat<0?a.duration():a.totalDuration())/(a.reversed()?-t:t));if(a._dirty){for(i=a.parent;s;)e=s._prev,s._dirty&&s.totalDuration(),o<(r=s._start)&&a._sort&&s._ts&&!a._lock?(a._lock=1,Ka(a,s,r-s._delay,1)._lock=0):o=r,r<0&&s._ts&&(n-=r,(!i&&!a._dp||i&&i.smoothChildTiming)&&(a._start+=r/a._ts,a._time-=r,a._tTime-=r),a.shiftChildren(-r,!1,-Infinity),o=0),s._end>n&&s._ts&&(n=s._end),s=e;Ra(a,a===I&&a._time>n?a._time:n,1,1),a._dirty=0}return a._tDur},Timeline.updateRoot=function updateRoot(t){if(I._ts&&(na(I,Ga(t,I)),f=Rt.frame),Rt.frame>=mt){mt+=q.autoSleep||120;var e=I._first;if((!e||!e._ts)&&q.autoSleep&&Rt._listeners.length<2){for(;e&&!e._ts;)e=e._next;e||Rt.sleep()}}},Timeline}(Ut);qa(Xt.prototype,{_lock:0,_hasPause:0,_forcing:0});function ac(t,e,i,n,a,o){var u,h,l,f;if(pt[t]&&!1!==(u=new pt[t]).init(a,u.rawVars?e[t]:function _processVars(t,e,i,n,a){if(s(t)&&(t=Kt(t,a,e,i,n)),!v(t)||t.style&&t.nodeType||Z(t)||$(t))return r(t)?Kt(t,a,e,i,n):t;var o,u={};for(o in t)u[o]=Kt(t[o],a,e,i,n);return u}(e[t],n,a,o,i),i,n,o)&&(i._pt=h=new _e(i._pt,a,t,0,1,u.render,u,0,u.priority),i!==d))for(l=i._ptLookup[i._targets.indexOf(a)],f=u._props.length;f--;)l[u._props[f]]=h;return u}function gc(t,r,e,i){var n,a,s=r.ease||i||"power1.inOut";if(Z(r))a=e[t]||(e[t]=[]),r.forEach(function(t,e){return a.push({t:e/(r.length-1)*100,v:t,e:s})});else for(n in r)a=e[n]||(e[n]=[]),"ease"===n||a.push({t:parseFloat(t),v:r[n],e:s})}var Nt,Gt,Wt=function _addPropTween(t,e,i,n,a,o,u,h,l,f){s(n)&&(n=n(a||0,t,o));var d,c=t[e],p="get"!==i?i:s(c)?l?t[e.indexOf("set")||!s(t["get"+e.substr(3)])?e:"get"+e.substr(3)](l):t[e]():c,_=s(c)?l?re:te:Zt;if(r(n)&&(~n.indexOf("random(")&&(n=ob(n)),"="===n.charAt(1)&&(!(d=ka(p,n)+(Ya(p)||0))&&0!==d||(n=d))),!f||p!==n||Gt)return isNaN(p*n)||""===n?(c||e in t||Q(e,n),function _addComplexStringPropTween(t,e,r,i,n,a,s){var o,u,h,l,f,d,c,p,_=new _e(this._pt,t,e,0,1,ue,null,n),m=0,g=0;for(_.b=r,_.e=i,r+="",(c=~(i+="").indexOf("random("))&&(i=ob(i)),a&&(a(p=[r,i],t,e),r=p[0],i=p[1]),u=r.match(it)||[];o=it.exec(i);)l=o[0],f=i.substring(m,o.index),h?h=(h+1)%5:"rgba("===f.substr(-5)&&(h=1),l!==u[g++]&&(d=parseFloat(u[g-1])||0,_._pt={_next:_._pt,p:f||1===g?f:",",s:d,c:"="===l.charAt(1)?ka(d,l)-d:parseFloat(l)-d,m:h&&h<4?Math.round:0},m=it.lastIndex);return _.c=m<i.length?i.substring(m,i.length):"",_.fp=s,(nt.test(i)||c)&&(_.e=0),this._pt=_}.call(this,t,e,p,n,_,h||q.stringFilter,l)):(d=new _e(this._pt,t,e,+p||0,n-(p||0),"boolean"==typeof c?se:ae,0,_),l&&(d.fp=l),u&&d.modifier(u,this,t),this._pt=d)},Qt=function _initTween(t,e,r){var i,n,a,s,o,u,h,l,f,d,c,p,_,m=t.vars,g=m.ease,v=m.startAt,y=m.immediateRender,T=m.lazy,b=m.onUpdate,x=m.runBackwards,O=m.yoyoEase,k=m.keyframes,M=m.autoRevert,P=t._dur,C=t._startAt,A=t._targets,S=t.parent,z=S&&"nested"===S.data?S.vars.targets:A,E="auto"===t._overwrite&&!F,D=t.timeline;if(!D||k&&g||(g="none"),t._ease=jt(g,V.ease),t._yEase=O?Yt(jt(!0===O?g:O,V.ease)):0,O&&t._yoyo&&!t._repeat&&(O=t._yEase,t._yEase=t._ease,t._ease=O),t._from=!D&&!!m.runBackwards,!D||k&&!m.stagger){if(p=(l=A[0]?fa(A[0]).harness:0)&&m[l.prop],i=ua(m,ft),C&&(C._zTime<0&&C.progress(1),e<0&&x&&y&&!M?C.render(-1,!0):C.revert(x&&P?ht:ut),C._lazy=0),v){if(za(t._startAt=$t.set(A,qa({data:"isStart",overwrite:!1,parent:S,immediateRender:!0,lazy:!C&&w(T),startAt:null,delay:0,onUpdate:b&&function(){return Ct(t,"onUpdate")},stagger:0},v))),t._startAt._dp=0,t._startAt._sat=t,e<0&&(L||!y&&!M)&&t._startAt.revert(ht),y&&P&&e<=0&&r<=0)return void(e&&(t._zTime=e))}else if(x&&P&&!C)if(e&&(y=!1),a=qa({overwrite:!1,data:"isFromStart",lazy:y&&!C&&w(T),immediateRender:y,stagger:0,parent:S},i),p&&(a[l.prop]=p),za(t._startAt=$t.set(A,a)),t._startAt._dp=0,t._startAt._sat=t,e<0&&(L?t._startAt.revert(ht):t._startAt.render(-1,!0)),t._zTime=e,y){if(!e)return}else _initTween(t._startAt,X,X);for(t._pt=t._ptCache=0,T=P&&w(T)||T&&!P,n=0;n<A.length;n++){if(h=(o=A[n])._gsap||ea(A)[n]._gsap,t._ptLookup[n]=d={},ct[h.id]&&dt.length&&ma(),c=z===A?n:z.indexOf(o),l&&!1!==(f=new l).init(o,p||i,t,c,z)&&(t._pt=s=new _e(t._pt,o,f.name,0,1,f.render,f,0,f.priority),f._props.forEach(function(t){d[t]=s}),f.priority&&(u=1)),!l||p)for(a in i)pt[a]&&(f=ac(a,i,t,c,o,z))?f.priority&&(u=1):d[a]=s=Wt.call(t,o,a,"get",i[a],c,z,0,m.stringFilter);t._op&&t._op[n]&&t.kill(o,t._op[n]),E&&t._pt&&(Nt=t,I.killTweensOf(o,d,t.globalTime(e)),_=!t.parent,Nt=0),t._pt&&T&&(ct[h.id]=1)}u&&pe(t),t._onInit&&t._onInit(t)}t._onUpdate=b,t._initted=(!t._op||t._pt)&&!_,k&&e<=0&&D.render(U,!0,!0)},Kt=function _parseFuncOrString(t,e,i,n,a){return s(t)?t.call(e,i,n,a):r(t)&&~t.indexOf("random(")?ob(t):t},Jt=vt+"repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert",Ht={};ha(Jt+",id,stagger,delay,duration,paused,scrollTrigger",function(t){return Ht[t]=1});var $t=function(D){function Tween(e,r,i,n){var a;"number"==typeof r&&(i.duration=r,r=i,i=null);var s,o,u,h,l,f,d,c,p=(a=D.call(this,n?r:va(r))||this).vars,_=p.duration,m=p.delay,g=p.immediateRender,T=p.stagger,b=p.overwrite,x=p.keyframes,O=p.defaults,k=p.scrollTrigger,M=p.yoyoEase,P=r.parent||I,C=(Z(e)||$(e)?t(e[0]):"length"in r)?[e]:Mt(e);if(a._targets=C.length?ea(C):R("GSAP target "+e+" not found. https://gsap.com",!q.nullTargetWarn)||[],a._ptLookup=[],a._overwrite=b,x||T||y(_)||y(m)){if(r=a.vars,(s=a.timeline=new Xt({data:"nested",defaults:O||{},targets:P&&"nested"===P.data?P.vars.targets:C})).kill(),s.parent=s._dp=_assertThisInitialized(a),s._start=0,T||y(_)||y(m)){if(h=C.length,d=T&&eb(T),v(T))for(l in T)~Jt.indexOf(l)&&((c=c||{})[l]=T[l]);for(o=0;o<h;o++)(u=ua(r,Ht)).stagger=0,M&&(u.yoyoEase=M),c&&yt(u,c),f=C[o],u.duration=+Kt(_,_assertThisInitialized(a),o,f,C),u.delay=(+Kt(m,_assertThisInitialized(a),o,f,C)||0)-a._delay,!T&&1===h&&u.delay&&(a._delay=m=u.delay,a._start+=m,u.delay=0),s.to(f,u,d?d(o,f,C):0),s._ease=Lt.none;s.duration()?_=m=0:a.timeline=0}else if(x){va(qa(s.vars.defaults,{ease:"none"})),s._ease=jt(x.ease||r.ease||"none");var A,S,z,E=0;if(Z(x))x.forEach(function(t){return s.to(C,t,">")}),s.duration();else{for(l in u={},x)"ease"===l||"easeEach"===l||gc(l,x[l],u,x.easeEach);for(l in u)for(A=u[l].sort(function(t,e){return t.t-e.t}),o=E=0;o<A.length;o++)(z={ease:(S=A[o]).e,duration:(S.t-(o?A[o-1].t:0))/100*_})[l]=S.v,s.to(C,z,E),E+=z.duration;s.duration()<_&&s.to({},{duration:_-s.duration()})}}_||a.duration(_=s.duration())}else a.timeline=0;return!0!==b||F||(Nt=_assertThisInitialized(a),I.killTweensOf(C),Nt=0),Ka(P,_assertThisInitialized(a),i),r.reversed&&a.reverse(),r.paused&&a.paused(!0),(g||!_&&!x&&a._start===ja(P._time)&&w(g)&&function _hasNoPausedAncestors(t){return!t||t._ts&&_hasNoPausedAncestors(t.parent)}(_assertThisInitialized(a))&&"nested"!==P.data)&&(a._tTime=-X,a.render(Math.max(0,-m)||0)),k&&La(_assertThisInitialized(a),k),a}_inheritsLoose(Tween,D);var e=Tween.prototype;return e.render=function render(t,e,r){var i,n,a,s,o,u,h,l,f,d=this._time,c=this._tDur,p=this._dur,_=t<0,m=c-X<t&&!_?c:t<X?0:t;if(p){if(m!==this._tTime||!t||r||!this._initted&&this._tTime||this._startAt&&this._zTime<0!=_){if(i=m,l=this.timeline,this._repeat){if(s=p+this._rDelay,this._repeat<-1&&_)return this.totalTime(100*s+t,e,r);if(i=ja(m%s),m===c?(a=this._repeat,i=p):((a=~~(m/s))&&a===ja(m/s)&&(i=p,a--),p<i&&(i=p)),(u=this._yoyo&&1&a)&&(f=this._yEase,i=p-i),o=Tt(this._tTime,s),i===d&&!r&&this._initted&&a===o)return this._tTime=m,this;a!==o&&(l&&this._yEase&&Qb(l,u),this.vars.repeatRefresh&&!u&&!this._lock&&this._time!==s&&this._initted&&(this._lock=r=1,this.render(ja(s*a),!0).invalidate()._lock=0))}if(!this._initted){if(Ma(this,_?t:i,r,e,m))return this._tTime=0,this;if(!(d===this._time||r&&this.vars.repeatRefresh&&a!==o))return this;if(p!==this._dur)return this.render(t,e,r)}if(this._tTime=m,this._time=i,!this._act&&this._ts&&(this._act=1,this._lazy=0),this.ratio=h=(f||this._ease)(i/p),this._from&&(this.ratio=h=1-h),i&&!d&&!e&&!a&&(Ct(this,"onStart"),this._tTime!==m))return this;for(n=this._pt;n;)n.r(h,n.d),n=n._next;l&&l.render(t<0?t:l._dur*l._ease(i/this._dur),e,r)||this._startAt&&(this._zTime=t),this._onUpdate&&!e&&(_&&Ca(this,t,0,r),Ct(this,"onUpdate")),this._repeat&&a!==o&&this.vars.onRepeat&&!e&&this.parent&&Ct(this,"onRepeat"),m!==this._tDur&&m||this._tTime!==m||(_&&!this._onUpdate&&Ca(this,t,0,!0),!t&&p||!(m===this._tDur&&0<this._ts||!m&&this._ts<0)||za(this,1),e||_&&!d||!(m||d||u)||(Ct(this,m===c?"onComplete":"onReverseComplete",!0),!this._prom||m<c&&0<this.timeScale()||this._prom()))}}else!function _renderZeroDurationTween(t,e,r,i){var n,a,s,o=t.ratio,u=e<0||!e&&(!t._start&&function _parentPlayheadIsBeforeStart(t){var e=t.parent;return e&&e._ts&&e._initted&&!e._lock&&(e.rawTime()<0||_parentPlayheadIsBeforeStart(e))}(t)&&(t._initted||!bt(t))||(t._ts<0||t._dp._ts<0)&&!bt(t))?0:1,h=t._rDelay,l=0;if(h&&t._repeat&&(l=Ot(0,t._tDur,e),a=Tt(l,h),t._yoyo&&1&a&&(u=1-u),a!==Tt(t._tTime,h)&&(o=1-u,t.vars.repeatRefresh&&t._initted&&t.invalidate())),u!==o||L||i||t._zTime===X||!e&&t._zTime){if(!t._initted&&Ma(t,e,i,r,l))return;for(s=t._zTime,t._zTime=e||(r?X:0),r=r||e&&!s,t.ratio=u,t._from&&(u=1-u),t._time=0,t._tTime=l,n=t._pt;n;)n.r(u,n.d),n=n._next;e<0&&Ca(t,e,0,!0),t._onUpdate&&!r&&Ct(t,"onUpdate"),l&&t._repeat&&!r&&t.parent&&Ct(t,"onRepeat"),(e>=t._tDur||e<0)&&t.ratio===u&&(u&&za(t,1),r||L||(Ct(t,u?"onComplete":"onReverseComplete",!0),t._prom&&t._prom()))}else t._zTime||(t._zTime=e)}(this,t,e,r);return this},e.targets=function targets(){return this._targets},e.invalidate=function invalidate(t){return t&&this.vars.runBackwards||(this._startAt=0),this._pt=this._op=this._onUpdate=this._lazy=this.ratio=0,this._ptLookup=[],this.timeline&&this.timeline.invalidate(t),D.prototype.invalidate.call(this,t)},e.resetTo=function resetTo(t,e,r,i,n){c||Rt.wake(),this._ts||this.play();var a,s=Math.min(this._dur,(this._dp._time-this._start)*this._ts);return this._initted||Qt(this,s),a=this._ease(s/this._dur),function _updatePropTweens(t,e,r,i,n,a,s,o){var u,h,l,f,d=(t._pt&&t._ptCache||(t._ptCache={}))[e];if(!d)for(d=t._ptCache[e]=[],l=t._ptLookup,f=t._targets.length;f--;){if((u=l[f][e])&&u.d&&u.d._pt)for(u=u.d._pt;u&&u.p!==e&&u.fp!==e;)u=u._next;if(!u)return Gt=1,t.vars[e]="+=0",Qt(t,s),Gt=0,o?R(e+" not eligible for reset"):1;d.push(u)}for(f=d.length;f--;)(u=(h=d[f])._pt||h).s=!i&&0!==i||n?u.s+(i||0)+a*u.c:i,u.c=r-u.s,h.e&&(h.e=ia(r)+Ya(h.e)),h.b&&(h.b=u.s+Ya(h.b))}(this,t,e,r,i,a,s,n)?this.resetTo(t,e,r,i,1):(Ia(this,0),this.parent||xa(this._dp,this,"_first","_last",this._dp._sort?"_start":0),this.render(0))},e.kill=function kill(t,e){if(void 0===e&&(e="all"),!(t||e&&"all"!==e))return this._lazy=this._pt=0,this.parent?tb(this):this;if(this.timeline){var i=this.timeline.totalDuration();return this.timeline.killTweensOf(t,e,Nt&&!0!==Nt.vars.overwrite)._first||tb(this),this.parent&&i!==this.timeline.totalDuration()&&Ra(this,this._dur*this.timeline._tDur/i,0,1),this}var n,a,s,o,u,h,l,f=this._targets,d=t?Mt(t):f,c=this._ptLookup,p=this._pt;if((!e||"all"===e)&&function _arraysMatch(t,e){for(var r=t.length,i=r===e.length;i&&r--&&t[r]===e[r];);return r<0}(f,d))return"all"===e&&(this._pt=0),tb(this);for(n=this._op=this._op||[],"all"!==e&&(r(e)&&(u={},ha(e,function(t){return u[t]=1}),e=u),e=function _addAliasesToVars(t,e){var r,i,n,a,s=t[0]?fa(t[0]).harness:0,o=s&&s.aliases;if(!o)return e;for(i in r=yt({},e),o)if(i in r)for(n=(a=o[i].split(",")).length;n--;)r[a[n]]=r[i];return r}(f,e)),l=f.length;l--;)if(~d.indexOf(f[l]))for(u in a=c[l],"all"===e?(n[l]=e,o=a,s={}):(s=n[l]=n[l]||{},o=e),o)(h=a&&a[u])&&("kill"in h.d&&!0!==h.d.kill(u)||ya(this,h,"_pt"),delete a[u]),"all"!==s&&(s[u]=1);return this._initted&&!this._pt&&p&&tb(this),this},Tween.to=function to(t,e,r){return new Tween(t,e,r)},Tween.from=function from(t,e){return Va(1,arguments)},Tween.delayedCall=function delayedCall(t,e,r,i){return new Tween(e,0,{immediateRender:!1,lazy:!1,overwrite:!1,delay:t,onComplete:e,onReverseComplete:e,onCompleteParams:r,onReverseCompleteParams:r,callbackScope:i})},Tween.fromTo=function fromTo(t,e,r){return Va(2,arguments)},Tween.set=function set(t,e){return e.duration=0,e.repeatDelay||(e.repeat=0),new Tween(t,e)},Tween.killTweensOf=function killTweensOf(t,e,r){return I.killTweensOf(t,e,r)},Tween}(Ut);qa($t.prototype,{_targets:[],_lazy:0,_startAt:0,_op:0,_onInit:0}),ha("staggerTo,staggerFrom,staggerFromTo",function(r){$t[r]=function(){var t=new Xt,e=kt.call(arguments,0);return e.splice("staggerFromTo"===r?5:4,0,0),t[r].apply(t,e)}});function oc(t,e,r){return t.setAttribute(e,r)}function wc(t,e,r,i){i.mSet(t,e,i.m.call(i.tween,r,i.mt),i)}var Zt=function _setterPlain(t,e,r){return t[e]=r},te=function _setterFunc(t,e,r){return t[e](r)},re=function _setterFuncWithParam(t,e,r,i){return t[e](i.fp,r)},ne=function _getSetter(t,e){return s(t[e])?te:u(t[e])&&t.setAttribute?oc:Zt},ae=function _renderPlain(t,e){return e.set(e.t,e.p,Math.round(1e6*(e.s+e.c*t))/1e6,e)},se=function _renderBoolean(t,e){return e.set(e.t,e.p,!!(e.s+e.c*t),e)},ue=function _renderComplexString(t,e){var r=e._pt,i="";if(!t&&e.b)i=e.b;else if(1===t&&e.e)i=e.e;else{for(;r;)i=r.p+(r.m?r.m(r.s+r.c*t):Math.round(1e4*(r.s+r.c*t))/1e4)+i,r=r._next;i+=e.c}e.set(e.t,e.p,i,e)},he=function _renderPropTweens(t,e){for(var r=e._pt;r;)r.r(t,r.d),r=r._next},fe=function _addPluginModifier(t,e,r,i){for(var n,a=this._pt;a;)n=a._next,a.p===i&&a.modifier(t,e,r),a=n},ce=function _killPropTweensOf(t){for(var e,r,i=this._pt;i;)r=i._next,i.p===t&&!i.op||i.op===t?ya(this,i,"_pt"):i.dep||(e=1),i=r;return!e},pe=function _sortPropTweensByPriority(t){for(var e,r,i,n,a=t._pt;a;){for(e=a._next,r=i;r&&r.pr>a.pr;)r=r._next;(a._prev=r?r._prev:n)?a._prev._next=a:i=a,(a._next=r)?r._prev=a:n=a,a=e}t._pt=i},_e=(PropTween.prototype.modifier=function modifier(t,e,r){this.mSet=this.mSet||this.set,this.set=wc,this.m=t,this.mt=r,this.tween=e},PropTween);function PropTween(t,e,r,i,n,a,s,o,u){this.t=e,this.s=i,this.c=n,this.p=r,this.r=a||ae,this.d=s||this,this.set=o||Zt,this.pr=u||0,(this._next=t)&&(t._prev=this)}ha(vt+"parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger",function(t){return ft[t]=1}),ot.TweenMax=ot.TweenLite=$t,ot.TimelineLite=ot.TimelineMax=Xt,I=new Xt({sortChildren:!1,defaults:V,autoRemoveChildren:!0,id:"root",smoothChildTiming:!0}),q.stringFilter=Fb;function Ec(t){return(ye[t]||Te).map(function(t){return t()})}function Fc(){var t=Date.now(),o=[];2<t-Oe&&(Ec("matchMediaInit"),ge.forEach(function(t){var e,r,i,n,a=t.queries,s=t.conditions;for(r in a)(e=h.matchMedia(a[r]).matches)&&(i=1),e!==s[r]&&(s[r]=e,n=1);n&&(t.revert(),i&&o.push(t))}),Ec("matchMediaRevert"),o.forEach(function(e){return e.onMatch(e,function(t){return e.add(null,t)})}),Oe=t,Ec("matchMedia"))}var me,ge=[],ye={},Te=[],Oe=0,Me=0,Pe=((me=Context.prototype).add=function add(t,i,n){function Gw(){var t,e=l,r=a.selector;return e&&e!==a&&e.data.push(a),n&&(a.selector=cb(n)),l=a,t=i.apply(a,arguments),s(t)&&a._r.push(t),l=e,a.selector=r,a.isReverted=!1,t}s(t)&&(n=i,i=t,t=s);var a=this;return a.last=Gw,t===s?Gw(a,function(t){return a.add(null,t)}):t?a[t]=Gw:Gw},me.ignore=function ignore(t){var e=l;l=null,t(this),l=e},me.getTweens=function getTweens(){var e=[];return this.data.forEach(function(t){return t instanceof Context?e.push.apply(e,t.getTweens()):t instanceof $t&&!(t.parent&&"nested"===t.parent.data)&&e.push(t)}),e},me.clear=function clear(){this._r.length=this.data.length=0},me.kill=function kill(i,t){var n=this;if(i?function(){for(var t,e=n.getTweens(),r=n.data.length;r--;)"isFlip"===(t=n.data[r]).data&&(t.revert(),t.getChildren(!0,!0,!1).forEach(function(t){return e.splice(e.indexOf(t),1)}));for(e.map(function(t){return{g:t._dur||t._delay||t._sat&&!t._sat.vars.immediateRender?t.globalTime(0):-1/0,t:t}}).sort(function(t,e){return e.g-t.g||-1/0}).forEach(function(t){return t.t.revert(i)}),r=n.data.length;r--;)(t=n.data[r])instanceof Xt?"nested"!==t.data&&(t.scrollTrigger&&t.scrollTrigger.revert(),t.kill()):t instanceof $t||!t.revert||t.revert(i);n._r.forEach(function(t){return t(i,n)}),n.isReverted=!0}():this.data.forEach(function(t){return t.kill&&t.kill()}),this.clear(),t)for(var e=ge.length;e--;)ge[e].id===this.id&&ge.splice(e,1)},me.revert=function revert(t){this.kill(t||{})},Context);function Context(t,e){this.selector=e&&cb(e),this.data=[],this._r=[],this.isReverted=!1,this.id=Me++,t&&this.add(t)}var Ce,Ae=((Ce=MatchMedia.prototype).add=function add(t,e,r){v(t)||(t={matches:t});var i,n,a,s=new Pe(0,r||this.scope),o=s.conditions={};for(n in l&&!s.selector&&(s.selector=l.selector),this.contexts.push(s),e=s.add("onMatch",e),s.queries=t)"all"===n?a=1:(i=h.matchMedia(t[n]))&&(ge.indexOf(s)<0&&ge.push(s),(o[n]=i.matches)&&(a=1),i.addListener?i.addListener(Fc):i.addEventListener("change",Fc));return a&&e(s,function(t){return s.add(null,t)}),this},Ce.revert=function revert(t){this.kill(t||{})},Ce.kill=function kill(e){this.contexts.forEach(function(t){return t.kill(e,!0)})},MatchMedia);function MatchMedia(t){this.contexts=[],this.scope=t,l&&l.data.push(this)}var Se={registerPlugin:function registerPlugin(){for(var t=arguments.length,e=new Array(t),r=0;r<t;r++)e[r]=arguments[r];e.forEach(function(t){return wb(t)})},timeline:function timeline(t){return new Xt(t)},getTweensOf:function getTweensOf(t,e){return I.getTweensOf(t,e)},getProperty:function getProperty(i,t,e,n){r(i)&&(i=Mt(i)[0]);var a=fa(i||{}).get,s=e?pa:oa;return"native"===e&&(e=""),i?t?s((pt[t]&&pt[t].get||a)(i,t,e,n)):function(t,e,r){return s((pt[t]&&pt[t].get||a)(i,t,e,r))}:i},quickSetter:function quickSetter(r,e,i){if(1<(r=Mt(r)).length){var n=r.map(function(t){return ze.quickSetter(t,e,i)}),a=n.length;return function(t){for(var e=a;e--;)n[e](t)}}r=r[0]||{};var s=pt[e],o=fa(r),u=o.harness&&(o.harness.aliases||{})[e]||e,h=s?function(t){var e=new s;d._pt=0,e.init(r,i?t+i:t,d,0,[r]),e.render(1,e),d._pt&&he(1,d)}:o.set(r,u);return s?h:function(t){return h(r,u,i?t+i:t,o,1)}},quickTo:function quickTo(t,i,e){function $x(t,e,r){return n.resetTo(i,t,e,r)}var r,n=ze.to(t,yt(((r={})[i]="+=0.1",r.paused=!0,r),e||{}));return $x.tween=n,$x},isTweening:function isTweening(t){return 0<I.getTweensOf(t,!0).length},defaults:function defaults(t){return t&&t.ease&&(t.ease=jt(t.ease,V.ease)),ta(V,t||{})},config:function config(t){return ta(q,t||{})},registerEffect:function registerEffect(t){var i=t.name,n=t.effect,e=t.plugins,a=t.defaults,r=t.extendTimeline;(e||"").split(",").forEach(function(t){return t&&!pt[t]&&!ot[t]&&R(i+" effect requires "+t+" plugin.")}),_t[i]=function(t,e,r){return n(Mt(t),qa(e||{},a),r)},r&&(Xt.prototype[i]=function(t,e,r){return this.add(_t[i](t,v(e)?e:(r=e)&&{},this),r)})},registerEase:function registerEase(t,e){Lt[t]=jt(e)},parseEase:function parseEase(t,e){return arguments.length?jt(t,e):Lt},getById:function getById(t){return I.getById(t)},exportRoot:function exportRoot(t,e){void 0===t&&(t={});var r,i,n=new Xt(t);for(n.smoothChildTiming=w(t.smoothChildTiming),I.remove(n),n._dp=0,n._time=n._tTime=I._time,r=I._first;r;)i=r._next,!e&&!r._dur&&r instanceof $t&&r.vars.onComplete===r._targets[0]||Ka(n,r,r._start-r._delay),r=i;return Ka(I,n,0),n},context:function context(t,e){return t?new Pe(t,e):l},matchMedia:function matchMedia(t){return new Ae(t)},matchMediaRefresh:function matchMediaRefresh(){return ge.forEach(function(t){var e,r,i=t.conditions;for(r in i)i[r]&&(i[r]=!1,e=1);e&&t.revert()})||Fc()},addEventListener:function addEventListener(t,e){var r=ye[t]||(ye[t]=[]);~r.indexOf(e)||r.push(e)},removeEventListener:function removeEventListener(t,e){var r=ye[t],i=r&&r.indexOf(e);0<=i&&r.splice(i,1)},utils:{wrap:function wrap(e,t,r){var i=t-e;return Z(e)?lb(e,wrap(0,e.length),t):Wa(r,function(t){return(i+(t-e)%i)%i+e})},wrapYoyo:function wrapYoyo(e,t,r){var i=t-e,n=2*i;return Z(e)?lb(e,wrapYoyo(0,e.length-1),t):Wa(r,function(t){return e+(i<(t=(n+(t-e)%n)%n||0)?n-t:t)})},distribute:eb,random:hb,snap:gb,normalize:function normalize(t,e,r){return Pt(t,e,0,1,r)},getUnit:Ya,clamp:function clamp(e,r,t){return Wa(t,function(t){return Ot(e,r,t)})},splitColor:Ab,toArray:Mt,selector:cb,mapRange:Pt,pipe:function pipe(){for(var t=arguments.length,e=new Array(t),r=0;r<t;r++)e[r]=arguments[r];return function(t){return e.reduce(function(t,e){return e(t)},t)}},unitize:function unitize(e,r){return function(t){return e(parseFloat(t))+(r||Ya(t))}},interpolate:function interpolate(e,i,t,n){var a=isNaN(e+i)?0:function(t){return(1-t)*e+t*i};if(!a){var s,o,u,h,l,f=r(e),d={};if(!0===t&&(n=1)&&(t=null),f)e={p:e},i={p:i};else if(Z(e)&&!Z(i)){for(u=[],h=e.length,l=h-2,o=1;o<h;o++)u.push(interpolate(e[o-1],e[o]));h--,a=function func(t){t*=h;var e=Math.min(l,~~t);return u[e](t-e)},t=i}else n||(e=yt(Z(e)?[]:{},e));if(!u){for(s in i)Wt.call(d,e,s,"get",i[s]);a=function func(t){return he(t,d)||(f?e.p:e)}}}return Wa(t,a)},shuffle:db},install:P,effects:_t,ticker:Rt,updateRoot:Xt.updateRoot,plugins:pt,globalTimeline:I,core:{PropTween:_e,globals:S,Tween:$t,Timeline:Xt,Animation:Ut,getCache:fa,_removeLinkedListItem:ya,reverting:function reverting(){return L},context:function context(t){return t&&l&&(l.data.push(t),t._ctx=l),l},suppressOverwrites:function suppressOverwrites(t){return F=t}}};ha("to,from,fromTo,delayedCall,set,killTweensOf",function(t){return Se[t]=$t[t]}),Rt.add(Xt.updateRoot),d=Se.to({},{duration:0});function Jc(t,e){for(var r=t._pt;r&&r.p!==e&&r.op!==e&&r.fp!==e;)r=r._next;return r}function Lc(t,a){return{name:t,rawVars:1,init:function init(t,n,e){e._onInit=function(t){var e,i;if(r(n)&&(e={},ha(n,function(t){return e[t]=1}),n=e),a){for(i in e={},n)e[i]=a(n[i]);n=e}!function _addModifiers(t,e){var r,i,n,a=t._targets;for(r in e)for(i=a.length;i--;)(n=(n=t._ptLookup[i][r])&&n.d)&&(n._pt&&(n=Jc(n,r)),n&&n.modifier&&n.modifier(e[r],t,a[i],r))}(t,n)}}}}var ze=Se.registerPlugin({name:"attr",init:function init(t,e,r,i,n){var a,s,o;for(a in this.tween=r,e)o=t.getAttribute(a)||"",(s=this.add(t,"setAttribute",(o||0)+"",e[a],i,n,0,0,a)).op=a,s.b=o,this._props.push(a)},render:function render(t,e){for(var r=e._pt;r;)L?r.set(r.t,r.p,r.b,r):r.r(t,r.d),r=r._next}},{name:"endArray",init:function init(t,e){for(var r=e.length;r--;)this.add(t,r,t[r]||0,e[r],0,0,0,0,0,1)}},Lc("roundProps",fb),Lc("modifiers"),Lc("snap",gb))||Se;$t.version=Xt.version=ze.version="3.12.5",o=1,x()&&Ft();function vd(t,e){return e.set(e.t,e.p,Math.round(1e4*(e.s+e.c*t))/1e4+e.u,e)}function wd(t,e){return e.set(e.t,e.p,1===t?e.e:Math.round(1e4*(e.s+e.c*t))/1e4+e.u,e)}function xd(t,e){return e.set(e.t,e.p,t?Math.round(1e4*(e.s+e.c*t))/1e4+e.u:e.b,e)}function yd(t,e){var r=e.s+e.c*t;e.set(e.t,e.p,~~(r+(r<0?-.5:.5))+e.u,e)}function zd(t,e){return e.set(e.t,e.p,t?e.e:e.b,e)}function Ad(t,e){return e.set(e.t,e.p,1!==t?e.b:e.e,e)}function Bd(t,e,r){return t.style[e]=r}function Cd(t,e,r){return t.style.setProperty(e,r)}function Dd(t,e,r){return t._gsap[e]=r}function Ed(t,e,r){return t._gsap.scaleX=t._gsap.scaleY=r}function Fd(t,e,r,i,n){var a=t._gsap;a.scaleX=a.scaleY=r,a.renderTransform(n,a)}function Gd(t,e,r,i,n){var a=t._gsap;a[e]=r,a.renderTransform(n,a)}function Jd(t,e){var r=this,i=this.target,n=i.style,a=i._gsap;if(t in ar&&n){if(this.tfm=this.tfm||{},"transform"===t)return dr.transform.split(",").forEach(function(t){return Jd.call(r,t,e)});if(~(t=dr[t]||t).indexOf(",")?t.split(",").forEach(function(t){return r.tfm[t]=yr(i,t)}):this.tfm[t]=a.x?a[t]:yr(i,t),t===pr&&(this.tfm.zOrigin=a.zOrigin),0<=this.props.indexOf(cr))return;a.svg&&(this.svgo=i.getAttribute("data-svg-origin"),this.props.push(pr,e,"")),t=cr}(n||e)&&this.props.push(t,e,n[t])}function Kd(t){t.translate&&(t.removeProperty("translate"),t.removeProperty("scale"),t.removeProperty("rotate"))}function Ld(){var t,e,r=this.props,i=this.target,n=i.style,a=i._gsap;for(t=0;t<r.length;t+=3)r[t+1]?i[r[t]]=r[t+2]:r[t+2]?n[r[t]]=r[t+2]:n.removeProperty("--"===r[t].substr(0,2)?r[t]:r[t].replace(hr,"-$1").toLowerCase());if(this.tfm){for(e in this.tfm)a[e]=this.tfm[e];a.svg&&(a.renderTransform(),i.setAttribute("data-svg-origin",this.svgo||"")),(t=Be())&&t.isStart||n[cr]||(Kd(n),a.zOrigin&&n[pr]&&(n[pr]+=" "+a.zOrigin+"px",a.zOrigin=0,a.renderTransform()),a.uncache=1)}}function Md(t,e){var r={target:t,props:[],revert:Ld,save:Jd};return t._gsap||ze.core.getCache(t),e&&e.split(",").forEach(function(t){return r.save(t)}),r}function Od(t,e){var r=De.createElementNS?De.createElementNS((e||"http://www.w3.org/1999/xhtml").replace(/^https/,"http"),t):De.createElement(t);return r&&r.style?r:De.createElement(t)}function Pd(t,e,r){var i=getComputedStyle(t);return i[e]||i.getPropertyValue(e.replace(hr,"-$1").toLowerCase())||i.getPropertyValue(e)||!r&&Pd(t,mr(e)||e,1)||""}function Sd(){(function _windowExists(){return"undefined"!=typeof window})()&&window.document&&(Ee=window,De=Ee.document,Re=De.documentElement,Le=Od("div")||{style:{}},Od("div"),cr=mr(cr),pr=cr+"Origin",Le.style.cssText="border-width:0;line-height:0;position:absolute;padding:0",Ye=!!mr("perspective"),Be=ze.core.reverting,Fe=1)}function Td(t){var e,r=Od("svg",this.ownerSVGElement&&this.ownerSVGElement.getAttribute("xmlns")||"http://www.w3.org/2000/svg"),i=this.parentNode,n=this.nextSibling,a=this.style.cssText;if(Re.appendChild(r),r.appendChild(this),this.style.display="block",t)try{e=this.getBBox(),this._gsapBBox=this.getBBox,this.getBBox=Td}catch(t){}else this._gsapBBox&&(e=this._gsapBBox());return i&&(n?i.insertBefore(this,n):i.appendChild(this)),Re.removeChild(r),this.style.cssText=a,e}function Ud(t,e){for(var r=e.length;r--;)if(t.hasAttribute(e[r]))return t.getAttribute(e[r])}function Vd(e){var r;try{r=e.getBBox()}catch(t){r=Td.call(e,!0)}return r&&(r.width||r.height)||e.getBBox===Td||(r=Td.call(e,!0)),!r||r.width||r.x||r.y?r:{x:+Ud(e,["x","cx","x1"])||0,y:+Ud(e,["y","cy","y1"])||0,width:0,height:0}}function Wd(t){return!(!t.getCTM||t.parentNode&&!t.ownerSVGElement||!Vd(t))}function Xd(t,e){if(e){var r,i=t.style;e in ar&&e!==pr&&(e=cr),i.removeProperty?("ms"!==(r=e.substr(0,2))&&"webkit"!==e.substr(0,6)||(e="-"+e),i.removeProperty("--"===r?e:e.replace(hr,"-$1").toLowerCase())):i.removeAttribute(e)}}function Yd(t,e,r,i,n,a){var s=new _e(t._pt,e,r,0,1,a?Ad:zd);return(t._pt=s).b=i,s.e=n,t._props.push(r),s}function _d(t,e,r,i){var n,a,s,o,u=parseFloat(r)||0,h=(r+"").trim().substr((u+"").length)||"px",l=Le.style,f=lr.test(e),d="svg"===t.tagName.toLowerCase(),c=(d?"client":"offset")+(f?"Width":"Height"),p="px"===i,_="%"===i;if(i===h||!u||gr[i]||gr[h])return u;if("px"===h||p||(u=_d(t,e,r,"px")),o=t.getCTM&&Wd(t),(_||"%"===h)&&(ar[e]||~e.indexOf("adius")))return n=o?t.getBBox()[f?"width":"height"]:t[c],ia(_?u/n*100:u/100*n);if(l[f?"width":"height"]=100+(p?h:i),a=~e.indexOf("adius")||"em"===i&&t.appendChild&&!d?t:t.parentNode,o&&(a=(t.ownerSVGElement||{}).parentNode),a&&a!==De&&a.appendChild||(a=De.body),(s=a._gsap)&&_&&s.width&&f&&s.time===Rt.time&&!s.uncache)return ia(u/s.width*100);if(!_||"height"!==e&&"width"!==e)!_&&"%"!==h||vr[Pd(a,"display")]||(l.position=Pd(t,"position")),a===t&&(l.position="static"),a.appendChild(Le),n=Le[c],a.removeChild(Le),l.position="absolute";else{var m=t.style[e];t.style[e]=100+i,n=t[c],m?t.style[e]=m:Xd(t,e)}return f&&_&&((s=fa(a)).time=Rt.time,s.width=a[c]),ia(p?n*u/100:n&&u?100/n*u:0)}function be(t,e,r,i){if(!r||"none"===r){var n=mr(e,t,1),a=n&&Pd(t,n,1);a&&a!==r?(e=n,r=a):"borderColor"===e&&(r=Pd(t,"borderTopColor"))}var s,o,u,h,l,f,d,c,p,_,m,g=new _e(this._pt,t.style,e,0,1,ue),v=0,y=0;if(g.b=r,g.e=i,r+="","auto"===(i+="")&&(f=t.style[e],t.style[e]=i,i=Pd(t,e)||i,f?t.style[e]=f:Xd(t,e)),Fb(s=[r,i]),i=s[1],u=(r=s[0]).match(rt)||[],(i.match(rt)||[]).length){for(;o=rt.exec(i);)d=o[0],p=i.substring(v,o.index),l?l=(l+1)%5:"rgba("!==p.substr(-5)&&"hsla("!==p.substr(-5)||(l=1),d!==(f=u[y++]||"")&&(h=parseFloat(f)||0,m=f.substr((h+"").length),"="===d.charAt(1)&&(d=ka(h,d)+m),c=parseFloat(d),_=d.substr((c+"").length),v=rt.lastIndex-_.length,_||(_=_||q.units[e]||m,v===i.length&&(i+=_,g.e+=_)),m!==_&&(h=_d(t,e,f,_)||0),g._pt={_next:g._pt,p:p||1===y?p:",",s:h,c:c-h,m:l&&l<4||"zIndex"===e?Math.round:0});g.c=v<i.length?i.substring(v,i.length):""}else g.r="display"===e&&"none"===i?Ad:zd;return nt.test(i)&&(g.e=0),this._pt=g}function de(t){var e=t.split(" "),r=e[0],i=e[1]||"50%";return"top"!==r&&"bottom"!==r&&"left"!==i&&"right"!==i||(t=r,r=i,i=t),e[0]=Tr[r]||r,e[1]=Tr[i]||i,e.join(" ")}function ee(t,e){if(e.tween&&e.tween._time===e.tween._dur){var r,i,n,a=e.t,s=a.style,o=e.u,u=a._gsap;if("all"===o||!0===o)s.cssText="",i=1;else for(n=(o=o.split(",")).length;-1<--n;)r=o[n],ar[r]&&(i=1,r="transformOrigin"===r?pr:cr),Xd(a,r);i&&(Xd(a,cr),u&&(u.svg&&a.removeAttribute("transform"),Or(a,1),u.uncache=1,Kd(s)))}}function ie(t){return"matrix(1, 0, 0, 1, 0, 0)"===t||"none"===t||!t}function je(t){var e=Pd(t,cr);return ie(e)?wr:e.substr(7).match(et).map(ia)}function ke(t,e){var r,i,n,a,s=t._gsap||fa(t),o=t.style,u=je(t);return s.svg&&t.getAttribute("transform")?"1,0,0,1,0,0"===(u=[(n=t.transform.baseVal.consolidate().matrix).a,n.b,n.c,n.d,n.e,n.f]).join(",")?wr:u:(u!==wr||t.offsetParent||t===Re||s.svg||(n=o.display,o.display="block",(r=t.parentNode)&&t.offsetParent||(a=1,i=t.nextElementSibling,Re.appendChild(t)),u=je(t),n?o.display=n:Xd(t,"display"),a&&(i?r.insertBefore(t,i):r?r.appendChild(t):Re.removeChild(t))),e&&6<u.length?[u[0],u[1],u[4],u[5],u[12],u[13]]:u)}function le(t,e,r,i,n,a){var s,o,u,h=t._gsap,l=n||ke(t,!0),f=h.xOrigin||0,d=h.yOrigin||0,c=h.xOffset||0,p=h.yOffset||0,_=l[0],m=l[1],g=l[2],v=l[3],y=l[4],T=l[5],b=e.split(" "),w=parseFloat(b[0])||0,x=parseFloat(b[1])||0;r?l!==wr&&(o=_*v-m*g)&&(u=w*(-m/o)+x*(_/o)-(_*T-m*y)/o,w=w*(v/o)+x*(-g/o)+(g*T-v*y)/o,x=u):(w=(s=Vd(t)).x+(~b[0].indexOf("%")?w/100*s.width:w),x=s.y+(~(b[1]||b[0]).indexOf("%")?x/100*s.height:x)),i||!1!==i&&h.smooth?(y=w-f,T=x-d,h.xOffset=c+(y*_+T*g)-y,h.yOffset=p+(y*m+T*v)-T):h.xOffset=h.yOffset=0,h.xOrigin=w,h.yOrigin=x,h.smooth=!!i,h.origin=e,h.originIsAbsolute=!!r,t.style[pr]="0px 0px",a&&(Yd(a,h,"xOrigin",f,w),Yd(a,h,"yOrigin",d,x),Yd(a,h,"xOffset",c,h.xOffset),Yd(a,h,"yOffset",p,h.yOffset)),t.setAttribute("data-svg-origin",w+" "+x)}function oe(t,e,r){var i=Ya(e);return ia(parseFloat(e)+parseFloat(_d(t,"x",r+"px",i)))+i}function ve(t,e,i,n,a){var s,o,u=360,h=r(a),l=parseFloat(a)*(h&&~a.indexOf("rad")?sr:1)-n,f=n+l+"deg";return h&&("short"===(s=a.split("_")[1])&&(l%=u)!==l%180&&(l+=l<0?u:-u),"cw"===s&&l<0?l=(l+36e9)%u-~~(l/u)*u:"ccw"===s&&0<l&&(l=(l-36e9)%u-~~(l/u)*u)),t._pt=o=new _e(t._pt,e,i,n,l,wd),o.e=f,o.u="deg",t._props.push(i),o}function we(t,e){for(var r in e)t[r]=e[r];return t}function xe(t,e,r){var i,n,a,s,o,u,h,l=we({},r._gsap),f=r.style;for(n in l.svg?(a=r.getAttribute("transform"),r.setAttribute("transform",""),f[cr]=e,i=Or(r,1),Xd(r,cr),r.setAttribute("transform",a)):(a=getComputedStyle(r)[cr],f[cr]=e,i=Or(r,1),f[cr]=a),ar)(a=l[n])!==(s=i[n])&&"perspective,force3D,transformOrigin,svgOrigin".indexOf(n)<0&&(o=Ya(a)!==(h=Ya(s))?_d(r,n,a,h):parseFloat(a),u=parseFloat(s),t._pt=new _e(t._pt,i,n,o,u-o,vd),t._pt.u=h||0,t._props.push(n));we(i,l)}var Ee,De,Re,Fe,Le,Ie,Be,Ye,qe=Lt.Power0,Ve=Lt.Power1,Ue=Lt.Power2,Xe=Lt.Power3,Ne=Lt.Power4,Ge=Lt.Linear,We=Lt.Quad,Qe=Lt.Cubic,Ke=Lt.Quart,Je=Lt.Quint,He=Lt.Strong,$e=Lt.Elastic,Ze=Lt.Back,tr=Lt.SteppedEase,er=Lt.Bounce,rr=Lt.Sine,ir=Lt.Expo,nr=Lt.Circ,ar={},sr=180/Math.PI,or=Math.PI/180,ur=Math.atan2,hr=/([A-Z])/g,lr=/(left|right|width|margin|padding|x)/i,fr=/[\s,\(]\S/,dr={autoAlpha:"opacity,visibility",scale:"scaleX,scaleY",alpha:"opacity"},cr="transform",pr=cr+"Origin",_r="O,Moz,ms,Ms,Webkit".split(","),mr=function _checkPropPrefix(t,e,r){var i=(e||Le).style,n=5;if(t in i&&!r)return t;for(t=t.charAt(0).toUpperCase()+t.substr(1);n--&&!(_r[n]+t in i););return n<0?null:(3===n?"ms":0<=n?_r[n]:"")+t},gr={deg:1,rad:1,turn:1},vr={grid:1,flex:1},yr=function _get(t,e,r,i){var n;return Fe||Sd(),e in dr&&"transform"!==e&&~(e=dr[e]).indexOf(",")&&(e=e.split(",")[0]),ar[e]&&"transform"!==e?(n=Or(t,i),n="transformOrigin"!==e?n[e]:n.svg?n.origin:kr(Pd(t,pr))+" "+n.zOrigin+"px"):(n=t.style[e])&&"auto"!==n&&!i&&!~(n+"").indexOf("calc(")||(n=br[e]&&br[e](t,e,r)||Pd(t,e)||ga(t,e)||("opacity"===e?1:0)),r&&!~(n+"").trim().indexOf(" ")?_d(t,e,n,r)+r:n},Tr={top:"0%",bottom:"100%",left:"0%",right:"100%",center:"50%"},br={clearProps:function clearProps(t,e,r,i,n){if("isFromStart"!==n.data){var a=t._pt=new _e(t._pt,e,r,0,0,ee);return a.u=i,a.pr=-10,a.tween=n,t._props.push(r),1}}},wr=[1,0,0,1,0,0],xr={},Or=function _parseTransform(t,e){var r=t._gsap||new Vt(t);if("x"in r&&!e&&!r.uncache)return r;var i,n,a,s,o,u,h,l,f,d,c,p,_,m,g,v,y,T,b,w,x,O,k,M,P,C,A,S,z,E,D,R,F=t.style,L=r.scaleX<0,I="deg",B=getComputedStyle(t),Y=Pd(t,pr)||"0";return i=n=a=u=h=l=f=d=c=0,s=o=1,r.svg=!(!t.getCTM||!Wd(t)),B.translate&&("none"===B.translate&&"none"===B.scale&&"none"===B.rotate||(F[cr]=("none"!==B.translate?"translate3d("+(B.translate+" 0 0").split(" ").slice(0,3).join(", ")+") ":"")+("none"!==B.rotate?"rotate("+B.rotate+") ":"")+("none"!==B.scale?"scale("+B.scale.split(" ").join(",")+") ":"")+("none"!==B[cr]?B[cr]:"")),F.scale=F.rotate=F.translate="none"),m=ke(t,r.svg),r.svg&&(M=r.uncache?(P=t.getBBox(),Y=r.xOrigin-P.x+"px "+(r.yOrigin-P.y)+"px",""):!e&&t.getAttribute("data-svg-origin"),le(t,M||Y,!!M||r.originIsAbsolute,!1!==r.smooth,m)),p=r.xOrigin||0,_=r.yOrigin||0,m!==wr&&(T=m[0],b=m[1],w=m[2],x=m[3],i=O=m[4],n=k=m[5],6===m.length?(s=Math.sqrt(T*T+b*b),o=Math.sqrt(x*x+w*w),u=T||b?ur(b,T)*sr:0,(f=w||x?ur(w,x)*sr+u:0)&&(o*=Math.abs(Math.cos(f*or))),r.svg&&(i-=p-(p*T+_*w),n-=_-(p*b+_*x))):(R=m[6],E=m[7],A=m[8],S=m[9],z=m[10],D=m[11],i=m[12],n=m[13],a=m[14],h=(g=ur(R,z))*sr,g&&(M=O*(v=Math.cos(-g))+A*(y=Math.sin(-g)),P=k*v+S*y,C=R*v+z*y,A=O*-y+A*v,S=k*-y+S*v,z=R*-y+z*v,D=E*-y+D*v,O=M,k=P,R=C),l=(g=ur(-w,z))*sr,g&&(v=Math.cos(-g),D=x*(y=Math.sin(-g))+D*v,T=M=T*v-A*y,b=P=b*v-S*y,w=C=w*v-z*y),u=(g=ur(b,T))*sr,g&&(M=T*(v=Math.cos(g))+b*(y=Math.sin(g)),P=O*v+k*y,b=b*v-T*y,k=k*v-O*y,T=M,O=P),h&&359.9<Math.abs(h)+Math.abs(u)&&(h=u=0,l=180-l),s=ia(Math.sqrt(T*T+b*b+w*w)),o=ia(Math.sqrt(k*k+R*R)),g=ur(O,k),f=2e-4<Math.abs(g)?g*sr:0,c=D?1/(D<0?-D:D):0),r.svg&&(M=t.getAttribute("transform"),r.forceCSS=t.setAttribute("transform","")||!ie(Pd(t,cr)),M&&t.setAttribute("transform",M))),90<Math.abs(f)&&Math.abs(f)<270&&(L?(s*=-1,f+=u<=0?180:-180,u+=u<=0?180:-180):(o*=-1,f+=f<=0?180:-180)),e=e||r.uncache,r.x=i-((r.xPercent=i&&(!e&&r.xPercent||(Math.round(t.offsetWidth/2)===Math.round(-i)?-50:0)))?t.offsetWidth*r.xPercent/100:0)+"px",r.y=n-((r.yPercent=n&&(!e&&r.yPercent||(Math.round(t.offsetHeight/2)===Math.round(-n)?-50:0)))?t.offsetHeight*r.yPercent/100:0)+"px",r.z=a+"px",r.scaleX=ia(s),r.scaleY=ia(o),r.rotation=ia(u)+I,r.rotationX=ia(h)+I,r.rotationY=ia(l)+I,r.skewX=f+I,r.skewY=d+I,r.transformPerspective=c+"px",(r.zOrigin=parseFloat(Y.split(" ")[2])||!e&&r.zOrigin||0)&&(F[pr]=kr(Y)),r.xOffset=r.yOffset=0,r.force3D=q.force3D,r.renderTransform=r.svg?zr:Ye?Sr:Mr,r.uncache=0,r},kr=function _firstTwoOnly(t){return(t=t.split(" "))[0]+" "+t[1]},Mr=function _renderNon3DTransforms(t,e){e.z="0px",e.rotationY=e.rotationX="0deg",e.force3D=0,Sr(t,e)},Pr="0deg",Cr="0px",Ar=") ",Sr=function _renderCSSTransforms(t,e){var r=e||this,i=r.xPercent,n=r.yPercent,a=r.x,s=r.y,o=r.z,u=r.rotation,h=r.rotationY,l=r.rotationX,f=r.skewX,d=r.skewY,c=r.scaleX,p=r.scaleY,_=r.transformPerspective,m=r.force3D,g=r.target,v=r.zOrigin,y="",T="auto"===m&&t&&1!==t||!0===m;if(v&&(l!==Pr||h!==Pr)){var b,w=parseFloat(h)*or,x=Math.sin(w),O=Math.cos(w);w=parseFloat(l)*or,b=Math.cos(w),a=oe(g,a,x*b*-v),s=oe(g,s,-Math.sin(w)*-v),o=oe(g,o,O*b*-v+v)}_!==Cr&&(y+="perspective("+_+Ar),(i||n)&&(y+="translate("+i+"%, "+n+"%) "),!T&&a===Cr&&s===Cr&&o===Cr||(y+=o!==Cr||T?"translate3d("+a+", "+s+", "+o+") ":"translate("+a+", "+s+Ar),u!==Pr&&(y+="rotate("+u+Ar),h!==Pr&&(y+="rotateY("+h+Ar),l!==Pr&&(y+="rotateX("+l+Ar),f===Pr&&d===Pr||(y+="skew("+f+", "+d+Ar),1===c&&1===p||(y+="scale("+c+", "+p+Ar),g.style[cr]=y||"translate(0, 0)"},zr=function _renderSVGTransforms(t,e){var r,i,n,a,s,o=e||this,u=o.xPercent,h=o.yPercent,l=o.x,f=o.y,d=o.rotation,c=o.skewX,p=o.skewY,_=o.scaleX,m=o.scaleY,g=o.target,v=o.xOrigin,y=o.yOrigin,T=o.xOffset,b=o.yOffset,w=o.forceCSS,x=parseFloat(l),O=parseFloat(f);d=parseFloat(d),c=parseFloat(c),(p=parseFloat(p))&&(c+=p=parseFloat(p),d+=p),d||c?(d*=or,c*=or,r=Math.cos(d)*_,i=Math.sin(d)*_,n=Math.sin(d-c)*-m,a=Math.cos(d-c)*m,c&&(p*=or,s=Math.tan(c-p),n*=s=Math.sqrt(1+s*s),a*=s,p&&(s=Math.tan(p),r*=s=Math.sqrt(1+s*s),i*=s)),r=ia(r),i=ia(i),n=ia(n),a=ia(a)):(r=_,a=m,i=n=0),(x&&!~(l+"").indexOf("px")||O&&!~(f+"").indexOf("px"))&&(x=_d(g,"x",l,"px"),O=_d(g,"y",f,"px")),(v||y||T||b)&&(x=ia(x+v-(v*r+y*n)+T),O=ia(O+y-(v*i+y*a)+b)),(u||h)&&(s=g.getBBox(),x=ia(x+u/100*s.width),O=ia(O+h/100*s.height)),s="matrix("+r+","+i+","+n+","+a+","+x+","+O+")",g.setAttribute("transform",s),w&&(g.style[cr]=s)};ha("padding,margin,Width,Radius",function(e,r){var t="Right",i="Bottom",n="Left",o=(r<3?["Top",t,i,n]:["Top"+n,"Top"+t,i+t,i+n]).map(function(t){return r<2?e+t:"border"+t+e});br[1<r?"border"+e:e]=function(e,t,r,i,n){var a,s;if(arguments.length<4)return a=o.map(function(t){return yr(e,t,r)}),5===(s=a.join(" ")).split(a[0]).length?a[0]:s;a=(i+"").split(" "),s={},o.forEach(function(t,e){return s[t]=a[e]=a[e]||a[(e-1)/2|0]}),e.init(t,s,n)}});var Er,Dr,Rr,Fr={name:"css",register:Sd,targetTest:function targetTest(t){return t.style&&t.nodeType},init:function init(t,e,i,n,a){var s,o,u,h,l,f,d,c,p,_,m,g,v,y,T,b,w=this._props,x=t.style,O=i.vars.startAt;for(d in Fe||Sd(),this.styles=this.styles||Md(t),b=this.styles.props,this.tween=i,e)if("autoRound"!==d&&(o=e[d],!pt[d]||!ac(d,e,i,n,t,a)))if(l=typeof o,f=br[d],"function"===l&&(l=typeof(o=o.call(i,n,t,a))),"string"===l&&~o.indexOf("random(")&&(o=ob(o)),f)f(this,t,d,o,i)&&(T=1);else if("--"===d.substr(0,2))s=(getComputedStyle(t).getPropertyValue(d)+"").trim(),o+="",Et.lastIndex=0,Et.test(s)||(c=Ya(s),p=Ya(o)),p?c!==p&&(s=_d(t,d,s,p)+p):c&&(o+=c),this.add(x,"setProperty",s,o,n,a,0,0,d),w.push(d),b.push(d,0,x[d]);else if("undefined"!==l){if(O&&d in O?(s="function"==typeof O[d]?O[d].call(i,n,t,a):O[d],r(s)&&~s.indexOf("random(")&&(s=ob(s)),Ya(s+"")||"auto"===s||(s+=q.units[d]||Ya(yr(t,d))||""),"="===(s+"").charAt(1)&&(s=yr(t,d))):s=yr(t,d),h=parseFloat(s),(_="string"===l&&"="===o.charAt(1)&&o.substr(0,2))&&(o=o.substr(2)),u=parseFloat(o),d in dr&&("autoAlpha"===d&&(1===h&&"hidden"===yr(t,"visibility")&&u&&(h=0),b.push("visibility",0,x.visibility),Yd(this,x,"visibility",h?"inherit":"hidden",u?"inherit":"hidden",!u)),"scale"!==d&&"transform"!==d&&~(d=dr[d]).indexOf(",")&&(d=d.split(",")[0])),m=d in ar)if(this.styles.save(d),g||((v=t._gsap).renderTransform&&!e.parseTransform||Or(t,e.parseTransform),y=!1!==e.smoothOrigin&&v.smooth,(g=this._pt=new _e(this._pt,x,cr,0,1,v.renderTransform,v,0,-1)).dep=1),"scale"===d)this._pt=new _e(this._pt,v,"scaleY",v.scaleY,(_?ka(v.scaleY,_+u):u)-v.scaleY||0,vd),this._pt.u=0,w.push("scaleY",d),d+="X";else{if("transformOrigin"===d){b.push(pr,0,x[pr]),o=de(o),v.svg?le(t,o,0,y,0,this):((p=parseFloat(o.split(" ")[2])||0)!==v.zOrigin&&Yd(this,v,"zOrigin",v.zOrigin,p),Yd(this,x,d,kr(s),kr(o)));continue}if("svgOrigin"===d){le(t,o,1,y,0,this);continue}if(d in xr){ve(this,v,d,h,_?ka(h,_+o):o);continue}if("smoothOrigin"===d){Yd(this,v,"smooth",v.smooth,o);continue}if("force3D"===d){v[d]=o;continue}if("transform"===d){xe(this,o,t);continue}}else d in x||(d=mr(d)||d);if(m||(u||0===u)&&(h||0===h)&&!fr.test(o)&&d in x)u=u||0,(c=(s+"").substr((h+"").length))!==(p=Ya(o)||(d in q.units?q.units[d]:c))&&(h=_d(t,d,s,p)),this._pt=new _e(this._pt,m?v:x,d,h,(_?ka(h,_+u):u)-h,m||"px"!==p&&"zIndex"!==d||!1===e.autoRound?vd:yd),this._pt.u=p||0,c!==p&&"%"!==p&&(this._pt.b=s,this._pt.r=xd);else if(d in x)be.call(this,t,d,s,_?_+o:o);else if(d in t)this.add(t,d,s||t[d],_?_+o:o,n,a);else if("parseTransform"!==d){Q(d,o);continue}m||(d in x?b.push(d,0,x[d]):b.push(d,1,s||t[d])),w.push(d)}T&&pe(this)},render:function render(t,e){if(e.tween._time||!Be())for(var r=e._pt;r;)r.r(t,r.d),r=r._next;else e.styles.revert()},get:yr,aliases:dr,getSetter:function getSetter(t,e,r){var i=dr[e];return i&&i.indexOf(",")<0&&(e=i),e in ar&&e!==pr&&(t._gsap.x||yr(t,"x"))?r&&Ie===r?"scale"===e?Ed:Dd:(Ie=r||{})&&("scale"===e?Fd:Gd):t.style&&!u(t.style[e])?Bd:~e.indexOf("-")?Cd:ne(t,e)},core:{_removeProperty:Xd,_getMatrix:ke}};ze.utils.checkPrefix=mr,ze.core.getStyleSaver=Md,Rr=ha((Er="x,y,z,scale,scaleX,scaleY,xPercent,yPercent")+","+(Dr="rotation,rotationX,rotationY,skewX,skewY")+",transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective",function(t){ar[t]=1}),ha(Dr,function(t){q.units[t]="deg",xr[t]=1}),dr[Rr[13]]=Er+","+Dr,ha("0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY",function(t){var e=t.split(":");dr[e[1]]=Rr[e[0]]}),ha("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective",function(t){q.units[t]="px"}),ze.registerPlugin(Fr);var Lr=ze.registerPlugin(Fr)||ze,Ir=Lr.core.Tween;e.Back=Ze,e.Bounce=er,e.CSSPlugin=Fr,e.Circ=nr,e.Cubic=Qe,e.Elastic=$e,e.Expo=ir,e.Linear=Ge,e.Power0=qe,e.Power1=Ve,e.Power2=Ue,e.Power3=Xe,e.Power4=Ne,e.Quad=We,e.Quart=Ke,e.Quint=Je,e.Sine=rr,e.SteppedEase=tr,e.Strong=He,e.TimelineLite=Xt,e.TimelineMax=Xt,e.TweenLite=$t,e.TweenMax=Ir,e.default=Lr,e.gsap=Lr;if (typeof(window)==="undefined"||window!==e){Object.defineProperty(e,"__esModule",{value:!0})} else {delete e.default}});
|
| 11 |
+
|