UNPKG

git-contri-merged

Version:

A React component to display merged GitHub contribution graphs from multiple contributors

1,082 lines (1,081 loc) 35.6 kB
import { jsxs as S, jsx as f, Fragment as yt } from "react/jsx-runtime"; import { useState as M, useRef as wt, useCallback as bt, useEffect as xt, useMemo as Ct } from "react"; function St(t, e) { if (t.match(/^[a-z]+:\/\//i)) return t; if (t.match(/^\/\//)) return window.location.protocol + t; if (t.match(/^[a-z]+:/i)) return t; const n = document.implementation.createHTMLDocument(), r = n.createElement("base"), i = n.createElement("a"); return n.head.appendChild(r), n.body.appendChild(i), e && (r.href = e), i.href = t, i.href; } const vt = /* @__PURE__ */ (() => { let t = 0; const e = () => ( // eslint-disable-next-line no-bitwise `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4) ); return () => (t += 1, `u${e()}${t}`); })(); function $(t) { const e = []; for (let n = 0, r = t.length; n < r; n++) e.push(t[n]); return e; } let F = null; function et(t = {}) { return F || (t.includeStyleProperties ? (F = t.includeStyleProperties, F) : (F = $(window.getComputedStyle(document.documentElement)), F)); } function U(t, e) { const r = (t.ownerDocument.defaultView || window).getComputedStyle(t).getPropertyValue(e); return r ? parseFloat(r.replace("px", "")) : 0; } function Et(t) { const e = U(t, "border-left-width"), n = U(t, "border-right-width"); return t.clientWidth + e + n; } function $t(t) { const e = U(t, "border-top-width"), n = U(t, "border-bottom-width"); return t.clientHeight + e + n; } function nt(t, e = {}) { const n = e.width || Et(t), r = e.height || $t(t); return { width: n, height: r }; } function Rt() { let t, e; try { e = process; } catch { } const n = e && e.env ? e.env.devicePixelRatio : null; return n && (t = parseInt(n, 10), Number.isNaN(t) && (t = 1)), t || window.devicePixelRatio || 1; } const C = 16384; function Dt(t) { (t.width > C || t.height > C) && (t.width > C && t.height > C ? t.width > t.height ? (t.height *= C / t.width, t.width = C) : (t.width *= C / t.height, t.height = C) : t.width > C ? (t.height *= C / t.width, t.width = C) : (t.width *= C / t.height, t.height = C)); } function O(t) { return new Promise((e, n) => { const r = new Image(); r.onload = () => { r.decode().then(() => { requestAnimationFrame(() => e(r)); }); }, r.onerror = n, r.crossOrigin = "anonymous", r.decoding = "async", r.src = t; }); } async function Tt(t) { return Promise.resolve().then(() => new XMLSerializer().serializeToString(t)).then(encodeURIComponent).then((e) => `data:image/svg+xml;charset=utf-8,${e}`); } async function Ft(t, e, n) { const r = "http://www.w3.org/2000/svg", i = document.createElementNS(r, "svg"), o = document.createElementNS(r, "foreignObject"); return i.setAttribute("width", `${e}`), i.setAttribute("height", `${n}`), i.setAttribute("viewBox", `0 0 ${e} ${n}`), o.setAttribute("width", "100%"), o.setAttribute("height", "100%"), o.setAttribute("x", "0"), o.setAttribute("y", "0"), o.setAttribute("externalResourcesRequired", "true"), i.appendChild(o), o.appendChild(t), Tt(i); } const w = (t, e) => { if (t instanceof e) return !0; const n = Object.getPrototypeOf(t); return n === null ? !1 : n.constructor.name === e.name || w(n, e); }; function kt(t) { const e = t.getPropertyValue("content"); return `${t.cssText} content: '${e.replace(/'|"/g, "")}';`; } function Lt(t, e) { return et(e).map((n) => { const r = t.getPropertyValue(n), i = t.getPropertyPriority(n); return `${n}: ${r}${i ? " !important" : ""};`; }).join(" "); } function Pt(t, e, n, r) { const i = `.${t}:${e}`, o = n.cssText ? kt(n) : Lt(n, r); return document.createTextNode(`${i}{${o}}`); } function z(t, e, n, r) { const i = window.getComputedStyle(t, n), o = i.getPropertyValue("content"); if (o === "" || o === "none") return; const s = vt(); try { e.className = `${e.className} ${s}`; } catch { return; } const a = document.createElement("style"); a.appendChild(Pt(s, n, i, r)), e.appendChild(a); } function It(t, e, n) { z(t, e, ":before", n), z(t, e, ":after", n); } const J = "application/font-woff", X = "image/jpeg", At = { woff: J, woff2: J, ttf: "application/font-truetype", eot: "application/vnd.ms-fontobject", png: "image/png", jpg: X, jpeg: X, gif: "image/gif", tiff: "image/tiff", svg: "image/svg+xml", webp: "image/webp" }; function Mt(t) { const e = /\.([^./]*?)$/g.exec(t); return e ? e[1] : ""; } function V(t) { const e = Mt(t).toLowerCase(); return At[e] || ""; } function Ut(t) { return t.split(/,/)[1]; } function B(t) { return t.search(/^(data:)/) !== -1; } function Ot(t, e) { return `data:${e};base64,${t}`; } async function rt(t, e, n) { const r = await fetch(t, e); if (r.status === 404) throw new Error(`Resource "${r.url}" not found`); const i = await r.blob(); return new Promise((o, s) => { const a = new FileReader(); a.onerror = s, a.onloadend = () => { try { o(n({ res: r, result: a.result })); } catch (c) { s(c); } }, a.readAsDataURL(i); }); } const j = {}; function Ht(t, e, n) { let r = t.replace(/\?.*/, ""); return n && (r = t), /ttf|otf|eot|woff2?/i.test(r) && (r = r.replace(/.*\//, "")), e ? `[${e}]${r}` : r; } async function _(t, e, n) { const r = Ht(t, e, n.includeQueryParams); if (j[r] != null) return j[r]; n.cacheBust && (t += (/\?/.test(t) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime()); let i; try { const o = await rt(t, n.fetchRequestInit, ({ res: s, result: a }) => (e || (e = s.headers.get("Content-Type") || ""), Ut(a))); i = Ot(o, e); } catch (o) { i = n.imagePlaceholder || ""; let s = `Failed to fetch resource: ${t}`; o && (s = typeof o == "string" ? o : o.message), s && console.warn(s); } return j[r] = i, i; } async function Wt(t) { const e = t.toDataURL(); return e === "data:," ? t.cloneNode(!1) : O(e); } async function jt(t, e) { if (t.currentSrc) { const o = document.createElement("canvas"), s = o.getContext("2d"); o.width = t.clientWidth, o.height = t.clientHeight, s == null || s.drawImage(t, 0, 0, o.width, o.height); const a = o.toDataURL(); return O(a); } const n = t.poster, r = V(n), i = await _(n, r, e); return O(i); } async function Bt(t, e) { var n; try { if (!((n = t == null ? void 0 : t.contentDocument) === null || n === void 0) && n.body) return await H(t.contentDocument.body, e, !0); } catch { } return t.cloneNode(!1); } async function Vt(t, e) { return w(t, HTMLCanvasElement) ? Wt(t) : w(t, HTMLVideoElement) ? jt(t, e) : w(t, HTMLIFrameElement) ? Bt(t, e) : t.cloneNode(ot(t)); } const _t = (t) => t.tagName != null && t.tagName.toUpperCase() === "SLOT", ot = (t) => t.tagName != null && t.tagName.toUpperCase() === "SVG"; async function Gt(t, e, n) { var r, i; if (ot(e)) return e; let o = []; return _t(t) && t.assignedNodes ? o = $(t.assignedNodes()) : w(t, HTMLIFrameElement) && (!((r = t.contentDocument) === null || r === void 0) && r.body) ? o = $(t.contentDocument.body.childNodes) : o = $(((i = t.shadowRoot) !== null && i !== void 0 ? i : t).childNodes), o.length === 0 || w(t, HTMLVideoElement) || await o.reduce((s, a) => s.then(() => H(a, n)).then((c) => { c && e.appendChild(c); }), Promise.resolve()), e; } function qt(t, e, n) { const r = e.style; if (!r) return; const i = window.getComputedStyle(t); i.cssText ? (r.cssText = i.cssText, r.transformOrigin = i.transformOrigin) : et(n).forEach((o) => { let s = i.getPropertyValue(o); o === "font-size" && s.endsWith("px") && (s = `${Math.floor(parseFloat(s.substring(0, s.length - 2))) - 0.1}px`), w(t, HTMLIFrameElement) && o === "display" && s === "inline" && (s = "block"), o === "d" && e.getAttribute("d") && (s = `path(${e.getAttribute("d")})`), r.setProperty(o, s, i.getPropertyPriority(o)); }); } function Yt(t, e) { w(t, HTMLTextAreaElement) && (e.innerHTML = t.value), w(t, HTMLInputElement) && e.setAttribute("value", t.value); } function zt(t, e) { if (w(t, HTMLSelectElement)) { const n = e, r = Array.from(n.children).find((i) => t.value === i.getAttribute("value")); r && r.setAttribute("selected", ""); } } function Jt(t, e, n) { return w(e, Element) && (qt(t, e, n), It(t, e, n), Yt(t, e), zt(t, e)), e; } async function Xt(t, e) { const n = t.querySelectorAll ? t.querySelectorAll("use") : []; if (n.length === 0) return t; const r = {}; for (let o = 0; o < n.length; o++) { const a = n[o].getAttribute("xlink:href"); if (a) { const c = t.querySelector(a), h = document.querySelector(a); !c && h && !r[a] && (r[a] = await H(h, e, !0)); } } const i = Object.values(r); if (i.length) { const o = "http://www.w3.org/1999/xhtml", s = document.createElementNS(o, "svg"); s.setAttribute("xmlns", o), s.style.position = "absolute", s.style.width = "0", s.style.height = "0", s.style.overflow = "hidden", s.style.display = "none"; const a = document.createElementNS(o, "defs"); s.appendChild(a); for (let c = 0; c < i.length; c++) a.appendChild(i[c]); t.appendChild(s); } return t; } async function H(t, e, n) { return !n && e.filter && !e.filter(t) ? null : Promise.resolve(t).then((r) => Vt(r, e)).then((r) => Gt(t, r, e)).then((r) => Jt(t, r, e)).then((r) => Xt(r, e)); } const it = /url\((['"]?)([^'"]+?)\1\)/g, Kt = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g, Qt = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g; function Zt(t) { const e = t.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1"); return new RegExp(`(url\\(['"]?)(${e})(['"]?\\))`, "g"); } function Nt(t) { const e = []; return t.replace(it, (n, r, i) => (e.push(i), n)), e.filter((n) => !B(n)); } async function te(t, e, n, r, i) { try { const o = n ? St(e, n) : e, s = V(e); let a; return i || (a = await _(o, s, r)), t.replace(Zt(e), `$1${a}$3`); } catch { } return t; } function ee(t, { preferredFontFormat: e }) { return e ? t.replace(Qt, (n) => { for (; ; ) { const [r, , i] = Kt.exec(n) || []; if (!i) return ""; if (i === e) return `src: ${r};`; } }) : t; } function st(t) { return t.search(it) !== -1; } async function at(t, e, n) { if (!st(t)) return t; const r = ee(t, n); return Nt(r).reduce((o, s) => o.then((a) => te(a, s, e, n)), Promise.resolve(r)); } async function k(t, e, n) { var r; const i = (r = e.style) === null || r === void 0 ? void 0 : r.getPropertyValue(t); if (i) { const o = await at(i, null, n); return e.style.setProperty(t, o, e.style.getPropertyPriority(t)), !0; } return !1; } async function ne(t, e) { await k("background", t, e) || await k("background-image", t, e), await k("mask", t, e) || await k("-webkit-mask", t, e) || await k("mask-image", t, e) || await k("-webkit-mask-image", t, e); } async function re(t, e) { const n = w(t, HTMLImageElement); if (!(n && !B(t.src)) && !(w(t, SVGImageElement) && !B(t.href.baseVal))) return; const r = n ? t.src : t.href.baseVal, i = await _(r, V(r), e); await new Promise((o, s) => { t.onload = o, t.onerror = e.onImageErrorHandler ? (...c) => { try { o(e.onImageErrorHandler(...c)); } catch (h) { s(h); } } : s; const a = t; a.decode && (a.decode = o), a.loading === "lazy" && (a.loading = "eager"), n ? (t.srcset = "", t.src = i) : t.href.baseVal = i; }); } async function oe(t, e) { const r = $(t.childNodes).map((i) => ct(i, e)); await Promise.all(r).then(() => t); } async function ct(t, e) { w(t, Element) && (await ne(t, e), await re(t, e), await oe(t, e)); } function ie(t, e) { const { style: n } = t; e.backgroundColor && (n.backgroundColor = e.backgroundColor), e.width && (n.width = `${e.width}px`), e.height && (n.height = `${e.height}px`); const r = e.style; return r != null && Object.keys(r).forEach((i) => { n[i] = r[i]; }), t; } const K = {}; async function Q(t) { let e = K[t]; if (e != null) return e; const r = await (await fetch(t)).text(); return e = { url: t, cssText: r }, K[t] = e, e; } async function Z(t, e) { let n = t.cssText; const r = /url\(["']?([^"')]+)["']?\)/g, o = (n.match(/url\([^)]+\)/g) || []).map(async (s) => { let a = s.replace(r, "$1"); return a.startsWith("https://") || (a = new URL(a, t.url).href), rt(a, e.fetchRequestInit, ({ result: c }) => (n = n.replace(s, `url(${c})`), [s, c])); }); return Promise.all(o).then(() => n); } function N(t) { if (t == null) return []; const e = [], n = /(\/\*[\s\S]*?\*\/)/gi; let r = t.replace(n, ""); const i = new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})", "gi"); for (; ; ) { const c = i.exec(r); if (c === null) break; e.push(c[0]); } r = r.replace(i, ""); const o = /@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi, s = "((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})", a = new RegExp(s, "gi"); for (; ; ) { let c = o.exec(r); if (c === null) { if (c = a.exec(r), c === null) break; o.lastIndex = a.lastIndex; } else a.lastIndex = o.lastIndex; e.push(c[0]); } return e; } async function se(t, e) { const n = [], r = []; return t.forEach((i) => { if ("cssRules" in i) try { $(i.cssRules || []).forEach((o, s) => { if (o.type === CSSRule.IMPORT_RULE) { let a = s + 1; const c = o.href, h = Q(c).then((d) => Z(d, e)).then((d) => N(d).forEach((l) => { try { i.insertRule(l, l.startsWith("@import") ? a += 1 : i.cssRules.length); } catch (g) { console.error("Error inserting rule from remote css", { rule: l, error: g }); } })).catch((d) => { console.error("Error loading remote css", d.toString()); }); r.push(h); } }); } catch (o) { const s = t.find((a) => a.href == null) || document.styleSheets[0]; i.href != null && r.push(Q(i.href).then((a) => Z(a, e)).then((a) => N(a).forEach((c) => { s.insertRule(c, s.cssRules.length); })).catch((a) => { console.error("Error loading remote stylesheet", a); })), console.error("Error inlining remote css file", o); } }), Promise.all(r).then(() => (t.forEach((i) => { if ("cssRules" in i) try { $(i.cssRules || []).forEach((o) => { n.push(o); }); } catch (o) { console.error(`Error while reading CSS rules from ${i.href}`, o); } }), n)); } function ae(t) { return t.filter((e) => e.type === CSSRule.FONT_FACE_RULE).filter((e) => st(e.style.getPropertyValue("src"))); } async function ce(t, e) { if (t.ownerDocument == null) throw new Error("Provided element is not within a Document"); const n = $(t.ownerDocument.styleSheets), r = await se(n, e); return ae(r); } function lt(t) { return t.trim().replace(/["']/g, ""); } function le(t) { const e = /* @__PURE__ */ new Set(); function n(r) { (r.style.fontFamily || getComputedStyle(r).fontFamily).split(",").forEach((o) => { e.add(lt(o)); }), Array.from(r.children).forEach((o) => { o instanceof HTMLElement && n(o); }); } return n(t), e; } async function ue(t, e) { const n = await ce(t, e), r = le(t); return (await Promise.all(n.filter((o) => r.has(lt(o.style.fontFamily))).map((o) => { const s = o.parentStyleSheet ? o.parentStyleSheet.href : null; return at(o.cssText, s, e); }))).join(` `); } async function fe(t, e) { const n = e.fontEmbedCSS != null ? e.fontEmbedCSS : e.skipFonts ? null : await ue(t, e); if (n) { const r = document.createElement("style"), i = document.createTextNode(n); r.appendChild(i), t.firstChild ? t.insertBefore(r, t.firstChild) : t.appendChild(r); } } async function he(t, e = {}) { const { width: n, height: r } = nt(t, e), i = await H(t, e, !0); return await fe(i, e), await ct(i, e), ie(i, e), await Ft(i, n, r); } async function de(t, e = {}) { const { width: n, height: r } = nt(t, e), i = await he(t, e), o = await O(i), s = document.createElement("canvas"), a = s.getContext("2d"), c = e.pixelRatio || Rt(), h = e.canvasWidth || n, d = e.canvasHeight || r; return s.width = h * c, s.height = d * c, e.skipAutoScale || Dt(s), s.style.width = `${h}`, s.style.height = `${d}`, e.backgroundColor && (a.fillStyle = e.backgroundColor, a.fillRect(0, 0, s.width, s.height)), a.drawImage(o, 0, 0, s.width, s.height), s; } async function ge(t, e = {}) { return (await de(t, e)).toDataURL(); } async function me(t, e, n) { var c, h, d; const r = (/* @__PURE__ */ new Date()).getFullYear(), i = e || r, o = `${i}-01-01T00:00:00Z`, s = `${i}-12-31T23:59:59Z`, a = ` query($username: String!, $from: DateTime!, $to: DateTime!) { user(login: $username) { contributionsCollection(from: $from, to: $to) { contributionCalendar { totalContributions weeks { contributionDays { date contributionCount color } } } } } viewer { login contributionsCollection(from: $from, to: $to) { contributionCalendar { totalContributions weeks { contributionDays { date contributionCount color } } } } } } `; try { const l = { "Content-Type": "application/json" }; n && (l.Authorization = `Bearer ${n}`); const g = await fetch("https://api.github.com/graphql", { method: "POST", headers: l, body: JSON.stringify({ query: a, variables: { username: t, from: o, to: s } }) }); if (!g.ok) throw new Error(`GitHub API error: ${g.statusText}`); const u = await g.json(); if (u.errors && (!u.errors.find((v) => v.message.includes("Could not resolve to a User")) || !((c = u.data) != null && c.viewer))) throw new Error(`GraphQL errors: ${JSON.stringify(u.errors)}`); let m; if ((h = u.data) != null && h.viewer && u.data.viewer.login.toLowerCase() === t.toLowerCase()) m = u.data.viewer.contributionsCollection.contributionCalendar; else if ((d = u.data) != null && d.user) m = u.data.user.contributionsCollection.contributionCalendar; else throw new Error(`User ${t} not found`); const b = [], R = m.weeks; for (const D of R) for (const v of D.contributionDays) b.push({ date: v.date, count: v.contributionCount, level: we(v.contributionCount) }); return b; } catch (l) { throw console.error(`Error fetching contributions for ${t}:`, l), l; } } async function pe(t, e, n) { const r = /* @__PURE__ */ new Map(), i = (/* @__PURE__ */ new Date()).getFullYear(), o = e || [i]; for (const s of t) try { const a = []; for (const c of o) { const h = await me(s, c, n); a.push(...h); } r.set(s, a); } catch (a) { console.error(`Failed to fetch contributions for ${s}:`, a); } return r; } async function ye(t, e) { try { const [n, r] = t.split("/"); if (!n || !r) throw new Error('Invalid repository name. Format should be "owner/repo"'); const i = []; let o = 1; const s = 100; for (; ; ) { const a = { Accept: "application/vnd.github.v3+json" }; e && (a.Authorization = `Bearer ${e}`); const c = await fetch( `https://api.github.com/repos/${n}/${r}/contributors?per_page=${s}&page=${o}`, { headers: a } ); if (!c.ok) throw new Error(`GitHub API error: ${c.statusText}`); const h = await c.json(); if (h.length === 0) break; for (const d of h) d.login && d.type === "User" && i.push(d.login); if (h.length < s) break; o++; } return i; } catch (n) { throw console.error(`Error fetching contributors for ${t}:`, n), n; } } function we(t) { return t === 0 ? 0 : t <= 3 ? 1 : t <= 6 ? 2 : t <= 9 ? 3 : 4; } function be(t) { const e = /* @__PURE__ */ new Map(), n = {}; for (const [i, o] of t.entries()) for (const s of o) { const c = (e.get(s.date) || 0) + s.count; e.set(s.date, c); const h = new Date(s.date).getFullYear(); n[h] = (n[h] || 0) + s.count; } const r = Array.from(e.entries()).map(([i, o]) => ({ date: i, count: o, level: xe(o) })).sort((i, o) => new Date(i.date).getTime() - new Date(o.date).getTime()); return { total: n, contributions: r }; } function xe(t) { return t === 0 ? 0 : t <= 5 ? 1 : t <= 10 ? 2 : t <= 15 ? 3 : 4; } function ut(t, e, n) { const r = [], i = new Map( t.map((s) => [s.date, s]) ), o = new Date(e); for (; o <= n; ) { const s = o.toISOString().split("T")[0], a = i.get(s); a ? r.push(a) : r.push({ date: s, count: 0, level: 0 }), o.setDate(o.getDate() + 1); } return r; } function Ce(t) { if (t.length === 0) { const n = /* @__PURE__ */ new Date(), r = /* @__PURE__ */ new Date(); return r.setFullYear(r.getFullYear() - 1), { start: r, end: n }; } const e = t.map((n) => new Date(n.date)); return { start: new Date(Math.min(...e.map((n) => n.getTime()))), end: new Date(Math.max(...e.map((n) => n.getTime()))) }; } function Se(t) { if (t.length === 0) return []; const e = []; let n = []; const r = new Date(t[0].date), i = r.getDay(); for (let o = 0; o < i; o++) { const s = new Date(r); s.setDate(s.getDate() - (i - o)), n.push({ date: s.toISOString().split("T")[0], count: 0, level: 0 }); } for (const o of t) n.push(o), n.length === 7 && (e.push(n), n = []); if (n.length > 0) { const o = new Date(n[n.length - 1].date); for (; n.length < 7; ) o.setDate(o.getDate() + 1), n.push({ date: o.toISOString().split("T")[0], count: 0, level: 0 }); e.push(n); } return e; } const ve = { level0: "#ebedf0", level1: "#9be9a8", level2: "#40c463", level3: "#30a14e", level4: "#216e39", text: "#24292f", background: "#ffffff" }, Ee = { level0: "#161b22", level1: "#0e4429", level2: "#006d32", level3: "#26a641", level4: "#39d353", text: "#c9d1d9", background: "#0d1117" }; function ft(t) { return t === "light" ? ve : Ee; } const $e = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], tt = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], ht = ({ contributions: t, theme: e, blockSize: n = 12, blockMargin: r = 3, showWeekdayLabels: i = !0, showMonthLabels: o = !0 }) => { const s = Se(t), a = (l) => e[`level${l}`], c = (l) => { if (!o || l >= s.length) return null; const g = s[l][0], m = new Date(g.date).getMonth(); if (l === 0) return tt[m]; const b = s[l - 1][0], D = new Date(b.date).getMonth(); return m !== D ? tt[m] : null; }, d = i ? 30 : 0; return /* @__PURE__ */ S( "svg", { width: d + s.length * (n + r) + r, height: o ? 7 * (n + r) + 30 : 7 * (n + r) + 10, style: { fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif' }, children: [ o && /* @__PURE__ */ f("g", { transform: `translate(${d}, 0)`, children: (() => { const l = []; if (s.forEach((g, u) => { const m = c(u); m && l.push({ x: u * (n + r), label: m }); }), l.length > 1) { const g = l[0], u = l[1], m = 2 * (n + r); u.x - g.x < m && l.shift(); } return l.map((g, u) => /* @__PURE__ */ f( "text", { x: g.x, y: 10, fontSize: "10", fill: e.text, children: g.label }, `month-${u}-${g.label}` )); })() }), i && /* @__PURE__ */ f("g", { transform: `translate(0, ${o ? 20 : 0})`, children: [1, 3, 5].map((l) => /* @__PURE__ */ f( "text", { x: 0, y: l * (n + r) + n, fontSize: "9", fill: e.text, textAnchor: "start", children: $e[l] }, `weekday-${l}` )) }), /* @__PURE__ */ f("g", { transform: `translate(${d}, ${o ? 20 : 0})`, children: s.map( (l, g) => l.map((u, m) => { const b = g * (n + r), R = m * (n + r); return /* @__PURE__ */ f( "rect", { x: b, y: R, width: n, height: n, rx: 2, ry: 2, fill: a(u.level), "data-date": u.date, "data-count": u.count, children: /* @__PURE__ */ f("title", { children: `${u.date}: ${u.count} contribution${u.count !== 1 ? "s" : ""}` }) }, `${u.date}` ); }) ) }) ] } ); }, Te = (t) => { const { years: e, colorScheme: n = "light", blockSize: r = 12, blockMargin: i = 3, fontSize: o = 14, showWeekdayLabels: s = !0, showMonthLabels: a = !0, loading: c, error: h, githubToken: d, onDataLoad: l, onContributorsLoad: g } = t, [u, m] = M(null), [b, R] = M([]), [D, v] = M(!0), [G, q] = M(null), P = wt(null), p = ft(n), L = "usernames" in t ? t.usernames : void 0, E = "repoName" in t ? t.repoName : void 0, dt = bt(async () => { if (P.current !== null) try { const y = await ge(P.current, { cacheBust: !0, filter: (T) => { var A; return !((A = T.classList) != null && A.contains("download-btn")); }, backgroundColor: p.background, style: { display: "inline-block", height: "auto" } }), x = document.createElement("a"); x.download = `${E || "merged-contributions"}.png`, x.href = y, x.click(); } catch (y) { console.error("Failed to download image", y); } }, [P, E, p.background]); if (xt(() => { (L || E) && (async () => { try { v(!0), q(null); let x = []; if (E) { const W = await ye(E, d); x = W, R(W), g == null || g(W); } else L && (x = L, R(L)); if (x.length === 0) { v(!1); return; } const T = await pe(x, e, d), I = be(T), { start: A, end: mt } = Ce(I.contributions), pt = ut(I.contributions, A, mt), Y = { ...I, contributions: pt }; m(Y), l == null || l(Y); } catch (x) { const T = x instanceof Error ? x : new Error("Failed to load contributions"); q(T), console.error("Error loading contributions:", T); } finally { v(!1); } })(); }, [L, E, e, l, g, d]), D) return c ? /* @__PURE__ */ f(yt, { children: c }) : /* @__PURE__ */ f("div", { style: { padding: "20px", color: p.text }, children: "Loading contributions..." }); if (G) return /* @__PURE__ */ f("div", { style: { padding: "20px", color: p.text }, children: h || `Error: ${G.message}` }); if (!u || u.contributions.length === 0) return /* @__PURE__ */ f("div", { style: { padding: "20px", color: p.text }, children: "No contributions found" }); const gt = Object.values(u.total).reduce( (y, x) => y + x, 0 ); return /* @__PURE__ */ S( "div", { ref: P, style: { padding: "20px", backgroundColor: p.background, borderRadius: "6px", fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif' }, children: [ /* @__PURE__ */ S("div", { style: { marginBottom: "16px", display: "flex", justifyContent: "space-between", alignItems: "flex-start" }, children: [ /* @__PURE__ */ S("div", { children: [ /* @__PURE__ */ f("h3", { style: { margin: "0 0 8px 0", color: p.text, fontSize: o }, children: E ? `${E} - Merged Contributions` : "Merged Contributions" }), /* @__PURE__ */ S("div", { style: { color: p.text, fontSize: o - 2, opacity: 0.8 }, children: [ b.length, " contributor", b.length !== 1 ? "s" : "", " • ", gt, " total contributions" ] }), /* @__PURE__ */ f("div", { style: { color: p.text, fontSize: o - 3, opacity: 0.6, marginTop: "4px" }, children: b.length <= 10 ? b.join(", ") : `${b.slice(0, 10).join(", ")} and ${b.length - 10} more` }) ] }), /* @__PURE__ */ S( "button", { className: "download-btn", onClick: dt, style: { background: "transparent", border: `1px solid ${p.text}`, borderRadius: "4px", cursor: "pointer", padding: "6px 10px", color: p.text, opacity: 0.7, display: "flex", alignItems: "center", gap: "6px", fontSize: o - 2, transition: "all 0.2s ease" }, onMouseEnter: (y) => { y.currentTarget.style.opacity = "1", y.currentTarget.style.backgroundColor = p.text + "10"; }, onMouseLeave: (y) => { y.currentTarget.style.opacity = "0.7", y.currentTarget.style.backgroundColor = "transparent"; }, title: "Download as Image", children: [ /* @__PURE__ */ S("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [ /* @__PURE__ */ f("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), /* @__PURE__ */ f("polyline", { points: "7 10 12 15 17 10" }), /* @__PURE__ */ f("line", { x1: "12", y1: "15", x2: "12", y2: "3" }) ] }), "Download" ] } ) ] }), /* @__PURE__ */ f( ht, { contributions: u.contributions, theme: p, blockSize: r, blockMargin: i, showWeekdayLabels: s, showMonthLabels: a } ), /* @__PURE__ */ S("div", { style: { marginTop: "12px", display: "flex", alignItems: "center", gap: "8px", fontSize: o - 3 }, children: [ /* @__PURE__ */ f("span", { style: { color: p.text, opacity: 0.6 }, children: "Less" }), [0, 1, 2, 3, 4].map((y) => /* @__PURE__ */ f( "div", { style: { width: r, height: r, backgroundColor: p[`level${y}`], borderRadius: "2px" }, title: `Level ${y}` }, y )), /* @__PURE__ */ f("span", { style: { color: p.text, opacity: 0.6 }, children: "More" }) ] }) ] } ); }, Fe = ({ colorScheme: t, blockSize: e = 12, blockMargin: n = 3 }) => { const r = ft(t), i = Ct(() => { const o = (/* @__PURE__ */ new Date()).getFullYear(), s = new Date(o, 0, 1), a = new Date(o, 11, 31); return ut([], s, a); }, []); return /* @__PURE__ */ S( "div", { style: { padding: "20px", backgroundColor: r.background, borderRadius: "6px", fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif' }, children: [ /* @__PURE__ */ S("div", { style: { marginBottom: "16px", display: "flex", justifyContent: "space-between", alignItems: "flex-start" }, children: [ /* @__PURE__ */ S("div", { children: [ /* @__PURE__ */ f( "div", { style: { height: "20px", width: "250px", backgroundColor: r.level0, borderRadius: "4px", marginBottom: "8px" } } ), /* @__PURE__ */ f( "div", { style: { height: "14px", width: "180px", backgroundColor: r.level0, borderRadius: "4px", marginBottom: "4px" } } ), /* @__PURE__ */ f( "div", { style: { height: "12px", width: "300px", backgroundColor: r.level0, borderRadius: "4px", marginTop: "4px" } } ) ] }), /* @__PURE__ */ f( "div", { style: { height: "28px", width: "80px", backgroundColor: r.level0, borderRadius: "4px", opacity: 0.5 } } ) ] }), /* @__PURE__ */ f("div", { className: "skeleton-shimmer", style: { display: "inline-block", borderRadius: "4px" }, children: /* @__PURE__ */ f( ht, { contributions: i, theme: r, blockSize: e, blockMargin: n, showWeekdayLabels: !0, showMonthLabels: !0 } ) }), /* @__PURE__ */ S( "div", { style: { marginTop: "12px", display: "flex", gap: "8px", alignItems: "center" }, children: [ /* @__PURE__ */ f( "div", { style: { height: "10px", width: "30px", backgroundColor: r.level0, borderRadius: "2px" } } ), /* @__PURE__ */ f("div", { style: { display: "flex", gap: "3px" }, children: [0, 1, 2, 3, 4].map((o) => /* @__PURE__ */ f( "div", { style: { width: e, height: e, backgroundColor: r.level0, borderRadius: "2px" } }, o )) }), /* @__PURE__ */ f( "div", { style: { height: "10px", width: "30px", backgroundColor: r.level0, borderRadius: "2px" } } ) ] } ) ] } ); }; export { Te as MergedGitHubCalendar, Fe as SkeletonCalendar, Ee as darkTheme, ft as getTheme, ve as lightTheme };