diff --git a/theme/_data/blogrollStatus.js b/theme/_data/blogrollStatus.js
deleted file mode 100644
index aee1601..0000000
--- a/theme/_data/blogrollStatus.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Blogroll Status Data
- * Checks if the blogroll API backend is available at build time.
- * Used for conditional navigation — the blogroll page itself loads data client-side.
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-const INDIEKIT_URL = process.env.SITE_URL || "https://example.com";
-
-export default async function () {
- try {
- const url = `${INDIEKIT_URL}/blogrollapi/api/status`;
- console.log(`[blogrollStatus] Checking API: ${url}`);
- const data = await EleventyFetch(url, {
- duration: "15m",
- type: "json",
- });
- console.log("[blogrollStatus] API available");
- return {
- available: true,
- source: "indiekit",
- ...data,
- };
- } catch (error) {
- console.log(
- `[blogrollStatus] API unavailable: ${error.message}`
- );
- return {
- available: false,
- source: "unavailable",
- };
- }
-}
diff --git a/theme/_data/blueskyFeed.js b/theme/_data/blueskyFeed.js
deleted file mode 100644
index 00e604b..0000000
--- a/theme/_data/blueskyFeed.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Bluesky Feed Data
- * Fetches recent posts from Bluesky using the AT Protocol API
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-export default async function () {
- const rawHandle = (process.env.BLUESKY_HANDLE || "")
- .trim()
- .replace(/^@+/, "");
- const handle =
- rawHandle && !rawHandle.includes(".") && !rawHandle.startsWith("did:")
- ? `${rawHandle}.bsky.social`
- : rawHandle;
-
- if (!handle) {
- return [];
- }
-
- try {
- // Get the author's feed using public API (no auth needed for public posts)
- const feedUrl = `https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=${handle}&limit=10`;
-
- const response = await EleventyFetch(feedUrl, {
- duration: "15m", // Cache for 15 minutes
- type: "json",
- fetchOptions: {
- headers: {
- Accept: "application/json",
- },
- },
- });
-
- if (!response.feed) {
- console.log("No Bluesky feed found for handle:", handle);
- return [];
- }
-
- // Transform the feed into a simpler format
- return response.feed.map((item) => {
- // Extract rkey from AT URI (at://did:plc:xxx/app.bsky.feed.post/rkey)
- const rkey = item.post.uri.split("/").pop();
- const postUrl = `https://bsky.app/profile/${item.post.author.handle}/post/${rkey}`;
-
- return {
- text: item.post.record.text,
- createdAt: item.post.record.createdAt,
- uri: item.post.uri,
- url: postUrl,
- cid: item.post.cid,
- author: {
- handle: item.post.author.handle,
- displayName: item.post.author.displayName,
- avatar: item.post.author.avatar,
- },
- likeCount: item.post.likeCount || 0,
- repostCount: item.post.repostCount || 0,
- replyCount: item.post.replyCount || 0,
- // Extract any embedded links or images
- embed: item.post.embed
- ? {
- type: item.post.embed.$type,
- images: item.post.embed.images || [],
- external: item.post.embed.external || null,
- }
- : null,
- };
- });
- } catch (error) {
- console.error("Error fetching Bluesky feed:", error.message);
- return [];
- }
-}
diff --git a/theme/_data/conversationMentions.js b/theme/_data/conversationMentions.js
deleted file mode 100644
index 1652f37..0000000
--- a/theme/_data/conversationMentions.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-export default async function () {
- try {
- const data = await EleventyFetch(
- "http://127.0.0.1:8080/conversations/api/mentions?per-page=10000",
- { duration: "15m", type: "json" }
- );
- return data.children || [];
- } catch (e) {
- console.log(`[conversationMentions] API unavailable: ${e.message}`);
- return [];
- }
-}
diff --git a/theme/_data/cv.js b/theme/_data/cv.js
deleted file mode 100644
index 10f0e8e..0000000
--- a/theme/_data/cv.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * CV Data
- *
- * API-first for split backend/frontend deployments:
- * - Try Indiekit public API (`/cvapi/data.json`, fallback `/cv/data.json`)
- * - Fallback to local plugin file (`content/.indiekit/cv.json`)
- *
- * Returns empty defaults if neither source is available.
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-import { readFileSync } from "node:fs";
-import { resolve, dirname } from "node:path";
-import { fileURLToPath } from "node:url";
-import cvStatic from "./cvStatic.js";
-
-const __dirname = dirname(fileURLToPath(import.meta.url));
-const INDIEKIT_URL =
- process.env.INDIEKIT_URL || process.env.SITE_URL || "https://example.com";
-
-const EMPTY_CV = {
- lastUpdated: null,
- experience: [],
- projects: [],
- skills: {},
- skillTypes: {},
- languages: [],
- education: [],
- interests: {},
- interestTypes: {},
-};
-
-async function fetchFromIndiekit(path) {
- const urls = [
- `${INDIEKIT_URL}/cvapi/${path}`,
- `${INDIEKIT_URL}/cv/${path}`,
- ];
-
- for (const url of urls) {
- try {
- console.log(`[cv] Fetching from Indiekit: ${url}`);
- const data = await EleventyFetch(url, {
- duration: "15m",
- type: "json",
- });
- console.log(`[cv] Indiekit ${path} success via ${url}`);
- return data;
- } catch (error) {
- console.log(`[cv] Indiekit API unavailable at ${url}: ${error.message}`);
- }
- }
-
- return null;
-}
-
-function readLocalCvFile() {
- try {
- const cvPath = resolve(__dirname, "..", "content", ".indiekit", "cv.json");
- const raw = readFileSync(cvPath, "utf8");
- const data = JSON.parse(raw);
- console.log("[cv] Loaded CV data from local plugin file");
- return data;
- } catch {
- return null;
- }
-}
-
-export default async function () {
- const apiData = await fetchFromIndiekit("data.json");
- if (apiData && typeof apiData === "object") {
- return { ...EMPTY_CV, ...apiData };
- }
-
- const localData = readLocalCvFile();
- if (localData && typeof localData === "object") {
- return { ...EMPTY_CV, ...localData };
- }
-
- if (cvStatic && typeof cvStatic === "object") {
- return { ...EMPTY_CV, ...cvStatic };
- }
-
- return EMPTY_CV;
-}
diff --git a/theme/_data/cvPageConfig.js b/theme/_data/cvPageConfig.js
deleted file mode 100644
index 0776008..0000000
--- a/theme/_data/cvPageConfig.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * CV Page Configuration Data
- *
- * API-first for split backend/frontend deployments:
- * - Try Indiekit public API (`/cvapi/page.json`, fallback `/cv/page.json`)
- * - Fallback to local plugin file (`content/.indiekit/cv-page.json`)
- *
- * Falls back to null so cv.njk can use the hardcoded default layout.
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-import { readFileSync } from "node:fs";
-import { resolve, dirname } from "node:path";
-import { fileURLToPath } from "node:url";
-import cvPageConfigStatic from "./cvPageConfigStatic.js";
-
-const __dirname = dirname(fileURLToPath(import.meta.url));
-const INDIEKIT_URL =
- process.env.INDIEKIT_URL || process.env.SITE_URL || "https://example.com";
-
-async function fetchFromIndiekit(path) {
- const urls = [
- `${INDIEKIT_URL}/cvapi/${path}`,
- `${INDIEKIT_URL}/cv/${path}`,
- ];
-
- for (const url of urls) {
- try {
- console.log(`[cvPageConfig] Fetching from Indiekit: ${url}`);
- const data = await EleventyFetch(url, {
- duration: "15m",
- type: "json",
- });
- console.log(`[cvPageConfig] Indiekit ${path} success via ${url}`);
- return data;
- } catch (error) {
- console.log(
- `[cvPageConfig] Indiekit API unavailable at ${url}: ${error.message}`
- );
- }
- }
-
- return null;
-}
-
-function readLocalConfigFile() {
- try {
- const configPath = resolve(
- __dirname,
- "..",
- "content",
- ".indiekit",
- "cv-page.json"
- );
- const raw = readFileSync(configPath, "utf8");
- const config = JSON.parse(raw);
- console.log("[cvPageConfig] Loaded local CV page builder config");
- return config;
- } catch {
- return null;
- }
-}
-
-export default async function () {
- const apiConfig = await fetchFromIndiekit("page.json");
- if (apiConfig && typeof apiConfig === "object") {
- return apiConfig;
- }
-
- const localConfig = readLocalConfigFile();
- if (localConfig && typeof localConfig === "object") {
- return localConfig;
- }
-
- if (cvPageConfigStatic && typeof cvPageConfigStatic === "object") {
- return cvPageConfigStatic;
- }
-
- return null;
-}
diff --git a/theme/_data/cvPageConfigStatic.js b/theme/_data/cvPageConfigStatic.js
deleted file mode 100644
index f40e810..0000000
--- a/theme/_data/cvPageConfigStatic.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Repository-managed CV page config fallback.
- * Keep `null` to use the default layout in cv.njk.
- */
-
-export default null;
diff --git a/theme/_data/cvStatic.js b/theme/_data/cvStatic.js
deleted file mode 100644
index 9a46e41..0000000
--- a/theme/_data/cvStatic.js
+++ /dev/null
@@ -1,250 +0,0 @@
-/**
- * Repository-managed CV fallback data.
- * Edit this file to maintain CV content without the backend CV plugin.
- */
-
-export default {
- lastUpdated: "2026-03-08T12:00:00.000Z",
- experience: [
- {
- title: "Public Relations Specialist",
- company: "Landratsamt Garmisch-Partenkirchen",
- location: "Garmisch-Partenkirchen, Germany",
- startDate: "2024",
- endDate: null,
- type: "full-time",
- experienceType: "work",
- description:
- "Spearheaded strategic communication initiatives, improved public outreach, and strengthened stakeholder relationships.",
- highlights: [
- "Media campaigns",
- "Press releases",
- "Stakeholder communication",
- "Public image management",
- ],
- },
- {
- title: "Social Worker",
- company: "BIB Augsburg",
- location: "Garmisch-Partenkirchen, Germany",
- startDate: "2021",
- endDate: "2024",
- type: "full-time",
- experienceType: "work",
- description:
- "Provided social support and counseling with a focus on integration, empowerment, and crisis intervention.",
- highlights: [
- "Social integration",
- "Crisis intervention",
- "Family support",
- "Agency collaboration",
- ],
- },
- {
- title: "Founder and Communication Consultant",
- company: "Textbureau & Communication Giersig",
- location: "Konstanz and Murnau, Germany",
- startDate: "2014",
- endDate: "2023-12",
- type: "self-employed",
- experienceType: "work",
- description:
- "Built and ran a communication agency delivering content, editing, and strategic communication across industries.",
- highlights: [
- "Agency leadership",
- "Project management",
- "Client engagement",
- "Content creation",
- "Editorial work",
- ],
- },
- {
- title: "Store Manager",
- company: "Jack Wolfskin",
- location: "Murnau, Germany",
- startDate: "2017",
- endDate: "2021",
- type: "full-time",
- experienceType: "work",
- description:
- "Managed daily store operations, team leadership, and sales strategy with consistent growth and strong customer service outcomes.",
- highlights: [
- "Retail operations",
- "Team leadership",
- "Sales strategy",
- "Customer satisfaction",
- ],
- },
- {
- title: "Sales Professional",
- company: "Jack Wolfskin and Vaude",
- location: "Konstanz, Germany",
- startDate: "2012",
- endDate: "2017",
- type: "full-time",
- experienceType: "work",
- description:
- "Built strong customer relationships and product expertise in outdoor retail while improving sales performance.",
- highlights: [
- "Customer service",
- "Product consulting",
- "Sales performance",
- "Brand representation",
- ],
- },
- {
- title: "Research Assistant",
- company: "University of Constance",
- location: "Konstanz, Germany",
- startDate: "2007",
- endDate: "2012",
- type: "part-time",
- experienceType: "work",
- description:
- "Supported sociological research projects, contributed to publications, and tutored students in qualitative and quantitative methods.",
- highlights: [
- "Research design",
- "Data analysis",
- "Academic publications",
- "Methods tutoring",
- ],
- },
- {
- title: "UNIX Consultant",
- company: "Netzwerk2000 and Emprise Network Consulting",
- location: "Waiblingen and Stuttgart, Germany",
- startDate: "1998",
- endDate: "2002",
- type: "full-time",
- experienceType: "work",
- description:
- "Delivered UNIX consulting in networked environments, covering system administration, troubleshooting, and technical support.",
- highlights: [
- "UNIX system administration",
- "Troubleshooting",
- "Technical support",
- "Large network environments",
- ],
- },
- ],
- projects: [
- {
- name: "Communication Agency Development",
- url: "",
- description:
- "Built and scaled an independent communication agency and delivered tailored messaging for clients across industries.",
- technologies: [
- "Project management",
- "Client communication",
- "Messaging frameworks",
- "Editorial production",
- ],
- status: "completed",
- projectType: "work",
- startDate: "2014",
- endDate: "2023-12",
- },
- {
- name: "Public Outreach and Media Work",
- url: "",
- description:
- "Designed and executed public communication initiatives for social topics in district administration.",
- technologies: [
- "Public relations",
- "Press writing",
- "Media coordination",
- "Stakeholder relations",
- ],
- status: "active",
- projectType: "work",
- startDate: "2024",
- endDate: null,
- },
- {
- name: "Social Integration Support Programs",
- url: "",
- description:
- "Worked with families, young people, and refugees through social support and integration-focused services.",
- technologies: [
- "Counseling",
- "Case coordination",
- "Community partnerships",
- "Intercultural communication",
- ],
- status: "completed",
- projectType: "work",
- startDate: "2021",
- endDate: "2024",
- },
- ],
- skills: {
- Communication: [
- "Strategic communication",
- "Public relations",
- "Press releases",
- "Media campaigns",
- "Content creation",
- ],
- Research: [
- "Ethnographic perspective",
- "Qualitative methods",
- "Quantitative methods",
- "Sociological analysis",
- ],
- "Social Work": [
- "Social integration",
- "Crisis intervention",
- "Counseling",
- "Community collaboration",
- ],
- Operations: ["Project management", "Team leadership", "Adaptability", "Client engagement"],
- },
- skillTypes: {
- Communication: "work",
- Research: "work",
- "Social Work": "work",
- Operations: "work",
- },
- languages: [
- { name: "German", level: "native" },
- { name: "English", level: "fluent" },
- ],
- education: [
- {
- degree: "B.A. Sociology (Minor Subjects: Politics and Administration, Gender Studies)",
- institution: "University of Constance",
- location: "Constance, Germany",
- startDate: "2007",
- endDate: "2018",
- educationType: "work",
- description: "Academic training in sociology with a strong methodological and social-theory foundation.",
- },
- {
- degree: "A Level / Abitur",
- institution: "Kolping-Kolleg Stuttgart",
- location: "Stuttgart, Germany",
- startDate: "2003",
- endDate: "2007",
- educationType: "work",
- description: "General university entrance qualification.",
- },
- ],
- interests: {
- "Professional Focus": [
- "Social issues",
- "Community communication",
- "Ethnographic inquiry",
- "Grassroots movements",
- ],
- Personal: [
- "Long-distance hiking in the Alps",
- "Designing and sewing ultralight hiking gear",
- "Running blogs",
- "Minimal techno",
- ],
- },
- interestTypes: {
- "Professional Focus": "work",
- Personal: "work",
- },
-};
diff --git a/theme/_data/eleventyComputed.js b/theme/_data/eleventyComputed.js
deleted file mode 100644
index 7ef08a2..0000000
--- a/theme/_data/eleventyComputed.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Computed data resolved during the data cascade.
- *
- * Eleventy 3.x parallel rendering causes `page.url`, `page.fileSlug`,
- * and `page.inputPath` to return values from OTHER pages being processed
- * concurrently. This affects both templates and eleventyComputed functions.
- *
- * IMPORTANT: Only `permalink` is computed here, because it reads from the
- * file's own frontmatter data (per-file, immune to race conditions).
- * OG image lookups are done in templates using the `permalink` data value
- * and Nunjucks filters (see base.njk).
- *
- * NEVER use `page.url`, `page.fileSlug`, or `page.inputPath` here.
- *
- * See: https://github.com/11ty/eleventy/issues/3183
- */
-
-const normalizeOutputPermalink = (permalink) => {
- if (typeof permalink !== "string") return permalink;
-
- // Convert accidental absolute URLs to Eleventy output paths.
- if (/^https?:\/\//i.test(permalink)) {
- try {
- const { pathname } = new URL(permalink);
- if (!pathname) return "/";
- return pathname.endsWith("/") ? pathname : `${pathname}/`;
- } catch {
- return permalink;
- }
- }
-
- return permalink;
-};
-
-export default {
- eleventyComputed: {
- // Compute permalink from file path for posts without explicit frontmatter permalink.
- // Pattern: content/{type}/{yyyy}-{MM}-{dd}-{slug}.md → /{type}/{yyyy}/{MM}/{dd}/{slug}/
- permalink: (data) => {
- // Convert stale /content/ permalinks from pre-beta.37 posts to canonical format
- const explicitPermalink = normalizeOutputPermalink(data.permalink);
-
- if (explicitPermalink && typeof explicitPermalink === "string") {
- const contentMatch = explicitPermalink.match(
- /^\/content\/([^/]+)\/(\d{4})-(\d{2})-(\d{2})-(.+?)\/?$/
- );
- if (contentMatch) {
- const [, type, year, month, day, slug] = contentMatch;
- return `/${type}/${year}/${month}/${day}/${slug}/`;
- }
- // Valid non-/content/ permalink — use as-is
- return explicitPermalink;
- }
-
- // No frontmatter permalink — compute from file path
- // NOTE: data.page.inputPath may be wrong due to parallel rendering,
- // but posts without frontmatter permalink are rare (only pre-beta.37 edge cases)
- const inputPath = data.page?.inputPath || "";
- const match = inputPath.match(
- /content\/([^/]+)\/(\d{4})-(\d{2})-(\d{2})-(.+)\.md$/
- );
- if (match) {
- const [, type, year, month, day, slug] = match;
- return `/${type}/${year}/${month}/${day}/${slug}/`;
- }
-
- // For non-matching files (pages, root files), let Eleventy decide
- return data.permalink;
- },
- },
-};
diff --git a/theme/_data/enabledPostTypes.js b/theme/_data/enabledPostTypes.js
deleted file mode 100644
index 989bc7a..0000000
--- a/theme/_data/enabledPostTypes.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import { readFileSync } from "node:fs";
-import { resolve } from "node:path";
-
-const CONTENT_DIR = process.env.CONTENT_DIR || "/data/content";
-
-// Standard post types for any Indiekit deployment
-const ALL_POST_TYPES = [
- { type: "article", label: "Articles", path: "/articles/", createUrl: "/posts/create?type=article" },
- { type: "note", label: "Notes", path: "/notes/", createUrl: "/posts/create?type=note" },
- { type: "photo", label: "Photos", path: "/photos/", createUrl: "/posts/create?type=photo" },
- { type: "bookmark", label: "Bookmarks", path: "/bookmarks/", createUrl: "/posts/create?type=bookmark" },
- { type: "like", label: "Likes", path: "/likes/", createUrl: "/posts/create?type=like" },
- { type: "reply", label: "Replies", path: "/replies/", createUrl: "/posts/create?type=reply" },
- { type: "repost", label: "Reposts", path: "/reposts/", createUrl: "/posts/create?type=repost" },
-];
-
-/**
- * Returns the list of enabled post types.
- *
- * Resolution order:
- * 1. .indiekit/post-types.json in content dir (written by Indiekit or deployer)
- * 2. POST_TYPES env var (comma-separated: "article,note,photo")
- * 3. All standard post types (default)
- */
-export default function () {
- // 1. Try config file
- try {
- const configPath = resolve(CONTENT_DIR, ".indiekit", "post-types.json");
- const raw = readFileSync(configPath, "utf8");
- const types = JSON.parse(raw);
- if (Array.isArray(types)) {
- // Array of type strings: ["article", "note"]
- return ALL_POST_TYPES.filter((pt) => types.includes(pt.type));
- }
- // Array of objects with at least { type }
- return types;
- } catch {
- // File doesn't exist — fall through
- }
-
- // 2. Try env var
- const envTypes = process.env.POST_TYPES;
- if (envTypes) {
- const types = envTypes.split(",").map((t) => t.trim().toLowerCase());
- return ALL_POST_TYPES.filter((pt) => types.includes(pt.type));
- }
-
- // 3. Default — all standard types
- return ALL_POST_TYPES;
-}
diff --git a/theme/_data/funkwhaleActivity.js b/theme/_data/funkwhaleActivity.js
deleted file mode 100644
index 63f2af3..0000000
--- a/theme/_data/funkwhaleActivity.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * Funkwhale Activity Data
- * Fetches from Indiekit's endpoint-funkwhale public API
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-const INDIEKIT_URL =
- process.env.INDIEKIT_URL || process.env.SITE_URL || "https://example.com";
-const FUNKWHALE_INSTANCE = process.env.FUNKWHALE_INSTANCE || "";
-const DEFAULT_FETCH_CACHE_DURATION = "5m";
-const LISTENING_FETCH_CACHE_DURATION =
- (process.env.LISTENING_FETCH_CACHE_DURATION || "").trim() || DEFAULT_FETCH_CACHE_DURATION;
-const FUNKWHALE_FETCH_CACHE_DURATION =
- (process.env.FUNKWHALE_FETCH_CACHE_DURATION || "").trim() || LISTENING_FETCH_CACHE_DURATION;
-
-/**
- * Fetch from Indiekit's public Funkwhale API endpoint
- */
-async function fetchFromIndiekit(endpoint) {
- const urls = [
- `${INDIEKIT_URL}/funkwhale/api/${endpoint}`,
- `${INDIEKIT_URL}/funkwhaleapi/api/${endpoint}`,
- ];
-
- for (const url of urls) {
- try {
- console.log(`[funkwhaleActivity] Fetching from Indiekit: ${url}`);
- const data = await EleventyFetch(url, {
- duration: FUNKWHALE_FETCH_CACHE_DURATION,
- type: "json",
- });
- console.log(`[funkwhaleActivity] Indiekit ${endpoint} success via ${url}`);
- return data;
- } catch (error) {
- console.log(
- `[funkwhaleActivity] Indiekit API unavailable for ${endpoint} at ${url}: ${error.message}`
- );
- }
- }
-
- return null;
-}
-
-/**
- * Format duration in seconds to human-readable string
- */
-function formatDuration(seconds) {
- if (!seconds || seconds < 0) return "0:00";
-
- const hours = Math.floor(seconds / 3600);
- const minutes = Math.floor((seconds % 3600) / 60);
-
- if (hours > 24) {
- const days = Math.floor(hours / 24);
- return `${days}d`;
- }
-
- if (hours > 0) {
- return `${hours}h ${minutes}m`;
- }
-
- return `${minutes}m`;
-}
-
-export default async function () {
- try {
- console.log("[funkwhaleActivity] Fetching Funkwhale data...");
- console.log(
- `[funkwhaleActivity] EleventyFetch cache duration: ${FUNKWHALE_FETCH_CACHE_DURATION}`
- );
-
- // Fetch all data from Indiekit API
- const [nowPlaying, listenings, favorites, stats] = await Promise.all([
- fetchFromIndiekit("now-playing"),
- fetchFromIndiekit("listenings"),
- fetchFromIndiekit("favorites"),
- fetchFromIndiekit("stats"),
- ]);
-
- // Check if we got data
- const hasData = nowPlaying || listenings?.listenings?.length || stats?.summary;
-
- if (!hasData) {
- console.log("[funkwhaleActivity] No data available from Indiekit");
- return {
- nowPlaying: null,
- listenings: [],
- favorites: [],
- stats: null,
- instanceUrl: FUNKWHALE_INSTANCE,
- source: "unavailable",
- };
- }
-
- console.log("[funkwhaleActivity] Using Indiekit API data");
-
- // Format stats with human-readable durations
- let formattedStats = null;
- if (stats?.summary) {
- formattedStats = {
- ...stats,
- summary: {
- all: {
- ...stats.summary.all,
- totalDurationFormatted: formatDuration(stats.summary.all?.totalDuration || 0),
- },
- month: {
- ...stats.summary.month,
- totalDurationFormatted: formatDuration(stats.summary.month?.totalDuration || 0),
- },
- week: {
- ...stats.summary.week,
- totalDurationFormatted: formatDuration(stats.summary.week?.totalDuration || 0),
- },
- },
- };
- }
-
- return {
- nowPlaying: nowPlaying || null,
- listenings: listenings?.listenings || [],
- favorites: favorites?.favorites || [],
- stats: formattedStats,
- instanceUrl: FUNKWHALE_INSTANCE,
- source: "indiekit",
- };
- } catch (error) {
- console.error("[funkwhaleActivity] Error:", error.message);
- return {
- nowPlaying: null,
- listenings: [],
- favorites: [],
- stats: null,
- instanceUrl: FUNKWHALE_INSTANCE,
- source: "error",
- };
- }
-}
diff --git a/theme/_data/githubActivity.js b/theme/_data/githubActivity.js
deleted file mode 100644
index 0693786..0000000
--- a/theme/_data/githubActivity.js
+++ /dev/null
@@ -1,291 +0,0 @@
-/**
- * GitHub Activity Data
- * Fetches from Indiekit's endpoint-github public API
- * Falls back to direct GitHub API if Indiekit is unavailable
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-const GITHUB_USERNAME = process.env.GITHUB_USERNAME || "";
-const INDIEKIT_URL = process.env.SITE_URL || "https://example.com";
-
-// Fallback featured repos if Indiekit API unavailable (from env: comma-separated)
-const FALLBACK_FEATURED_REPOS = process.env.GITHUB_FEATURED_REPOS?.split(",").filter(Boolean) || [];
-
-/**
- * Fetch from Indiekit's public GitHub API endpoint
- */
-async function fetchFromIndiekit(endpoint) {
- const urls = [
- `${INDIEKIT_URL}/github/api/${endpoint}`,
- `${INDIEKIT_URL}/githubapi/api/${endpoint}`,
- ];
-
- for (const url of urls) {
- try {
- console.log(`[githubActivity] Fetching from Indiekit: ${url}`);
- const data = await EleventyFetch(url, {
- duration: "15m",
- type: "json",
- });
- console.log(`[githubActivity] Indiekit ${endpoint} success via ${url}`);
- return data;
- } catch (error) {
- console.log(
- `[githubActivity] Indiekit API unavailable for ${endpoint} at ${url}: ${error.message}`
- );
- }
- }
-
- return null;
-}
-
-/**
- * Fetch from GitHub API directly
- */
-async function fetchFromGitHub(endpoint) {
- const url = `https://api.github.com${endpoint}`;
- const headers = {
- Accept: "application/vnd.github.v3+json",
- "User-Agent": "Eleventy-Site",
- };
-
- if (process.env.GITHUB_TOKEN) {
- headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
- }
-
- return await EleventyFetch(url, {
- duration: "15m",
- type: "json",
- fetchOptions: { headers },
- });
-}
-
-/**
- * Truncate text with ellipsis
- */
-function truncate(text, maxLength = 80) {
- if (!text || text.length <= maxLength) return text || "";
- return text.slice(0, maxLength - 1) + "...";
-}
-
-/**
- * Extract commits from push events
- */
-function extractCommits(events) {
- if (!Array.isArray(events)) return [];
-
- return events
- .filter((event) => event.type === "PushEvent")
- .flatMap((event) =>
- (event.payload?.commits || []).map((commit) => ({
- sha: commit.sha.slice(0, 7),
- message: truncate(commit.message.split("\n")[0]),
- url: `https://github.com/${event.repo.name}/commit/${commit.sha}`,
- repo: event.repo.name,
- repoUrl: `https://github.com/${event.repo.name}`,
- date: event.created_at,
- }))
- )
- .slice(0, 10);
-}
-
-/**
- * Extract PRs/Issues from events
- */
-function extractContributions(events) {
- if (!Array.isArray(events)) return [];
-
- return events
- .filter(
- (event) =>
- (event.type === "PullRequestEvent" || event.type === "IssuesEvent") &&
- event.payload?.action === "opened"
- )
- .map((event) => {
- const item = event.payload.pull_request || event.payload.issue;
- return {
- type: event.type === "PullRequestEvent" ? "pr" : "issue",
- title: truncate(item?.title),
- url: item?.html_url,
- repo: event.repo.name,
- repoUrl: `https://github.com/${event.repo.name}`,
- number: item?.number,
- date: event.created_at,
- };
- })
- .slice(0, 10);
-}
-
-/**
- * Format starred repos
- */
-function formatStarred(repos) {
- if (!Array.isArray(repos)) return [];
-
- return repos.map((repo) => ({
- name: repo.full_name,
- description: truncate(repo.description, 120),
- url: repo.html_url,
- stars: repo.stargazers_count,
- language: repo.language,
- topics: repo.topics?.slice(0, 5) || [],
- }));
-}
-
-/**
- * Fetch featured repos directly from GitHub (fallback)
- */
-async function fetchFeaturedFromGitHub(repoList) {
- const featured = [];
-
- for (const repoFullName of repoList) {
- try {
- const repo = await fetchFromGitHub(`/repos/${repoFullName}`);
- let commits = [];
- try {
- const commitsData = await fetchFromGitHub(
- `/repos/${repoFullName}/commits?per_page=5`
- );
- commits = commitsData.map((c) => ({
- sha: c.sha.slice(0, 7),
- message: truncate(c.commit.message.split("\n")[0]),
- url: c.html_url,
- date: c.commit.author.date,
- }));
- } catch (e) {
- console.log(`[githubActivity] Could not fetch commits for ${repoFullName}`);
- }
-
- featured.push({
- fullName: repo.full_name,
- name: repo.name,
- description: repo.description,
- url: repo.html_url,
- stars: repo.stargazers_count,
- forks: repo.forks_count,
- language: repo.language,
- isPrivate: repo.private,
- commits,
- });
- } catch (error) {
- console.log(`[githubActivity] Could not fetch ${repoFullName}: ${error.message}`);
- }
- }
-
- return featured;
-}
-
-/**
- * Fetch commits directly from user's recently pushed repos
- * Fallback when events API doesn't include commit details
- */
-async function fetchCommitsFromRepos(username, limit = 10) {
- try {
- const repos = await fetchFromGitHub(
- `/users/${username}/repos?sort=pushed&per_page=5`
- );
-
- if (!Array.isArray(repos) || repos.length === 0) {
- return [];
- }
-
- const allCommits = [];
- for (const repo of repos.slice(0, 5)) {
- try {
- const repoCommits = await fetchFromGitHub(
- `/repos/${repo.full_name}/commits?per_page=5`
- );
- for (const c of repoCommits) {
- allCommits.push({
- sha: c.sha.slice(0, 7),
- message: truncate(c.commit?.message?.split("\n")[0]),
- url: c.html_url,
- repo: repo.full_name,
- repoUrl: repo.html_url,
- date: c.commit?.author?.date,
- });
- }
- } catch {
- // Skip repos we can't access
- }
- }
-
- // Sort by date and limit
- return allCommits
- .sort((a, b) => new Date(b.date) - new Date(a.date))
- .slice(0, limit);
- } catch (error) {
- console.log(`[githubActivity] Could not fetch commits from repos: ${error.message}`);
- return [];
- }
-}
-
-export default async function () {
- try {
- console.log("[githubActivity] Fetching GitHub data...");
-
- // Try Indiekit public API first
- const [indiekitStars, indiekitCommits, indiekitContributions, indiekitActivity, indiekitFeatured] =
- await Promise.all([
- fetchFromIndiekit("stars"),
- fetchFromIndiekit("commits"),
- fetchFromIndiekit("contributions"),
- fetchFromIndiekit("activity"),
- fetchFromIndiekit("featured"),
- ]);
-
- // Check if Indiekit API is available
- const hasIndiekitData =
- indiekitStars?.stars ||
- indiekitCommits?.commits ||
- indiekitFeatured?.featured;
-
- if (hasIndiekitData) {
- console.log("[githubActivity] Using Indiekit API data");
- return {
- stars: indiekitStars?.stars || [],
- commits: indiekitCommits?.commits || [],
- contributions: indiekitContributions?.contributions || [],
- activity: indiekitActivity?.activity || [],
- featured: indiekitFeatured?.featured || [],
- source: "indiekit",
- };
- }
-
- // Fallback to direct GitHub API
- console.log("[githubActivity] Falling back to GitHub API");
-
- const [events, starred, featured] = await Promise.all([
- fetchFromGitHub(`/users/${GITHUB_USERNAME}/events/public?per_page=50`),
- fetchFromGitHub(`/users/${GITHUB_USERNAME}/starred?per_page=20&sort=created`),
- fetchFeaturedFromGitHub(FALLBACK_FEATURED_REPOS),
- ]);
-
- // Try to extract commits from events first
- let commits = extractCommits(events || []);
-
- // If events API didn't have commits, fetch directly from repos
- if (commits.length === 0 && GITHUB_USERNAME) {
- console.log("[githubActivity] Events API returned no commits, fetching from repos");
- commits = await fetchCommitsFromRepos(GITHUB_USERNAME, 10);
- }
-
- return {
- stars: formatStarred(starred || []),
- commits,
- contributions: extractContributions(events || []),
- featured,
- source: "github",
- };
- } catch (error) {
- console.error("[githubActivity] Error:", error.message);
- return {
- stars: [],
- commits: [],
- contributions: [],
- featured: [],
- source: "error",
- };
- }
-}
diff --git a/theme/_data/githubRepos.js b/theme/_data/githubRepos.js
deleted file mode 100644
index 1b8fe5f..0000000
--- a/theme/_data/githubRepos.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * GitHub Repos Data
- * Fetches public repositories from GitHub API
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-export default async function () {
- const username = process.env.GITHUB_USERNAME || "";
-
- try {
- // Fetch public repos, sorted by updated date
- const url = `https://api.github.com/users/${username}/repos?sort=updated&per_page=10&type=owner`;
-
- const repos = await EleventyFetch(url, {
- duration: "1h", // Cache for 1 hour
- type: "json",
- fetchOptions: {
- headers: {
- Accept: "application/vnd.github.v3+json",
- "User-Agent": "Eleventy-Site",
- },
- },
- });
-
- // Filter and transform repos
- return repos
- .filter((repo) => !repo.fork && !repo.private) // Exclude forks and private repos
- .map((repo) => ({
- name: repo.name,
- full_name: repo.full_name,
- description: repo.description,
- html_url: repo.html_url,
- homepage: repo.homepage,
- language: repo.language,
- stargazers_count: repo.stargazers_count,
- forks_count: repo.forks_count,
- open_issues_count: repo.open_issues_count,
- topics: repo.topics || [],
- updated_at: repo.updated_at,
- created_at: repo.created_at,
- }))
- .slice(0, 10); // Limit to 10 repos
- } catch (error) {
- console.error("Error fetching GitHub repos:", error.message);
- return [];
- }
-}
diff --git a/theme/_data/githubStarred.js b/theme/_data/githubStarred.js
deleted file mode 100644
index ca5cf71..0000000
--- a/theme/_data/githubStarred.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * GitHub Starred Repos Metadata
- * Fetches the starred API response (cached 15min) to extract totalCount.
- * Only totalCount is passed to Eleventy's data cascade — the full star
- * list is discarded after parsing, keeping build memory low.
- * The starred page fetches all data client-side via Alpine.js.
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-const INDIEKIT_URL = process.env.SITE_URL || "https://example.com";
-
-export default async function () {
- try {
- const urls = [
- `${INDIEKIT_URL}/github/api/starred/all`,
- `${INDIEKIT_URL}/githubapi/api/starred/all`,
- ];
-
- for (const url of urls) {
- try {
- const response = await EleventyFetch(url, {
- duration: "15m",
- type: "json",
- });
-
- return {
- totalCount: response.totalCount || 0,
- buildDate: new Date().toISOString(),
- };
- } catch (error) {
- console.log(`[githubStarred] Could not fetch ${url}: ${error.message}`);
- }
- }
-
- throw new Error("No GitHub starred endpoint responded");
- } catch (error) {
- console.log(`[githubStarred] Could not fetch starred count: ${error.message}`);
- return {
- totalCount: 0,
- buildDate: new Date().toISOString(),
- };
- }
-}
diff --git a/theme/_data/homepageConfig.js b/theme/_data/homepageConfig.js
deleted file mode 100644
index ed5b2a7..0000000
--- a/theme/_data/homepageConfig.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Homepage Configuration Data
- * Reads config from indiekit-endpoint-homepage plugin (when installed).
- * Falls back to null — home.njk then uses the default layout.
- *
- * Future: The homepage plugin will write a .indiekit/homepage.json file
- * that Eleventy watches. On change, a rebuild picks up the new config,
- * allowing layout changes without a Docker rebuild.
- */
-
-import { readFileSync } from "node:fs";
-import { resolve, dirname } from "node:path";
-import { fileURLToPath } from "node:url";
-
-const __dirname = dirname(fileURLToPath(import.meta.url));
-
-export default function () {
- try {
- // Resolve via the content/ symlink relative to the Eleventy project
- const configPath = resolve(__dirname, "..", "content", ".indiekit", "homepage.json");
- const raw = readFileSync(configPath, "utf8");
- const config = JSON.parse(raw);
- console.log("[homepageConfig] Loaded plugin config");
- return config;
- } catch {
- // No homepage plugin config — this is the normal case for most deployments
- return null;
- }
-}
diff --git a/theme/_data/lastfmActivity.js b/theme/_data/lastfmActivity.js
deleted file mode 100644
index 7be3ff0..0000000
--- a/theme/_data/lastfmActivity.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * Last.fm Activity Data
- * Fetches from Indiekit's endpoint-lastfm public API
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-const INDIEKIT_URL =
- process.env.INDIEKIT_URL || process.env.SITE_URL || "https://example.com";
-const LASTFM_USERNAME = process.env.LASTFM_USERNAME || "";
-const DEFAULT_FETCH_CACHE_DURATION = "5m";
-const LISTENING_FETCH_CACHE_DURATION =
- (process.env.LISTENING_FETCH_CACHE_DURATION || "").trim() || DEFAULT_FETCH_CACHE_DURATION;
-const LASTFM_FETCH_CACHE_DURATION =
- (process.env.LASTFM_FETCH_CACHE_DURATION || "").trim() || LISTENING_FETCH_CACHE_DURATION;
-
-/**
- * Fetch from Indiekit's public Last.fm API endpoint
- */
-async function fetchFromIndiekit(path) {
- const urls = [
- `${INDIEKIT_URL}/lastfmapi/api/${path}`,
- `${INDIEKIT_URL}/lastfm/api/${path}`,
- ];
-
- for (const url of urls) {
- try {
- console.log(`[lastfmActivity] Fetching from Indiekit: ${url}`);
- const data = await EleventyFetch(url, {
- duration: LASTFM_FETCH_CACHE_DURATION,
- type: "json",
- });
- console.log(`[lastfmActivity] Indiekit ${path} success via ${url}`);
- return data;
- } catch (error) {
- console.log(
- `[lastfmActivity] Indiekit API unavailable for ${path} at ${url}: ${error.message}`
- );
- }
- }
-
- return null;
-}
-
-export default async function () {
- try {
- console.log("[lastfmActivity] Fetching Last.fm data...");
- console.log(
- `[lastfmActivity] EleventyFetch cache duration: ${LASTFM_FETCH_CACHE_DURATION}`
- );
-
- // Fetch all data from Indiekit API
- const [nowPlaying, scrobbles, loved, stats] = await Promise.all([
- fetchFromIndiekit("now-playing"),
- fetchFromIndiekit("scrobbles?period=alltime&limit=10"),
- fetchFromIndiekit("loved?limit=10"),
- fetchFromIndiekit("stats?period=alltime"),
- ]);
-
- // Check if we got data
- const hasData = nowPlaying || scrobbles?.scrobbles?.length || stats?.summary;
-
- if (!hasData) {
- console.log("[lastfmActivity] No data available from Indiekit");
- return {
- nowPlaying: null,
- scrobbles: [],
- loved: [],
- stats: null,
- username: LASTFM_USERNAME,
- profileUrl: LASTFM_USERNAME ? `https://www.last.fm/user/${LASTFM_USERNAME}` : null,
- source: "unavailable",
- };
- }
-
- console.log("[lastfmActivity] Using Indiekit API data");
-
- return {
- nowPlaying: nowPlaying || null,
- scrobbles: scrobbles?.scrobbles || [],
- loved: loved?.loved || [],
- stats: stats || null,
- username: LASTFM_USERNAME,
- profileUrl: LASTFM_USERNAME ? `https://www.last.fm/user/${LASTFM_USERNAME}` : null,
- source: "indiekit",
- };
- } catch (error) {
- console.error("[lastfmActivity] Error:", error.message);
- return {
- nowPlaying: null,
- scrobbles: [],
- loved: [],
- stats: null,
- username: LASTFM_USERNAME,
- profileUrl: null,
- source: "error",
- };
- }
-}
diff --git a/theme/_data/mastodonFeed.js b/theme/_data/mastodonFeed.js
deleted file mode 100644
index 4255b48..0000000
--- a/theme/_data/mastodonFeed.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Mastodon Feed Data
- * Fetches recent posts from Mastodon using the public API
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-export default async function () {
- const instance = (
- process.env.MASTODON_URL ||
- process.env.MASTODON_INSTANCE ||
- ""
- )
- .replace(/^https?:\/\//, "")
- .replace(/\/+$/, "");
- const username = (
- process.env.MASTODON_USER ||
- process.env.MASTODON_USERNAME ||
- ""
- ).trim().replace(/^@+/, "");
-
- if (!instance || !username) {
- console.log("[mastodonFeed] MASTODON_URL/MASTODON_USER not set, skipping");
- return [];
- }
-
- try {
- // First, look up the account ID
- const lookupUrl = `https://${instance}/api/v1/accounts/lookup?acct=${username}`;
-
- const account = await EleventyFetch(lookupUrl, {
- duration: "1h", // Cache account lookup for 1 hour
- type: "json",
- fetchOptions: {
- headers: {
- Accept: "application/json",
- },
- },
- });
-
- if (!account || !account.id) {
- console.log("Mastodon account not found:", username);
- return [];
- }
-
- // Fetch recent statuses (excluding replies and boosts for cleaner feed)
- const statusesUrl = `https://${instance}/api/v1/accounts/${account.id}/statuses?limit=10&exclude_replies=true&exclude_reblogs=true`;
-
- const statuses = await EleventyFetch(statusesUrl, {
- duration: "15m", // Cache for 15 minutes
- type: "json",
- fetchOptions: {
- headers: {
- Accept: "application/json",
- },
- },
- });
-
- if (!statuses || !Array.isArray(statuses)) {
- console.log("No Mastodon statuses found for:", username);
- return [];
- }
-
- // Transform statuses into a simpler format
- return statuses.map((status) => ({
- id: status.id,
- url: status.url,
- text: stripHtml(status.content),
- htmlContent: status.content,
- createdAt: status.created_at,
- author: {
- username: status.account.username,
- displayName: status.account.display_name || status.account.username,
- avatar: status.account.avatar,
- url: status.account.url,
- },
- favouritesCount: status.favourites_count || 0,
- reblogsCount: status.reblogs_count || 0,
- repliesCount: status.replies_count || 0,
- // Media attachments
- media: status.media_attachments
- ? status.media_attachments.map((m) => ({
- type: m.type,
- url: m.url,
- previewUrl: m.preview_url,
- description: m.description,
- }))
- : [],
- }));
- } catch (error) {
- console.error("Error fetching Mastodon feed:", error.message);
- return [];
- }
-}
-
-// Simple HTML stripper for plain text display
-function stripHtml(html) {
- if (!html) return "";
- return html
- .replace(/ /gi, " ")
- .replace(/<\/p>/gi, " ")
- .replace(/<[^>]+>/g, "")
- .replace(/&/g, "&")
- .replace(/</g, "<")
- .replace(/>/g, ">")
- .replace(/"/g, '"')
- .replace(/'/g, "'")
- .replace(/ /g, " ")
- .replace(/\s+/g, " ")
- .trim();
-}
diff --git a/theme/_data/newsActivity.js b/theme/_data/newsActivity.js
deleted file mode 100644
index 47499b8..0000000
--- a/theme/_data/newsActivity.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * News/RSS Activity Data
- * Fetches from Indiekit's endpoint-rss public API
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-const INDIEKIT_URL = process.env.SITE_URL || "https://example.com";
-
-/**
- * Fetch from Indiekit's public RSS API endpoint
- */
-async function fetchFromIndiekit(endpoint) {
- try {
- const url = `${INDIEKIT_URL}/rssapi/api/${endpoint}`;
- console.log(`[newsActivity] Fetching from Indiekit: ${url}`);
- const data = await EleventyFetch(url, {
- duration: "15m",
- type: "json",
- });
- console.log(`[newsActivity] Indiekit ${endpoint} success`);
- return data;
- } catch (error) {
- console.log(
- `[newsActivity] Indiekit API unavailable for ${endpoint}: ${error.message}`
- );
- return null;
- }
-}
-
-export default async function () {
- try {
- console.log("[newsActivity] Fetching RSS feed data...");
-
- // Fetch all data from Indiekit API
- const [itemsRes, feedsRes, statusRes] = await Promise.all([
- fetchFromIndiekit("items?limit=50"),
- fetchFromIndiekit("feeds"),
- fetchFromIndiekit("status"),
- ]);
-
- // Check if we got data
- const hasData = itemsRes?.items?.length || feedsRes?.feeds?.length;
-
- if (!hasData) {
- console.log("[newsActivity] No data available from Indiekit");
- return {
- items: [],
- feeds: [],
- status: null,
- lastUpdated: null,
- source: "unavailable",
- };
- }
-
- console.log(
- `[newsActivity] Got ${itemsRes?.items?.length || 0} items from ${feedsRes?.feeds?.length || 0} feeds`
- );
-
- // Create a map of feed IDs to feed info for quick lookup
- const feedMap = new Map();
- for (const feed of feedsRes?.feeds || []) {
- feedMap.set(feed.id, feed);
- }
-
- // Enhance items with additional feed info
- const items = (itemsRes?.items || []).map((item) => {
- const feed = feedMap.get(item.feedId);
- return {
- ...item,
- feedInfo: feed
- ? {
- title: feed.title,
- siteUrl: feed.siteUrl,
- imageUrl: feed.imageUrl,
- }
- : null,
- };
- });
-
- return {
- items,
- feeds: feedsRes?.feeds || [],
- pagination: itemsRes?.pagination || null,
- status: statusRes || null,
- lastUpdated: statusRes?.lastSync || new Date().toISOString(),
- source: "indiekit",
- };
- } catch (error) {
- console.error("[newsActivity] Error:", error.message);
- return {
- items: [],
- feeds: [],
- status: null,
- lastUpdated: null,
- source: "error",
- };
- }
-}
diff --git a/theme/_data/podrollStatus.js b/theme/_data/podrollStatus.js
deleted file mode 100644
index cf117e5..0000000
--- a/theme/_data/podrollStatus.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Podroll Status Data
- * Checks if the podroll API backend is available at build time.
- * Used for conditional navigation — the podroll page itself loads data client-side.
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-const INDIEKIT_URL = process.env.SITE_URL || "https://example.com";
-
-export default async function () {
- try {
- const url = `${INDIEKIT_URL}/podrollapi/api/status`;
- console.log(`[podrollStatus] Checking API: ${url}`);
- const data = await EleventyFetch(url, {
- duration: "15m",
- type: "json",
- });
- console.log("[podrollStatus] API available");
- return {
- available: true,
- source: "indiekit",
- ...data,
- };
- } catch (error) {
- console.log(
- `[podrollStatus] API unavailable: ${error.message}`
- );
- return {
- available: false,
- source: "unavailable",
- };
- }
-}
diff --git a/theme/_data/recentComments.js b/theme/_data/recentComments.js
deleted file mode 100644
index bdd1ede..0000000
--- a/theme/_data/recentComments.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Recent Comments Data
- * Fetches the 5 most recent comments at build time for the sidebar widget.
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-const INDIEKIT_URL = process.env.SITE_URL || "https://example.com";
-
-export default async function () {
- try {
- const url = `${INDIEKIT_URL}/comments/api/comments?limit=5`;
- console.log(`[recentComments] Fetching: ${url}`);
- const data = await EleventyFetch(url, {
- duration: "15m",
- type: "json",
- });
- console.log(`[recentComments] Got ${(data.children || []).length} comments`);
- return data.children || [];
- } catch (error) {
- console.log(`[recentComments] Unavailable: ${error.message}`);
- return [];
- }
-}
diff --git a/theme/_data/site.js b/theme/_data/site.js
deleted file mode 100644
index 7d3d342..0000000
--- a/theme/_data/site.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * Site configuration for Eleventy
- *
- * Configure via environment variables in Cloudron app settings.
- * All values have sensible defaults for initial deployment.
- */
-
-// Parse social links from env (format: "name|url|icon,name|url|icon")
-function parseSocialLinks(envVar) {
- if (!envVar) return [];
- return envVar.split(",").map((link) => {
- const [name, url, icon] = link.split("|").map((s) => s.trim());
- // Bluesky requires "me atproto" for verification
- const rel = url.includes("bsky.app") ? "me atproto" : "me";
- return { name, url, rel, icon: icon || name.toLowerCase() };
- });
-}
-
-// Get fediverse handle for fediverse:creator meta tag
-// Prefers the site's own ActivityPub identity over external Mastodon account
-function getFediverseCreator() {
- // Primary: site's own ActivityPub actor (canonical fediverse identity)
- const apHandle = process.env.ACTIVITYPUB_HANDLE;
- if (apHandle) {
- const domain = (process.env.SITE_URL || "https://example.com").replace(/^https?:\/\//, "");
- return `@${apHandle}@${domain}`;
- }
- // Fallback: external Mastodon account (syndication target)
- const instance = process.env.MASTODON_INSTANCE?.replace("https://", "") || "";
- const user = process.env.MASTODON_USER || "";
- if (instance && user) {
- return `@${user}@${instance}`;
- }
- return "";
-}
-
-// Auto-generate social links from feed config when SITE_SOCIAL is not set
-function buildSocialFromFeeds() {
- const links = [];
- const github = process.env.GITHUB_USERNAME;
- if (github) {
- links.push({ name: "GitHub", url: `https://github.com/${github}`, rel: "me", icon: "github" });
- }
- const bskyHandle = process.env.BLUESKY_HANDLE;
- if (bskyHandle) {
- links.push({ name: "Bluesky", url: `https://bsky.app/profile/${bskyHandle}`, rel: "me atproto", icon: "bluesky" });
- }
- const mastoInstance = process.env.MASTODON_INSTANCE?.replace("https://", "");
- const mastoUser = process.env.MASTODON_USER;
- if (mastoInstance && mastoUser) {
- links.push({ name: "Mastodon", url: `https://${mastoInstance}/@${mastoUser}`, rel: "me", icon: "mastodon" });
- }
- const linkedin = process.env.LINKEDIN_USERNAME;
- if (linkedin) {
- links.push({ name: "LinkedIn", url: `https://linkedin.com/in/${linkedin}`, rel: "me", icon: "linkedin" });
- }
- const apHandle = process.env.ACTIVITYPUB_HANDLE;
- if (apHandle) {
- const siteUrl = process.env.SITE_URL || "https://example.com";
- links.push({ name: "ActivityPub", url: `${siteUrl}/activitypub/users/${apHandle}`, rel: "me", icon: "activitypub" });
- }
- return links;
-}
-
-// site.url: no trailing slash — used as URL base for path concatenation ({{ site.url }}/path)
-// site.me / site.author.url: trailing slash — Mastodon rel="me" requires exact match
-const siteUrlBase = (process.env.SITE_URL || "https://example.com").replace(/\/$/, "");
-const siteUrlWithSlash = siteUrlBase + "/";
-
-export default {
- // Basic site info
- name: process.env.SITE_NAME || "My IndieWeb Blog",
- url: siteUrlBase,
- me: siteUrlWithSlash,
- locale: process.env.SITE_LOCALE || "en",
- description:
- process.env.SITE_DESCRIPTION ||
- "An IndieWeb-powered blog with Micropub support",
-
- // Author info (shown in h-card, about page, etc.)
- author: {
- name: process.env.AUTHOR_NAME || "Blog Author",
- url: siteUrlWithSlash,
- avatar: process.env.AUTHOR_AVATAR || "/images/default-avatar.svg",
- title: process.env.AUTHOR_TITLE || "",
- bio: process.env.AUTHOR_BIO || "Welcome to my IndieWeb blog.",
- location: process.env.AUTHOR_LOCATION || "",
- locality: process.env.AUTHOR_LOCALITY || "",
- region: process.env.AUTHOR_REGION || "",
- country: process.env.AUTHOR_COUNTRY || "",
- org: process.env.AUTHOR_ORG || "",
- pronoun: process.env.AUTHOR_PRONOUN || "",
- categories: process.env.AUTHOR_CATEGORIES?.split(",").map(s => s.trim()) || [],
- keyUrl: process.env.AUTHOR_KEY_URL || "",
- email: process.env.AUTHOR_EMAIL || "",
- },
-
- // Social links (for rel="me" and h-card)
- // Set SITE_SOCIAL env var as: "GitHub|https://github.com/user|github,Mastodon|https://mastodon.social/@user|mastodon"
- // Falls back to auto-generating from feed config (GITHUB_USERNAME, BLUESKY_HANDLE, etc.)
- social: parseSocialLinks(process.env.SITE_SOCIAL).length > 0
- ? parseSocialLinks(process.env.SITE_SOCIAL)
- : buildSocialFromFeeds(),
-
- // Feed integrations (usernames for data fetching)
- feeds: {
- github: process.env.GITHUB_USERNAME || "",
- bluesky: process.env.BLUESKY_HANDLE || "",
- mastodon: {
- instance: process.env.MASTODON_INSTANCE?.replace("https://", "") || "",
- username: process.env.MASTODON_USER || "",
- },
- },
-
- // Webmentions configuration
- webmentions: {
- domain: process.env.SITE_URL?.replace("https://", "").replace("http://", "") || "example.com",
- },
-
- // Fediverse creator for meta tag (e.g., @rick@rmendes.net)
- fediverseCreator: getFediverseCreator(),
-
- // Support/monetization configuration (used in _textcasting JSON Feed extension)
- support: {
- url: process.env.SUPPORT_URL || null,
- stripe: process.env.SUPPORT_STRIPE_URL || null,
- lightning: process.env.SUPPORT_LIGHTNING_ADDRESS || null,
- paymentPointer: process.env.SUPPORT_PAYMENT_POINTER || null,
- },
-
- // Markdown for Agents — serve clean Markdown to AI agents
- // Set MARKDOWN_AGENTS_ENABLED to "false" to disable entirely
- markdownAgents: {
- enabled: (process.env.MARKDOWN_AGENTS_ENABLED || "true").toLowerCase() === "true",
- aiTrain: process.env.MARKDOWN_AGENTS_AI_TRAIN || "yes",
- search: process.env.MARKDOWN_AGENTS_SEARCH || "yes",
- aiInput: process.env.MARKDOWN_AGENTS_AI_INPUT || "yes",
- },
-};
diff --git a/theme/_data/urlAliases.js b/theme/_data/urlAliases.js
deleted file mode 100644
index 1478a1f..0000000
--- a/theme/_data/urlAliases.js
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * URL Aliases for Webmention Recovery
- *
- * Maps new URLs to their old URLs so webmentions from previous
- * URL structures can be displayed on current pages.
- *
- * Place redirect map files in the parent directory of this theme:
- * - redirects.map (e.g., micro.blog: /YYYY/MM/DD/slug.html → /notes/...)
- * - old-blog-redirects.map (e.g., Known/WP: /YYYY/slug → /content/...)
- */
-
-import { readFileSync, existsSync } from "fs";
-import { resolve, dirname } from "path";
-import { fileURLToPath } from "url";
-
-const __dirname = dirname(fileURLToPath(import.meta.url));
-const siteUrl = process.env.SITE_URL || "https://example.com";
-
-/**
- * Parse a redirect map file into URL mappings
- * Format: old_path new_path;
- */
-function parseRedirectMap(filePath) {
- const aliases = {};
-
- if (!existsSync(filePath)) {
- console.log(`[urlAliases] File not found: ${filePath}`);
- return aliases;
- }
-
- try {
- const content = readFileSync(filePath, "utf-8");
- const lines = content.split("\n").filter((line) => {
- const trimmed = line.trim();
- return trimmed && !trimmed.startsWith("#");
- });
-
- for (const line of lines) {
- // Format: /old/path /new/path;
- const match = line.match(/^(\S+)\s+(\S+);?$/);
- if (match) {
- const [, oldPath, newPath] = match;
- // Normalize paths (remove trailing slashes, ensure leading slash)
- const normalizedNew = newPath.replace(/;$/, "").replace(/\/$/, "");
- const normalizedOld = oldPath.replace(/\/$/, "");
-
- // Map new URL → array of old URLs
- if (!aliases[normalizedNew]) {
- aliases[normalizedNew] = [];
- }
- aliases[normalizedNew].push(normalizedOld);
- }
- }
- } catch (error) {
- console.error(`[urlAliases] Error parsing ${filePath}:`, error.message);
- }
-
- return aliases;
-}
-
-/**
- * Merge multiple alias maps
- */
-function mergeAliases(...maps) {
- const merged = {};
- for (const map of maps) {
- for (const [newUrl, oldUrls] of Object.entries(map)) {
- if (!merged[newUrl]) {
- merged[newUrl] = [];
- }
- merged[newUrl].push(...oldUrls);
- }
- }
- return merged;
-}
-
-// Parse redirect maps from /app/pkg (Docker) or parent directory (local dev)
-// In Docker: eleventy-site is at /app/pkg/eleventy-site, maps are at /app/pkg/
-// In local dev: maps might be at ../
-const pkgRoot = resolve(__dirname, "../..");
-
-// Helper to find first existing file
-function findFile(candidates) {
- for (const path of candidates) {
- if (existsSync(path)) {
- console.log(`[urlAliases] Found: ${path}`);
- return path;
- }
- }
- console.log(`[urlAliases] No file found in: ${candidates.join(", ")}`);
- return null;
-}
-
-// Try multiple possible locations for each map type
-const microblogMapPath = findFile([
- resolve(pkgRoot, "redirects.map"),
- resolve(__dirname, "../../redirects.map"),
-]);
-
-const knownMapPath = findFile([
- resolve(pkgRoot, "old-blog-redirects.map"),
- resolve(__dirname, "../../old-blog-redirects.map"),
-]);
-
-const microblogAliases = microblogMapPath ? parseRedirectMap(microblogMapPath) : {};
-const knownAliases = knownMapPath ? parseRedirectMap(knownMapPath) : {};
-
-const allAliases = mergeAliases(microblogAliases, knownAliases);
-
-// Log summary
-const totalMappings = Object.keys(allAliases).length;
-const totalOldUrls = Object.values(allAliases).reduce((sum, urls) => sum + urls.length, 0);
-console.log(`[urlAliases] Loaded ${totalMappings} URL mappings with ${totalOldUrls} old URLs`);
-
-export default {
- // The merged alias map: new URL → [old URLs]
- aliases: allAliases,
-
- // Site URL for building absolute URLs
- siteUrl,
-
- /**
- * Get all URLs (old and new) that should be checked for webmentions
- * @param {string} url - Current page URL (relative)
- * @returns {string[]} - Array of absolute URLs to check
- */
- getAllUrls(url) {
- const normalizedUrl = url.replace(/\/$/, "");
- const urls = [
- `${siteUrl}${url}`,
- `${siteUrl}${normalizedUrl}`,
- ];
-
- // Add old URL variations
- const oldUrls = allAliases[normalizedUrl] || [];
- for (const oldUrl of oldUrls) {
- urls.push(`${siteUrl}${oldUrl}`);
- // Also try with trailing slash
- urls.push(`${siteUrl}${oldUrl}/`);
- }
-
- // Deduplicate
- return [...new Set(urls)];
- },
-
- /**
- * Get just the old URLs for a given new URL
- * @param {string} url - Current page URL (relative)
- * @returns {string[]} - Array of old relative URLs
- */
- getOldUrls(url) {
- const normalizedUrl = url.replace(/\/$/, "");
- return allAliases[normalizedUrl] || [];
- },
-};
diff --git a/theme/_data/whereCheckins.js b/theme/_data/whereCheckins.js
deleted file mode 100644
index 3ffb0cd..0000000
--- a/theme/_data/whereCheckins.js
+++ /dev/null
@@ -1,455 +0,0 @@
-/**
- * Where/Checkin data
- *
- * Reads local check-ins created by this site's Micropub endpoint.
- * Supports OwnYourSwarm JSON mode and simple mode payloads once they are
- * written to local markdown content.
- */
-
-import matter from "gray-matter";
-import { existsSync, readdirSync, readFileSync } from "node:fs";
-import { extname, join, relative } from "node:path";
-import { fileURLToPath } from "node:url";
-
-function resolveContentDir() {
- const candidates = ["../content", "../../content"].map((value) =>
- fileURLToPath(new URL(value, import.meta.url))
- );
- return candidates.find((dirPath) => existsSync(dirPath)) || candidates[0];
-}
-
-const CONTENT_DIR = resolveContentDir();
-const SWARM_HOST = "swarmapp.com";
-
-function first(value) {
- if (Array.isArray(value)) return value[0];
- return value;
-}
-
-function asArray(value) {
- if (value === null || value === undefined || value === "") return [];
- return Array.isArray(value) ? value : [value];
-}
-
-function asText(value) {
- if (value === null || value === undefined) return "";
- if (typeof value === "string") return value;
- if (typeof value === "number") return String(value);
- if (value instanceof Date) return value.toISOString();
- if (typeof value === "object") {
- if (typeof value.value === "string") return value.value;
- if (typeof value.text === "string") return value.text;
- if (typeof value.url === "string") return value.url;
- }
- return "";
-}
-
-function asNumber(value) {
- const raw = first(asArray(value));
- const num = Number(raw);
- return Number.isFinite(num) ? num : null;
-}
-
-function uniqueStrings(values) {
- return [...new Set(values.filter(Boolean))];
-}
-
-function joinLocation(locality, region, country) {
- return [locality, region, country].filter(Boolean).join(", ");
-}
-
-function toRelativePath(filePath) {
- return relative(CONTENT_DIR, filePath).replace(/\\/g, "/");
-}
-
-function walkMarkdownFiles(dirPath) {
- const files = [];
-
- for (const entry of readdirSync(dirPath, { withFileTypes: true })) {
- const fullPath = join(dirPath, entry.name);
- if (entry.isDirectory()) {
- files.push(...walkMarkdownFiles(fullPath));
- continue;
- }
-
- if (entry.isFile() && extname(entry.name).toLowerCase() === ".md") {
- files.push(fullPath);
- }
- }
-
- return files;
-}
-
-function toPropertiesObject(value) {
- if (!value || typeof value !== "object") return {};
- if (value.properties && typeof value.properties === "object") {
- return value.properties;
- }
- return value;
-}
-
-function getEntryProperties(frontmatter) {
- return toPropertiesObject(frontmatter.properties);
-}
-
-function isSwarmUrl(url) {
- return asText(url).toLowerCase().includes(SWARM_HOST);
-}
-
-function parseGeoUri(value) {
- const raw = asText(value).trim();
- const match = raw.match(/^geo:\s*([-+]?\d+(?:\.\d+)?),\s*([-+]?\d+(?:\.\d+)?)/i);
- if (!match) {
- return {
- latitude: null,
- longitude: null,
- };
- }
-
- const latitude = Number(match[1]);
- const longitude = Number(match[2]);
-
- return {
- latitude: Number.isFinite(latitude) ? latitude : null,
- longitude: Number.isFinite(longitude) ? longitude : null,
- };
-}
-
-function extractSimpleModeVenueName(contentValue) {
- const text = asText(contentValue).trim();
- if (!text) return "";
-
- const match = text.match(/^Checked in (?:at|to)\s+(.+?)(?:\.\s|$)/i);
- return match ? match[1].trim() : "";
-}
-
-function parsePersonCard(card) {
- if (!card || typeof card !== "object") return null;
- const props = toPropertiesObject(card);
-
- const urls = asArray(props.url).map((url) => asText(url)).filter(Boolean);
- const photos = asArray(props.photo).map((photo) => asText(photo)).filter(Boolean);
-
- return {
- name:
- asText(first(asArray(props.name))) ||
- asText(props.firstName) ||
- "",
- url: urls[0] || "",
- urls,
- photo: photos[0] || "",
- };
-}
-
-function parseCategory(categoryValues) {
- const tags = [];
- const people = [];
-
- for (const value of categoryValues) {
- if (typeof value === "string") {
- tags.push(value.trim());
- continue;
- }
-
- if (!value || typeof value !== "object") continue;
-
- const type = Array.isArray(value.type) ? value.type : [];
- const looksLikePersonTag =
- type.includes("h-card") ||
- Boolean(value.properties) ||
- value.name !== undefined ||
- value.url !== undefined;
-
- if (looksLikePersonTag) {
- const person = parsePersonCard(value);
- if (person && (person.name || person.url)) {
- people.push(person);
- }
- }
- }
-
- const normalizedTags = uniqueStrings(tags).filter(
- (tag) => !["where", "slashpage"].includes(tag.toLowerCase())
- );
-
- return {
- tags: normalizedTags,
- people,
- };
-}
-
-function isCheckinFrontmatter(frontmatter, relativePath) {
- if (relativePath === "pages/where.md") return false;
-
- const properties = getEntryProperties(frontmatter);
-
- const checkinValue =
- properties.checkin ??
- frontmatter.checkin ??
- frontmatter["check-in"];
-
- const syndicationValues = asArray(properties.syndication ?? frontmatter.syndication)
- .map((value) => asText(value))
- .filter(Boolean);
-
- const categories = asArray(properties.category ?? frontmatter.category)
- .map((value) => asText(value).toLowerCase())
- .filter(Boolean);
-
- const locationValue = properties.location ?? frontmatter.location;
- const geoCoords = parseGeoUri(first(asArray(locationValue)));
-
- const hasCheckinField = checkinValue !== undefined;
- const hasSwarmSyndication = syndicationValues.some((url) => isSwarmUrl(url));
- const hasLocationField = locationValue !== undefined;
- const hasCoordinates =
- properties.latitude !== undefined ||
- properties.longitude !== undefined ||
- frontmatter.latitude !== undefined ||
- frontmatter.longitude !== undefined ||
- (geoCoords.latitude !== null && geoCoords.longitude !== null);
-
- const hasCheckinCategory =
- categories.includes("where") ||
- categories.includes("checkin") ||
- categories.includes("swarm");
-
- return hasCheckinField || hasSwarmSyndication || (hasCheckinCategory && (hasLocationField || hasCoordinates));
-}
-
-function normalizeCheckin(frontmatter, relativePath) {
- const properties = getEntryProperties(frontmatter);
-
- const checkinValue = first(
- asArray(properties.checkin ?? frontmatter.checkin ?? frontmatter["check-in"])
- );
- const locationValue = first(asArray(properties.location ?? frontmatter.location));
-
- const checkinProps = toPropertiesObject(checkinValue);
- const locationProps = toPropertiesObject(locationValue);
- const locationGeo = parseGeoUri(locationValue);
-
- const venueUrlsFromCard = asArray(checkinProps.url).map((url) => asText(url)).filter(Boolean);
- const venueUrlFromSimpleMode =
- typeof checkinValue === "string" ? checkinValue : asText(checkinValue?.value);
- const venueUrls = uniqueStrings(
- venueUrlFromSimpleMode ? [venueUrlFromSimpleMode, ...venueUrlsFromCard] : venueUrlsFromCard
- );
-
- const venueUrl = venueUrls[0] || "";
- const venueWebsiteUrl = venueUrls[1] || "";
- const venueSocialUrl = venueUrls[2] || "";
-
- const contentValue = first(asArray(properties.content ?? frontmatter.content));
- const simpleModeVenueName = extractSimpleModeVenueName(contentValue);
-
- const name =
- asText(first(asArray(checkinProps.name))) ||
- simpleModeVenueName ||
- asText(frontmatter.title) ||
- "Unknown place";
-
- const locality =
- asText(first(asArray(checkinProps.locality))) ||
- asText(first(asArray(locationProps.locality))) ||
- asText(properties.locality) ||
- asText(frontmatter.locality);
- const region =
- asText(first(asArray(checkinProps.region))) ||
- asText(first(asArray(locationProps.region))) ||
- asText(properties.region) ||
- asText(frontmatter.region);
- const country =
- asText(first(asArray(checkinProps["country-name"]))) ||
- asText(first(asArray(locationProps["country-name"]))) ||
- asText(properties["country-name"]) ||
- asText(frontmatter["country-name"]);
- const postalCode =
- asText(first(asArray(checkinProps["postal-code"]))) ||
- asText(first(asArray(locationProps["postal-code"]))) ||
- asText(properties["postal-code"]) ||
- asText(frontmatter["postal-code"]);
-
- const latitude =
- asNumber(checkinProps.latitude) ??
- asNumber(locationProps.latitude) ??
- asNumber(properties.latitude) ??
- asNumber(frontmatter.latitude) ??
- locationGeo.latitude;
- const longitude =
- asNumber(checkinProps.longitude) ??
- asNumber(locationProps.longitude) ??
- asNumber(properties.longitude) ??
- asNumber(frontmatter.longitude) ??
- locationGeo.longitude;
-
- const published =
- asText(first(asArray(properties.published ?? frontmatter.published))) ||
- asText(frontmatter.date);
-
- const syndicationUrls = asArray(properties.syndication ?? frontmatter.syndication)
- .map((url) => asText(url))
- .filter(Boolean);
- const syndication =
- syndicationUrls.find((url) => isSwarmUrl(url)) ||
- syndicationUrls[0] ||
- "";
-
- const visibility = asText(
- first(asArray(properties.visibility ?? frontmatter.visibility))
- ).toLowerCase();
-
- const categoryValues = asArray(properties.category ?? frontmatter.category);
- const category = parseCategory(categoryValues);
-
- const checkedInByValue = first(
- asArray(
- properties["checked-in-by"] ??
- frontmatter["checked-in-by"] ??
- frontmatter.checkedInBy
- )
- );
- const checkedInBy = parsePersonCard(checkedInByValue);
-
- const addedPhotos =
- frontmatter.add && typeof frontmatter.add === "object"
- ? asArray(frontmatter.add.photo)
- : [];
- const photoValues = [
- ...asArray(properties.photo ?? frontmatter.photo),
- ...addedPhotos,
- ];
- const photos = uniqueStrings(
- photoValues
- .map((photo) => {
- if (typeof photo === "string") return photo;
- if (photo && typeof photo === "object") {
- return asText(photo.url || photo.value || photo.src || "");
- }
- return "";
- })
- .filter(Boolean)
- );
-
- if (!checkinValue && !syndication && latitude === null && longitude === null) {
- return null;
- }
-
- const mapUrl =
- latitude !== null && longitude !== null
- ? `https://www.openstreetmap.org/?mlat=${latitude}&mlon=${longitude}#map=16/${latitude}/${longitude}`
- : "";
-
- const coordinatesText =
- latitude !== null && longitude !== null
- ? `${latitude.toFixed(5)}, ${longitude.toFixed(5)}`
- : "";
-
- const locationText = joinLocation(locality, region, country);
- const timestamp = published ? Date.parse(published) || 0 : 0;
- const permalink = asText(frontmatter.permalink);
- const id = syndication || permalink || `${relativePath}-${published || "unknown"}`;
-
- return {
- id,
- sourcePath: relativePath,
- published,
- timestamp,
- syndication,
- visibility,
- isPrivate: visibility === "private",
- name,
- photos,
- tags: category.tags,
- taggedPeople: category.people,
- checkedInBy,
- venueUrl,
- venueWebsiteUrl,
- venueSocialUrl,
- locality,
- region,
- country,
- postalCode,
- locationText,
- latitude,
- longitude,
- coordinatesText,
- mapUrl,
- };
-}
-
-function normalizeCheckins(items) {
- const seen = new Set();
- const checkins = [];
-
- for (const item of items) {
- if (!item) continue;
- if (seen.has(item.id)) continue;
- seen.add(item.id);
- checkins.push(item);
- }
-
- return checkins.sort((a, b) => b.timestamp - a.timestamp);
-}
-
-export default async function () {
- const checkedAt = new Date().toISOString();
- const errors = [];
-
- let filePaths = [];
-
- try {
- filePaths = walkMarkdownFiles(CONTENT_DIR);
- } catch (error) {
- const message = `[whereCheckins] Unable to scan local content: ${error.message}`;
- console.log(message);
- return {
- source: "local-endpoint",
- available: false,
- checkedAt,
- scannedFiles: 0,
- checkins: [],
- errors: [message],
- stats: {
- total: 0,
- withCoordinates: 0,
- },
- };
- }
-
- const items = [];
-
- for (const filePath of filePaths) {
- const relativePath = toRelativePath(filePath);
-
- try {
- const raw = readFileSync(filePath, "utf-8");
- const frontmatter = matter(raw).data || {};
-
- if (!isCheckinFrontmatter(frontmatter, relativePath)) continue;
-
- const checkin = normalizeCheckin(frontmatter, relativePath);
- if (checkin) items.push(checkin);
- } catch (error) {
- errors.push(`[whereCheckins] Skipped ${relativePath}: ${error.message}`);
- }
- }
-
- const checkins = normalizeCheckins(items);
- const withCoordinates = checkins.filter(
- (item) => item.latitude !== null && item.longitude !== null
- ).length;
-
- return {
- source: "local-endpoint",
- available: checkins.length > 0,
- checkedAt,
- scannedFiles: filePaths.length,
- checkins,
- errors,
- stats: {
- total: checkins.length,
- withCoordinates,
- },
- };
-}
diff --git a/theme/_data/youtubeChannel.js b/theme/_data/youtubeChannel.js
deleted file mode 100644
index 7fbf461..0000000
--- a/theme/_data/youtubeChannel.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/**
- * YouTube Channel Data
- * Fetches from Indiekit's endpoint-youtube public API
- * Supports single or multiple channels
- */
-
-import EleventyFetch from "@11ty/eleventy-fetch";
-
-const INDIEKIT_URL = process.env.SITE_URL || "https://example.com";
-
-/**
- * Fetch from Indiekit's public YouTube API endpoint
- */
-async function fetchFromIndiekit(endpoint) {
- try {
- const url = `${INDIEKIT_URL}/youtubeapi/api/${endpoint}`;
- console.log(`[youtubeChannel] Fetching from Indiekit: ${url}`);
- const data = await EleventyFetch(url, {
- duration: "5m",
- type: "json",
- });
- console.log(`[youtubeChannel] Indiekit ${endpoint} success`);
- return data;
- } catch (error) {
- console.log(
- `[youtubeChannel] Indiekit API unavailable for ${endpoint}: ${error.message}`
- );
- return null;
- }
-}
-
-/**
- * Format large numbers with locale separators
- */
-function formatNumber(num) {
- if (!num) return "0";
- return new Intl.NumberFormat().format(num);
-}
-
-/**
- * Format view count with K/M suffix for compact display
- */
-function formatViewCount(num) {
- if (!num) return "0";
- if (num >= 1000000) {
- return (num / 1000000).toFixed(1).replace(/\.0$/, "") + "M";
- }
- if (num >= 1000) {
- return (num / 1000).toFixed(1).replace(/\\.0$/, "") + "K";
- }
- return num.toString();
-}
-
-/**
- * Format relative time from ISO date string
- */
-function formatRelativeTime(dateString) {
- if (!dateString) return "";
- const date = new Date(dateString);
- const now = new Date();
- const diffMs = now - date;
- const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
-
- if (diffDays === 0) return "Today";
- if (diffDays === 1) return "Yesterday";
- if (diffDays < 7) return `${diffDays} days ago`;
- if (diffDays < 30) return `${Math.floor(diffDays / 7)} weeks ago`;
- if (diffDays < 365) return `${Math.floor(diffDays / 30)} months ago`;
- return `${Math.floor(diffDays / 365)} years ago`;
-}
-
-/**
- * Format channel data with computed fields
- */
-function formatChannel(channel) {
- if (!channel) return null;
- return {
- ...channel,
- subscriberCountFormatted: formatNumber(channel.subscriberCount),
- videoCountFormatted: formatNumber(channel.videoCount),
- viewCountFormatted: formatNumber(channel.viewCount),
- url: `https://www.youtube.com/channel/${channel.id}`,
- };
-}
-
-/**
- * Format video data with computed fields
- */
-function formatVideo(video) {
- return {
- ...video,
- viewCountFormatted: formatViewCount(video.viewCount),
- relativeTime: formatRelativeTime(video.publishedAt),
- };
-}
-
-export default async function () {
- try {
- console.log("[youtubeChannel] Fetching YouTube data...");
-
- // Fetch all data from Indiekit API
- const [channelData, videosData, liveData] = await Promise.all([
- fetchFromIndiekit("channel"),
- fetchFromIndiekit("videos"),
- fetchFromIndiekit("live"),
- ]);
-
- // Check if we got data
- const hasData =
- channelData?.channel ||
- channelData?.channels?.length ||
- videosData?.videos?.length;
-
- if (!hasData) {
- console.log("[youtubeChannel] No data available from Indiekit");
- return {
- channel: null,
- channels: [],
- videos: [],
- videosByChannel: {},
- liveStatus: null,
- liveStatuses: [],
- isMultiChannel: false,
- source: "unavailable",
- };
- }
-
- console.log("[youtubeChannel] Using Indiekit API data");
-
- // Determine if multi-channel mode
- const isMultiChannel = !!(channelData?.channels && channelData.channels.length > 1);
-
- // Format channels
- let channels = [];
- let channel = null;
-
- if (isMultiChannel) {
- channels = (channelData.channels || []).map(formatChannel).filter(Boolean);
- channel = channels[0] || null;
- } else {
- channel = formatChannel(channelData?.channel);
- channels = channel ? [channel] : [];
- }
-
- // Format videos
- const videos = (videosData?.videos || []).map(formatVideo);
-
- // Group videos by channel if multi-channel
- let videosByChannel = {};
- if (isMultiChannel && videosData?.videosByChannel) {
- for (const [channelName, channelVideos] of Object.entries(videosData.videosByChannel)) {
- videosByChannel[channelName] = (channelVideos || []).map(formatVideo);
- }
- } else if (channel) {
- videosByChannel[channel.configName || channel.title] = videos;
- }
-
- // Format live status
- let liveStatus = null;
- let liveStatuses = [];
-
- if (liveData) {
- if (isMultiChannel && liveData.liveStatuses) {
- liveStatuses = liveData.liveStatuses;
- // Find first live or upcoming
- const live = liveStatuses.find((s) => s.isLive);
- const upcoming = liveStatuses.find((s) => s.isUpcoming && !s.isLive);
- liveStatus = {
- isLive: !!live,
- isUpcoming: !live && !!upcoming,
- stream: live?.stream || upcoming?.stream || null,
- };
- } else {
- liveStatus = {
- isLive: liveData.isLive || false,
- isUpcoming: liveData.isUpcoming || false,
- stream: liveData.stream || null,
- };
- liveStatuses = [{ ...liveStatus, channelConfigName: channel?.configName }];
- }
- }
-
- return {
- channel,
- channels,
- videos,
- videosByChannel,
- liveStatus,
- liveStatuses,
- isMultiChannel,
- source: "indiekit",
- };
- } catch (error) {
- console.error("[youtubeChannel] Error:", error.message);
- return {
- channel: null,
- channels: [],
- videos: [],
- videosByChannel: {},
- liveStatus: null,
- liveStatuses: [],
- isMultiChannel: false,
- source: "error",
- };
- }
-}
diff --git a/theme/_includes/components/blog-sidebar.njk b/theme/_includes/components/blog-sidebar.njk
deleted file mode 100644
index d22ebc0..0000000
--- a/theme/_includes/components/blog-sidebar.njk
+++ /dev/null
@@ -1,315 +0,0 @@
-{# Blog Sidebar - Shown on individual post pages #}
-{# Data-driven when homepageConfig.blogPostSidebar is configured, otherwise falls back to default widgets #}
-{# Each widget is wrapped in a collapsible container with localStorage persistence #}
-{% from "components/icon.njk" import icon %}
-
-{% set isArticlePost = (postType == "article") or (page.url and page.url.startsWith('/articles/') and page.url != '/articles/') %}
-{% set showArticleToc = isArticlePost %}
-
-{% if homepageConfig and homepageConfig.blogPostSidebar and homepageConfig.blogPostSidebar.length %}
- {# === Data-driven mode: render configured widgets === #}
- {% set hasConfiguredToc = '"toc"' in (homepageConfig.blogPostSidebar | dump) %}
- {% for widget in homepageConfig.blogPostSidebar %}
-
- {# Resolve widget title #}
- {% if widget.type == "search" %}{% set widgetTitle = "Search" %}
- {% elif widget.type == "social-activity" %}{% set widgetTitle = "Social Activity" %}
- {% elif widget.type == "github-repos" %}{% set widgetTitle = "GitHub" %}
- {% elif widget.type == "funkwhale" %}{% set widgetTitle = "Listening" %}
- {% elif widget.type == "recent-posts" %}{% set widgetTitle = "Recent Posts" %}
- {% elif widget.type == "blogroll" %}{% set widgetTitle = "Blogroll" %}
- {% elif widget.type == "feedland" %}{% set widgetTitle = "FeedLand" %}
- {% elif widget.type == "categories" %}{% set widgetTitle = "Categories" %}
- {% elif widget.type == "webmentions" %}{% set widgetTitle = "Webmentions" %}
- {% elif widget.type == "recent-comments" %}{% set widgetTitle = "Recent Comments" %}
- {% elif widget.type == "fediverse-follow" %}{% set widgetTitle = "Fediverse" %}
- {% elif widget.type == "author-card" %}{% set widgetTitle = "Author" %}
- {% elif widget.type == "author-card-compact" %}{% set widgetTitle = "Author" %}
- {% elif widget.type == "subscribe" %}{% set widgetTitle = "Subscribe" %}
- {% elif widget.type == "toc" %}{% set widgetTitle = "Table of Contents" %}
- {% elif widget.type == "post-categories" %}{% set widgetTitle = "Categories" %}
- {% elif widget.type == "share" %}{% set widgetTitle = "Share" %}
- {% elif widget.type == "ai-usage" %}{% set widgetTitle = "AI Transparency" %}
- {% elif widget.type == "custom-html" %}{% set widgetTitle = (widget.config.title if widget.config and widget.config.title) or "Custom" %}
- {% else %}{% set widgetTitle = widget.type %}
- {% endif %}
-
- {# Resolve widget icon and accent border #}
- {% if widget.type == "social-activity" %}
- {% set widgetIcon = "globe" %}{% set widgetIconClass = "w-5 h-5 text-[#0085ff]" %}{% set widgetBorder = "border-l-[3px] border-l-[#0085ff]" %}
- {% elif widget.type == "github-repos" %}
- {% set widgetIcon = "github" %}{% set widgetIconClass = "w-5 h-5 text-surface-800 dark:text-surface-200" %}{% set widgetBorder = "border-l-[3px] border-l-surface-400 dark:border-l-surface-500" %}
- {% elif widget.type == "funkwhale" %}
- {% set widgetIcon = "headphones" %}{% set widgetIconClass = "w-5 h-5 text-purple-500" %}{% set widgetBorder = "border-l-[3px] border-l-purple-400 dark:border-l-purple-500" %}
- {% elif widget.type == "blogroll" %}
- {% set widgetIcon = "book-open" %}{% set widgetIconClass = "w-5 h-5 text-amber-500" %}{% set widgetBorder = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif widget.type == "feedland" %}
- {% set widgetIcon = "rss" %}{% set widgetIconClass = "w-5 h-5 text-amber-500" %}{% set widgetBorder = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif widget.type == "subscribe" %}
- {% set widgetIcon = "rss" %}{% set widgetIconClass = "w-5 h-5 text-orange-500" %}{% set widgetBorder = "border-l-[3px] border-l-orange-400 dark:border-l-orange-500" %}
- {% elif widget.type == "fediverse-follow" %}
- {% set widgetIcon = "user-plus" %}{% set widgetIconClass = "w-5 h-5 text-[#a730b8]" %}{% set widgetBorder = "border-l-[3px] border-l-[#a730b8]" %}
- {% elif widget.type == "author-card" or widget.type == "author-card-compact" %}
- {% set widgetIcon = "user" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "recent-posts" %}
- {% set widgetIcon = "list" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "categories" or widget.type == "post-categories" %}
- {% set widgetIcon = "tag" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "recent-comments" %}
- {% set widgetIcon = "chat" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "search" %}
- {% set widgetIcon = "search" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "webmentions" %}
- {% set widgetIcon = "share" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "ai-usage" %}
- {% set widgetIcon = "zap" %}{% set widgetIconClass = "w-5 h-5 text-amber-500" %}{% set widgetBorder = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif widget.type == "toc" %}
- {% set widgetIcon = "list" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "share" %}
- {% set widgetIcon = "share" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% else %}
- {% set widgetIcon = "" %}{% set widgetIconClass = "" %}{% set widgetBorder = "" %}
- {% endif %}
-
- {% set widgetKey = "post-widget-" + widget.type + "-" + loop.index0 %}
- {% set defaultOpen = "true" if loop.index0 < 3 else "false" %}
-
- {# Collapsible wrapper — Alpine.js handles toggle, localStorage persists state #}
-
-
- {% if showArticleToc and not hasConfiguredToc and (widget.type == "author-card" or widget.type == "author-card-compact") %}
- {% set widgetKey = "post-widget-toc-article" %}
-
- {% endif %}
-
- {% endfor %}
-{% else %}
- {# === Fallback: aligned with rmendes.net article sidebar === #}
-
- {# Author #}
- {% set widgetKey = "post-widget-author-card-compact-0" %}
-
-
- {% if showArticleToc %}
- {# Table of Contents (articles only) #}
- {% set widgetKey = "post-widget-toc-article" %}
-
- {% endif %}
-
- {# Post Categories #}
- {% set widgetKey = "post-widget-post-categories-2" %}
-
-
- {# Share #}
- {% set widgetKey = "post-widget-share-1" %}
-
-
- {# Social Activity #}
- {% set widgetKey = "post-widget-social-activity-3" %}
-
-
- {# Listening #}
- {% set widgetKey = "post-widget-funkwhale-4" %}
-
-
- {# Blogroll #}
- {% if blogrollStatus and blogrollStatus.source == "indiekit" %}
- {% set widgetKey = "post-widget-blogroll-5" %}
-
- {% endif %}
-
- {# Subscribe #}
- {% set widgetKey = "post-widget-subscribe-6" %}
-
-
- {# Fediverse #}
- {% set widgetKey = "post-widget-fediverse-follow-7" %}
-
-{% endif %}
diff --git a/theme/_includes/components/comments.njk b/theme/_includes/components/comments.njk
deleted file mode 100644
index ddf074c..0000000
--- a/theme/_includes/components/comments.njk
+++ /dev/null
@@ -1,109 +0,0 @@
-{# Comments section — shown on post pages before webmentions #}
-{# Collapsed when empty, auto-opens when comments exist #}
-{% set absoluteUrl = site.url + page.url %}
-
-
-
-
diff --git a/theme/_includes/components/cv-builder.njk b/theme/_includes/components/cv-builder.njk
deleted file mode 100644
index 3699f73..0000000
--- a/theme/_includes/components/cv-builder.njk
+++ /dev/null
@@ -1,169 +0,0 @@
-{#
- CV Page Builder - renders configured layout, sections, and sidebar
- from cvPageConfig (written by indiekit-endpoint-cv plugin)
-#}
-
-{% set layout = cvPageConfig.layout or "single-column" %}
-{% set hasSidebar = cvPageConfig.sidebar and cvPageConfig.sidebar.length %}
-
-{# CV identity — check cvPageConfig.identity first, fall back to site.author #}
-{% set cvId = cvPageConfig.identity if (cvPageConfig and cvPageConfig.identity) else {} %}
-{% set authorName = cvId.name or site.author.name %}
-{% set authorAvatar = cvId.avatar or site.author.avatar %}
-{% set authorTitle = cvId.title or site.author.title %}
-{% set authorBio = cvId.bio or site.author.bio %}
-{% set authorDescription = cvId.description or '' %}
-{% set socialLinks = cvId.social if (cvId.social and cvId.social.length) else site.social %}
-{% set cvLocality = cvId.locality or site.author.locality %}
-{% set cvCountry = cvId.country or site.author.country %}
-{% set cvOrg = cvId.org or site.author.org %}
-{% set cvUrl = cvId.url or '' %}
-{% set cvEmail = cvId.email or site.author.email %}
-{% set cvKeyUrl = cvId.keyUrl or site.author.keyUrl %}
-
-{# Hero — rendered at top when enabled (default: true) #}
-{% if cvPageConfig.hero.enabled != false %}
-
-
-
-
-
- {{ authorName }}
-
- {% if authorTitle %}
-
- {{ authorTitle }}
-
- {% endif %}
- {% if authorBio %}
-
- {{ authorBio }}
-
- {% endif %}
- {% if authorDescription %}
-
-
- More about me ↓
-
-
- {{ authorDescription }}
-
-
- {% endif %}
- {% from "components/social-icon.njk" import socialIcon, socialIconColorClass %}
- {% if cvPageConfig.hero.showSocial != false and socialLinks %}
-
- {% endif %}
- {# Contact details — location, organization, website, email, PGP #}
- {% if cvLocality or cvCountry or cvOrg or cvUrl or cvEmail or cvKeyUrl %}
-
- {% if cvLocality or cvCountry %}
-
{% if cvLocality %}{{ cvLocality }}{% endif %}{% if cvLocality and cvCountry %}, {% endif %}{% if cvCountry %}{{ cvCountry }}{% endif %}
- {% endif %}
- {% if cvOrg %}
-
{{ cvOrg }}
- {% endif %}
- {% if cvUrl %}
-
{{ cvUrl | replace("https://", "") | replace("http://", "") }}
- {% endif %}
- {% if cvEmail %}
-
{{ cvEmail }}
- {% endif %}
- {% if cvKeyUrl %}
-
PGP Key
- {% endif %}
-
- {% endif %}
-
-
-
-{% endif %}
-
-{# Layout wrapper #}
-{% if layout == "single-column" %}
-
- {# Single column — no sidebar, full width sections #}
-
- {% for section in cvPageConfig.sections %}
- {% include "components/homepage-section.njk" %}
- {% endfor %}
-
-
-{% elif layout == "two-column" and hasSidebar %}
-
- {# Two column — sections + sidebar #}
-
-
-{% elif layout == "full-width-hero" %}
-
- {# Full width hero (already rendered above), then two-column below #}
- {% if hasSidebar %}
-
- {% else %}
-
- {% for section in cvPageConfig.sections %}
- {% include "components/homepage-section.njk" %}
- {% endfor %}
-
- {% endif %}
-
-{% else %}
-
- {# Fallback — two-column without sidebar, or unknown layout #}
-
- {% for section in cvPageConfig.sections %}
- {% include "components/homepage-section.njk" %}
- {% endfor %}
-
-
-{% endif %}
-
-{# Last Updated #}
-{% if cv.lastUpdated %}
-
- Last updated: {{ cv.lastUpdated | date("PPP") }}
-
-{% endif %}
-
-{# Footer — rendered after the main layout, full width #}
-{% include "components/cv-footer.njk" %}
diff --git a/theme/_includes/components/cv-footer.njk b/theme/_includes/components/cv-footer.njk
deleted file mode 100644
index c86957e..0000000
--- a/theme/_includes/components/cv-footer.njk
+++ /dev/null
@@ -1,26 +0,0 @@
-{# CV Page Builder Footer — renders footer items in a responsive 3-column grid #}
-{% if cvPageConfig.footer and cvPageConfig.footer.length %}
-
-{% endif %}
diff --git a/theme/_includes/components/cv-sidebar.njk b/theme/_includes/components/cv-sidebar.njk
deleted file mode 100644
index 5b4d164..0000000
--- a/theme/_includes/components/cv-sidebar.njk
+++ /dev/null
@@ -1,45 +0,0 @@
-{# CV Page Builder Sidebar — renders widgets from cvPageConfig.sidebar #}
-{% if cvPageConfig.sidebar and cvPageConfig.sidebar.length %}
- {% for widget in cvPageConfig.sidebar %}
- {% if widget.type == "recent-comments" or widget.type == "categories" or widget.type == "post-categories" %}
- {# Hidden sidebar widgets by request #}
- {% elif widget.type == "author-card" %}
- {% include "components/widgets/author-card.njk" %}
- {% elif widget.type == "social-activity" %}
- {% include "components/widgets/social-activity.njk" %}
- {% elif widget.type == "github-repos" %}
- {% include "components/widgets/github-repos.njk" %}
- {% elif widget.type == "funkwhale" %}
- {% include "components/widgets/funkwhale.njk" %}
- {% elif widget.type == "recent-posts" %}
- {% include "components/widgets/recent-posts.njk" %}
- {% elif widget.type == "blogroll" %}
- {% include "components/widgets/blogroll.njk" %}
- {% elif widget.type == "feedland" %}
- {% include "components/widgets/feedland.njk" %}
- {% elif widget.type == "categories" %}
- {% include "components/widgets/categories.njk" %}
- {% elif widget.type == "search" %}
- {% include "components/widgets/search.njk" %}
- {% elif widget.type == "webmentions" %}
- {% include "components/widgets/webmentions.njk" %}
- {% elif widget.type == "custom-html" %}
- {# Custom content widget #}
- {% set wConfig = widget.config or {} %}
-
-
-
- {% else %}
-
- {% endif %}
- {% endfor %}
-{% endif %}
diff --git a/theme/_includes/components/empty-collection.njk b/theme/_includes/components/empty-collection.njk
deleted file mode 100644
index 8198853..0000000
--- a/theme/_includes/components/empty-collection.njk
+++ /dev/null
@@ -1,27 +0,0 @@
-{# Empty collection placeholder — encourages creating content #}
-{# Usage: {% include "components/empty-collection.njk" %} with postType set before include #}
-{% set typeInfo = null %}
-{% for pt in enabledPostTypes %}
- {% if pt.type == postType %}{% set typeInfo = pt %}{% endif %}
-{% endfor %}
-
-
-
-
No {{ title | lower }} yet
-
- This is where your {{ title | lower }} will appear once you start creating content.
-
- {% if typeInfo %}
-
-
-
-
- Create your first {{ postType }}
-
- {% endif %}
-
diff --git a/theme/_includes/components/fediverse-modal.njk b/theme/_includes/components/fediverse-modal.njk
deleted file mode 100644
index 30699e0..0000000
--- a/theme/_includes/components/fediverse-modal.njk
+++ /dev/null
@@ -1,81 +0,0 @@
-{# Shared fediverse instance picker modal #}
-{# Used by post.njk (interact), fediverse-follow.njk (follow), share.njk (share) #}
-{# Requires: modalTitle, modalDescription variables set before include #}
-
-
- {# Backdrop #}
-
- {# Panel #}
-
-
{{ modalTitle }}
-
{{ modalDescription }}
-
- {# Saved domains list #}
-
-
-
-
Use a different instance
-
-
- Cancel
-
-
-
-
-
- {# New domain input #}
-
-
-
-
-
-
-
-
-
-
- Go
-
-
-
-
-
-
-
diff --git a/theme/_includes/components/funkwhale-stats-content.njk b/theme/_includes/components/funkwhale-stats-content.njk
deleted file mode 100644
index b7123a2..0000000
--- a/theme/_includes/components/funkwhale-stats-content.njk
+++ /dev/null
@@ -1,66 +0,0 @@
-{# Stats Summary Cards #}
-{% if summary %}
-
-
- {{ summary.totalPlays or 0 }}
- Plays
-
-
- {{ summary.uniqueTracks or 0 }}
- Tracks
-
-
- {{ summary.uniqueArtists or 0 }}
- Artists
-
-
- {{ summary.totalDurationFormatted or '0m' }}
- Listened
-
-
-{% endif %}
-
-{# Top Artists #}
-{% if topArtists and topArtists.length %}
-
-
Top Artists
-
- {% for artist in topArtists | head(5) %}
-
- {{ loop.index }}
- {{ artist.name }}
- {{ artist.playCount }} plays
-
- {% endfor %}
-
-
-{% endif %}
-
-{# Top Albums #}
-{% if topAlbums and topAlbums.length %}
-
-
Top Albums
-
- {% for album in topAlbums | head(5) %}
-
- {% if album.coverUrl %}
-
- {% else %}
-
- {% endif %}
-
{{ album.title }}
-
{{ album.artist }}
-
{{ album.playCount }} plays
-
- {% endfor %}
-
-
-{% endif %}
-
-{% if not summary and not topArtists and not topAlbums %}
-No statistics available for this period.
-{% endif %}
diff --git a/theme/_includes/components/h-card.njk b/theme/_includes/components/h-card.njk
deleted file mode 100644
index dd1d4a7..0000000
--- a/theme/_includes/components/h-card.njk
+++ /dev/null
@@ -1,115 +0,0 @@
-{# h-card - IndieWeb identity microformat #}
-{# See: https://microformats.org/wiki/h-card #}
-{#
- This is the canonical h-card component for the site.
- Include in sidebar widgets, author cards, etc.
-#}
-{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
-{% set authorName = id.name if (id.name is defined) else site.author.name %}
-{% set authorAvatar = id.avatar if (id.avatar is defined) else site.author.avatar %}
-{% set authorTitle = id.title if (id.title is defined) else site.author.title %}
-{% set authorBio = id.bio if (id.bio is defined) else site.author.bio %}
-{% set authorUrl = id.url if (id.url is defined and id.url) else site.author.url %}
-{% set authorPronoun = id.pronoun if (id.pronoun is defined) else site.author.pronoun %}
-{% set authorLocality = id.locality if (id.locality is defined) else site.author.locality %}
-{% set authorCountry = id.country if (id.country is defined) else site.author.country %}
-{% set authorLocation = id.location if (id.location is defined) else site.author.location %}
-{% set authorOrg = id.org if (id.org is defined) else site.author.org %}
-{% set authorEmail = id.email if (id.email is defined) else site.author.email %}
-{% set authorKeyUrl = id.keyUrl if (id.keyUrl is defined) else site.author.keyUrl %}
-{% set authorCategories = id.categories if (id.categories is defined) else site.author.categories %}
-{% set socialLinks = id.social if (id.social is defined) else site.social %}
-
-
- {# Hidden u-photo for reliable microformat parsing (some parsers struggle with img inside links) #}
-
-
-
-
-
-
-
-
- {{ authorName }}
-
- {% if authorPronoun %}
-
({{ authorPronoun }})
- {% endif %}
- {% if authorTitle %}
-
{{ authorTitle }}
- {% endif %}
- {# Structured address #}
-
- {% if authorLocality %}
- {{ authorLocality }} {% if authorCountry %}, {% endif %}
- {% endif %}
- {% if authorCountry %}
- {{ authorCountry }}
- {% endif %}
- {# Fallback to legacy location field #}
- {% if not authorLocality and authorLocation %}
- {{ authorLocation }}
- {% endif %}
-
-
-
-
- {# Bio #}
- {% if authorBio %}
-
{{ authorBio }}
- {% endif %}
-
- {# Organization #}
- {% if authorOrg %}
-
- {{ authorOrg }}
-
- {% endif %}
-
- {# Email and PGP Key #}
-
- {% if authorEmail %}
- {# Display text obfuscated to deter spam harvesters; href kept plain for browser compatibility #}
-
- ✉️ {{ authorEmail | obfuscateEmail | safe }}
-
- {% endif %}
- {% if authorKeyUrl %}
-
- 🔐 PGP Key
-
- {% endif %}
-
-
- {# Categories / Skills #}
- {% if authorCategories and authorCategories.length %}
-
- {% for category in authorCategories %}
- {{ category }}
- {% endfor %}
-
- {% endif %}
-
- {# Social links with rel="me" - critical for IndieWeb identity verification #}
- {% from "components/social-icon.njk" import socialIcon %}
- {% if socialLinks and socialLinks.length %}
-
- {% for link in socialLinks %}
-
- {{ socialIcon(link.icon, "w-5 h-5") }}
-
- {% endfor %}
-
- {% endif %}
-
diff --git a/theme/_includes/components/homepage-builder.njk b/theme/_includes/components/homepage-builder.njk
deleted file mode 100644
index b0ba263..0000000
--- a/theme/_includes/components/homepage-builder.njk
+++ /dev/null
@@ -1,86 +0,0 @@
-{#
- Homepage Builder - renders configured layout, sections, and sidebar
- from homepageConfig (written by indiekit-endpoint-homepage plugin)
-#}
-
-{% set layout = homepageConfig.layout or "two-column" %}
-{% set hasSidebar = homepageConfig.sidebar and homepageConfig.sidebar.length %}
-
-{# Hero — rendered before layout wrapper when enabled #}
-{% if homepageConfig.hero and homepageConfig.hero.enabled %}
- {% include "components/sections/hero.njk" %}
-{% endif %}
-
-{# Layout wrapper #}
-{% if layout == "single-column" %}
-
- {# Single column — no sidebar, full width sections #}
-
- {% for section in homepageConfig.sections %}
- {% if section.type != "hero" %}
- {% include "components/homepage-section.njk" %}
- {% endif %}
- {% endfor %}
-
-
-{% elif layout == "two-column" and hasSidebar %}
-
- {# Two column — sections + sidebar #}
-
-
-{% elif layout == "full-width-hero" %}
-
- {# Full width hero (already rendered above), then two-column below #}
- {% if hasSidebar %}
-
- {% else %}
-
- {% for section in homepageConfig.sections %}
- {% if section.type != "hero" %}
- {% include "components/homepage-section.njk" %}
- {% endif %}
- {% endfor %}
-
- {% endif %}
-
-{% else %}
-
- {# Fallback — two-column without sidebar, or unknown layout #}
-
- {% for section in homepageConfig.sections %}
- {% if section.type != "hero" %}
- {% include "components/homepage-section.njk" %}
- {% endif %}
- {% endfor %}
-
-
-{% endif %}
-
-{# Footer — rendered after the main layout, full width #}
-{% include "components/homepage-footer.njk" %}
diff --git a/theme/_includes/components/homepage-footer.njk b/theme/_includes/components/homepage-footer.njk
deleted file mode 100644
index d6f917b..0000000
--- a/theme/_includes/components/homepage-footer.njk
+++ /dev/null
@@ -1,26 +0,0 @@
-{# Homepage Builder Footer — renders footer items in a responsive 3-column grid #}
-{% if homepageConfig.footer and homepageConfig.footer.length %}
-
-{% endif %}
diff --git a/theme/_includes/components/homepage-section.njk b/theme/_includes/components/homepage-section.njk
deleted file mode 100644
index e7b8ee0..0000000
--- a/theme/_includes/components/homepage-section.njk
+++ /dev/null
@@ -1,56 +0,0 @@
-{# Homepage Section Dispatcher — maps section.type to the right partial #}
-{% if section.type == "featured-posts" %}
- {% include "components/sections/featured-posts.njk" %}
-{% elif section.type == "recent-posts" %}
- {% include "components/sections/recent-posts.njk" %}
-{% elif section.type == "custom-html" %}
- {% include "components/sections/custom-html.njk" %}
-{% elif section.type == "cv-experience" %}
- {% include "components/sections/cv-experience.njk" ignore missing %}
-{% elif section.type == "cv-projects" %}
- {% include "components/sections/cv-projects.njk" ignore missing %}
-{% elif section.type == "cv-projects-personal" %}
- {% include "components/sections/cv-projects-personal.njk" ignore missing %}
-{% elif section.type == "cv-projects-work" %}
- {% include "components/sections/cv-projects-work.njk" ignore missing %}
-{% elif section.type == "cv-skills" %}
- {% include "components/sections/cv-skills.njk" ignore missing %}
-{% elif section.type == "cv-education" %}
- {% include "components/sections/cv-education.njk" ignore missing %}
-{% elif section.type == "cv-interests" %}
- {% include "components/sections/cv-interests.njk" ignore missing %}
-{% elif section.type == "cv-experience-personal" %}
- {% include "components/sections/cv-experience-personal.njk" ignore missing %}
-{% elif section.type == "cv-experience-work" %}
- {% include "components/sections/cv-experience-work.njk" ignore missing %}
-{% elif section.type == "cv-education-personal" %}
- {% include "components/sections/cv-education-personal.njk" ignore missing %}
-{% elif section.type == "cv-education-work" %}
- {% include "components/sections/cv-education-work.njk" ignore missing %}
-{% elif section.type == "cv-skills-personal" %}
- {% include "components/sections/cv-skills-personal.njk" ignore missing %}
-{% elif section.type == "cv-skills-work" %}
- {% include "components/sections/cv-skills-work.njk" ignore missing %}
-{% elif section.type == "cv-interests-personal" %}
- {% include "components/sections/cv-interests-personal.njk" ignore missing %}
-{% elif section.type == "cv-interests-work" %}
- {% include "components/sections/cv-interests-work.njk" ignore missing %}
-{% elif section.type == "cv-languages" %}
- {% include "components/sections/cv-languages.njk" ignore missing %}
-{% elif section.type == "blogroll" %}
- {% include "components/sections/blogroll.njk" ignore missing %}
-{% elif section.type == "podroll" %}
- {% include "components/sections/podroll.njk" ignore missing %}
-{% elif section.type == "github-activity" %}
- {% include "components/sections/github-activity.njk" ignore missing %}
-{% elif section.type == "youtube" %}
- {% include "components/sections/youtube.njk" ignore missing %}
-{% elif section.type == "funkwhale" %}
- {% include "components/sections/funkwhale.njk" ignore missing %}
-{% elif section.type == "lastfm" %}
- {% include "components/sections/lastfm.njk" ignore missing %}
-{% elif section.type == "posting-activity" %}
- {% include "components/sections/posting-activity.njk" ignore missing %}
-{% else %}
-
-{% endif %}
diff --git a/theme/_includes/components/homepage-sidebar.njk b/theme/_includes/components/homepage-sidebar.njk
deleted file mode 100644
index 9601cd5..0000000
--- a/theme/_includes/components/homepage-sidebar.njk
+++ /dev/null
@@ -1,147 +0,0 @@
-{# Homepage Builder Sidebar — renders widgets from homepageConfig.sidebar #}
-{# Each widget is wrapped in a collapsible container with localStorage persistence #}
-{% from "components/icon.njk" import icon %}
-
-{% if homepageConfig.sidebar and homepageConfig.sidebar.length %}
- {% for widget in homepageConfig.sidebar %}
- {% set isHomepageAuthorWidget = widget.type == "author-card" or widget.type == "author-card-compact" %}
- {% if not isHomepageAuthorWidget %}
-
- {# Resolve widget title #}
- {% if widget.type == "search" %}{% set widgetTitle = "Search" %}
- {% elif widget.type == "social-activity" %}{% set widgetTitle = "Social Activity" %}
- {% elif widget.type == "github-repos" %}{% set widgetTitle = "GitHub" %}
- {% elif widget.type == "funkwhale" %}{% set widgetTitle = "Listening" %}
- {% elif widget.type == "recent-posts" %}{% set widgetTitle = "Recent Posts" %}
- {% elif widget.type == "blogroll" %}{% set widgetTitle = "Blogroll" %}
- {% elif widget.type == "feedland" %}{% set widgetTitle = "FeedLand" %}
- {% elif widget.type == "categories" %}{% set widgetTitle = "Categories" %}
- {% elif widget.type == "webmentions" %}{% set widgetTitle = "Webmentions" %}
- {% elif widget.type == "recent-comments" %}{% set widgetTitle = "Recent Comments" %}
- {% elif widget.type == "fediverse-follow" %}{% set widgetTitle = "Fediverse" %}
- {% elif widget.type == "author-card" %}{% set widgetTitle = "Author" %}
- {% elif widget.type == "ai-usage" %}{% set widgetTitle = "AI Transparency" %}
- {% elif widget.type == "custom-html" %}{% set widgetTitle = (widget.config.title if widget.config and widget.config.title) or "Custom" %}
- {% else %}{% set widgetTitle = widget.type %}
- {% endif %}
-
- {# Resolve widget icon and accent border #}
- {% if widget.type == "social-activity" %}
- {% set widgetIcon = "globe" %}{% set widgetIconClass = "w-5 h-5 text-[#0085ff]" %}{% set widgetBorder = "border-l-[3px] border-l-[#0085ff]" %}
- {% elif widget.type == "github-repos" %}
- {% set widgetIcon = "github" %}{% set widgetIconClass = "w-5 h-5 text-surface-800 dark:text-surface-200" %}{% set widgetBorder = "border-l-[3px] border-l-surface-400 dark:border-l-surface-500" %}
- {% elif widget.type == "funkwhale" %}
- {% set widgetIcon = "headphones" %}{% set widgetIconClass = "w-5 h-5 text-purple-500" %}{% set widgetBorder = "border-l-[3px] border-l-purple-400 dark:border-l-purple-500" %}
- {% elif widget.type == "blogroll" %}
- {% set widgetIcon = "book-open" %}{% set widgetIconClass = "w-5 h-5 text-amber-500" %}{% set widgetBorder = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif widget.type == "feedland" %}
- {% set widgetIcon = "rss" %}{% set widgetIconClass = "w-5 h-5 text-amber-500" %}{% set widgetBorder = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif widget.type == "subscribe" %}
- {% set widgetIcon = "rss" %}{% set widgetIconClass = "w-5 h-5 text-orange-500" %}{% set widgetBorder = "border-l-[3px] border-l-orange-400 dark:border-l-orange-500" %}
- {% elif widget.type == "fediverse-follow" %}
- {% set widgetIcon = "user-plus" %}{% set widgetIconClass = "w-5 h-5 text-[#a730b8]" %}{% set widgetBorder = "border-l-[3px] border-l-[#a730b8]" %}
- {% elif widget.type == "author-card" %}
- {% set widgetIcon = "user" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "recent-posts" %}
- {% set widgetIcon = "list" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "categories" %}
- {% set widgetIcon = "tag" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "recent-comments" %}
- {% set widgetIcon = "chat" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "search" %}
- {% set widgetIcon = "search" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "webmentions" %}
- {% set widgetIcon = "share" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "ai-usage" %}
- {% set widgetIcon = "zap" %}{% set widgetIconClass = "w-5 h-5 text-amber-500" %}{% set widgetBorder = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% else %}
- {% set widgetIcon = "" %}{% set widgetIconClass = "" %}{% set widgetBorder = "" %}
- {% endif %}
-
- {% set widgetKey = "widget-" + widget.type + "-" + loop.index0 %}
- {% set defaultOpen = "true" if loop.index0 < 3 else "false" %}
-
- {# Collapsible wrapper — Alpine.js handles toggle, localStorage persists state #}
-
-
- {% endif %}
-
- {% endfor %}
-{% endif %}
diff --git a/theme/_includes/components/icon.njk b/theme/_includes/components/icon.njk
deleted file mode 100644
index d538ddd..0000000
--- a/theme/_includes/components/icon.njk
+++ /dev/null
@@ -1,67 +0,0 @@
-{#
- Centralized UI icon macro
- Usage: {% from "components/icon.njk" import icon %}
- {{ icon("heart", "w-5 h-5 text-red-500") }}
-
- All icons use stroke-width="2" unless they are filled icons.
- Default size: w-5 h-5 (override via cssClass parameter)
-#}
-
-{% macro icon(name, cssClass) %}
-{% set cls = cssClass or "w-5 h-5" %}
-{%- if name == "heart" -%}
-
-{%- elif name == "bookmark" -%}
-
-{%- elif name == "repost" -%}
-
-{%- elif name == "reply" -%}
-
-{%- elif name == "camera" -%}
-
-{%- elif name == "article" -%}
-
-{%- elif name == "note" -%}
-
-{%- elif name == "music" -%}
-
-{%- elif name == "tag" -%}
-
-{%- elif name == "rss" -%}
-
-{%- elif name == "chat" -%}
-
-{%- elif name == "user" -%}
-
-{%- elif name == "search" -%}
-
-{%- elif name == "star" -%}
-
-{%- elif name == "external-link" -%}
-
-{%- elif name == "chevron-down" -%}
-
-{%- elif name == "chevron-right" -%}
-
-{%- elif name == "globe" -%}
-
-{%- elif name == "github" -%}
-
-{%- elif name == "list" -%}
-
-{%- elif name == "share" -%}
-
-{%- elif name == "book-open" -%}
-
-{%- elif name == "headphones" -%}
-
-{%- elif name == "mail" -%}
-
-{%- elif name == "podcast" -%}
-
-{%- elif name == "user-plus" -%}
-
-{%- else -%}
-
-{%- endif -%}
-{% endmacro %}
diff --git a/theme/_includes/components/post-navigation.njk b/theme/_includes/components/post-navigation.njk
deleted file mode 100644
index 0103704..0000000
--- a/theme/_includes/components/post-navigation.njk
+++ /dev/null
@@ -1,103 +0,0 @@
-{# Post Navigation - Previous/Next (image-first, inspired by zachleat.com) #}
-{% set _prevPost = collections.posts | previousInCollection(page) %}
-{% set _nextPost = collections.posts | nextInCollection(page) %}
-
-{% if _prevPost or _nextPost %}
-
-
-
- {# ── Previous Post ── #}
- {% if _prevPost %}
- {% set _prevOgSlug = _prevPost.url | ogSlug %}
- {% set _prevHasOg = _prevOgSlug | hasOgImage %}
- {% set _prevTitle = _prevPost.data.title or _prevPost.data.name %}
-
- {# Derive display text for non-article post types #}
- {% set _likedUrl = _prevPost.data.likeOf or _prevPost.data.like_of %}
- {% set _bookmarkedUrl = _prevPost.data.bookmarkOf or _prevPost.data.bookmark_of %}
- {% set _repostedUrl = _prevPost.data.repostOf or _prevPost.data.repost_of %}
- {% set _replyToUrl = _prevPost.data.inReplyTo or _prevPost.data.in_reply_to %}
- {% if not _prevTitle %}
- {% if _likedUrl %}
- {% set _prevTitle = "Liked " + (_likedUrl | replace("https://", "") | truncate(40)) %}
- {% elif _bookmarkedUrl %}
- {% set _prevTitle = "Bookmarked " + (_bookmarkedUrl | replace("https://", "") | truncate(35)) %}
- {% elif _repostedUrl %}
- {% set _prevTitle = "Reposted " + (_repostedUrl | replace("https://", "") | truncate(35)) %}
- {% elif _replyToUrl %}
- {% set _prevTitle = "Reply to " + (_replyToUrl | replace("https://", "") | truncate(35)) %}
- {% else %}
- {% set _prevTitle = (_prevPost.templateContent | striptags | truncate(60)) or "Note" %}
- {% endif %}
- {% endif %}
-
-
- {% if _prevHasOg %}
-
-
- ← Previous
-
- {% else %}
-
- ← Previous
-
- {{ _prevTitle }}
-
- {{ _prevPost.date | dateDisplay }}
-
- {% endif %}
-
-
- {% else %}
-
- {% endif %}
-
- {# ── Next Post ── #}
- {% if _nextPost %}
- {% set _nextOgSlug = _nextPost.url | ogSlug %}
- {% set _nextHasOg = _nextOgSlug | hasOgImage %}
- {% set _nextTitle = _nextPost.data.title or _nextPost.data.name %}
-
- {# Derive display text for non-article post types #}
- {% set _likedUrl = _nextPost.data.likeOf or _nextPost.data.like_of %}
- {% set _bookmarkedUrl = _nextPost.data.bookmarkOf or _nextPost.data.bookmark_of %}
- {% set _repostedUrl = _nextPost.data.repostOf or _nextPost.data.repost_of %}
- {% set _replyToUrl = _nextPost.data.inReplyTo or _nextPost.data.in_reply_to %}
- {% if not _nextTitle %}
- {% if _likedUrl %}
- {% set _nextTitle = "Liked " + (_likedUrl | replace("https://", "") | truncate(40)) %}
- {% elif _bookmarkedUrl %}
- {% set _nextTitle = "Bookmarked " + (_bookmarkedUrl | replace("https://", "") | truncate(35)) %}
- {% elif _repostedUrl %}
- {% set _nextTitle = "Reposted " + (_repostedUrl | replace("https://", "") | truncate(35)) %}
- {% elif _replyToUrl %}
- {% set _nextTitle = "Reply to " + (_replyToUrl | replace("https://", "") | truncate(35)) %}
- {% else %}
- {% set _nextTitle = (_nextPost.templateContent | striptags | truncate(60)) or "Note" %}
- {% endif %}
- {% endif %}
-
-
- {% if _nextHasOg %}
-
-
- Next →
-
- {% else %}
-
- Next →
-
- {{ _nextTitle }}
-
- {{ _nextPost.date | dateDisplay }}
-
- {% endif %}
-
-
- {% else %}
-
- {% endif %}
-
-
-
-{% endif %}
diff --git a/theme/_includes/components/reply-context.njk b/theme/_includes/components/reply-context.njk
deleted file mode 100644
index bfa2781..0000000
--- a/theme/_includes/components/reply-context.njk
+++ /dev/null
@@ -1,74 +0,0 @@
-{# Reply Context Component #}
-{# Displays rich context for replies, likes, reposts, and bookmarks #}
-{# Uses h-cite microformat for citing external content #}
-{# Includes unfurl card for rich link preview (OpenGraph metadata) #}
-
-{# Support both camelCase (Indiekit Eleventy preset) and underscore (legacy) property names #}
-{% set replyTo = inReplyTo or in_reply_to %}
-{% set likedUrl = likeOf or like_of %}
-{% set repostedUrl = repostOf or repost_of %}
-{% set bookmarkedUrl = bookmarkOf or bookmark_of %}
-
-{% if replyTo or likedUrl or repostedUrl or bookmarkedUrl %}
-
- {% if replyTo %}
-
- {% endif %}
-
- {% if likedUrl %}
-
- {% endif %}
-
- {% if repostedUrl %}
-
-
-
-
-
- Reposted:
-
- {% unfurl repostedUrl %}
-
- {{ repostedUrl }}
-
-
- {% endif %}
-
- {% if bookmarkedUrl %}
-
- {% endif %}
-
-{% endif %}
diff --git a/theme/_includes/components/sections/custom-html.njk b/theme/_includes/components/sections/custom-html.njk
deleted file mode 100644
index 5045160..0000000
--- a/theme/_includes/components/sections/custom-html.njk
+++ /dev/null
@@ -1,18 +0,0 @@
-{#
- Custom HTML Section - freeform HTML/markdown content block
- Rendered by homepage-builder when custom-html section is configured
-#}
-
-{% set sectionConfig = section.config or {} %}
-
-
- {% if sectionConfig.title %}
-
- {{ sectionConfig.title }}
-
- {% endif %}
-
-
- {{ sectionConfig.content | safe }}
-
-
diff --git a/theme/_includes/components/sections/cv-education-personal.njk b/theme/_includes/components/sections/cv-education-personal.njk
deleted file mode 100644
index fd937a7..0000000
--- a/theme/_includes/components/sections/cv-education-personal.njk
+++ /dev/null
@@ -1,2 +0,0 @@
-{% set filterType = "personal" %}
-{% include "components/sections/cv-education.njk" %}
diff --git a/theme/_includes/components/sections/cv-education-work.njk b/theme/_includes/components/sections/cv-education-work.njk
deleted file mode 100644
index 6d2e3ea..0000000
--- a/theme/_includes/components/sections/cv-education-work.njk
+++ /dev/null
@@ -1,2 +0,0 @@
-{% set filterType = "work" %}
-{% include "components/sections/cv-education.njk" %}
diff --git a/theme/_includes/components/sections/cv-education.njk b/theme/_includes/components/sections/cv-education.njk
deleted file mode 100644
index 3ff1ecf..0000000
--- a/theme/_includes/components/sections/cv-education.njk
+++ /dev/null
@@ -1,88 +0,0 @@
-{#
- CV Education Section - collapsible education cards (accordion)
- Data fetched from /cv/data.json via homepage plugin
- Each card gets a distinct color via cycling palette
-#}
-
-{% set hasEducation = cv and cv.education and cv.education.length %}
-
-{% if hasEducation %}
-
-
- {{ section.config.title or "Education" }}
-
-
-
- {% for item in cv.education %}
- {% if not filterType or item.educationType == filterType or not item.educationType %}
- {% set ci = loop.index0 % 8 %}
-
- {# Summary row — always visible, clickable #}
-
-
-
{{ item.degree }}
-
- {{ item.institution }}{% if item.location %} · {{ item.location }}{% endif %}
-
-
-
- {% if item.startDate %}
-
- {{ item.startDate }}{% if item.endDate %} – {{ item.endDate }}{% else %} – Present{% endif %}
-
- {% elif item.year %}
-
{{ item.year }}
- {% endif %}
-
-
-
-
-
-
- {# Detail section — collapsible #}
-
- {% if item.startDate %}
-
- {{ item.startDate }}{% if item.endDate %} – {{ item.endDate }}{% else %} – Present{% endif %}
-
- {% elif item.year %}
-
{{ item.year }}
- {% endif %}
-
- {% if item.description %}
-
{{ item.description }}
- {% endif %}
-
-
- {% endif %}
- {% endfor %}
-
-
-{% endif %}
diff --git a/theme/_includes/components/sections/cv-experience-personal.njk b/theme/_includes/components/sections/cv-experience-personal.njk
deleted file mode 100644
index 7d4c858..0000000
--- a/theme/_includes/components/sections/cv-experience-personal.njk
+++ /dev/null
@@ -1,2 +0,0 @@
-{% set filterType = "personal" %}
-{% include "components/sections/cv-experience.njk" %}
diff --git a/theme/_includes/components/sections/cv-experience-work.njk b/theme/_includes/components/sections/cv-experience-work.njk
deleted file mode 100644
index 57b91b3..0000000
--- a/theme/_includes/components/sections/cv-experience-work.njk
+++ /dev/null
@@ -1,2 +0,0 @@
-{% set filterType = "work" %}
-{% include "components/sections/cv-experience.njk" %}
diff --git a/theme/_includes/components/sections/cv-experience.njk b/theme/_includes/components/sections/cv-experience.njk
deleted file mode 100644
index b9ad71d..0000000
--- a/theme/_includes/components/sections/cv-experience.njk
+++ /dev/null
@@ -1,48 +0,0 @@
-{#
- CV Experience Section - work experience timeline
- Data fetched from /cv/data.json via homepage plugin
-#}
-
-{% set sectionConfig = section.config or {} %}
-{% set maxItems = sectionConfig.maxItems or 10 %}
-{% set showHighlights = sectionConfig.showHighlights if sectionConfig.showHighlights is defined else true %}
-
-{% if cv and cv.experience and cv.experience.length %}
-
-
- {{ sectionConfig.title or "Experience" }}
-
-
-
- {% for item in cv.experience | head(maxItems) %}
- {% if not filterType or item.experienceType == filterType or not item.experienceType %}
-
-
-
{{ item.title }}
-
- {{ item.company }}{% if item.location %} · {{ item.location }}{% endif %}
- {% if item.type %} · {{ item.type }} {% endif %}
-
- {% if item.startDate %}
-
- {{ item.startDate }}{% if item.endDate %} – {{ item.endDate }}{% else %} – Present{% endif %}
-
- {% endif %}
- {% if item.description %}
-
{{ item.description }}
- {% endif %}
- {% if showHighlights and item.highlights and item.highlights.length %}
-
- {% for h in item.highlights %}
-
- {{ h }}
-
- {% endfor %}
-
- {% endif %}
-
- {% endif %}
- {% endfor %}
-
-
-{% endif %}
diff --git a/theme/_includes/components/sections/cv-interests-personal.njk b/theme/_includes/components/sections/cv-interests-personal.njk
deleted file mode 100644
index 0d053a3..0000000
--- a/theme/_includes/components/sections/cv-interests-personal.njk
+++ /dev/null
@@ -1,2 +0,0 @@
-{% set filterType = "personal" %}
-{% include "components/sections/cv-interests.njk" %}
diff --git a/theme/_includes/components/sections/cv-interests-work.njk b/theme/_includes/components/sections/cv-interests-work.njk
deleted file mode 100644
index 7cbe270..0000000
--- a/theme/_includes/components/sections/cv-interests-work.njk
+++ /dev/null
@@ -1,2 +0,0 @@
-{% set filterType = "work" %}
-{% include "components/sections/cv-interests.njk" %}
diff --git a/theme/_includes/components/sections/cv-interests.njk b/theme/_includes/components/sections/cv-interests.njk
deleted file mode 100644
index 997f791..0000000
--- a/theme/_includes/components/sections/cv-interests.njk
+++ /dev/null
@@ -1,50 +0,0 @@
-{#
- CV Interests Section - interests grouped by category
- Data fetched from /cv/data.json via homepage plugin
- Each family gets a distinct color via cycling palette
-#}
-
-{% if cv and cv.interests and (cv.interests | dictsort | length) %}
-
-
- {{ section.config.title or "Interests" }}
-
-
-
- {% for category, items in cv.interests %}
- {% if not filterType or (cv.interestTypes and cv.interestTypes[category] == filterType) or not cv.interestTypes or not cv.interestTypes[category] %}
- {# Cycle through 8 distinct colors per family using loop.index0 #}
- {% set ci = loop.index0 % 8 %}
-
-
- {{ category }}
-
-
- {% for interest in items %}
- {% if ci == 0 %}
-
- {% elif ci == 1 %}
-
- {% elif ci == 2 %}
-
- {% elif ci == 3 %}
-
- {% elif ci == 4 %}
-
- {% elif ci == 5 %}
-
- {% elif ci == 6 %}
-
- {% elif ci == 7 %}
-
- {% endif %}
- {{ interest }}
-
- {% endfor %}
-
-
- {% endif %}
- {% endfor %}
-
-
-{% endif %}
diff --git a/theme/_includes/components/sections/cv-languages.njk b/theme/_includes/components/sections/cv-languages.njk
deleted file mode 100644
index 438905f..0000000
--- a/theme/_includes/components/sections/cv-languages.njk
+++ /dev/null
@@ -1,21 +0,0 @@
-{#
- CV Languages Section
- Data fetched from /cv/data.json via homepage plugin
-#}
-
-{% if cv and cv.languages and cv.languages.length %}
-
-
- {{ section.config.title or "Languages" }}
-
-
-
- {% for lang in cv.languages %}
-
- {{ lang.name }}
- {{ lang.level }}
-
- {% endfor %}
-
-
-{% endif %}
diff --git a/theme/_includes/components/sections/cv-projects-personal.njk b/theme/_includes/components/sections/cv-projects-personal.njk
deleted file mode 100644
index e3e6ab0..0000000
--- a/theme/_includes/components/sections/cv-projects-personal.njk
+++ /dev/null
@@ -1,124 +0,0 @@
-{#
- CV Personal Projects Section - collapsible project cards (accordion)
- Filters projects by projectType == "personal" (or unset)
- Data fetched from /cv/data.json via homepage plugin
-#}
-
-{% set sectionConfig = section.config or {} %}
-{% set maxItems = sectionConfig.maxItems or 10 %}
-{% set showTechnologies = sectionConfig.showTechnologies if sectionConfig.showTechnologies is defined else true %}
-
-{% set personalProjects = [] %}
-{% if cv and cv.projects %}
- {% for item in cv.projects %}
- {% if item.projectType == "personal" or not item.projectType %}
- {% set personalProjects = (personalProjects.push(item), personalProjects) %}
- {% endif %}
- {% endfor %}
-{% endif %}
-
-{% if personalProjects.length %}
-
-
- {{ sectionConfig.title or "Personal Projects" }}
-
-
-
- {% for item in personalProjects | head(maxItems) %}
- {% set ci = loop.index0 % 8 %}
-
- {# Summary row — always visible, clickable #}
-
-
-
- {% if item.url %}
- {{ item.name }}
- {% else %}
- {{ item.name }}
- {% endif %}
-
- {% if item.status %}
-
- {{ item.status }}
-
- {% endif %}
-
-
- {% if item.startDate %}
-
- {{ item.startDate }}{% if item.endDate %} – {{ item.endDate }}{% else %} – Present{% endif %}
-
- {% endif %}
-
-
-
-
-
-
- {# Detail section — collapsible #}
-
- {% if item.startDate %}
-
- {{ item.startDate }}{% if item.endDate %} – {{ item.endDate }}{% else %} – Present{% endif %}
-
- {% endif %}
-
- {% if item.description %}
-
{{ item.description }}
- {% endif %}
-
- {% if showTechnologies and item.technologies and item.technologies.length %}
-
- {% for tech in item.technologies %}
-
- {{ tech }}
-
- {% endfor %}
-
- {% endif %}
-
-
- {% endfor %}
-
-
-{% endif %}
diff --git a/theme/_includes/components/sections/cv-projects-work.njk b/theme/_includes/components/sections/cv-projects-work.njk
deleted file mode 100644
index 47d7014..0000000
--- a/theme/_includes/components/sections/cv-projects-work.njk
+++ /dev/null
@@ -1,124 +0,0 @@
-{#
- CV Work Projects Section - collapsible project cards (accordion)
- Filters projects by projectType == "work"
- Data fetched from /cv/data.json via homepage plugin
-#}
-
-{% set sectionConfig = section.config or {} %}
-{% set maxItems = sectionConfig.maxItems or 10 %}
-{% set showTechnologies = sectionConfig.showTechnologies if sectionConfig.showTechnologies is defined else true %}
-
-{% set workProjects = [] %}
-{% if cv and cv.projects %}
- {% for item in cv.projects %}
- {% if item.projectType == "work" %}
- {% set workProjects = (workProjects.push(item), workProjects) %}
- {% endif %}
- {% endfor %}
-{% endif %}
-
-{% if workProjects.length %}
-
-
- {{ sectionConfig.title or "Work Projects" }}
-
-
-
- {% for item in workProjects | head(maxItems) %}
- {% set ci = loop.index0 % 8 %}
-
- {# Summary row — always visible, clickable #}
-
-
-
- {% if item.url %}
- {{ item.name }}
- {% else %}
- {{ item.name }}
- {% endif %}
-
- {% if item.status %}
-
- {{ item.status }}
-
- {% endif %}
-
-
- {% if item.startDate %}
-
- {{ item.startDate }}{% if item.endDate %} – {{ item.endDate }}{% else %} – Present{% endif %}
-
- {% endif %}
-
-
-
-
-
-
- {# Detail section — collapsible #}
-
- {% if item.startDate %}
-
- {{ item.startDate }}{% if item.endDate %} – {{ item.endDate }}{% else %} – Present{% endif %}
-
- {% endif %}
-
- {% if item.description %}
-
{{ item.description }}
- {% endif %}
-
- {% if showTechnologies and item.technologies and item.technologies.length %}
-
- {% for tech in item.technologies %}
-
- {{ tech }}
-
- {% endfor %}
-
- {% endif %}
-
-
- {% endfor %}
-
-
-{% endif %}
diff --git a/theme/_includes/components/sections/cv-projects.njk b/theme/_includes/components/sections/cv-projects.njk
deleted file mode 100644
index 99cc152..0000000
--- a/theme/_includes/components/sections/cv-projects.njk
+++ /dev/null
@@ -1,114 +0,0 @@
-{#
- CV Projects Section - collapsible project cards (accordion)
- Data fetched from /cv/data.json via homepage plugin
-#}
-
-{% set sectionConfig = section.config or {} %}
-{% set maxItems = sectionConfig.maxItems or 10 %}
-{% set showTechnologies = sectionConfig.showTechnologies if sectionConfig.showTechnologies is defined else true %}
-
-{% if cv and cv.projects and cv.projects.length %}
-
-
- {{ sectionConfig.title or "Projects" }}
-
-
-
- {% for item in cv.projects | head(maxItems) %}
- {% set ci = loop.index0 % 8 %}
-
- {# Summary row — always visible, clickable #}
-
-
-
- {% if item.url %}
- {{ item.name }}
- {% else %}
- {{ item.name }}
- {% endif %}
-
- {% if item.status %}
-
- {{ item.status }}
-
- {% endif %}
-
-
- {% if item.startDate %}
-
- {{ item.startDate }}{% if item.endDate %} – {{ item.endDate }}{% else %} – Present{% endif %}
-
- {% endif %}
-
-
-
-
-
-
- {# Detail section — collapsible #}
-
- {% if item.startDate %}
-
- {{ item.startDate }}{% if item.endDate %} – {{ item.endDate }}{% else %} – Present{% endif %}
-
- {% endif %}
-
- {% if item.description %}
-
{{ item.description }}
- {% endif %}
-
- {% if showTechnologies and item.technologies and item.technologies.length %}
-
- {% for tech in item.technologies %}
-
- {{ tech }}
-
- {% endfor %}
-
- {% endif %}
-
-
- {% endfor %}
-
-
-{% endif %}
diff --git a/theme/_includes/components/sections/cv-skills-personal.njk b/theme/_includes/components/sections/cv-skills-personal.njk
deleted file mode 100644
index baa52be..0000000
--- a/theme/_includes/components/sections/cv-skills-personal.njk
+++ /dev/null
@@ -1,2 +0,0 @@
-{% set filterType = "personal" %}
-{% include "components/sections/cv-skills.njk" %}
diff --git a/theme/_includes/components/sections/cv-skills-work.njk b/theme/_includes/components/sections/cv-skills-work.njk
deleted file mode 100644
index cc1332a..0000000
--- a/theme/_includes/components/sections/cv-skills-work.njk
+++ /dev/null
@@ -1,2 +0,0 @@
-{% set filterType = "work" %}
-{% include "components/sections/cv-skills.njk" %}
diff --git a/theme/_includes/components/sections/cv-skills.njk b/theme/_includes/components/sections/cv-skills.njk
deleted file mode 100644
index 6b55cde..0000000
--- a/theme/_includes/components/sections/cv-skills.njk
+++ /dev/null
@@ -1,50 +0,0 @@
-{#
- CV Skills Section - skills grouped by category
- Data fetched from /cv/data.json via homepage plugin
- Each family gets a distinct color via cycling palette
-#}
-
-{% if cv and cv.skills and (cv.skills | dictsort | length) %}
-
-
- {{ section.config.title or "Skills" }}
-
-
-
- {% for category, items in cv.skills %}
- {% if not filterType or (cv.skillTypes and cv.skillTypes[category] == filterType) or not cv.skillTypes or not cv.skillTypes[category] %}
- {# Cycle through 8 distinct colors per family using loop.index0 #}
- {% set ci = loop.index0 % 8 %}
-
-
- {{ category }}
-
-
- {% for skill in items %}
- {% if ci == 0 %}
-
- {% elif ci == 1 %}
-
- {% elif ci == 2 %}
-
- {% elif ci == 3 %}
-
- {% elif ci == 4 %}
-
- {% elif ci == 5 %}
-
- {% elif ci == 6 %}
-
- {% elif ci == 7 %}
-
- {% endif %}
- {{ skill }}
-
- {% endfor %}
-
-
- {% endif %}
- {% endfor %}
-
-
-{% endif %}
diff --git a/theme/_includes/components/sections/featured-posts.njk b/theme/_includes/components/sections/featured-posts.njk
deleted file mode 100644
index 730fdbe..0000000
--- a/theme/_includes/components/sections/featured-posts.njk
+++ /dev/null
@@ -1,259 +0,0 @@
-{#
- Featured Posts Section - displays curated posts with `featured: true` frontmatter
- Rendered by homepage-builder when featured-posts section is configured
- Supports type-aware rendering for articles, notes, likes, bookmarks, reposts, replies, photos
-#}
-
-{% set sectionConfig = section.config or {} %}
-{% set maxItems = sectionConfig.maxItems or 6 %}
-{% set showSummary = sectionConfig.showSummary if sectionConfig.showSummary is defined else true %}
-
-{% if collections.featuredPosts and collections.featuredPosts.length %}
-
-
-
-
-
- {{ sectionConfig.title or "Featured" }}
-
-
-
- {% for post in collections.featuredPosts | head(maxItems) %}
- {# Detect post type from frontmatter properties #}
- {% set likedUrl = post.data.likeOf or post.data.like_of %}
- {% set bookmarkedUrl = post.data.bookmarkOf or post.data.bookmark_of %}
- {% set repostedUrl = post.data.repostOf or post.data.repost_of %}
- {% set replyToUrl = post.data.inReplyTo or post.data.in_reply_to %}
- {% set hasPhotos = post.data.photo and post.data.photo.length %}
-
- {# Determine border color by post type #}
- {% set borderClass = "" %}
- {% if likedUrl %}
- {% set borderClass = "border-l-[3px] border-l-red-400 dark:border-l-red-500" %}
- {% elif bookmarkedUrl %}
- {% set borderClass = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif repostedUrl %}
- {% set borderClass = "border-l-[3px] border-l-green-400 dark:border-l-green-500" %}
- {% elif replyToUrl %}
- {% set borderClass = "border-l-[3px] border-l-sky-400 dark:border-l-sky-500" %}
- {% elif hasPhotos %}
- {% set borderClass = "border-l-[3px] border-l-purple-400 dark:border-l-purple-500" %}
- {% else %}
- {% set borderClass = "border-l-[3px] border-l-surface-300 dark:border-l-surface-600" %}
- {% endif %}
-
-
-
- {% if likedUrl %}
- {# ── Like card ── #}
-
-
-
-
- Liked
-
- {{ post.date | dateDisplay }}
-
-
- {{ likedUrl | unfurlCard | safe }}
-
- {{ likedUrl }}
-
- {% if post.templateContent %}
-
- {{ post.templateContent | safe }}
-
- {% endif %}
-
Permalink
-
-
-
- {% elif bookmarkedUrl %}
- {# ── Bookmark card ── #}
-
-
-
-
- Bookmarked
-
- {{ post.date | dateDisplay }}
-
-
- {% if post.data.title %}
-
- {% endif %}
- {{ bookmarkedUrl | unfurlCard | safe }}
-
- {{ bookmarkedUrl }}
-
- {% if post.templateContent %}
-
- {{ post.templateContent | safe }}
-
- {% endif %}
-
Permalink
-
-
-
- {% elif repostedUrl %}
- {# ── Repost card ── #}
-
-
-
-
- Reposted
-
- {{ post.date | dateDisplay }}
-
-
- {{ repostedUrl | unfurlCard | safe }}
-
- {{ repostedUrl }}
-
- {% if post.templateContent %}
-
- {{ post.templateContent | safe }}
-
- {% endif %}
-
Permalink
-
-
-
- {% elif replyToUrl %}
- {# ── Reply card ── #}
-
-
-
-
- In reply to
-
- {{ post.date | dateDisplay }}
-
-
- {{ replyToUrl | unfurlCard | safe }}
-
- {{ replyToUrl }}
-
- {% if post.templateContent %}
-
- {{ post.templateContent | safe }}
-
- {% endif %}
-
Permalink
-
-
-
- {% elif hasPhotos %}
- {# ── Photo card ── #}
-
-
-
-
- Photo
-
- {{ post.date | dateDisplay }}
-
-
-
- {% for img in post.data.photo | head(2) %}
- {% set photoUrl = img.url %}
- {% if photoUrl and photoUrl[0] != '/' and 'http' not in photoUrl %}
- {% set photoUrl = '/' + photoUrl %}
- {% endif %}
-
-
-
- {% endfor %}
-
- {% if post.templateContent %}
-
- {{ post.templateContent | safe }}
-
- {% endif %}
-
Permalink
-
-
-
- {% elif post.data.title %}
- {# ── Article/Page card ── #}
-
- {% if showSummary and post.templateContent %}
-
- {{ post.templateContent | striptags | truncate(250) }}
-
- {% endif %}
-
-
- {{ post.date | dateDisplay }}
-
- {% if post.data.postType %}
-
- {{ post.data.postType }}
-
- {% endif %}
-
-
- {% else %}
- {# ── Note card ── #}
-
-
-
- {{ post.date | dateDisplay }}
-
-
- {% if post.data.postType %}
-
- {{ post.data.postType }}
-
- {% endif %}
-
- {% if post.templateContent %}
-
- {{ post.templateContent | safe }}
-
- {% endif %}
-
- Permalink
-
- {% endif %}
-
-
- {% endfor %}
-
-
- {% if collections.featuredPosts.length > maxItems %}
-
- {% endif %}
-
-{% endif %}
diff --git a/theme/_includes/components/sections/hero.njk b/theme/_includes/components/sections/hero.njk
deleted file mode 100644
index e8ff3df..0000000
--- a/theme/_includes/components/sections/hero.njk
+++ /dev/null
@@ -1,68 +0,0 @@
-{#
- Hero Section - author intro with avatar, name, title, bio
- Rendered by homepage-builder when hero is enabled
-#}
-
-{% set heroConfig = homepageConfig.hero or {} %}
-{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
-{% set authorName = id.name if (id.name is defined) else site.author.name %}
-{% set authorAvatar = id.avatar if (id.avatar is defined) else site.author.avatar %}
-{% set authorTitle = id.title if (id.title is defined) else site.author.title %}
-{% set authorBio = id.bio if (id.bio is defined) else site.author.bio %}
-{% set siteDescription = id.description if (id.description is defined) else site.description %}
-{% set socialLinks = id.social if (id.social is defined) else site.social %}
-
-
-
- {# Avatar #}
- {% if heroConfig.showAvatar != false %}
-
- {% endif %}
-
- {# Introduction #}
-
-
- {{ authorName }}
-
- {% if authorTitle %}
-
- {{ authorTitle }}
-
- {% endif %}
- {% if authorBio %}
-
- {{ authorBio }}
-
- {% endif %}
- {% if siteDescription %}
-
- {{ siteDescription }}
- Read more →
-
- {% endif %}
-
- {# Social Links #}
- {% from "components/social-icon.njk" import socialIcon, socialIconColorClass %}
- {% if heroConfig.showSocial != false and socialLinks %}
-
- {% endif %}
-
-
-
diff --git a/theme/_includes/components/sections/posting-activity.njk b/theme/_includes/components/sections/posting-activity.njk
deleted file mode 100644
index 976dba5..0000000
--- a/theme/_includes/components/sections/posting-activity.njk
+++ /dev/null
@@ -1,24 +0,0 @@
-{# Posting Activity Section — configurable post-graph contribution grid #}
-{% set sectionConfig = section.config or {} %}
-{% set graphTitle = sectionConfig.title or "Posting Activity" %}
-
-{% if collections.posts and collections.posts.length %}
-
-
- {{ graphTitle }}
-
- {% set graphOptions = {} %}
- {% if sectionConfig.years and sectionConfig.years.length %}
- {% set graphOptions = { only: sectionConfig.years } %}
- {% elif sectionConfig.limit %}
- {% set graphOptions = { limit: sectionConfig.limit } %}
- {% endif %}
- {% postGraph collections.posts, graphOptions %}
-
- View full history
-
-
-
-
-
-{% endif %}
diff --git a/theme/_includes/components/sections/recent-posts.njk b/theme/_includes/components/sections/recent-posts.njk
deleted file mode 100644
index 36c85cf..0000000
--- a/theme/_includes/components/sections/recent-posts.njk
+++ /dev/null
@@ -1,338 +0,0 @@
-{#
- Recent Posts Section - displays latest posts from any collection
- Rendered by homepage-builder when recent-posts section is configured
- Redesigned to match the visual language used on /blog/
-#}
-
-{% set sectionConfig = section.config or {} %}
-{% set maxItems = sectionConfig.maxItems or 5 %}
-{% set showSummary = sectionConfig.showSummary if sectionConfig.showSummary is defined else true %}
-{% set primaryPosts = collections.posts if (collections and collections.posts) else [] %}
-{% set fallbackRecentPosts = collections.recentPosts if (collections and collections.recentPosts) else [] %}
-{% set listedPosts = primaryPosts | excludeUnlistedPosts %}
-{% if not (listedPosts and listedPosts.length) %}
- {% set listedPosts = fallbackRecentPosts | excludeUnlistedPosts %}
-{% endif %}
-
-{% if listedPosts and listedPosts.length %}
-
-
- {{ sectionConfig.title or "Recent Posts" }}
-
-
-
- {% for post in listedPosts | head(maxItems) %}
- {# Detect post type from frontmatter properties #}
- {% set likedUrl = post.data.likeOf or post.data.like_of %}
- {% set bookmarkedUrl = post.data.bookmarkOf or post.data.bookmark_of %}
- {% set repostedUrl = post.data.repostOf or post.data.repost_of %}
- {% set replyToUrl = post.data.inReplyTo or post.data.in_reply_to %}
- {% set hasPhotos = post.data.photo and post.data.photo.length %}
-
- {% set borderClass = "" %}
- {% if likedUrl %}
- {% set borderClass = "border-l-[3px] border-l-red-400 dark:border-l-red-500" %}
- {% elif bookmarkedUrl %}
- {% set borderClass = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif repostedUrl %}
- {% set borderClass = "border-l-[3px] border-l-green-400 dark:border-l-green-500" %}
- {% elif replyToUrl %}
- {% set borderClass = "border-l-[3px] border-l-sky-400 dark:border-l-sky-500" %}
- {% elif hasPhotos %}
- {% set borderClass = "border-l-[3px] border-l-purple-400 dark:border-l-purple-500" %}
- {% elif post.data.title %}
- {% set borderClass = "border-l-[3px] border-l-indigo-400 dark:border-l-indigo-500" %}
- {% else %}
- {% set borderClass = "border-l-[3px] border-l-teal-400 dark:border-l-teal-500" %}
- {% endif %}
-
-
- {% if likedUrl %}
- {# Like #}
-
-
- {% elif bookmarkedUrl %}
- {# Bookmark #}
-
-
- {% elif repostedUrl %}
- {# Repost #}
-
-
- {% elif replyToUrl %}
- {# Reply #}
-
-
- {% elif hasPhotos %}
- {# Photo #}
-
-
- {% elif post.data.title and (post.data.title | trim) %}
- {# Article #}
-
- {% if showSummary and post.templateContent %}
-
- {{ post.templateContent | striptags | truncate(250) }}
-
- {% endif %}
-
- Read more →
-
-
- {% else %}
- {# Note #}
-
-
- {% if post.content and post.content.html %}
- {{ post.content.html | safe }}
- {% else %}
- {{ post.templateContent | safe }}
- {% endif %}
-
-
- {% endif %}
-
- {% endfor %}
-
-
- {% if sectionConfig.showViewAll != false %}
-
- {{ sectionConfig.viewAllText or "View all posts" }}
-
-
-
-
- {% endif %}
-
-{% endif %}
diff --git a/theme/_includes/components/sidebar.njk b/theme/_includes/components/sidebar.njk
deleted file mode 100644
index 78b02ff..0000000
--- a/theme/_includes/components/sidebar.njk
+++ /dev/null
@@ -1,261 +0,0 @@
-{# Sidebar — for blog listing pages (/blog/, /notes/, /articles/...) #}
-{# Data-driven when homepageConfig.blogListingSidebar is configured, otherwise falls back to default widgets #}
-{# Each widget is wrapped in a collapsible container with localStorage persistence #}
-{% from "components/icon.njk" import icon %}
-
-{% if homepageConfig and homepageConfig.blogListingSidebar and homepageConfig.blogListingSidebar.length %}
- {# === Data-driven mode: render configured widgets === #}
- {% for widget in homepageConfig.blogListingSidebar %}
- {% set isHomepageAuthorWidget = page.url == "/" and (widget.type == "author-card" or widget.type == "author-card-compact") %}
- {% if not isHomepageAuthorWidget %}
-
- {# Resolve widget title #}
- {% if widget.type == "search" %}{% set widgetTitle = "Search" %}
- {% elif widget.type == "social-activity" %}{% set widgetTitle = "Social Activity" %}
- {% elif widget.type == "github-repos" %}{% set widgetTitle = "GitHub" %}
- {% elif widget.type == "funkwhale" %}{% set widgetTitle = "Listening" %}
- {% elif widget.type == "recent-posts" %}{% set widgetTitle = "Recent Posts" %}
- {% elif widget.type == "blogroll" %}{% set widgetTitle = "Blogroll" %}
- {% elif widget.type == "feedland" %}{% set widgetTitle = "FeedLand" %}
- {% elif widget.type == "categories" %}{% set widgetTitle = "Categories" %}
- {% elif widget.type == "webmentions" %}{% set widgetTitle = "Webmentions" %}
- {% elif widget.type == "recent-comments" %}{% set widgetTitle = "Recent Comments" %}
- {% elif widget.type == "fediverse-follow" %}{% set widgetTitle = "Fediverse" %}
- {% elif widget.type == "author-card" %}{% set widgetTitle = "Author" %}
- {% elif widget.type == "author-card-compact" %}{% set widgetTitle = "Author" %}
- {% elif widget.type == "subscribe" %}{% set widgetTitle = "Subscribe" %}
- {% elif widget.type == "ai-usage" %}{% set widgetTitle = "AI Transparency" %}
- {% elif widget.type == "custom-html" %}{% set widgetTitle = (widget.config.title if widget.config and widget.config.title) or "Custom" %}
- {% else %}{% set widgetTitle = widget.type %}
- {% endif %}
-
- {# Resolve widget icon and accent border #}
- {% if widget.type == "social-activity" %}
- {% set widgetIcon = "globe" %}{% set widgetIconClass = "w-5 h-5 text-[#0085ff]" %}{% set widgetBorder = "border-l-[3px] border-l-[#0085ff]" %}
- {% elif widget.type == "github-repos" %}
- {% set widgetIcon = "github" %}{% set widgetIconClass = "w-5 h-5 text-surface-800 dark:text-surface-200" %}{% set widgetBorder = "border-l-[3px] border-l-surface-400 dark:border-l-surface-500" %}
- {% elif widget.type == "funkwhale" %}
- {% set widgetIcon = "headphones" %}{% set widgetIconClass = "w-5 h-5 text-purple-500" %}{% set widgetBorder = "border-l-[3px] border-l-purple-400 dark:border-l-purple-500" %}
- {% elif widget.type == "blogroll" %}
- {% set widgetIcon = "book-open" %}{% set widgetIconClass = "w-5 h-5 text-amber-500" %}{% set widgetBorder = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif widget.type == "feedland" %}
- {% set widgetIcon = "rss" %}{% set widgetIconClass = "w-5 h-5 text-amber-500" %}{% set widgetBorder = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif widget.type == "subscribe" %}
- {% set widgetIcon = "rss" %}{% set widgetIconClass = "w-5 h-5 text-orange-500" %}{% set widgetBorder = "border-l-[3px] border-l-orange-400 dark:border-l-orange-500" %}
- {% elif widget.type == "fediverse-follow" %}
- {% set widgetIcon = "user-plus" %}{% set widgetIconClass = "w-5 h-5 text-[#a730b8]" %}{% set widgetBorder = "border-l-[3px] border-l-[#a730b8]" %}
- {% elif widget.type == "author-card" or widget.type == "author-card-compact" %}
- {% set widgetIcon = "user" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "recent-posts" %}
- {% set widgetIcon = "list" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "categories" %}
- {% set widgetIcon = "tag" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "recent-comments" %}
- {% set widgetIcon = "chat" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "search" %}
- {% set widgetIcon = "search" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "webmentions" %}
- {% set widgetIcon = "share" %}{% set widgetIconClass = "w-5 h-5 text-surface-600 dark:text-surface-400" %}{% set widgetBorder = "" %}
- {% elif widget.type == "ai-usage" %}
- {% set widgetIcon = "zap" %}{% set widgetIconClass = "w-5 h-5 text-amber-500" %}{% set widgetBorder = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% else %}
- {% set widgetIcon = "" %}{% set widgetIconClass = "" %}{% set widgetBorder = "" %}
- {% endif %}
-
- {% set widgetKey = "listing-widget-" + widget.type + "-" + loop.index0 %}
- {% set defaultOpen = "true" if loop.index0 < 3 else "false" %}
-
- {# Collapsible wrapper — Alpine.js handles toggle, localStorage persists state #}
-
-
- {% endif %}
-
- {% endfor %}
-{% else %}
- {# === Fallback: aligned with rmendes.net default sidebar === #}
-
- {# Recent Posts #}
- {% set widgetKey = "widget-recent-posts-0" %}
-
-
- {# Social Activity #}
- {% set widgetKey = "widget-social-activity-1" %}
-
-
- {# Blogroll #}
- {% if blogrollStatus and blogrollStatus.source == "indiekit" %}
- {% set widgetKey = "widget-blogroll-2" %}
-
- {% endif %}
-
- {# GitHub #}
- {% set widgetKey = "widget-github-repos-3" %}
-
-
- {# Listening #}
- {% set widgetKey = "widget-funkwhale-4" %}
-
-
- {% if page.url != "/" %}
- {# Author #}
- {% set widgetKey = "widget-author-card-5" %}
-
- {% endif %}
-
- {# Fediverse #}
- {% set widgetKey = "widget-fediverse-follow-6" %}
-
-{% endif %}
diff --git a/theme/_includes/components/social-icon.njk b/theme/_includes/components/social-icon.njk
deleted file mode 100644
index 54638b2..0000000
--- a/theme/_includes/components/social-icon.njk
+++ /dev/null
@@ -1,131 +0,0 @@
-{#
- Social Icon Macro
- Usage: {% from "components/social-icon.njk" import socialIcon, socialIconColorClass %}
- {{ socialIcon("github", "w-5 h-5") }}
- {{ socialIcon("github", "w-5 h-5") }}
-
- SVG paths sourced from Simple Icons (simpleicons.org) - CC0 1.0 Universal
- All icons render at 24x24 viewBox with fill="currentColor"
- Brand colors from official brand guidelines
-#}
-
-{# Returns Tailwind color classes for an icon's brand color (light + dark) #}
-{% macro socialIconColorClass(name) %}
-{%- if name == "activitypub" -%}text-[#f1027e]
-{%- elif name == "github" -%}text-[#181717] dark:text-[#e6edf3]
-{%- elif name == "gitlab" -%}text-[#FC6D26]
-{%- elif name == "forgejo" -%}text-[#609926]
-{%- elif name == "codeberg" -%}text-[#2185D0]
-{%- elif name == "mastodon" -%}text-[#6364FF]
-{%- elif name == "bluesky" -%}text-[#0085FF]
-{%- elif name == "pixelfed" -%}text-[#6C42C9]
-{%- elif name == "linkedin" -%}text-[#0A66C2]
-{%- elif name == "twitter" -%}text-[#000000] dark:text-[#e7e9ea]
-{%- elif name == "threads" -%}text-[#000000] dark:text-[#f5f5f5]
-{%- elif name == "youtube" -%}text-[#FF0000]
-{%- elif name == "twitch" -%}text-[#9146FF]
-{%- elif name == "spotify" -%}text-[#1DB954]
-{%- elif name == "bandcamp" -%}text-[#629aa9]
-{%- elif name == "soundcloud" -%}text-[#FF5500]
-{%- elif name == "rss" -%}text-[#F26522]
-{%- elif name == "discord" -%}text-[#5865F2]
-{%- elif name == "signal" -%}text-[#3A76F0]
-{%- elif name == "telegram" -%}text-[#26A5E4]
-{%- elif name == "matrix" -%}text-[#000000] dark:text-[#e6e6e6]
-{%- elif name == "reddit" -%}text-[#FF4500]
-{%- elif name == "hackernews" -%}text-[#FF6600]
-{%- elif name == "funkwhale" -%}text-[#0D47A1]
-{%- elif name == "lastfm" -%}text-[#D51007]
-{%- elif name == "peertube" -%}text-[#F1680D]
-{%- elif name == "bookwyrm" -%}text-[#002200] dark:text-[#78b578]
-{%- elif name == "indieweb" -%}text-[#FF5C00]
-{%- elif name == "email" -%}text-surface-600 dark:text-surface-400
-{%- elif name == "website" -%}text-surface-600 dark:text-surface-400
-{%- elif name == "keybase" -%}text-[#33A0FF]
-{%- elif name == "orcid" -%}text-[#A6CE39]
-{%- elif name == "flickr" -%}text-[#0063DC]
-{%- elif name == "xmpp" -%}text-[#002B5C] dark:text-[#5badff]
-{%- elif name == "sourcehut" -%}text-[#000000] dark:text-[#e0e0e0]
-{%- elif name == "facebook" -%}text-[#0866FF]
-{%- elif name == "instagram" -%}text-[#E4405F]
-{%- else -%}text-surface-600 dark:text-surface-400
-{%- endif -%}
-{% endmacro %}
-
-{% macro socialIcon(name, cssClass) %}
-{%- if name == "github" -%}
-
-{%- elif name == "gitlab" -%}
-
-{%- elif name == "forgejo" -%}
-
-{%- elif name == "codeberg" -%}
-
-{%- elif name == "sourcehut" -%}
-
-{%- elif name == "linkedin" -%}
-
-{%- elif name == "bluesky" -%}
-
-{%- elif name == "mastodon" -%}
-
-{%- elif name == "activitypub" -%}
-
-{%- elif name == "pixelfed" -%}
-
-{%- elif name == "twitter" -%}
-
-{%- elif name == "facebook" -%}
-
-{%- elif name == "instagram" -%}
-
-{%- elif name == "threads" -%}
-
-{%- elif name == "youtube" -%}
-
-{%- elif name == "twitch" -%}
-
-{%- elif name == "flickr" -%}
-
-{%- elif name == "spotify" -%}
-
-{%- elif name == "bandcamp" -%}
-
-{%- elif name == "soundcloud" -%}
-
-{%- elif name == "rss" -%}
-
-{%- elif name == "matrix" -%}
-
-{%- elif name == "discord" -%}
-
-{%- elif name == "signal" -%}
-
-{%- elif name == "telegram" -%}
-
-{%- elif name == "xmpp" -%}
-
-{%- elif name == "reddit" -%}
-
-{%- elif name == "hackernews" -%}
-
-{%- elif name == "keybase" -%}
-
-{%- elif name == "orcid" -%}
-
-{%- elif name == "indieweb" -%}
-
-{%- elif name == "website" -%}
-
-{%- elif name == "email" -%}
-
-{%- elif name == "funkwhale" -%}
-
-{%- elif name == "lastfm" -%}
-
-{%- elif name == "peertube" -%}
-
-{%- elif name == "bookwyrm" -%}
-
-{%- endif -%}
-{% endmacro %}
diff --git a/theme/_includes/components/webmentions.njk b/theme/_includes/components/webmentions.njk
deleted file mode 100644
index 971984b..0000000
--- a/theme/_includes/components/webmentions.njk
+++ /dev/null
@@ -1,206 +0,0 @@
-{# Webmentions Component #}
-{# Displays likes, reposts, and replies for a post #}
-{# Also checks legacy URLs from micro.blog and old blog for historical webmentions #}
-{# Client-side JS supplements build-time data with real-time fetches #}
-
-{% set mentions = webmentions | webmentionsForUrl(page.url, urlAliases, conversationMentions) %}
-{% set absoluteUrl = site.url + page.url %}
-{% set buildTimestamp = "" | timestamp %}
-
-{# Data container for client-side JS to fetch new webmentions #}
-
-
-{% if mentions.length %}
-
-
- Webmentions ({{ mentions.length }})
-
-
- {# Likes #}
- {% set likes = mentions | webmentionsByType('likes') %}
- {% if likes.length %}
-
-
- {{ likes.length }} Like{% if likes.length != 1 %}s{% endif %}
-
-
-
- {% for like in likes %}
-
-
-
- {% endfor %}
-
-
-
- {% endif %}
-
- {# Reposts #}
- {% set reposts = mentions | webmentionsByType('reposts') %}
- {% if reposts.length %}
-
-
- {{ reposts.length }} Repost{% if reposts.length != 1 %}s{% endif %}
-
-
-
- {% for repost in reposts %}
-
-
-
- {% endfor %}
-
-
-
- {% endif %}
-
- {# Bookmarks #}
- {% set bookmarks = mentions | webmentionsByType('bookmarks') %}
- {% if bookmarks.length %}
-
-
- {{ bookmarks.length }} Bookmark{% if bookmarks.length != 1 %}s{% endif %}
-
-
-
- {% for bookmark in bookmarks %}
-
-
-
- {% endfor %}
-
-
-
- {% endif %}
-
- {# Replies #}
- {% set replies = mentions | webmentionsByType('replies') %}
- {% if replies.length %}
-
-
- {{ replies.length }} Repl{% if replies.length != 1 %}ies{% else %}y{% endif %}
-
-
- {% for reply in replies %}
-
-
-
-
-
-
-
-
- {{ reply.content.html | safe if reply.content.html else reply.content.text }}
-
-
-
-
- {% endfor %}
-
-
- {% endif %}
-
- {# Other mentions #}
- {% set otherMentions = mentions | webmentionsByType('mentions') %}
- {% if otherMentions.length %}
-
-
- {{ otherMentions.length }} Mention{% if otherMentions.length != 1 %}s{% endif %}
-
-
-
- {% endif %}
-
-{% endif %}
-
-{# Webmention send form — collapsed by default #}
-
-
-
-
-
- Send a Webmention
-
-
-
- Have you written a response to this post? Send a webmention by entering your post URL below.
-
-
-
-
diff --git a/theme/_includes/components/widgets/author-card-compact.njk b/theme/_includes/components/widgets/author-card-compact.njk
deleted file mode 100644
index f213550..0000000
--- a/theme/_includes/components/widgets/author-card-compact.njk
+++ /dev/null
@@ -1,43 +0,0 @@
-{# Author Compact Card - h-card microformat (compact version for blog sidebars) #}
-{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
-{% set authorName = id.name if (id.name is defined) else site.author.name %}
-{% set authorAvatar = id.avatar if (id.avatar is defined) else site.author.avatar %}
-{% set authorTitle = id.title if (id.title is defined) else site.author.title %}
-{% set authorUrl = id.url if (id.url is defined and id.url) else site.author.url %}
-{% set authorLocality = id.locality if (id.locality is defined) else site.author.locality %}
-{% set authorCountry = id.country if (id.country is defined) else site.author.country %}
-{% set authorBio = id.bio if (id.bio is defined) else site.author.bio %}
-{% set authorEmail = id.email if (id.email is defined) else site.author.email %}
-{% set authorOrg = id.org if (id.org is defined) else site.author.org %}
-
-
-
-
diff --git a/theme/_includes/components/widgets/author-card.njk b/theme/_includes/components/widgets/author-card.njk
deleted file mode 100644
index f205d58..0000000
--- a/theme/_includes/components/widgets/author-card.njk
+++ /dev/null
@@ -1,6 +0,0 @@
-{# Author Card Widget - includes the canonical h-card component #}
-
-
- {% include "components/h-card.njk" %}
-
-
diff --git a/theme/_includes/components/widgets/blogroll.njk b/theme/_includes/components/widgets/blogroll.njk
deleted file mode 100644
index 572cff0..0000000
--- a/theme/_includes/components/widgets/blogroll.njk
+++ /dev/null
@@ -1,110 +0,0 @@
-{# Blogroll Widget - Dynamic loading from API with source tabs #}
-
-
-
-
-
diff --git a/theme/_includes/components/widgets/categories.njk b/theme/_includes/components/widgets/categories.njk
deleted file mode 100644
index b071191..0000000
--- a/theme/_includes/components/widgets/categories.njk
+++ /dev/null
@@ -1,15 +0,0 @@
-{# Categories/Tags Widget #}
-{% if categories and categories.length %}
-
-
-
-{% endif %}
diff --git a/theme/_includes/components/widgets/fediverse-follow.njk b/theme/_includes/components/widgets/fediverse-follow.njk
deleted file mode 100644
index b99dbb3..0000000
--- a/theme/_includes/components/widgets/fediverse-follow.njk
+++ /dev/null
@@ -1,41 +0,0 @@
-{# Fediverse Follow Me Widget — uses the fediverseInteract Alpine.js component #}
-{# Requires fediverse-interact.js loaded in base.njk (already present) #}
-{# Determines actor URI from site social links: prefers self-hosted AP, falls back to Mastodon #}
-
-{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
-{% set socialLinks = id.social if (id.social is defined) else site.social %}
-
-{% set actorUrl = "" %}
-{% for link in socialLinks %}
- {% if link.icon == "activitypub" and not actorUrl %}
- {% set actorUrl = link.url %}
- {% endif %}
-{% endfor %}
-{% if not actorUrl %}
- {% for link in socialLinks %}
- {% if link.icon == "mastodon" and not actorUrl %}
- {% set actorUrl = link.url %}
- {% endif %}
- {% endfor %}
-{% endif %}
-
-{% if actorUrl %}
-
-
-
-{% endif %}
diff --git a/theme/_includes/components/widgets/feedland.njk b/theme/_includes/components/widgets/feedland.njk
deleted file mode 100644
index 5a4b1c3..0000000
--- a/theme/_includes/components/widgets/feedland.njk
+++ /dev/null
@@ -1,383 +0,0 @@
-{# FeedLand Widget - Matches Dave Winer's blogroll.js visual rendering #}
-{# Uses Alpine.js + blogroll API instead of jQuery + external blogroll.js #}
-
-
-
-
-
-
-
-
-
-
diff --git a/theme/_includes/components/widgets/funkwhale.njk b/theme/_includes/components/widgets/funkwhale.njk
deleted file mode 100644
index 0f9bbac..0000000
--- a/theme/_includes/components/widgets/funkwhale.njk
+++ /dev/null
@@ -1,115 +0,0 @@
-{# Listening Widget — combined Funkwhale + Last.fm recent tracks #}
-{% set hasListening = (funkwhaleActivity and (funkwhaleActivity.nowPlaying or funkwhaleActivity.listenings.length)) or (lastfmActivity and (lastfmActivity.nowPlaying or lastfmActivity.scrobbles.length)) %}
-{% if hasListening %}
-
-
-
-{% endif %}
diff --git a/theme/_includes/components/widgets/github-repos.njk b/theme/_includes/components/widgets/github-repos.njk
deleted file mode 100644
index 69c46be..0000000
--- a/theme/_includes/components/widgets/github-repos.njk
+++ /dev/null
@@ -1,316 +0,0 @@
-{# GitHub Activity Widget - Tabbed Commits/Repos/Featured/PRs with live API data #}
-
-{% set ghFallbackCommits = githubActivity.commits if githubActivity and githubActivity.commits else [] %}
-{% set ghFallbackFeatured = githubActivity.featured if githubActivity and githubActivity.featured else [] %}
-{% set ghFallbackContributions = githubActivity.contributions if githubActivity and githubActivity.contributions else [] %}
-{% set ghFallbackRepos = githubRepos if githubRepos else [] %}
-{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
-{% set socialLinks = id.social if (id.social is defined) else site.social %}
-{% set githubProfileUrl = "" %}
-{% for link in socialLinks %}
- {% if not githubProfileUrl and (link.icon == "github" or "github.com/" in link.url) %}
- {% set githubProfileUrl = link.url %}
- {% endif %}
-{% endfor %}
-{% if not githubProfileUrl and site.feeds.github %}
- {% set githubProfileUrl = "https://github.com/" + site.feeds.github %}
-{% endif %}
-
-
-
-
diff --git a/theme/_includes/components/widgets/post-categories.njk b/theme/_includes/components/widgets/post-categories.njk
deleted file mode 100644
index 0d015d5..0000000
--- a/theme/_includes/components/widgets/post-categories.njk
+++ /dev/null
@@ -1,21 +0,0 @@
-{# Categories for This Post #}
-{% if category %}
-
-
-
-{% endif %}
diff --git a/theme/_includes/components/widgets/post-navigation.njk b/theme/_includes/components/widgets/post-navigation.njk
deleted file mode 100644
index f0b0155..0000000
--- a/theme/_includes/components/widgets/post-navigation.njk
+++ /dev/null
@@ -1,66 +0,0 @@
-{# Post Navigation Widget - Previous/Next #}
-{# Uses previousInCollection/nextInCollection filters to find adjacent posts #}
-{% set _prevPost = collections.posts | previousInCollection(page) %}
-{% set _nextPost = collections.posts | nextInCollection(page) %}
-
-{% if _prevPost or _nextPost %}
-
-
-
-{% endif %}
diff --git a/theme/_includes/components/widgets/recent-comments.njk b/theme/_includes/components/widgets/recent-comments.njk
deleted file mode 100644
index 9e0b78a..0000000
--- a/theme/_includes/components/widgets/recent-comments.njk
+++ /dev/null
@@ -1,27 +0,0 @@
-{# Recent Comments Widget — sidebar #}
-{% if recentComments and recentComments.length %}
-
-
-
-{% endif %}
diff --git a/theme/_includes/components/widgets/recent-posts-blog.njk b/theme/_includes/components/widgets/recent-posts-blog.njk
deleted file mode 100644
index eb04095..0000000
--- a/theme/_includes/components/widgets/recent-posts-blog.njk
+++ /dev/null
@@ -1,108 +0,0 @@
-{# Recent Posts Widget — type-aware, for blog/post sidebars #}
-{# Uses collections.posts directly (all post types, not just recentPosts collection) #}
-{% set listedPosts = collections.posts | excludeUnlistedPosts %}
-{% if listedPosts and listedPosts.length %}
-
-
-
-{% endif %}
diff --git a/theme/_includes/components/widgets/recent-posts.njk b/theme/_includes/components/widgets/recent-posts.njk
deleted file mode 100644
index 82e8b0d..0000000
--- a/theme/_includes/components/widgets/recent-posts.njk
+++ /dev/null
@@ -1,117 +0,0 @@
-{# Recent Posts Widget (sidebar) - compact type-aware list #}
-{% set recentPosts = recentPosts or collections.recentPosts %}
-{% set listedRecentPosts = recentPosts | excludeUnlistedPosts %}
-{% if listedRecentPosts and listedRecentPosts.length %}
-
-
-
-{% endif %}
diff --git a/theme/_includes/components/widgets/search.njk b/theme/_includes/components/widgets/search.njk
deleted file mode 100644
index c547241..0000000
--- a/theme/_includes/components/widgets/search.njk
+++ /dev/null
@@ -1,10 +0,0 @@
-{# Search Widget — redirects to /search/?q=query #}
-
diff --git a/theme/_includes/components/widgets/share.njk b/theme/_includes/components/widgets/share.njk
deleted file mode 100644
index 0c8d9b1..0000000
--- a/theme/_includes/components/widgets/share.njk
+++ /dev/null
@@ -1,31 +0,0 @@
-{# Share Widget #}
-{% set shareText = title + " " + site.url + page.url %}
-
-
-
diff --git a/theme/_includes/components/widgets/social-activity.njk b/theme/_includes/components/widgets/social-activity.njk
deleted file mode 100644
index e6a2e69..0000000
--- a/theme/_includes/components/widgets/social-activity.njk
+++ /dev/null
@@ -1,121 +0,0 @@
-{# Social Feed Widget - Tabbed Bluesky/Mastodon #}
-{% if (blueskyFeed and blueskyFeed.length) or (mastodonFeed and mastodonFeed.length) %}
-{% set id = homepageConfig.identity if (homepageConfig and homepageConfig.identity) else {} %}
-{% set socialLinks = id.social if (id.social is defined) else site.social %}
-
-{% set blueskyProfileUrl = "" %}
-{% set mastodonProfileUrl = "" %}
-{% for link in socialLinks %}
- {% if not blueskyProfileUrl and (link.icon == "bluesky" or "bsky.app/profile/" in link.url) %}
- {% set blueskyProfileUrl = link.url %}
- {% endif %}
- {% if not mastodonProfileUrl and (link.icon == "mastodon" or "@" in link.url) %}
- {% set mastodonProfileUrl = link.url %}
- {% endif %}
-{% endfor %}
-{% if not blueskyProfileUrl and site.feeds.bluesky %}
- {% set blueskyProfileUrl = "https://bsky.app/profile/" + site.feeds.bluesky %}
-{% endif %}
-{% if not mastodonProfileUrl and site.feeds.mastodon.instance and site.feeds.mastodon.username %}
- {% set mastodonProfileUrl = "https://" + site.feeds.mastodon.instance + "/@" + site.feeds.mastodon.username %}
-{% endif %}
-
-
-{% set defaultSocialTab = "mastodon" if mastodonFeed and mastodonFeed.length else "bluesky" %}
-
-
-{% endif %}
diff --git a/theme/_includes/components/widgets/subscribe.njk b/theme/_includes/components/widgets/subscribe.njk
deleted file mode 100644
index 61f4005..0000000
--- a/theme/_includes/components/widgets/subscribe.njk
+++ /dev/null
@@ -1,20 +0,0 @@
-{# Subscribe Widget #}
-
-
-
diff --git a/theme/_includes/components/widgets/toc.njk b/theme/_includes/components/widgets/toc.njk
deleted file mode 100644
index aaffdc3..0000000
--- a/theme/_includes/components/widgets/toc.njk
+++ /dev/null
@@ -1,59 +0,0 @@
-{# Table of Contents Widget (for articles with headings) #}
-
-
-
diff --git a/theme/_includes/components/widgets/webmentions.njk b/theme/_includes/components/widgets/webmentions.njk
deleted file mode 100644
index ae51b4d..0000000
--- a/theme/_includes/components/widgets/webmentions.njk
+++ /dev/null
@@ -1,168 +0,0 @@
-{# Recent Webmentions Widget - site-wide inbound/outbound activity #}
-{# Uses client-side fetch from /webmentions/api/mentions (same as /interactions page) #}
-{# Outbound tab uses Eleventy collections (likes, replies, bookmarks, reposts) #}
-
-
-
-
-
diff --git a/theme/_includes/layouts/base.njk b/theme/_includes/layouts/base.njk
deleted file mode 100644
index a6a4401..0000000
--- a/theme/_includes/layouts/base.njk
+++ /dev/null
@@ -1,551 +0,0 @@
-
-
-
- {# OG image resolution handled by og-fix transform in eleventy.config.js
- to bypass Eleventy 3.x parallel rendering race condition (#3183).
- Template outputs __OG_IMAGE_PLACEHOLDER__ and __TWITTER_CARD_PLACEHOLDER__
- which the transform replaces using the correct slug derived from outputPath. #}
-
-
-
- {% if title %}{{ title }} - {% endif %}{{ site.name }}
-
- {# OpenGraph meta tags #}
- {% set ogTitle = title | default(site.name) %}
- {% set ogDesc = description | default(content | ogDescription(200)) | default(site.description) %}
- {# Normalize photo - could be array for multi-photo posts #}
- {% set ogPhoto = photo %}
- {% if ogPhoto %}
- {% if ogPhoto[0] and (ogPhoto[0] | length) > 10 %}
- {% set ogPhoto = ogPhoto[0] %}
- {% endif %}
- {% endif %}
-
-
-
-
-
-
- {% if ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10 %}
-
- {% elif image and image != "" and (image | length) > 10 %}
-
- {% else %}
-
- {% endif %}
-
-
-
-
- {# Twitter Card meta tags #}
- {% set hasExplicitImage = (ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10) or (image and image != "" and (image | length) > 10) %}
-
-
-
- {% if ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10 %}
-
- {% elif image and image != "" and (image | length) > 10 %}
-
- {% else %}
-
- {% endif %}
-
- {# Favicon #}
-
-
-
- {# Critical CSS — inlined for fast first paint #}
-
- {# Defer full stylesheet — loads after first paint #}
-
-
-
-
-
-
-
-
-
- {# Alpine.js components — MUST load before Alpine core (Alpine.data() registration via alpine:init) #}
-
-
-
-
-
-
- {# Graceful no-JS fallback: show content that Alpine would normally control #}
-
-
-
-
-
-
-
- {% if site.markdownAgents.enabled and page.url and page.url.startsWith('/articles/') and page.url != '/articles/' %}
-
- {% endif %}
- {% if category and page.url and page.url.startsWith('/categories/') and page.url != '/categories/' %}
-
-
- {% endif %}
-
-
-
-
-
-
-
-
-
- {# Fediverse creator meta tag for Mastodon verification #}
- {% if site.fediverseCreator %}
-
- {% endif %}
-
- {# IndieAuth rel="me" links for identity verification #}
- {# Note: Bluesky links use "me atproto" for verification #}
- {% for social in site.social %}
-
- {% endfor %}
-
-
-
-
-
-
- {% if withSidebar and page.url == "/" and homepageConfig and homepageConfig.sections %}
- {# Homepage: builder controls its own layout and sidebar #}
- {{ content | safe }}
- {% elif withSidebar %}
-
- {% elif withBlogSidebar %}
-
- {% else %}
- {{ content | safe }}
- {% endif %}
-
-
-
-
- {# Island architecture - lazy hydration for widgets #}
-
- {# Relative date display - progressively enhances elements #}
-
- {# Responsive tables - auto-enhances on narrow screens #}
-
- {# Client-side filtering for archive pages #}
-
- {# Client-side webmention fetcher - supplements build-time cache with real-time data #}
-
- {# Admin auth detection - shows dashboard link + FAB when logged in #}
-
- {# Save for Later buttons — active when logged in #}
-
- {# Share Post buttons — opens share form popup when logged in #}
-
-
- {# Floating Action Button - visible only when logged in #}
-
- {# Backdrop #}
-
- {# Menu items #}
-
- {# FAB button #}
-
-
-
-
-
-
- {# Pagefind — load at end of body so all DOM elements exist, then process queue #}
-
-
-
-
diff --git a/theme/_includes/layouts/fullwidth.njk b/theme/_includes/layouts/fullwidth.njk
deleted file mode 100644
index 7a84d59..0000000
--- a/theme/_includes/layouts/fullwidth.njk
+++ /dev/null
@@ -1,25 +0,0 @@
----
-layout: layouts/base.njk
----
-{# Full-width layout for rich HTML pages (interactive guides, architecture diagrams, etc.)
- Inherits site header + footer from base.njk but renders content at full container width
- with no sidebar, no post metadata, and no prose constraints. #}
-
-
- {% if title %}
-
-
- {{ title }}
-
- {% if description %}
-
- {{ description }}
-
- {% endif %}
-
- {% endif %}
-
-
- {{ content | safe }}
-
-
diff --git a/theme/_includes/layouts/home.njk b/theme/_includes/layouts/home.njk
deleted file mode 100644
index b66a90f..0000000
--- a/theme/_includes/layouts/home.njk
+++ /dev/null
@@ -1,175 +0,0 @@
----
-layout: layouts/base.njk
-withSidebar: true
----
-
-{# Homepage content — two-tier fallback: #}
-{# 1. Plugin config (homepageConfig) — homepage builder controls everything #}
-{# 2. Default — show recent posts with default hero #}
-
-{# Default hero — only shown for Tier 2 (plugin controls its own hero) #}
-{% if not (homepageConfig and homepageConfig.sections) %}
-
-
- {# Avatar #}
-
-
- {# Introduction #}
-
-
- {{ site.author.name }}
-
-
- {{ site.author.title }}
-
- {% if site.author.bio %}
-
- {{ site.author.bio }}
-
- {% endif %}
- {% if site.description %}
-
- {{ site.description }}
- Read more →
-
- {% endif %}
-
- {# Social Links #}
- {% from "components/social-icon.njk" import socialIcon, socialIconColorClass %}
-
-
-
-
-{% endif %}
-
-{# --- Tier 1: Plugin-driven layout --- #}
-{% if homepageConfig and homepageConfig.sections %}
- {% include "components/homepage-builder.njk" %}
-
-{# --- Tier 2: Default — recent posts and explore links --- #}
-{% else %}
-
-{# Recent Posts #}
-{% if collections.posts and collections.posts.length %}
-
- Recent Posts
-
- {% for post in collections.posts | head(10) %}
- {% set likedUrl = post.data.likeOf or post.data.like_of %}
- {% set bookmarkedUrl = post.data.bookmarkOf or post.data.bookmark_of %}
- {% set repostedUrl = post.data.repostOf or post.data.repost_of %}
- {% set replyToUrl = post.data.inReplyTo or post.data.in_reply_to %}
-
- {% set borderClass = "border-l-[3px] border-l-surface-300 dark:border-l-surface-600" %}
- {% if likedUrl %}
- {% set borderClass = "border-l-[3px] border-l-red-400 dark:border-l-red-500" %}
- {% elif bookmarkedUrl %}
- {% set borderClass = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif repostedUrl %}
- {% set borderClass = "border-l-[3px] border-l-green-400 dark:border-l-green-500" %}
- {% elif replyToUrl %}
- {% set borderClass = "border-l-[3px] border-l-sky-400 dark:border-l-sky-500" %}
- {% endif %}
-
- {% set postTitle = ((post.data.title or post.data.name or "") | trim) %}
-
- {% if postTitle %}
-
- {% endif %}
-
- {% if post.data.summary %}
-
- {{ post.data.summary }}
-
- {% endif %}
-
-
-
- {{ (post.data.published or post.date) | date("MMM d, yyyy") }}
-
- {% if postTitle %}
-
Read more →
- {% else %}
-
Permalink
- {% endif %}
-
-
- {% endfor %}
-
-
- View all posts
-
-
-
-{% endif %}
-
-{# Explore — quick links to key sections #}
-
-
-{# Posting Activity — contribution graph (Tier 2 default only) #}
-{% if collections.posts and collections.posts.length %}
-
-{% endif %}
-
-{% endif %} {# end two-tier fallback #}
diff --git a/theme/_includes/layouts/page.njk b/theme/_includes/layouts/page.njk
deleted file mode 100644
index a03e386..0000000
--- a/theme/_includes/layouts/page.njk
+++ /dev/null
@@ -1,136 +0,0 @@
----
-layout: layouts/base.njk
-withSidebar: true
----
-{# Layout for slash pages (/about, /now, /uses, etc.) #}
-{# These are root-level pages created via Indiekit's page post type #}
-
-
-
-
-
- {{ content | safe }}
-
-
- {# AI post-graph — shown only on the /ai/ page #}
- {% if page.url == "/ai/" and collections.posts %}
- {% set stats = collections.posts | aiStats %}
- {% set aiPostsList = collections.posts | aiPosts %}
-
- AI Usage Across Posts
-
-
-
{{ stats.total }}
-
Total posts
-
-
-
{{ stats.aiCount }}
-
AI-involved
-
-
-
{{ stats.total - stats.aiCount }}
-
Human-only
-
-
-
{{ stats.percentage }}%
-
AI ratio
-
-
-
- {# Breakdown by level #}
-
-
- Level 0 (None): {{ stats.byLevel[0] }}
-
-
- Level 1 (Editorial): {{ stats.byLevel[1] }}
-
-
- Level 2 (Co-drafted): {{ stats.byLevel[2] }}
-
-
- Level 3 (AI-generated): {{ stats.byLevel[3] }}
-
-
-
- {# Post graph showing AI posts (highlighted) on the full year grid #}
- AI-Involved Posts Over Time
- Highlighted days had posts with AI involvement (level 1+). Empty boxes represent days with no AI-involved posts.
- {% postGraph aiPostsList, { prefix: "ai", highlightColorLight: "#d97706", highlightColorDark: "#fbbf24" } %}
-
- {% endif %}
-
- {# AI usage disclosure #}
- {% set aiTextLevel = aiTextLevel or ai_text_level %}
- {% set aiCodeLevel = aiCodeLevel or ai_code_level %}
- {% set aiTools = aiTools or ai_tools %}
- {% set aiDescription = aiDescription or ai_description %}
- {% if aiTextLevel or aiCodeLevel or aiTools %}
-
-
-
- {% if aiTextLevel %}
-
- Text: {% if aiTextLevel === "0" %}None{% elif aiTextLevel === "1" %}Editorial{% elif aiTextLevel === "2" %}Co-drafted{% elif aiTextLevel === "3" %}AI-generated{% endif %}
-
- {% endif %}
- {% if aiCodeLevel %}
-
- Code: {% if aiCodeLevel === "0" %}Human{% elif aiCodeLevel === "1" %}AI-assisted{% elif aiCodeLevel === "2" %}AI-generated{% endif %}
-
- {% endif %}
- {% if aiTools %}
-
- Tools: {{ aiTools }}
-
- {% endif %}
-
- {% if aiDescription %}
- {{ aiDescription }}
- {% endif %}
-
- {% endif %}
-
- {# Categories/tags if present #}
- {% if category %}
-
- {% endif %}
-
- {# Hidden metadata for microformats #}
-
-
-
diff --git a/theme/_includes/layouts/post.njk b/theme/_includes/layouts/post.njk
deleted file mode 100644
index 9261778..0000000
--- a/theme/_includes/layouts/post.njk
+++ /dev/null
@@ -1,263 +0,0 @@
----
-layout: layouts/base.njk
-withBlogSidebar: true
----
-
- {# Support both camelCase (Indiekit Eleventy preset) and underscore (legacy) property names #}
- {% set bookmarkedUrl = bookmarkOf or bookmark_of %}
- {% set likedUrl = likeOf or like_of %}
- {% set replyTo = inReplyTo or in_reply_to %}
- {% set repostedUrl = repostOf or repost_of %}
-
- {% if title and not repostedUrl %}
- {{ title }}
- {% else %}
-
-
- {% if replyTo %}↩ Reply{% elif likedUrl %}♥ Like{% elif repostedUrl %}♻ Repost{% elif bookmarkedUrl %}🔖 Bookmark{% else %}✎ Note{% endif %}
-
-
- {% endif %}
-
-
- {% if date %}
- {{ date | dateDisplay }}
- {% endif %}
- {% if category %}
-
- {# Handle both string and array categories #}
- {% if category is string %}
- {{ category }}
- {% else %}
- {% for cat in category %}
- {{ cat }}
- {% endfor %}
- {% endif %}
-
- {% endif %}
-
-
- {# Bridgy syndication content - controls what gets posted to social networks #}
- {# For interaction types (bookmarks, likes, replies, reposts), include the target URL #}
- {% set bridgySummary = description or summary or (content | ogDescription(280)) %}
- {% set interactionUrl = bookmarkedUrl or likedUrl or replyTo or repostedUrl %}
-
- {% if bridgySummary or interactionUrl %}
- {% if bookmarkedUrl %}🔖 {{ bookmarkedUrl }}{% if bridgySummary %} - {{ bridgySummary }}{% endif %}{% elif likedUrl %}❤️ {{ likedUrl }}{% if bridgySummary %} - {{ bridgySummary }}{% endif %}{% elif replyTo %}↩️ {{ replyTo }}{% if bridgySummary %} - {{ bridgySummary }}{% endif %}{% elif repostedUrl %}🔁 {{ repostedUrl }}{% if bridgySummary %} - {{ bridgySummary }}{% endif %}{% else %}{{ bridgySummary }}{% endif %}
- {% endif %}
-
- {# Render photo(s) from frontmatter for photo posts - use eleventy:ignore to skip image transform #}
- {% if photo %}
-
- {% for img in photo %}
- {% set photoUrl = img.url %}
- {% if photoUrl and photoUrl[0] != '/' and 'http' not in photoUrl %}
- {% set photoUrl = '/' + photoUrl %}
- {% endif %}
-
- {% endfor %}
-
- {% endif %}
-
- {% set isInteraction = replyTo or likedUrl or repostedUrl or bookmarkedUrl %}
- {% set hasContent = content and content | striptags | trim %}
-
- {{ content | safe }}
-
-
- {# Rich reply context with h-cite microformat #}
- {% include "components/reply-context.njk" %}
-
- {# AI usage disclosure — always shown, collapsed by default, placed after reply context #}
- {% set aiTextLevel = aiTextLevel or ai_text_level or "0" %}
- {% set aiCodeLevel = aiCodeLevel or ai_code_level %}
- {% set aiTools = aiTools or ai_tools %}
- {% set aiDescription = aiDescription or ai_description %}
-
-
-
-
-
- AI:
- Text {% if aiTextLevel === "0" %}None{% elif aiTextLevel === "1" %}Editorial{% elif aiTextLevel === "2" %}Co-drafted{% elif aiTextLevel === "3" %}AI-generated{% endif %}{% if aiCodeLevel %} · Code {% if aiCodeLevel === "0" %}Human{% elif aiCodeLevel === "1" %}AI-assisted{% elif aiCodeLevel === "2" %}AI-generated{% endif %}{% endif %}{% if aiTools %} · {{ aiTools }}{% endif %}
-
-
- {% if aiDescription %}
- {{ aiDescription }}
- {% endif %}
-
-
- {# Pending syndication targets (for services like IndieNews that require u-syndication before webmention) #}
- {% if mpSyndicateTo %}
-
- {% for url in mpSyndicateTo %}
- {% if "news.indieweb.org" in url %}
-
IndieNews
- {% endif %}
- {% endfor %}
-
- {% endif %}
-
- {# Syndication Footer - shows where this post was also published #}
- {# Separate self-hosted AP URLs from external syndication targets #}
- {% set externalSyndication = [] %}
- {% set selfHostedApUrl = "" %}
- {% if syndication %}
- {% for url in syndication %}
- {% if url.indexOf(site.url) == 0 %}
- {% set selfHostedApUrl = url %}
- {% else %}
- {% set externalSyndication = (externalSyndication.push(url), externalSyndication) %}
- {% endif %}
- {% endfor %}
- {% endif %}
- {% if externalSyndication.length or selfHostedApUrl %}
-
- {% endif %}
-
- Permalink
-
- {# Author h-card for IndieWeb authorship #}
-
- {{ site.author.name }}
-
-
-
- {# JSON-LD Structured Data for SEO #}
- {# Handle photo as potentially an array #}
- {% set postImage = photo %}
- {% if postImage %}
- {# If photo is an array, use first element (check if first element looks like a URL) #}
- {% if postImage[0] and (postImage[0] | length) > 10 %}
- {% set postImage = postImage[0] %}
- {% endif %}
- {% endif %}
- {% if not postImage or postImage == "" %}
- {% set postImage = image or (content | extractFirstImage) %}
- {% endif %}
- {% set postDesc = description | default(content | ogDescription(160)) %}
-
-
- {# Lightbox overlay for article images #}
-
-
-
×
-
- ‹
-
-
- ›
-
-
-
-
-
-
-
-{# Comments section #}
-{% include "components/comments.njk" %}
-
-{# Webmentions display - likes, reposts, replies #}
-{% include "components/webmentions.njk" %}
-
-{# Post Navigation - Previous/Next #}
-{% include "components/post-navigation.njk" %}
diff --git a/theme/_includes/layouts/where.njk b/theme/_includes/layouts/where.njk
deleted file mode 100644
index b2e2a47..0000000
--- a/theme/_includes/layouts/where.njk
+++ /dev/null
@@ -1,117 +0,0 @@
----
-layout: layouts/base.njk
-withSidebar: true
----
-{% set checkins = whereCheckins.checkins or [] %}
-
-
-
-
- {% if checkins.length %}
-
- {% for checkin in checkins %}
-
-
-
-
-
-
- {{ checkin.name }}
-
-
- {% if checkin.locationText or checkin.postalCode %}
-
- {{ checkin.locationText }}{% if checkin.locationText and checkin.postalCode %}, {% endif %}{{ checkin.postalCode }}
-
- {% endif %}
-
-
- {% if checkin.published %}
-
{{ checkin.published | date("MMM d, yyyy") }}
- {% endif %}
- {% if checkin.coordinatesText %}
-
{{ checkin.coordinatesText }}
- {% endif %}
- {% if checkin.isPrivate %}
-
Private
- {% endif %}
- {% if checkin.checkedInBy and (checkin.checkedInBy.name or checkin.checkedInBy.url) %}
-
- Checked in by {% if checkin.checkedInBy.url %}{{ checkin.checkedInBy.name or checkin.checkedInBy.url }} {% else %}{{ checkin.checkedInBy.name }}{% endif %}
-
- {% endif %}
-
-
- {% if checkin.tags and checkin.tags.length %}
-
- {% for tag in checkin.tags | head(8) %}
- #{{ tag }}
- {% endfor %}
-
- {% endif %}
-
- {% if checkin.taggedPeople and checkin.taggedPeople.length %}
-
- {% for person in checkin.taggedPeople | head(6) %}
- {% if person.url %}
-
{{ person.name or person.url }}
- {% else %}
-
{{ person.name }}
- {% endif %}
- {% endfor %}
-
- {% endif %}
-
-
- {% if checkin.mapUrl %}
-
Map
- {% endif %}
- {% if checkin.venueWebsiteUrl %}
-
Website
- {% endif %}
- {% if checkin.venueSocialUrl %}
-
Social
- {% endif %}
-
-
- {% if checkin.photos and checkin.photos.length %}
-
- {% for photo in checkin.photos | head(3) %}
-
-
-
- {% endfor %}
-
- {% endif %}
-
-
-
- {% endfor %}
-
- {% else %}
-
- No check-ins available yet
-
- This page reads local content created by your Micropub endpoint. Check-ins appear here when posts include fields like checkin, location, or coordinates.
-
-
- Scanned {{ whereCheckins.scannedFiles or 0 }} content files{% if whereCheckins.errors and whereCheckins.errors.length %} with {{ whereCheckins.errors.length }} parse warning(s){% endif %}.
-
-
- {% endif %}
-
diff --git a/theme/about.njk b/theme/about.njk
deleted file mode 100644
index 5cd5a40..0000000
--- a/theme/about.njk
+++ /dev/null
@@ -1,69 +0,0 @@
----
-layout: layouts/base.njk
-title: About
-permalink: false
-eleventyExcludeFromCollections: true
----
-
-
-
-
-
{{ site.author.bio }}
-
-
About This Site
-
- This site is powered by Indiekit , an IndieWeb
- server that supports Micropub, Webmentions, and other IndieWeb standards. It runs on
- Cloudron for easy self-hosting.
-
-
-
IndieWeb
-
- I'm part of the IndieWeb movement - owning my content
- and identity online. You can interact with my posts through Webmentions - reply, like,
- or repost from your own website and it will show up here.
-
-
- {% if site.social.length > 0 %}
-
Connect
-
Find me on:
-
- {% endif %}
-
- {% if site.author.email %}
-
- Or send me an email at
- {{ site.author.email }}
-
- {% endif %}
-
-
diff --git a/theme/articles.njk b/theme/articles.njk
deleted file mode 100644
index 5b6f2bb..0000000
--- a/theme/articles.njk
+++ /dev/null
@@ -1,100 +0,0 @@
----
-layout: layouts/base.njk
-title: Articles
-withSidebar: true
-pagination:
- data: collections.articles
- size: 20
- alias: paginatedArticles
- generatePageOnEmptyData: true
-permalink: "articles/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
----
-
-
-
Articles
- {% set sparklineSvg = collections.articles | postingFrequency %}
- {% if sparklineSvg %}
- {{ sparklineSvg | safe }}
- {% endif %}
-
-
- Long-form posts and essays.
- ({{ collections.articles.length }} total)
-
-
- {% if paginatedArticles.length > 0 %}
-
- {% for post in paginatedArticles %}
-
-
-
-
- {{ post.date | dateDisplay }}
-
- {% if post.data.category %}
-
- {% if post.data.category is string %}
- {{ post.data.category }}
- {% else %}
- {% for cat in post.data.category %}
- {{ cat }}
- {% endfor %}
- {% endif %}
-
- {% endif %}
-
-
- {{ post.templateContent | striptags | truncate(250) }}
-
-
- Read more →
-
-
- {% endfor %}
-
-
- {# Pagination controls #}
- {% if pagination.pages.length > 1 %}
-
- {% endif %}
-
- {% else %}
- {% set postType = "article" %}
- {% include "components/empty-collection.njk" %}
- {% endif %}
-
diff --git a/theme/blog.njk b/theme/blog.njk
deleted file mode 100644
index 1e16fc0..0000000
--- a/theme/blog.njk
+++ /dev/null
@@ -1,389 +0,0 @@
----
-layout: layouts/base.njk
-title: Blog
-withSidebar: true
-pagination:
- data: collections.listedPosts
- size: 20
- alias: paginatedPosts
-permalink: "blog/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
----
-
-
-
Blog
- {% set sparklineSvg = collections.listedPosts | postingFrequency %}
- {% if sparklineSvg %}
- {{ sparklineSvg | safe }}
- {% endif %}
-
-
- All posts including articles and notes.
- ({{ collections.listedPosts.length }} total)
-
-
- {% if paginatedPosts.length > 0 %}
-
-
-
- All Types
- Articles
- Notes
- Photos
- Bookmarks
- Likes
- Replies
- Reposts
-
-
-
-
- {% for post in paginatedPosts %}
- {# Detect post type from frontmatter properties #}
- {% set likedUrl = post.data.likeOf or post.data.like_of %}
- {% set bookmarkedUrl = post.data.bookmarkOf or post.data.bookmark_of %}
- {% set repostedUrl = post.data.repostOf or post.data.repost_of %}
- {% set replyToUrl = post.data.inReplyTo or post.data.in_reply_to %}
- {% set hasPhotos = post.data.photo and post.data.photo.length %}
- {% set _postType %}{% if likedUrl %}like{% elif bookmarkedUrl %}bookmark{% elif repostedUrl %}repost{% elif replyToUrl %}reply{% elif hasPhotos %}photo{% elif post.data.title %}article{% else %}note{% endif %}{% endset %}
- {% set borderClass = "" %}
- {% if likedUrl %}
- {% set borderClass = "border-l-[3px] border-l-red-400 dark:border-l-red-500" %}
- {% elif bookmarkedUrl %}
- {% set borderClass = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif repostedUrl %}
- {% set borderClass = "border-l-[3px] border-l-green-400 dark:border-l-green-500" %}
- {% elif replyToUrl %}
- {% set borderClass = "border-l-[3px] border-l-sky-400 dark:border-l-sky-500" %}
- {% elif hasPhotos %}
- {% set borderClass = "border-l-[3px] border-l-purple-400 dark:border-l-purple-500" %}
- {% else %}
- {% set borderClass = "border-l-[3px] border-l-surface-300 dark:border-l-surface-600" %}
- {% endif %}
-
-
- {% if likedUrl %}
- {# ── Like card ── #}
-
-
- {% elif bookmarkedUrl %}
- {# ── Bookmark card ── #}
-
-
- {% elif repostedUrl %}
- {# ── Repost card ── #}
-
-
- {% elif replyToUrl %}
- {# ── Reply card ── #}
-
-
- {% elif hasPhotos %}
- {# ── Photo card ── #}
-
-
- {% elif post.data.title %}
- {# ── Article card (unchanged) ── #}
-
-
- {{ post.templateContent | striptags | truncate(250) }}
-
-
- Read more →
-
-
- {% else %}
- {# ── Note card (unchanged) ── #}
-
-
- {{ post.templateContent | safe }}
-
-
- {% endif %}
-
- {# AI usage badge — only show when AI was actually used (level > 0) #}
- {% set postAiText = post.data.aiTextLevel or post.data.ai_text_level %}
- {% set postAiCode = post.data.aiCodeLevel or post.data.ai_code_level %}
- {% if (postAiText and postAiText !== "0") or (postAiCode and postAiCode !== "0") %}
-
-
- AI{% if postAiText %}: T{{ postAiText }}{% endif %}{% if postAiCode %}/C{{ postAiCode }}{% endif %}
-
- {% endif %}
-
- {% endfor %}
-
-
-
- {# Pagination controls #}
- {% if pagination.pages.length > 1 %}
-
- {% endif %}
-
- {% else %}
-
No posts yet. Create your first post using a Micropub client!
-
Some popular Micropub clients:
-
- Quill - Web-based
- IndiePass - Mobile app
- Micropublish - Web-based
-
- {% endif %}
-
diff --git a/theme/bookmarks.njk b/theme/bookmarks.njk
deleted file mode 100644
index 0feb73e..0000000
--- a/theme/bookmarks.njk
+++ /dev/null
@@ -1,109 +0,0 @@
----
-layout: layouts/base.njk
-title: Bookmarks
-withSidebar: true
-pagination:
- data: collections.bookmarks
- size: 20
- alias: paginatedBookmarks
- generatePageOnEmptyData: true
-permalink: "bookmarks/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
----
-
-
-
Bookmarks
- {% set sparklineSvg = collections.bookmarks | postingFrequency %}
- {% if sparklineSvg %}
- {{ sparklineSvg | safe }}
- {% endif %}
-
-
- Links I've saved for later.
- ({{ collections.bookmarks.length }} total)
-
-
- {% if paginatedBookmarks.length > 0 %}
-
- {% for post in paginatedBookmarks %}
-
-
-
-
- {{ post.date | dateDisplay }}
-
- {% if post.data.category %}
-
- {% if post.data.category is string %}
- {{ post.data.category }}
- {% else %}
- {% for cat in post.data.category %}
- {{ cat }}
- {% endfor %}
- {% endif %}
-
- {% endif %}
-
- {# Support both camelCase (Indiekit Eleventy preset) and underscore (legacy) property names #}
- {% set bookmarkedUrl = post.data.bookmarkOf or post.data.bookmark_of %}
- {% if bookmarkedUrl %}
- {% unfurl bookmarkedUrl %}
-
- {{ bookmarkedUrl }}
-
- {% endif %}
- {% if post.templateContent %}
-
- {{ post.templateContent | safe }}
-
- {% endif %}
-
- {% endfor %}
-
-
- {# Pagination controls #}
- {% if pagination.pages.length > 1 %}
-
- {% endif %}
-
- {% else %}
- {% set postType = "bookmark" %}
- {% include "components/empty-collection.njk" %}
- {% endif %}
-
diff --git a/theme/categories-index.njk b/theme/categories-index.njk
deleted file mode 100644
index 3c4d298..0000000
--- a/theme/categories-index.njk
+++ /dev/null
@@ -1,30 +0,0 @@
----
-layout: layouts/base.njk
-title: Categories
-withSidebar: true
-permalink: categories/
-eleventyImport:
- collections:
- - categories
----
-
-
Categories
-
- Browse posts by category.
- ({{ collections.categories.length }} categories)
-
-
- {% if collections.categories.length > 0 %}
-
- {% for cat in collections.categories %}
-
-
- {{ cat }}
-
-
- {% endfor %}
-
- {% else %}
-
No categories yet.
- {% endif %}
-
diff --git a/theme/categories.njk b/theme/categories.njk
deleted file mode 100644
index 087aa52..0000000
--- a/theme/categories.njk
+++ /dev/null
@@ -1,83 +0,0 @@
----
-layout: layouts/base.njk
-withSidebar: true
-pagination:
- data: collections.categories
- size: 1
- alias: category
-permalink: "categories/{{ category | slugify }}/"
-eleventyComputed:
- title: "{{ category }}"
----
-
-
{{ category }}
-
- Posts tagged with "{{ category }}".
-
-
- {% set categoryPosts = [] %}
- {% for post in collections.posts %}
- {% if post.data.category %}
- {% if post.data.category is string %}
- {% if post.data.category == category %}
- {% set categoryPosts = (categoryPosts.push(post), categoryPosts) %}
- {% endif %}
- {% else %}
- {% if category in post.data.category %}
- {% set categoryPosts = (categoryPosts.push(post), categoryPosts) %}
- {% endif %}
- {% endif %}
- {% endif %}
- {% endfor %}
-
- {% if categoryPosts.length > 0 %}
-
{{ categoryPosts.length }} post{% if categoryPosts.length != 1 %}s{% endif %}
-
- {% for post in categoryPosts %}
- {% set postType = post.inputPath | replace("./content/", "") %}
- {% set postType = postType.split("/")[0] %}
- {% set borderClass = "" %}
- {% if postType == "likes" %}
- {% set borderClass = "border-l-[3px] border-l-red-400 dark:border-l-red-500" %}
- {% elif postType == "bookmarks" %}
- {% set borderClass = "border-l-[3px] border-l-amber-400 dark:border-l-amber-500" %}
- {% elif postType == "reposts" %}
- {% set borderClass = "border-l-[3px] border-l-green-400 dark:border-l-green-500" %}
- {% elif postType == "replies" %}
- {% set borderClass = "border-l-[3px] border-l-accent-400 dark:border-l-accent-500" %}
- {% elif postType == "photos" %}
- {% set borderClass = "border-l-[3px] border-l-purple-400 dark:border-l-purple-500" %}
- {% else %}
- {% set borderClass = "border-l-[3px] border-l-surface-300 dark:border-l-surface-600" %}
- {% endif %}
-
-
-
-
- {{ post.date | dateDisplay }}
-
- {{ postType }}
-
-
- {{ post.templateContent | striptags | truncate(250) }}
-
-
- View →
-
-
- {% endfor %}
-
- {% else %}
-
No posts found with this category.
- {% endif %}
-
-
-
diff --git a/theme/category-feed-json.njk b/theme/category-feed-json.njk
deleted file mode 100644
index 7036984..0000000
--- a/theme/category-feed-json.njk
+++ /dev/null
@@ -1,70 +0,0 @@
----
-eleventyExcludeFromCollections: true
-eleventyImport:
- collections:
- - categoryFeeds
-pagination:
- data: collections.categoryFeeds
- size: 1
- alias: categoryFeed
-permalink: "categories/{{ categoryFeed.slug }}/feed.json"
----
-{
- "version": "https://jsonfeed.org/version/1.1",
- "title": "{{ site.name }} — {{ categoryFeed.name }}",
- "home_page_url": "{{ site.url }}/categories/{{ categoryFeed.slug }}/",
- "feed_url": "{{ site.url }}/categories/{{ categoryFeed.slug }}/feed.json",
- "hubs": [
- {
- "type": "WebSub",
- "url": "https://websubhub.com/hub"
- }
- ],
- "description": "Posts tagged with \"{{ categoryFeed.name }}\" on {{ site.name }}",
- "language": "{{ site.locale | default('en') }}",
- "authors": [
- {
- "name": "{{ site.author.name | default(site.name) }}",
- "url": "{{ site.url }}/"
- }
- ],
- "_textcasting": {
- "version": "1.0",
- "about": "https://textcasting.org/"
- {%- set hasSupport = site.support and (site.support.url or site.support.stripe or site.support.lightning or site.support.paymentPointer) %}
- {%- if hasSupport %},
- "support": {{ site.support | textcastingSupport | jsonEncode | safe }}
- {%- endif %}
- },
- {%- set listedCategoryPosts = categoryFeed.posts | excludeUnlistedPosts %}
- "items": [
- {%- for post in listedCategoryPosts %}
- {%- set absolutePostUrl = site.url + post.url %}
- {%- set postImage = post.data.photo %}
- {%- if postImage %}
- {%- if postImage[0] and (postImage[0] | length) > 10 %}
- {%- set postImage = postImage[0] %}
- {%- endif %}
- {%- endif %}
- {%- if not postImage or postImage == "" %}
- {%- set postImage = post.data.image or (post.content | extractFirstImage) %}
- {%- endif %}
- {
- "id": "{{ absolutePostUrl }}",
- "url": "{{ absolutePostUrl }}",
- "title": {% if post.data.title %}{{ post.data.title | jsonEncode | safe }}{% else %}null{% endif %},
- "content_html": {{ post.content | htmlToAbsoluteUrls(absolutePostUrl) | jsonEncode | safe }},
- "content_text": {{ post.content | striptags | jsonEncode | safe }},
- "date_published": "{{ post.date | dateToRfc3339 }}",
- "date_modified": "{{ (post.data.updated or post.date) | dateToRfc3339 }}"
- {%- if postImage and postImage != "" and (postImage | length) > 10 %},
- "image": "{{ postImage | url | absoluteUrl(site.url) }}"
- {%- endif %}
- {%- set attachments = post.data | feedAttachments %}
- {%- if attachments.length > 0 %},
- "attachments": {{ attachments | jsonEncode | safe }}
- {%- endif %}
- }{% if not loop.last %},{% endif %}
- {%- endfor %}
- ]
-}
diff --git a/theme/category-feed.njk b/theme/category-feed.njk
deleted file mode 100644
index 1eedf36..0000000
--- a/theme/category-feed.njk
+++ /dev/null
@@ -1,50 +0,0 @@
----
-eleventyExcludeFromCollections: true
-eleventyImport:
- collections:
- - categoryFeeds
-pagination:
- data: collections.categoryFeeds
- size: 1
- alias: categoryFeed
-permalink: "categories/{{ categoryFeed.slug }}/feed.xml"
----
-
-
-
- {{ site.name }} — {{ categoryFeed.name }}
- {{ site.url }}/categories/{{ categoryFeed.slug }}/
- Posts tagged with "{{ categoryFeed.name }}" on {{ site.name }}
- {{ site.locale | default('en') }}
-
-
- {%- set listedCategoryPosts = categoryFeed.posts | excludeUnlistedPosts %}
- {%- if listedCategoryPosts.length %}
- {{ listedCategoryPosts | getNewestCollectionItemDate | dateToRfc822 }}
- {%- endif %}
- {%- for post in listedCategoryPosts %}
- {%- set absolutePostUrl = site.url + post.url %}
- {%- set postImage = post.data.photo %}
- {%- if postImage %}
- {%- if postImage[0] and (postImage[0] | length) > 10 %}
- {%- set postImage = postImage[0] %}
- {%- endif %}
- {%- endif %}
- {%- if not postImage or postImage == "" %}
- {%- set postImage = post.data.image or (post.content | extractFirstImage) %}
- {%- endif %}
- -
-
{{ post.data.title | default(post.content | striptags | truncate(80)) | escape }}
- {{ absolutePostUrl }}
- {{ absolutePostUrl }}
- {{ post.date | dateToRfc822 }}
- {{ post.content | htmlToAbsoluteUrls(absolutePostUrl) | escape }}
- {%- if postImage and postImage != "" and (postImage | length) > 10 %}
- {%- set imageUrl = postImage | url | absoluteUrl(site.url) %}
-
-
- {%- endif %}
-
- {%- endfor %}
-
-
diff --git a/theme/changelog.njk b/theme/changelog.njk
deleted file mode 100644
index 6a06c04..0000000
--- a/theme/changelog.njk
+++ /dev/null
@@ -1,234 +0,0 @@
----
-layout: layouts/base.njk
-title: Changelog
-permalink: /changelog/
-eleventyExcludeFromCollections: true
-pagefindIgnore: true
-withSidebar: false
----
-
-
-
-
- {# Tab navigation #}
-
-
-
-
-
-
-
-
-
- {# Loading state #}
-
-
-
-
-
-
Loading changelog...
-
-
- {# Commit list #}
-
-
- No recent activity in this category.
-
-
-
-
-
-
-
-
-
-
-
-
- Show details
-
-
-
-
-
-
-
-
-
- {# Load more button #}
-
-
- {# Summary #}
-
-
- from the last days
- (all time)
-
-
-
-
-
diff --git a/theme/chardonsbleus.njk b/theme/chardonsbleus.njk
deleted file mode 100644
index 3368bc0..0000000
--- a/theme/chardonsbleus.njk
+++ /dev/null
@@ -1,28 +0,0 @@
----
-layout: layouts/base.njk
-title: ChardonsBleus
-permalink: /chardonsbleus/
-eleventyExcludeFromCollections: true
----
-
- ChardonsBleus
-
-
diff --git a/theme/css/critical.css b/theme/css/critical.css
deleted file mode 100644
index d662e18..0000000
--- a/theme/css/critical.css
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Critical CSS — inlined in for first paint */
-/* Covers: layout shell, header, dark mode toggle, font display, basic typography */
-
-*,*::before,*::after{box-sizing:border-box}
-body{margin:0;font-family:"Inter",system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;line-height:1.5;-webkit-font-smoothing:antialiased}
-
-/* Dark mode base — warm stone palette */
-body{background-color:#faf8f5;color:#1c1b19}
-.dark body{background-color:#0f0e0d;color:#faf8f5}
-
-/* Container */
-.container{max-width:64rem;margin-left:auto;margin-right:auto;padding-left:1rem;padding-right:1rem}
-
-/* Header — sticky, visible immediately */
-.site-header{background-color:#faf8f5;border-bottom:1px solid #e8e5df;padding-top:1rem;padding-bottom:1rem;position:sticky;top:0;z-index:50}
-.dark .site-header{background-color:#1c1b19;border-bottom-color:#3f3b35}
-.header-container{display:flex;align-items:center;justify-content:space-between}
-.site-title{font-size:1.25rem;font-weight:700;color:#1c1b19;text-decoration:none}
-.dark .site-title{color:#faf8f5}
-
-/* Header actions — hidden on mobile */
-.header-actions{display:none}
-@media(min-width:768px){.header-actions{display:flex;align-items:center;gap:1rem}}
-
-/* Mobile menu toggle */
-.menu-toggle{display:block;padding:0.5rem;border-radius:0.5rem;background:none;border:none;color:#5c5750;cursor:pointer}
-@media(min-width:768px){.menu-toggle{display:none}}
-.dark .menu-toggle{color:#a09a90}
-
-/* Hidden utility */
-.hidden{display:none!important}
-[x-cloak]{display:none!important}
-
-/* Dark mode theme toggle icons */
-.theme-toggle .sun-icon{display:none}
-.theme-toggle .moon-icon{display:block}
-.dark .theme-toggle .sun-icon{display:block}
-.dark .theme-toggle .moon-icon{display:none}
-
-/* Main content padding */
-main.container{padding-top:1.5rem;padding-bottom:1.5rem}
-@media(min-width:768px){main.container{padding-top:2rem;padding-bottom:2rem}}
-
-/* Layout with sidebar */
-.layout-with-sidebar{display:grid;grid-template-columns:1fr;gap:1.5rem}
-@media(min-width:1024px){.layout-with-sidebar{grid-template-columns:2fr 1fr;gap:2rem}}
-.main-content{min-width:0;overflow-x:hidden}
-
-/* Basic typography — prevent FOUT */
-h1,h2,h3,h4{margin:0;line-height:1.25}
-a{color:#b45309}
-.dark a{color:#fbbf24}
-
-/* Prevent flash of unstyled content for nav */
-.site-nav{display:flex;align-items:center;gap:1rem}
-.site-nav>a,.site-nav .nav-dropdown-trigger{color:#5c5750;text-decoration:none;padding-top:0.5rem;padding-bottom:0.5rem}
-.dark .site-nav>a,.dark .site-nav .nav-dropdown-trigger{color:#a09a90}
diff --git a/theme/css/lite-yt-embed.css b/theme/css/lite-yt-embed.css
deleted file mode 100644
index c96a472..0000000
--- a/theme/css/lite-yt-embed.css
+++ /dev/null
@@ -1,95 +0,0 @@
-lite-youtube {
- background-color: #000;
- position: relative;
- display: block;
- contain: content;
- background-position: center center;
- background-size: cover;
- cursor: pointer;
- max-width: 720px;
-}
-
-/* gradient */
-lite-youtube::before {
- content: attr(data-title);
- display: block;
- position: absolute;
- top: 0;
- /* Pixel-perfect port of YT's gradient PNG, using https://github.com/bluesmoon/pngtocss plus optimizations */
- background-image: linear-gradient(180deg, rgb(0 0 0 / 67%) 0%, rgb(0 0 0 / 54%) 14%, rgb(0 0 0 / 15%) 54%, rgb(0 0 0 / 5%) 72%, rgb(0 0 0 / 0%) 94%);
- height: 99px;
- width: 100%;
- font-family: "YouTube Noto",Roboto,Arial,Helvetica,sans-serif;
- color: hsl(0deg 0% 93.33%);
- text-shadow: 0 0 2px rgba(0,0,0,.5);
- font-size: 18px;
- padding: 25px 20px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- box-sizing: border-box;
-}
-
-lite-youtube:hover::before {
- color: white;
-}
-
-/* responsive iframe with a 16:9 aspect ratio
- thanks https://css-tricks.com/responsive-iframes/
-*/
-lite-youtube::after {
- content: "";
- display: block;
- padding-bottom: calc(100% / (16 / 9));
-}
-lite-youtube > iframe {
- width: 100%;
- height: 100%;
- position: absolute;
- top: 0;
- left: 0;
- border: 0;
-}
-
-/* play button */
-lite-youtube > .lty-playbtn {
- display: block;
- /* Make the button element cover the whole area for a large hover/click target… */
- width: 100%;
- height: 100%;
- /* …but visually it's still the same size */
- background: no-repeat center/68px 48px;
- /* YT's actual play button svg */
- background-image: url('data:image/svg+xml;utf8, ');
- position: absolute;
- cursor: pointer;
- z-index: 1;
- filter: grayscale(100%);
- transition: filter .1s cubic-bezier(0, 0, 0.2, 1);
- border: 0;
-}
-
-lite-youtube:hover > .lty-playbtn,
-lite-youtube .lty-playbtn:focus {
- filter: none;
-}
-
-/* Post-click styles */
-lite-youtube.lyt-activated {
- cursor: unset;
-}
-lite-youtube.lyt-activated::before,
-lite-youtube.lyt-activated > .lty-playbtn {
- opacity: 0;
- pointer-events: none;
-}
-
-.lyt-visually-hidden {
- clip: rect(0 0 0 0);
- clip-path: inset(50%);
- height: 1px;
- overflow: hidden;
- position: absolute;
- white-space: nowrap;
- width: 1px;
- }
diff --git a/theme/css/prism-theme.css b/theme/css/prism-theme.css
deleted file mode 100644
index 90bf299..0000000
--- a/theme/css/prism-theme.css
+++ /dev/null
@@ -1,201 +0,0 @@
-/* Syntax Highlighting — PrismJS theme for indiekit-eleventy-theme
- Light mode: clean, high-contrast colors
- Dark mode: scoped under .dark (Tailwind darkMode: "class") */
-
-/* ── Base code block styling ── */
-code[class*="language-"],
-pre[class*="language-"] {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- font-size: 0.875em;
- line-height: 1.7;
- direction: ltr;
- text-align: left;
- white-space: pre;
- word-spacing: normal;
- word-break: normal;
- tab-size: 2;
- hyphens: none;
-}
-
-pre[class*="language-"] {
- padding: 1.25em;
- margin: 1.5em 0;
- overflow: auto;
- border-radius: 0.5rem;
-}
-
-:not(pre) > code[class*="language-"] {
- padding: 0.2em 0.4em;
- border-radius: 0.25rem;
- white-space: normal;
-}
-
-/* ── Light Mode ── */
-code[class*="language-"],
-pre[class*="language-"] {
- color: #24292e;
-}
-
-pre[class*="language-"] {
- background: #f4f2ee;
- border: 1px solid #e1e4e8;
-}
-
-:not(pre) > code[class*="language-"] {
- background: #f4f2ee;
-}
-
-.token.comment,
-.token.prolog,
-.token.doctype,
-.token.cdata {
- color: #6a737d;
-}
-
-.token.punctuation {
- color: #24292e;
-}
-
-.token.namespace {
- opacity: 0.7;
-}
-
-.token.property,
-.token.tag,
-.token.boolean,
-.token.number,
-.token.constant,
-.token.symbol,
-.token.deleted {
- color: #005cc5;
-}
-
-.token.selector,
-.token.attr-name,
-.token.string,
-.token.char,
-.token.builtin,
-.token.inserted {
- color: #032f62;
-}
-
-.token.operator,
-.token.entity,
-.token.url,
-.language-css .token.string,
-.style .token.string {
- color: #d73a49;
-}
-
-.token.atrule,
-.token.attr-value,
-.token.keyword {
- color: #d73a49;
-}
-
-.token.function,
-.token.class-name {
- color: #6f42c1;
-}
-
-.token.regex,
-.token.important,
-.token.variable {
- color: #e36209;
-}
-
-.token.important,
-.token.bold {
- font-weight: bold;
-}
-
-.token.italic {
- font-style: italic;
-}
-
-.token.entity {
- cursor: help;
-}
-
-/* Line highlighting */
-.highlight-line-active {
- background-color: #fffbdd;
- display: inline-block;
- width: calc(100% + 2.5em);
- margin-left: -1.25em;
- padding-left: 1.25em;
-}
-
-/* ── Dark Mode ── */
-.dark code[class*="language-"],
-.dark pre[class*="language-"] {
- color: #e1e4e8;
-}
-
-.dark pre[class*="language-"] {
- background: #161b22;
- border-color: #30363d;
-}
-
-.dark :not(pre) > code[class*="language-"] {
- background: #161b22;
-}
-
-.dark .token.comment,
-.dark .token.prolog,
-.dark .token.doctype,
-.dark .token.cdata {
- color: #8b949e;
-}
-
-.dark .token.punctuation {
- color: #e1e4e8;
-}
-
-.dark .token.property,
-.dark .token.tag,
-.dark .token.boolean,
-.dark .token.number,
-.dark .token.constant,
-.dark .token.symbol,
-.dark .token.deleted {
- color: #79c0ff;
-}
-
-.dark .token.selector,
-.dark .token.attr-name,
-.dark .token.string,
-.dark .token.char,
-.dark .token.builtin,
-.dark .token.inserted {
- color: #a5d6ff;
-}
-
-.dark .token.operator,
-.dark .token.entity,
-.dark .token.url,
-.dark .language-css .token.string,
-.dark .style .token.string {
- color: #ff7b72;
-}
-
-.dark .token.atrule,
-.dark .token.attr-value,
-.dark .token.keyword {
- color: #ff7b72;
-}
-
-.dark .token.function,
-.dark .token.class-name {
- color: #d2a8ff;
-}
-
-.dark .token.regex,
-.dark .token.important,
-.dark .token.variable {
- color: #ffa657;
-}
-
-.dark .highlight-line-active {
- background-color: rgba(56, 139, 253, 0.15);
-}
diff --git a/theme/css/tailwind.css b/theme/css/tailwind.css
deleted file mode 100644
index fe7d4b4..0000000
--- a/theme/css/tailwind.css
+++ /dev/null
@@ -1,986 +0,0 @@
-/* Inter font — latin + latin-ext subsets, weights 400/500/600/700 */
-@font-face {
- font-family: 'Inter';
- font-style: normal;
- font-display: swap;
- font-weight: 400;
- src: url(/fonts/inter-latin-ext-400-normal.woff2) format('woff2');
- unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
-}
-@font-face {
- font-family: 'Inter';
- font-style: normal;
- font-display: swap;
- font-weight: 400;
- src: url(/fonts/inter-latin-400-normal.woff2) format('woff2');
- unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
-}
-@font-face {
- font-family: 'Inter';
- font-style: normal;
- font-display: swap;
- font-weight: 500;
- src: url(/fonts/inter-latin-ext-500-normal.woff2) format('woff2');
- unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
-}
-@font-face {
- font-family: 'Inter';
- font-style: normal;
- font-display: swap;
- font-weight: 500;
- src: url(/fonts/inter-latin-500-normal.woff2) format('woff2');
- unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
-}
-@font-face {
- font-family: 'Inter';
- font-style: normal;
- font-display: swap;
- font-weight: 600;
- src: url(/fonts/inter-latin-ext-600-normal.woff2) format('woff2');
- unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
-}
-@font-face {
- font-family: 'Inter';
- font-style: normal;
- font-display: swap;
- font-weight: 600;
- src: url(/fonts/inter-latin-600-normal.woff2) format('woff2');
- unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
-}
-@font-face {
- font-family: 'Inter';
- font-style: normal;
- font-display: swap;
- font-weight: 700;
- src: url(/fonts/inter-latin-ext-700-normal.woff2) format('woff2');
- unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
-}
-@font-face {
- font-family: 'Inter';
- font-style: normal;
- font-display: swap;
- font-weight: 700;
- src: url(/fonts/inter-latin-700-normal.woff2) format('woff2');
- unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
-}
-
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-/* Accessibility utilities */
-@layer utilities {
- .visually-hidden {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- white-space: nowrap;
- border: 0;
- }
-
- .skip-link {
- @apply absolute -top-full left-0 z-50 bg-accent-600 text-white px-4 py-2;
- }
-
- .skip-link:focus {
- @apply top-0;
- }
-}
-
-/* Reduce motion for accessibility */
-@media (prefers-reduced-motion: reduce) {
- *,
- *::before,
- *::after {
- animation-duration: 0.01ms !important;
- animation-iteration-count: 1 !important;
- transition-duration: 0.01ms !important;
- scroll-behavior: auto !important;
- }
-}
-
-/* Body background — warm stone canvas */
-@layer base {
- body {
- @apply bg-surface-50 dark:bg-surface-950 text-surface-900 dark:text-surface-100;
- }
-
- /* P1: Date typography — all elements get monospace for technical texture */
- time {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- }
-
- /* P2: Focus-visible states — keyboard-only focus rings for accessibility (WCAG 2.4.7) */
- button:focus-visible,
- [role="button"]:focus-visible,
- summary:focus-visible {
- @apply outline-none ring-2 ring-amber-500/70 ring-offset-2 ring-offset-surface-50 rounded-sm;
- }
-
- .dark button:focus-visible,
- .dark [role="button"]:focus-visible,
- .dark summary:focus-visible {
- @apply ring-offset-surface-900;
- }
-
- input:focus-visible,
- select:focus-visible,
- textarea:focus-visible {
- @apply outline-none ring-2 ring-amber-500/70 border-transparent;
- }
-
- a:focus-visible {
- @apply outline-none ring-2 ring-amber-500/70 ring-offset-1 ring-offset-surface-50 rounded-sm;
- }
-
- .dark a:focus-visible {
- @apply ring-offset-surface-900;
- }
-}
-
-/* Layout styles */
-@layer components {
- /* Site header */
- .site-header {
- @apply bg-surface-50 dark:bg-surface-900 border-b border-surface-200 dark:border-surface-700 py-4 sticky top-0 z-50;
- }
-
- .header-container {
- @apply flex items-center justify-between;
- }
-
- .site-title {
- @apply text-xl font-bold text-surface-900 dark:text-white no-underline hover:text-surface-600 dark:hover:text-surface-300 transition-colors;
- }
-
- /* Header actions (nav + theme toggle) */
- .header-actions {
- @apply hidden md:flex items-center gap-4;
- }
-
- .site-nav {
- @apply flex items-center gap-4;
- }
-
- .site-nav > a,
- .site-nav .nav-dropdown-trigger {
- @apply text-surface-600 dark:text-surface-400 hover:text-surface-900 dark:hover:text-surface-100 no-underline transition-colors py-2;
- }
-
- /* Navigation dropdown */
- .nav-dropdown {
- @apply relative;
- }
-
- .nav-dropdown-trigger {
- @apply flex items-center gap-1 cursor-pointer bg-transparent border-none text-base;
- }
-
- .nav-dropdown-menu {
- @apply absolute top-full left-0 mt-1 py-2 bg-surface-50 dark:bg-surface-800 border border-surface-200 dark:border-surface-700 rounded-lg shadow-lg min-w-[160px] z-50 overflow-y-auto;
- max-height: calc(100vh - 5rem);
- max-height: calc(100dvh - 5rem);
- }
-
- .nav-dropdown-menu a {
- @apply block px-4 py-2 text-sm text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-700 hover:text-surface-900 dark:hover:text-surface-100 no-underline;
- }
-
- .nav-dropdown-divider {
- @apply my-2 border-t border-surface-200 dark:border-surface-700;
- }
-
- /* Mobile menu toggle button */
- .menu-toggle {
- @apply md:hidden p-2 rounded-lg text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors;
- }
-
- /* Mobile navigation dropdown */
- .mobile-nav {
- @apply md:hidden border-t border-surface-200 dark:border-surface-700 bg-surface-50 dark:bg-surface-900 overflow-y-auto;
- max-height: calc(100vh - 4rem);
- max-height: calc(100dvh - 4rem);
- }
-
- .mobile-nav a {
- @apply block px-4 py-3 text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-100 no-underline transition-colors border-b border-surface-100 dark:border-surface-800 last:border-b-0;
- }
-
- /* Mobile nav collapsible sections */
- .mobile-nav-section {
- @apply border-b border-surface-100 dark:border-surface-800;
- }
-
- .mobile-nav-toggle {
- @apply flex items-center justify-between w-full px-4 py-3 text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-100 transition-colors bg-transparent border-none text-base text-left cursor-pointer;
- }
-
- .mobile-nav-submenu {
- @apply bg-surface-50 dark:bg-surface-800;
- }
-
- .mobile-nav-submenu a {
- @apply pl-8 py-2 text-sm border-b-0;
- }
-
- .mobile-nav-divider {
- @apply my-2 mx-4 border-t border-surface-200 dark:border-surface-700;
- }
-
- /* Theme toggle button */
- .theme-toggle {
- @apply p-2 rounded-lg text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors;
- }
-
- .theme-toggle .sun-icon {
- @apply hidden;
- }
-
- .theme-toggle .moon-icon {
- @apply block;
- }
-
- .dark .theme-toggle .sun-icon {
- @apply block;
- }
-
- .dark .theme-toggle .moon-icon {
- @apply hidden;
- }
-
- /* Mobile theme toggle */
- .mobile-theme-toggle {
- @apply flex items-center justify-between w-full px-4 py-3 text-surface-600 dark:text-surface-400 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-100 transition-colors bg-transparent border-none text-base text-left cursor-pointer border-t border-surface-200 dark:border-surface-700;
- }
-
- .mobile-theme-toggle .theme-label {
- @apply font-normal;
- }
-
- .mobile-theme-toggle .theme-icons {
- @apply flex items-center;
- }
-
- .mobile-theme-toggle .sun-icon {
- @apply hidden;
- }
-
- .mobile-theme-toggle .moon-icon {
- @apply block;
- }
-
- .dark .mobile-theme-toggle .sun-icon {
- @apply block;
- }
-
- .dark .mobile-theme-toggle .moon-icon {
- @apply hidden;
- }
-
- /* Container */
- .container {
- @apply max-w-5xl mx-auto px-4;
- }
-
- /* Site footer */
- .site-footer {
- @apply mt-12 py-8 border-t border-surface-200 dark:border-surface-700 text-center text-sm text-surface-500;
- }
-
- .site-footer a {
- @apply text-accent-600 dark:text-accent-400 hover:underline;
- }
-
- /* Layout with sidebar - mobile-first with responsive grid */
- .layout-with-sidebar {
- @apply grid grid-cols-1 gap-6 md:gap-8 lg:grid-cols-3;
- }
-
- .main-content {
- @apply lg:col-span-2 min-w-0 overflow-x-hidden; /* min-w-0 + overflow-x-hidden prevents layout breaking */
- }
-
- .sidebar {
- @apply space-y-6 lg:sticky lg:top-24 lg:self-start overflow-hidden;
- }
-
- /* Main content area - adjust padding for mobile */
- main.container {
- @apply py-6 md:py-8;
- }
-}
-
-/* Custom component styles */
-@layer components {
- /* Post list */
- .post-list {
- @apply list-none p-0 m-0 space-y-6;
- }
-
- .post-list li {
- @apply pb-6 border-b border-b-surface-200 dark:border-b-surface-700 last:border-0;
- }
-
- /* Post meta */
- .post-meta {
- @apply text-sm text-surface-600 dark:text-surface-400 flex flex-wrap gap-2 items-center;
- }
-
- /* Category tags (post metadata pills) */
- .p-category {
- @apply inline-block px-2 py-0.5 text-xs bg-surface-100 dark:bg-surface-800 text-surface-600 dark:text-surface-300 rounded border border-surface-200 dark:border-surface-700 hover:border-surface-400 dark:hover:border-surface-500 transition-colors;
- }
-
- /* Inline hashtags in post content — styled as subtle links, not pills */
- .e-content a.hashtag,
- .prose a.hashtag {
- @apply text-accent-600 dark:text-accent-400 no-underline hover:underline font-medium;
- /* Override prose default link styling (no border-bottom, no color shift) */
- text-decoration: none;
- }
-
- /* Webmention facepile - overlapping avatar display */
- .facepile {
- @apply flex flex-wrap items-center;
- }
-
- .facepile-avatar {
- @apply inline-block -ml-2 first:ml-0 transition-transform hover:z-10 hover:scale-110;
- }
-
- .facepile-avatar img {
- @apply w-8 h-8 rounded-full;
- }
-
- /* GitHub components */
- .repo-card {
- @apply p-4 border border-surface-200 dark:border-surface-700 rounded-lg;
- }
-
- .repo-meta {
- @apply flex gap-4 text-sm text-surface-600 dark:text-surface-400 mt-2;
- }
-
- /* Timeline for CV */
- .timeline {
- @apply relative pl-6 border-l-2 border-accent-500;
- }
-
- .timeline-item {
- @apply relative pb-6 last:pb-0;
- }
-
- .timeline-item::before {
- content: '';
- @apply absolute -left-[calc(1.5rem+5px)] top-1.5 w-3 h-3 bg-accent-500 rounded-full;
- }
-
- /* Skills badges */
- .skill-badge {
- @apply inline-block px-3 py-1 text-sm bg-surface-100 dark:bg-surface-800 rounded-full;
- }
-
- /* Ensure is-land custom elements don't break block layout flow */
- is-land {
- @apply block;
- }
-
- /* Widget cards */
- .widget {
- @apply p-4 mb-4 bg-surface-50 dark:bg-surface-800 rounded-lg border border-surface-200 dark:border-surface-700 shadow-sm overflow-hidden;
- }
-
- .widget-title {
- @apply font-bold text-lg mb-4;
- }
-
- /* Collapsible widget wrapper */
- .widget-header {
- @apply flex items-center justify-between cursor-pointer;
- }
-
- .widget-header .widget-title {
- @apply mb-0;
- }
-
- .widget-chevron {
- @apply w-4 h-4 text-surface-400 transition-transform duration-200 shrink-0;
- }
-
- /* Hide inner widget titles when the collapsible wrapper provides one */
- .widget-collapsible .widget .widget-title {
- @apply hidden;
- }
-
- /* Hide FeedLand's custom title in collapsible wrapper */
- .widget-collapsible .widget .fl-title {
- @apply hidden;
- }
-
- /* Neutralize inner widget card styling when inside collapsible wrapper */
- .widget-collapsible .widget {
- @apply border-0 shadow-none rounded-none mb-0 bg-transparent;
- }
-
- /* Post cards */
- .post-card {
- @apply p-5 bg-surface-50 dark:bg-surface-800 rounded-lg border border-surface-200 dark:border-surface-700 shadow-sm overflow-hidden;
- }
-
- .post-header {
- @apply flex flex-wrap items-center gap-2;
- }
-
- .post-footer {
- @apply pt-3 border-t border-surface-100 dark:border-surface-700;
- }
-
- /* Photo gallery on listing pages */
- .photo-list li {
- @apply pb-8;
- }
-
- .photo-gallery {
- @apply my-4 grid gap-2;
- }
-
- .photo-gallery img {
- @apply w-full max-h-[500px] object-cover rounded-lg;
- }
-
- .photo-link {
- @apply block;
- }
-
- .photo-caption {
- @apply mt-3 text-surface-600 dark:text-surface-400;
- }
-
- /* Multi-photo grid */
- .photo-gallery:has(img:nth-child(2)) {
- @apply grid-cols-2;
- }
-
- .photo-gallery:has(img:nth-child(3)) {
- @apply grid-cols-2;
- }
-
- .photo-gallery:has(img:nth-child(4)) {
- @apply grid-cols-2;
- }
-
- /* Pagination */
- .pagination {
- @apply mt-12 pt-8 border-t border-surface-200 dark:border-surface-700 flex flex-col sm:flex-row items-center justify-between gap-4;
- }
-
- .pagination-info {
- @apply text-sm text-surface-600 dark:text-surface-400;
- }
-
- .pagination-links {
- @apply flex items-center gap-2;
- }
-
- .pagination-link {
- @apply inline-flex items-center gap-1 px-4 py-2 text-sm font-medium bg-surface-100 dark:bg-surface-800 rounded-lg hover:bg-surface-200 dark:hover:bg-surface-700 transition-colors;
- }
-
- .pagination-link.disabled {
- @apply opacity-50 cursor-not-allowed hover:bg-surface-100 dark:hover:bg-surface-800;
- }
-}
-
-/* Focus states */
-@layer base {
- a:focus-visible,
- button:focus-visible,
- input:focus-visible,
- textarea:focus-visible,
- select:focus-visible {
- @apply outline-2 outline-offset-2 outline-accent-500;
- }
-}
-
-/* Active states — subtle press feedback on buttons */
-@layer base {
- button:active:not(:disabled),
- .pagination-link:active:not(.disabled) {
- transform: scale(0.97);
- }
-}
-
-/* Video embeds */
-@layer components {
- .video-embed {
- @apply relative w-full aspect-video my-4;
- }
-
- .video-embed iframe {
- @apply absolute inset-0 w-full h-full rounded-lg;
- }
-}
-
-/* Admin UI - FAB and dashboard link */
-@layer components {
- .fab-container {
- @apply fixed bottom-6 right-6 z-50 flex flex-col items-end;
- }
-
- .fab-backdrop {
- @apply fixed inset-0 bg-black/20 dark:bg-black/40 z-40;
- }
-
- .fab-button {
- @apply relative z-50 w-14 h-14 rounded-full bg-accent-600 hover:bg-accent-700 dark:bg-accent-500 dark:hover:bg-accent-600 text-white shadow-lg hover:shadow-xl transition-all duration-200 flex items-center justify-center;
- }
-
- .fab-button:focus-visible {
- @apply outline-2 outline-offset-2 outline-accent-500;
- }
-
- .fab-menu {
- @apply relative z-50 mb-3 flex flex-col gap-2 items-end;
- }
-
- .fab-menu-item {
- @apply flex items-center gap-3 px-4 py-3 rounded-xl bg-surface-50 dark:bg-surface-800 shadow-md hover:shadow-lg border border-surface-200 dark:border-surface-700 text-surface-700 dark:text-surface-200 hover:text-accent-600 dark:hover:text-accent-400 no-underline transition-all duration-150 text-sm font-medium;
- }
-
- .fab-menu-divider {
- @apply border-t border-surface-200 dark:border-surface-700 my-1 w-full;
- }
-
- .admin-nav-link {
- @apply text-accent-600 dark:text-accent-400 hover:text-accent-700 dark:hover:text-accent-300 no-underline transition-colors py-2 inline-flex items-center gap-1;
- }
-}
-
-/* Performance: content-visibility for off-screen rendering optimization */
-@layer utilities {
- .content-auto {
- content-visibility: auto;
- contain-intrinsic-size: auto 500px;
- }
-}
-
-/* Dates — monospace for technical texture (system.md: every gets font-mono) */
-@layer base {
- time {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- }
-}
-
-/* Apply content-visibility to images and post items for performance */
-@layer base {
- /* Responsive typography */
- html {
- @apply text-base md:text-lg;
- }
-
- /* Prevent horizontal overflow */
- body {
- @apply overflow-x-hidden;
- }
-
- /* Images - prevent overflow and add content-visibility */
- img {
- @apply max-w-full h-auto;
- content-visibility: auto;
- }
-
- /* Pre/code blocks - prevent overflow on mobile */
- pre {
- @apply overflow-x-auto max-w-full;
- -webkit-overflow-scrolling: touch;
- }
-
- code {
- @apply break-words;
- }
-
- pre code {
- word-break: normal;
- overflow-wrap: normal;
- }
-
- /* Links in content - break long URLs */
- .e-content a,
- .prose a {
- @apply break-words;
- word-break: break-word;
- }
-
- /* Content containers - clip horizontal overflow but allow pre blocks to scroll */
- .e-content,
- .prose {
- overflow-x: clip;
- max-width: 100%;
- }
-
- article {
- scroll-margin-top: 80px; /* Prevent header overlap when scrolling to anchors */
- }
-
- /* Heading anchors — generated by markdown-it-anchor */
- .prose h2[id],
- .prose h3[id],
- .prose h4[id] {
- scroll-margin-top: 80px;
- }
- .prose :is(h2, h3, h4) > a.header-anchor {
- color: inherit;
- text-decoration: none;
- }
- .prose :is(h2, h3, h4) > a.header-anchor:hover {
- text-decoration: underline;
- text-decoration-color: var(--tw-prose-links, currentColor);
- text-underline-offset: 4px;
- }
- .prose :is(h2, h3, h4) > a.header-anchor::after {
- content: " #";
- opacity: 0;
- font-weight: normal;
- transition: opacity 0.15s;
- }
- .prose :is(h2, h3, h4):hover > a.header-anchor::after {
- opacity: 0.4;
- }
-
- .post-list li {
- content-visibility: auto;
- contain-intrinsic-size: auto 200px;
- }
-
- /* Tables - responsive handling */
- table {
- @apply w-full;
- display: block;
- overflow-x: auto;
- -webkit-overflow-scrolling: touch;
- }
-
- /* Ensure truncate works properly in flex containers */
- .truncate {
- @apply overflow-hidden text-ellipsis whitespace-nowrap;
- }
-
- /* Video embeds - maintain aspect ratio */
- lite-youtube,
- iframe[src*="youtube"],
- iframe[src*="vimeo"] {
- @apply max-w-full;
- }
-}
-
-/* Pagefind UI theme overrides — outside @layer for higher specificity over Pagefind's :root defaults */
-#search .pagefind-ui {
- --pagefind-ui-scale: 1;
- --pagefind-ui-primary: #b45309;
- --pagefind-ui-text: #1c1b19;
- --pagefind-ui-background: #faf8f5;
- --pagefind-ui-border: #e8e5df;
- --pagefind-ui-tag: #f4f2ee;
- --pagefind-ui-border-width: 1px;
- --pagefind-ui-border-radius: 8px;
- --pagefind-ui-image-border-radius: 8px;
- --pagefind-ui-font: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
-}
-
-.dark #search .pagefind-ui {
- --pagefind-ui-primary: #fbbf24;
- --pagefind-ui-text: #faf8f5;
- --pagefind-ui-background: #0f0e0d;
- --pagefind-ui-border: #3f3b35;
- --pagefind-ui-tag: #2a2722;
-}
-
-/* Search input */
-#search .pagefind-ui__search-input {
- background-color: #faf8f5;
- color: #1c1b19;
- border-color: #e8e5df;
- font-weight: 400;
-}
-
-.dark #search .pagefind-ui__search-input {
- background-color: #1c1b19;
- color: #faf8f5;
- border-color: #3f3b35;
-}
-
-#search .pagefind-ui__search-input:focus {
- outline: 2px solid #d97706;
- outline-offset: 2px;
- border-color: #d97706;
-}
-
-.dark #search .pagefind-ui__search-input:focus {
- outline-color: #fbbf24;
- border-color: #fbbf24;
-}
-
-/* Search clear button */
-#search .pagefind-ui__search-clear {
- color: #5c5750;
- background-color: #faf8f5;
-}
-
-.dark #search .pagefind-ui__search-clear {
- color: #a09a90;
- background-color: #1c1b19;
-}
-
-#search .pagefind-ui__search-clear:hover {
- color: #1c1b19;
-}
-
-.dark #search .pagefind-ui__search-clear:hover {
- color: #faf8f5;
-}
-
-/* Result links */
-#search .pagefind-ui__result-link {
- color: #b45309;
-}
-
-#search .pagefind-ui__result-link:hover {
- text-decoration: underline;
-}
-
-.dark #search .pagefind-ui__result-link {
- color: #fbbf24;
-}
-
-/* Result excerpts */
-#search .pagefind-ui__result-excerpt {
- color: #5c5750;
-}
-
-.dark #search .pagefind-ui__result-excerpt {
- color: #a09a90;
-}
-
-/* Highlighted search terms in results */
-#search .pagefind-ui__result-excerpt mark,
-#search mark {
- background-color: #fef3c7;
- color: #92400e;
- padding: 0.1em 0.2em;
- border-radius: 2px;
-}
-
-.dark #search .pagefind-ui__result-excerpt mark,
-.dark #search mark {
- background-color: #78350f;
- color: #fde68a;
-}
-
-/* Message (result count) */
-#search .pagefind-ui__message {
- color: #5c5750;
-}
-
-.dark #search .pagefind-ui__message {
- color: #a09a90;
-}
-
-/* "Load more" button */
-#search .pagefind-ui__button {
- color: #b45309;
- background-color: #faf8f5;
- border-color: #e8e5df;
- cursor: pointer;
-}
-
-#search .pagefind-ui__button:hover {
- background-color: #fffbeb;
- border-color: #b45309;
-}
-
-.dark #search .pagefind-ui__button {
- color: #fbbf24;
- background-color: #0f0e0d;
- border-color: #3f3b35;
-}
-
-.dark #search .pagefind-ui__button:hover {
- background-color: #1c1b19;
- border-color: #fbbf24;
-}
-
-/* Filter panel labels */
-#search .pagefind-ui__filter-name,
-#search .pagefind-ui__filter-label {
- color: #18181b;
-}
-
-.dark #search .pagefind-ui__filter-name,
-.dark #search .pagefind-ui__filter-label {
- color: #f4f4f5;
-}
-
-/* Result tags */
-#search .pagefind-ui__result-tag {
- background-color: #f4f4f5;
- color: #52525b;
-}
-
-.dark #search .pagefind-ui__result-tag {
- background-color: #27272a;
- color: #a1a1aa;
-}
-
-/* Sub-result nested links */
-#search .pagefind-ui__result-nested .pagefind-ui__result-link {
- color: #2563eb;
- font-weight: 400;
-}
-
-.dark #search .pagefind-ui__result-nested .pagefind-ui__result-link {
- color: #60a5fa;
-}
-
-/* Mobile-specific improvements */
-@layer utilities {
- /* Ensure proper touch scrolling on overflow containers */
- .overflow-x-auto {
- -webkit-overflow-scrolling: touch;
- }
-
- /* Hide scrollbar but allow scrolling */
- .scrollbar-hide {
- -ms-overflow-style: none;
- scrollbar-width: none;
- }
-
- .scrollbar-hide::-webkit-scrollbar {
- display: none;
- }
-}
-
-/* Sparkline — inline SVG posting frequency chart */
-.sparkline {
- width: 120px;
- height: 28px;
- display: block;
-}
-
-@media (min-width: 640px) {
- .sparkline {
- width: 180px;
- height: 32px;
- }
-}
-
-/* Save for Later buttons — hidden until auth confirmed */
-.save-later-btn {
- display: none;
-}
-
-body[data-indiekit-auth="true"] .save-later-btn {
- display: inline-flex;
- align-items: center;
- gap: 4px;
- cursor: pointer;
- background: none;
- border: 1px solid transparent;
- border-radius: 6px;
- padding: 2px 8px;
- font-size: 0.75rem;
- color: #6b7280;
- transition: all 0.2s ease;
-}
-
-body[data-indiekit-auth="true"] .save-later-btn:hover {
- border-color: #d1d5db;
- color: #4a9eff;
-}
-
-.save-later--saved {
- color: #4a9eff !important;
- opacity: 0.6;
- pointer-events: none;
-}
-
-/* Share Post buttons — hidden until auth confirmed */
-.share-post-btn {
- display: none;
-}
-
-body[data-indiekit-auth="true"] .share-post-btn {
- display: inline-flex;
- align-items: center;
- gap: 4px;
- cursor: pointer;
- background: none;
- border: 1px solid transparent;
- border-radius: 6px;
- padding: 2px 8px;
- font-size: 0.75rem;
- color: #6b7280;
- transition: all 0.2s ease;
-}
-
-body[data-indiekit-auth="true"] .share-post-btn:hover {
- border-color: #d1d5db;
- color: #10b981;
-}
-
-/* Post type dropdown */
-.post-type-dropdown {
- display: none;
- position: absolute;
- bottom: 100%;
- left: 50%;
- transform: translateX(-50%);
- margin-bottom: 4px;
- background: white;
- border: 1px solid #e5e7eb;
- border-radius: 6px;
- box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); /* shadow-sm */
- z-index: 50;
- min-width: 120px;
- overflow: hidden;
-}
-
-.post-type-dropdown.open {
- display: block;
-}
-
-.post-type-dropdown-item {
- display: block;
- width: 100%;
- padding: 6px 12px;
- font-size: 13px;
- color: #374151;
- text-align: left;
- background: none;
- border: none;
- cursor: pointer;
- white-space: nowrap;
-}
-
-.post-type-dropdown-item:hover {
- background: #f3f4f6;
- color: #10b981;
-}
-
-/* Dark mode */
-@media (prefers-color-scheme: dark) {
- .post-type-dropdown {
- background: #1f2937;
- border-color: #374151;
- }
- .post-type-dropdown-item {
- color: #d1d5db;
- }
- .post-type-dropdown-item:hover {
- background: #374151;
- color: #34d399;
- }
-}
diff --git a/theme/cv.njk b/theme/cv.njk
deleted file mode 100644
index afb1116..0000000
--- a/theme/cv.njk
+++ /dev/null
@@ -1,146 +0,0 @@
----
-layout: layouts/base.njk
-withSidebar: false
-title: CV
-permalink: /cv/
-pagefindIgnore: true
----
-
-{# CV page — uses configurable layout when cvPageConfig exists, falls back to hardcoded layout #}
-
-{% set hasCvData = (cv.experience and cv.experience.length) or
- (cv.projects and cv.projects.length) or
- (cv.skills and ((cv.skills or {}) | dictsort | length)) or
- (cv.interests and ((cv.interests or {}) | dictsort | length)) %}
-
-{% if hasCvData %}
-
- {# Configurable layout — use cvPageConfig if available #}
- {% if cvPageConfig and cvPageConfig.sections %}
- {% include "components/cv-builder.njk" %}
-
- {# Fallback — hardcoded layout for backward compatibility #}
- {% else %}
-
- {# CV identity — check cvPageConfig.identity first, fall back to site.author #}
- {% set cvId = cvPageConfig.identity if (cvPageConfig and cvPageConfig.identity) else {} %}
- {% set authorName = cvId.name or site.author.name %}
- {% set authorAvatar = cvId.avatar or site.author.avatar %}
- {% set authorTitle = cvId.title or site.author.title %}
- {% set authorBio = cvId.bio or site.author.bio %}
- {% set socialLinks = cvId.social if (cvId.social and cvId.social.length) else site.social %}
- {% set cvLocality = cvId.locality or site.author.locality %}
- {% set cvCountry = cvId.country or site.author.country %}
- {% set cvOrg = cvId.org or site.author.org %}
- {% set cvUrl = cvId.url or '' %}
- {% set cvEmail = cvId.email or site.author.email %}
- {% set cvKeyUrl = cvId.keyUrl or site.author.keyUrl %}
-
- {# Hero / intro #}
-
-
-
-
-
- {{ authorName }}
-
- {% if authorTitle %}
-
- {{ authorTitle }}
-
- {% endif %}
- {% if authorBio %}
-
- {{ authorBio }}
-
- {% endif %}
- {% from "components/social-icon.njk" import socialIcon %}
- {% if socialLinks %}
-
- {% endif %}
- {# Contact details #}
- {% if cvLocality or cvCountry or cvOrg or cvUrl or cvEmail or cvKeyUrl %}
-
- {% if cvLocality or cvCountry %}
-
{% if cvLocality %}{{ cvLocality }}{% endif %}{% if cvLocality and cvCountry %}, {% endif %}{% if cvCountry %}{{ cvCountry }}{% endif %}
- {% endif %}
- {% if cvOrg %}
-
{{ cvOrg }}
- {% endif %}
- {% if cvUrl %}
-
{{ cvUrl | replace("https://", "") | replace("http://", "") }}
- {% endif %}
- {% if cvEmail %}
-
{{ cvEmail }}
- {% endif %}
- {% if cvKeyUrl %}
-
PGP Key
- {% endif %}
-
- {% endif %}
-
-
-
-
- {# Experience — work-only variant #}
- {% set section = { type: "cv-experience-work", config: {} } %}
- {% include "components/sections/cv-experience-work.njk" ignore missing %}
-
- {# Skills — work-only variant #}
- {% set section = { type: "cv-skills-work", config: {} } %}
- {% include "components/sections/cv-skills-work.njk" ignore missing %}
-
- {# Work Projects (only work-related projects on the CV page) #}
- {% set section = { type: "cv-projects-work", config: {} } %}
- {% include "components/sections/cv-projects-work.njk" ignore missing %}
-
- {# Education — work-only variant #}
- {% set section = { type: "cv-education-work", config: {} } %}
- {% include "components/sections/cv-education-work.njk" ignore missing %}
-
- {# Languages — standalone section #}
- {% set section = { type: "cv-languages", config: {} } %}
- {% include "components/sections/cv-languages.njk" ignore missing %}
-
- {# Interests — work-only variant #}
- {% set section = { type: "cv-interests-work", config: {} } %}
- {% include "components/sections/cv-interests-work.njk" ignore missing %}
-
- {# Last Updated #}
- {% if cv.lastUpdated %}
-
- Last updated: {{ cv.lastUpdated | date("PPP") }}
-
- {% endif %}
-
- {% endif %}
-
-{% else %}
-
-
-
CV
-
- No CV data available yet. Add your experience, projects, and skills via the
- admin dashboard .
-
-
-
-{% endif %}
diff --git a/theme/digest-feed.njk b/theme/digest-feed.njk
deleted file mode 100644
index 6505876..0000000
--- a/theme/digest-feed.njk
+++ /dev/null
@@ -1,31 +0,0 @@
----
-eleventyExcludeFromCollections: true
-eleventyImport:
- collections:
- - weeklyDigests
-permalink: /digest/feed.xml
----
-
-
-
- {{ site.name }} — Weekly Digest
- {{ site.url }}/digest/
- Weekly summary of all posts on {{ site.name }}. One update per week.
- {{ site.locale | default('en') }}
-
-
- {%- set latestDigests = collections.weeklyDigests | head(20) %}
- {%- if latestDigests.length %}
- {{ latestDigests[0].endDate | dateToRfc822 }}
- {%- endif %}
- {%- for digest in latestDigests %}
- -
-
{{ digest.label }} ({{ digest.startDate | dateDisplay }} – {{ digest.endDate | dateDisplay }})
- {{ site.url }}/digest/{{ digest.slug }}/
- {{ site.url }}/digest/{{ digest.slug }}/
- {{ digest.endDate | dateToRfc822 }}
- {{ digest | digestToHtml(site.url) | escape }}
-
- {%- endfor %}
-
-
diff --git a/theme/digest-index.njk b/theme/digest-index.njk
deleted file mode 100644
index 959788e..0000000
--- a/theme/digest-index.njk
+++ /dev/null
@@ -1,83 +0,0 @@
----
-layout: layouts/base.njk
-title: Weekly Digest
-withSidebar: true
-eleventyExcludeFromCollections: true
-eleventyImport:
- collections:
- - weeklyDigests
-pagination:
- data: collections.weeklyDigests
- size: 20
- alias: paginatedDigests
-permalink: "digest/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
----
-
-
Weekly Digest
-
- A weekly summary of all posts. Subscribe via RSS for one update per week.
-
-
- {% if paginatedDigests.length > 0 %}
-
-
- {% if pagination.pages.length > 1 %}
-
- {% endif %}
-
- {% else %}
-
No digests yet. Posts will be grouped into weekly digests automatically.
- {% endif %}
-
diff --git a/theme/digest.njk b/theme/digest.njk
deleted file mode 100644
index aa40bf8..0000000
--- a/theme/digest.njk
+++ /dev/null
@@ -1,168 +0,0 @@
----
-layout: layouts/base.njk
-withSidebar: true
-eleventyExcludeFromCollections: true
-eleventyImport:
- collections:
- - weeklyDigests
-pagination:
- data: collections.weeklyDigests
- size: 1
- alias: digest
-eleventyComputed:
- title: "{{ digest.label }}"
-permalink: "digest/{{ digest.slug }}/"
----
-
-
- {{ digest.label }}
-
-
- {{ digest.startDate | dateDisplay }} – {{ digest.endDate | dateDisplay }}
- ({{ digest.posts.length }} post{% if digest.posts.length != 1 %}s{% endif %})
-
-
- {# Type display order #}
- {% set typeOrder = [
- { key: "articles", label: "Articles" },
- { key: "notes", label: "Notes" },
- { key: "photos", label: "Photos" },
- { key: "bookmarks", label: "Bookmarks" },
- { key: "likes", label: "Likes" },
- { key: "reposts", label: "Reposts" }
- ] %}
-
- {% for typeInfo in typeOrder %}
- {% set typePosts = digest.byType[typeInfo.key] %}
- {% if typePosts and typePosts.length %}
-
-
- {{ typeInfo.label }}
- ({{ typePosts.length }})
-
-
- {% for post in typePosts %}
-
- {% if typeInfo.key == "likes" %}
- {% set targetUrl = post.data.likeOf or post.data.like_of %}
-
-
- {% elif typeInfo.key == "bookmarks" %}
- {% set targetUrl = post.data.bookmarkOf or post.data.bookmark_of %}
-
-
- {% elif typeInfo.key == "reposts" %}
- {% set targetUrl = post.data.repostOf or post.data.repost_of %}
-
-
- {% elif typeInfo.key == "photos" %}
-
- {% if post.data.photo and post.data.photo[0] %}
- {% set photoUrl = post.data.photo[0].url or post.data.photo[0] %}
- {% if photoUrl and photoUrl[0] != '/' and 'http' not in photoUrl %}
- {% set photoUrl = '/' + photoUrl %}
- {% endif %}
-
-
-
- {% endif %}
- {% if post.data.title %}
-
{{ post.data.title }}
- {% elif post.templateContent %}
-
{{ post.templateContent | striptags | truncate(120) }}
- {% endif %}
-
-
{{ post.date | dateDisplay }}
- ·
Permalink
-
-
-
- {% elif typeInfo.key == "articles" %}
-
-
- {% else %}
-
-
{{ post.templateContent | striptags | truncate(200) }}
-
-
{{ post.date | dateDisplay }}
- ·
Permalink
-
-
- {% endif %}
-
- {% endfor %}
-
-
- {% endif %}
- {% endfor %}
-
- {# Previous/Next digest navigation #}
- {% set allDigests = collections.weeklyDigests %}
- {% set currentIndex = -1 %}
- {% for d in allDigests %}
- {% if d.slug == digest.slug %}
- {% set currentIndex = loop.index0 %}
- {% endif %}
- {% endfor %}
-
-
- {% if currentIndex > 0 %}
- {% set newer = allDigests[currentIndex - 1] %}
-
- ← {{ newer.label }}
-
- {% else %}
-
- {% endif %}
- {% if currentIndex < allDigests.length - 1 %}
- {% set older = allDigests[currentIndex + 1] %}
-
- {{ older.label }} →
-
- {% else %}
-
- {% endif %}
-
-
diff --git a/theme/eleventy.config.js b/theme/eleventy.config.js
deleted file mode 100644
index 04848ed..0000000
--- a/theme/eleventy.config.js
+++ /dev/null
@@ -1,1327 +0,0 @@
-import pluginWebmentions from "@chrisburnell/eleventy-cache-webmentions";
-import pluginRss from "@11ty/eleventy-plugin-rss";
-import embedEverything from "eleventy-plugin-embed-everything";
-import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
-import sitemap from "@quasibit/eleventy-plugin-sitemap";
-import markdownIt from "markdown-it";
-import markdownItAnchor from "markdown-it-anchor";
-import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
-import { minify } from "html-minifier-terser";
-import registerUnfurlShortcode, { getCachedCard, prefetchUrl } from "./lib/unfurl-shortcode.js";
-import matter from "gray-matter";
-import { createHash, createHmac } from "crypto";
-import { createRequire } from "module";
-import { execFileSync } from "child_process";
-import { readFileSync, readdirSync, existsSync, mkdirSync, writeFileSync, copyFileSync } from "fs";
-import { resolve, dirname } from "path";
-import { fileURLToPath } from "url";
-
-const esmRequire = createRequire(import.meta.url);
-const postGraph = esmRequire("@rknightuk/eleventy-plugin-post-graph");
-
-const __dirname = dirname(fileURLToPath(import.meta.url));
-const siteUrl = process.env.SITE_URL || "https://example.com";
-
-export default function (eleventyConfig) {
- // Don't use .gitignore for determining what to process
- // (content/ is in .gitignore because it's a symlink, but we need to process it)
- eleventyConfig.setUseGitIgnore(false);
-
- // Ignore output directory (prevents re-processing generated files via symlink)
- eleventyConfig.ignores.add("_site");
- eleventyConfig.ignores.add("_site/**");
- eleventyConfig.ignores.add("/app/data/site");
- eleventyConfig.ignores.add("/app/data/site/**");
- eleventyConfig.ignores.add("node_modules");
- eleventyConfig.ignores.add("node_modules/**");
- eleventyConfig.ignores.add("CLAUDE.md");
- eleventyConfig.ignores.add("README.md");
-
- // Ignore Pagefind output directory
- eleventyConfig.ignores.add("pagefind");
- eleventyConfig.ignores.add("pagefind/**");
- // Ignore interactive assets (served via passthrough copy, not processed as templates)
- eleventyConfig.ignores.add("interactive");
- eleventyConfig.ignores.add("interactive/**");
-
- // Configure watch targets to exclude output directory
- eleventyConfig.watchIgnores.add("_site");
- eleventyConfig.watchIgnores.add("_site/**");
- eleventyConfig.watchIgnores.add("/app/data/site");
- eleventyConfig.watchIgnores.add("/app/data/site/**");
- eleventyConfig.watchIgnores.add("pagefind");
- eleventyConfig.watchIgnores.add("pagefind/**");
- eleventyConfig.watchIgnores.add(".cache/og");
- eleventyConfig.watchIgnores.add(".cache/og/**");
- eleventyConfig.watchIgnores.add(".cache/unfurl");
- eleventyConfig.watchIgnores.add(".cache/unfurl/**");
-
- // Watcher tuning: handle rapid successive file changes
- // When a post is created via Micropub, the file is written twice in quick
- // succession: first the initial content, then ~2s later a Micropub update
- // adds syndication URLs. awaitWriteFinish delays the watcher event until
- // the file is stable (no writes for 2s), so both changes are captured in
- // one build. The throttle adds a 3s build-level debounce on top.
- eleventyConfig.setChokidarConfig({
- awaitWriteFinish: {
- stabilityThreshold: 2000,
- pollInterval: 100,
- },
- });
- eleventyConfig.setWatchThrottleWaitTime(3000);
-
- // Configure markdown-it with linkify enabled (auto-convert URLs to links)
- const md = markdownIt({
- html: true,
- linkify: true, // Auto-convert URLs to clickable links
- typographer: true,
- });
- md.use(markdownItAnchor, {
- permalink: markdownItAnchor.permalink.headerLink(),
- slugify: (s) => s.toLowerCase().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, ""),
- level: [2, 3, 4],
- });
-
- // Hashtag plugin: converts #tag to category links on-site
- // Syndication targets (Bluesky, Mastodon) handle raw #tag natively via facet detection
- md.inline.ruler.push("hashtag", (state, silent) => {
- const pos = state.pos;
- if (state.src.charCodeAt(pos) !== 0x23 /* # */) return false;
-
- // Must be at start of string or preceded by whitespace/punctuation (not part of a URL fragment or hex color)
- if (pos > 0) {
- const prevChar = state.src.charAt(pos - 1);
- if (!/[\s()\[\]{},;:!?"'«»""'']/.test(prevChar)) return false;
- }
-
- // Match hashtag: # followed by letter/underscore, then word chars (letters, digits, underscores)
- const tail = state.src.slice(pos + 1);
- const match = tail.match(/^([a-zA-Z_]\w*)/);
- if (!match) return false;
-
- const tag = match[1];
-
- // Skip pure hex color codes (3, 4, 6, or 8 hex digits with nothing else)
- if (/^[0-9a-fA-F]{3,8}$/.test(tag)) return false;
-
- if (!silent) {
- const slug = tag.toLowerCase().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
- const tokenOpen = state.push("link_open", "a", 1);
- tokenOpen.attrSet("href", `/categories/${slug}/`);
- tokenOpen.attrSet("class", "p-category hashtag");
-
- const tokenText = state.push("text", "", 0);
- tokenText.content = `#${tag}`;
-
- state.push("link_close", "a", -1);
- }
-
- state.pos = pos + 1 + tag.length;
- return true;
- });
-
- eleventyConfig.setLibrary("md", md);
-
- // Syntax highlighting for fenced code blocks (```lang)
- eleventyConfig.addPlugin(syntaxHighlight);
-
- // RSS plugin for feed filters (dateToRfc822, absoluteUrl, etc.)
- // Custom feed templates in feed.njk and feed-json.njk use these filters
- eleventyConfig.addPlugin(pluginRss);
-
- // Post graph — GitHub-style contribution grid for posting frequency
- eleventyConfig.addPlugin(postGraph, {
- sort: "desc",
- limit: 2,
- dayBoxTitle: true,
- selectorLight: ":root",
- selectorDark: ".dark",
- boxColorLight: "#e7e5e4", // surface-200 (warm stone)
- highlightColorLight: "#d97706", // amber-600 (accent)
- textColorLight: "#1c1917", // surface-900
- boxColorDark: "#292524", // surface-800
- highlightColorDark: "#fbbf24", // amber-400
- textColorDark: "#fafaf9", // surface-50
- });
-
- // JSON encode filter for JSON feed
- eleventyConfig.addFilter("jsonEncode", (value) => {
- return JSON.stringify(value);
- });
-
- // Guess MIME type from URL extension
- function guessMimeType(url, category) {
- const lower = (typeof url === "string" ? url : "").toLowerCase();
- if (category === "photo") {
- if (lower.includes(".png")) return "image/png";
- if (lower.includes(".gif")) return "image/gif";
- if (lower.includes(".webp")) return "image/webp";
- if (lower.includes(".svg")) return "image/svg+xml";
- return "image/jpeg";
- }
- if (category === "audio") {
- if (lower.includes(".ogg") || lower.includes(".opus")) return "audio/ogg";
- if (lower.includes(".flac")) return "audio/flac";
- if (lower.includes(".wav")) return "audio/wav";
- return "audio/mpeg";
- }
- if (category === "video") {
- if (lower.includes(".webm")) return "video/webm";
- if (lower.includes(".mov")) return "video/quicktime";
- return "video/mp4";
- }
- return "application/octet-stream";
- }
-
- // Extract URL string from value that may be a string or {url, alt} object
- function resolveMediaUrl(value) {
- if (typeof value === "string") return value;
- if (value && typeof value === "object" && value.url) return value.url;
- return null;
- }
-
- // Feed attachments filter — builds JSON Feed attachments array from post data
- eleventyConfig.addFilter("feedAttachments", (postData) => {
- const attachments = [];
- const processMedia = (items, category) => {
- const list = Array.isArray(items) ? items : [items];
- for (const item of list) {
- const rawUrl = resolveMediaUrl(item);
- if (!rawUrl) continue;
- const url = rawUrl.startsWith("http") ? rawUrl : `${siteUrl}${rawUrl}`;
- attachments.push({ url, mime_type: guessMimeType(rawUrl, category) });
- }
- };
- if (postData.photo) processMedia(postData.photo, "photo");
- if (postData.audio) processMedia(postData.audio, "audio");
- if (postData.video) processMedia(postData.video, "video");
- return attachments;
- });
-
- // Textcasting support filter — builds clean support object excluding null values
- eleventyConfig.addFilter("textcastingSupport", (support) => {
- if (!support) return {};
- const obj = {};
- if (support.url) obj.url = support.url;
- if (support.stripe) obj.stripe = support.stripe;
- if (support.lightning) obj.lightning = support.lightning;
- if (support.paymentPointer) obj.payment_pointer = support.paymentPointer;
- return obj;
- });
-
- // Protocol type filter — classifies a URL by its origin protocol/network
- eleventyConfig.addFilter("protocolType", (url) => {
- if (!url || typeof url !== "string") return "web";
- const lower = url.toLowerCase();
- if (lower.includes("bsky.app") || lower.includes("bluesky")) return "atmosphere";
- // Match Fediverse instances by known domain patterns (avoid overly broad "social")
- if (lower.includes("mastodon.") || lower.includes("mstdn.") || lower.includes("fosstodon.") ||
- lower.includes("pleroma.") || lower.includes("misskey.") || lower.includes("pixelfed.") ||
- lower.includes("fediverse")) return "fediverse";
- return "web";
- });
-
- // Email obfuscation filter - converts email to HTML entities
- // Blocks ~95% of spam harvesters while remaining valid for microformat parsers
- // Usage: {{ email | obfuscateEmail }} or {{ email | obfuscateEmail("href") }}
- eleventyConfig.addFilter("obfuscateEmail", (email, mode = "display") => {
- if (!email) return "";
- // Convert each character to HTML decimal entity
- const encoded = [...email].map(char => `${char.charCodeAt(0)};`).join("");
- if (mode === "href") {
- // For mailto: links, also encode the "mailto:" prefix
- const mailto = [...("mailto:")].map(char => `${char.charCodeAt(0)};`).join("");
- return mailto + encoded;
- }
- return encoded;
- });
-
- // Alias dateToRfc822 (plugin provides dateToRfc2822)
- eleventyConfig.addFilter("dateToRfc822", (date) => {
- return pluginRss.dateToRfc2822(date);
- });
-
- // Embed Everything - auto-embed YouTube, Vimeo, Bluesky, Mastodon, etc.
- eleventyConfig.addPlugin(embedEverything, {
- use: ["youtube", "vimeo", "twitter", "mastodon", "bluesky", "spotify", "soundcloud"],
- youtube: {
- options: {
- lite: false,
- recommendSelfOnly: true,
- },
- },
- mastodon: {
- options: {
- server: "indieweb.social",
- },
- },
- });
-
- // Unfurl shortcode — renders any URL as a rich card (OpenGraph/Twitter Card metadata)
- // Usage in templates: {% unfurl "https://example.com/article" %}
- registerUnfurlShortcode(eleventyConfig);
-
- // Synchronous unfurl filter — reads from pre-populated disk cache.
- // Safe for deeply nested includes where async shortcodes fail silently.
- // Usage: {{ url | unfurlCard | safe }}
- eleventyConfig.addFilter("unfurlCard", getCachedCard);
-
- // Custom transform to convert YouTube links to embeds
- eleventyConfig.addTransform("youtube-link-to-embed", function (content, outputPath) {
- if (!outputPath || !outputPath.endsWith(".html")) {
- return content;
- }
- // Match tags where href contains youtube.com/watch or youtu.be
- // Link text can be: URL, www.youtube..., youtube..., or youtube-related text
- const youtubePattern = / ]+href="https?:\/\/(?:www\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]+)[^"]*"[^>]*>(?:https?:\/\/)?(?:www\.)?[^<]*(?:youtube|youtu\.be)[^<]*<\/a>/gi;
-
- content = content.replace(youtubePattern, (match, videoId) => {
- // Use standard YouTube iframe with exact oEmbed parameters
- return `VIDEO
`;
- });
-
- // Clean up empty
tags created by the replacement
- content = content.replace(/\s*<\/p>/g, '');
-
- return content;
- });
-
- // Image optimization - transforms tags automatically
- // PROCESS_REMOTE_IMAGES: set to "true" to let Sharp download and re-encode remote images.
- // Default "false" — skips remote URLs (adds eleventy:ignore) to avoid OOM from Sharp's
- // native memory usage when processing hundreds of external images (bookmarks, webmentions).
- const processRemoteImages = process.env.PROCESS_REMOTE_IMAGES === "true";
- if (!processRemoteImages) {
- eleventyConfig.htmlTransformer.addPosthtmlPlugin("html", () => {
- return (tree) => {
- tree.match({ tag: "img" }, (node) => {
- if (node.attrs?.src && /^https?:\/\//.test(node.attrs.src)) {
- node.attrs["eleventy:ignore"] = "";
- }
- return node;
- });
- return tree;
- };
- }, { priority: 1 }); // priority > 0 runs before image plugin (priority -1)
- }
-
- eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
- extensions: "html",
- formats: ["webp", "jpeg"],
- widths: ["auto"],
- failOnError: false,
- cacheOptions: {
- duration: process.env.ELEVENTY_RUN_MODE === "build" ? "1d" : "30d",
- },
- concurrency: 4,
- defaultAttributes: {
- loading: "lazy",
- decoding: "async",
- sizes: "auto",
- alt: "",
- },
- });
-
- // Sitemap generation
- eleventyConfig.addPlugin(sitemap, {
- sitemap: {
- hostname: siteUrl,
- },
- });
-
- // Wrap
elements in for responsive tables
- eleventyConfig.addTransform("table-saw-wrap", function (content, outputPath) {
- if (outputPath && outputPath.endsWith(".html")) {
- return content.replace(/)/g, " ");
- }
- return content;
- });
-
- // Fix OG image meta tags post-rendering — bypasses Eleventy 3.x race condition (#3183).
- // page.url is unreliable during parallel rendering, but outputPath IS correct
- // since files are written to the correct location. Derives the OG slug from
- // outputPath and replaces placeholders emitted by base.njk.
- eleventyConfig.addTransform("og-fix", function (content, outputPath) {
- if (!outputPath || !outputPath.endsWith(".html")) return content;
-
- // Derive correct page URL and OG slug from outputPath (immune to race condition)
- // Content pages match: .../type/yyyy/MM/dd/slug/index.html
- const dateMatch = outputPath.match(
- /\/([\w-]+)\/(\d{4})\/(\d{2})\/(\d{2})\/([\w-]+)\/index\.html$/
- );
-
- if (dateMatch) {
- const [, type, year, month, day, slug] = dateMatch;
- const pageUrlPath = `/${type}/${year}/${month}/${day}/${slug}/`;
- const correctFullUrl = `${siteUrl}${pageUrlPath}`;
- const ogSlug = `${year}-${month}-${day}-${slug}`;
- const hasOg = existsSync(resolve(__dirname, ".cache", "og", `${ogSlug}.png`));
- const ogImageUrl = hasOg
- ? `${siteUrl}/og/${ogSlug}.png`
- : `${siteUrl}/images/og-default.png`;
- const twitterCard = hasOg ? "summary_large_image" : "summary";
-
- // Fix og:url and canonical (also affected by race condition)
- content = content.replace(
- /( {
- if (!dateObj) return "";
- const date = new Date(dateObj);
- return date.toLocaleDateString("en-GB", {
- year: "numeric",
- month: "long",
- day: "numeric",
- });
- });
-
- // ISO date filter
- eleventyConfig.addFilter("isoDate", (dateObj) => {
- if (!dateObj) return "";
- return new Date(dateObj).toISOString();
- });
-
- // Digest-to-HTML filter for RSS feed descriptions
- eleventyConfig.addFilter("digestToHtml", (digest, siteUrl) => {
- const typeLabels = {
- articles: "Articles",
- notes: "Notes",
- photos: "Photos",
- bookmarks: "Bookmarks",
- likes: "Likes",
- reposts: "Reposts",
- };
- const typeOrder = ["articles", "notes", "photos", "bookmarks", "likes", "reposts"];
- let html = "";
-
- for (const type of typeOrder) {
- const posts = digest.byType[type];
- if (!posts || !posts.length) continue;
-
- html += `${typeLabels[type]} `;
- for (const post of posts) {
- const postUrl = siteUrl + post.url;
- let label;
- if (type === "likes") {
- const target = post.data.likeOf || post.data.like_of;
- label = `Liked: ${target}`;
- } else if (type === "bookmarks") {
- const target = post.data.bookmarkOf || post.data.bookmark_of;
- label = post.data.title || `Bookmarked: ${target}`;
- } else if (type === "reposts") {
- const target = post.data.repostOf || post.data.repost_of;
- label = `Reposted: ${target}`;
- } else if (post.data.title) {
- label = post.data.title;
- } else {
- const content = post.templateContent || "";
- label = content.replace(/<[^>]*>/g, "").slice(0, 120).trim() || "Untitled";
- }
- html += `${label} `;
- }
- html += ` `;
- }
-
- return html;
- });
-
- // Truncate filter
- eleventyConfig.addFilter("truncate", (str, len = 200) => {
- if (!str) return "";
- if (str.length <= len) return str;
- return str.slice(0, len).trim() + "...";
- });
-
- // Clean excerpt for OpenGraph - strips HTML, decodes entities, removes extra whitespace
- eleventyConfig.addFilter("ogDescription", (content, len = 200) => {
- if (!content) return "";
- // Strip HTML tags
- let text = content.replace(/<[^>]+>/g, ' ');
- // Decode common HTML entities
- text = text.replace(/&/g, '&')
- .replace(/</g, '<')
- .replace(/>/g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, "'")
- .replace(/ /g, ' ');
- // Remove extra whitespace
- text = text.replace(/\s+/g, ' ').trim();
- // Truncate
- if (text.length > len) {
- text = text.slice(0, len).trim() + "...";
- }
- return text;
- });
-
- // Extract first image from content for OpenGraph fallback
- eleventyConfig.addFilter("extractFirstImage", (content) => {
- if (!content) return null;
- // Match all tags, skip hidden ones and data URIs
- const imgRegex = / ]*?\ssrc=["']([^"']+)["'][^>]*>/gi;
- let match;
- while ((match = imgRegex.exec(content)) !== null) {
- const fullTag = match[0];
- const src = match[1];
- if (src.startsWith("data:")) continue;
- if (/\bhidden\b/.test(fullTag)) continue;
- return src;
- }
- return null;
- });
-
- // Head filter for arrays
- eleventyConfig.addFilter("head", (array, n) => {
- if (!Array.isArray(array) || n < 1) return array;
- return array.slice(0, n);
- });
-
- // Slugify filter
- eleventyConfig.addFilter("slugify", (str) => {
- if (!str) return "";
- return str
- .toLowerCase()
- .replace(/[^\w\s-]/g, "")
- .replace(/[\s_-]+/g, "-")
- .replace(/^-+|-+$/g, "");
- });
-
- eleventyConfig.addFilter("stripTrailingSlash", (url) => {
- if (!url || typeof url !== "string") return url || "";
- return url.endsWith("/") ? url.slice(0, -1) : url;
- });
-
- // Hash filter for cache busting - generates MD5 hash of file content
- eleventyConfig.addFilter("hash", (filePath) => {
- try {
- const fullPath = resolve(__dirname, filePath.startsWith("/") ? `.${filePath}` : filePath);
- const content = readFileSync(fullPath);
- return createHash("md5").update(content).digest("hex").slice(0, 8);
- } catch {
- // Return timestamp as fallback if file not found
- return Date.now().toString(36);
- }
- });
-
- // Derive OG slug from page.url (reliable) instead of page.fileSlug
- // (which suffers from Nunjucks race conditions in Eleventy 3.x parallel rendering).
- // OG images are named with the full date prefix to match URL segments exactly.
- eleventyConfig.addFilter("ogSlug", (url) => {
- if (!url) return "";
- const segments = url.split("/").filter(Boolean);
- // Date-based URL: /type/yyyy/MM/dd/slug/ → 5 segments → "yyyy-MM-dd-slug"
- if (segments.length === 5) {
- const [, year, month, day, slug] = segments;
- return `${year}-${month}-${day}-${slug}`;
- }
- // Fallback: last segment (for pages, legacy URLs)
- return segments[segments.length - 1] || "";
- });
-
- // Check if a generated OG image exists for this slug
- eleventyConfig.addFilter("hasOgImage", (slug) => {
- if (!slug) return false;
- const ogPath = resolve(__dirname, ".cache", "og", `${slug}.png`);
- return existsSync(ogPath);
- });
-
- // Inline file contents (for critical CSS inlining)
- eleventyConfig.addFilter("inlineFile", (filePath) => {
- try {
- const fullPath = resolve(__dirname, filePath.startsWith("/") ? `.${filePath}` : filePath);
- return readFileSync(fullPath, "utf-8");
- } catch {
- return "";
- }
- });
-
- // Extract raw Markdown body from a source file (strips front matter)
- eleventyConfig.addFilter("rawMarkdownBody", (inputPath) => {
- try {
- const src = readFileSync(inputPath, "utf-8");
- const { content } = matter(src);
- return content.trim();
- } catch {
- return "";
- }
- });
-
- // Current timestamp filter (for client-side JS buildtime)
- eleventyConfig.addFilter("timestamp", () => Date.now());
-
- // Date filter (for sidebar dates)
- eleventyConfig.addFilter("date", (dateObj, format) => {
- if (!dateObj) return "";
- const date = new Date(dateObj);
- const options = {};
-
- if (format.includes("MMM")) options.month = "short";
- if (format.includes("d")) options.day = "numeric";
- if (format.includes("yyyy")) options.year = "numeric";
-
- return date.toLocaleDateString("en-US", options);
- });
-
- // Webmention filters - with legacy URL support
- // This filter checks both current URL and any legacy URLs from redirects
- // Merges webmentions + conversations with deduplication (conversations first)
- eleventyConfig.addFilter("webmentionsForUrl", function (webmentions, url, urlAliases, conversationMentions = []) {
- if (!url) return [];
-
- // Merge conversations + webmentions with deduplication
- const seen = new Set();
- const merged = [];
-
- // Add conversations first (richer metadata)
- for (const item of conversationMentions) {
- const key = item['wm-id'] || item.url;
- if (key && !seen.has(key)) {
- seen.add(key);
- merged.push(item);
- }
- }
-
- // Add webmentions (skip duplicates)
- if (webmentions) {
- for (const item of webmentions) {
- const key = item['wm-id'];
- if (!key || seen.has(key)) continue;
- if (item.url && seen.has(item.url)) continue;
- seen.add(key);
- merged.push(item);
- }
- }
-
- // Build list of all URLs to check (current + legacy)
- const urlsToCheck = new Set();
-
- // Add current URL variations
- const absoluteUrl = url.startsWith("http") ? url : `${siteUrl}${url}`;
- urlsToCheck.add(absoluteUrl);
- urlsToCheck.add(absoluteUrl.replace(/\/$/, ""));
- urlsToCheck.add(absoluteUrl.endsWith("/") ? absoluteUrl : `${absoluteUrl}/`);
-
- // Add legacy URLs from aliases (if provided)
- if (urlAliases?.aliases) {
- const normalizedUrl = url.replace(/\/$/, "");
- const oldUrls = urlAliases.aliases[normalizedUrl] || [];
- for (const oldUrl of oldUrls) {
- urlsToCheck.add(`${siteUrl}${oldUrl}`);
- urlsToCheck.add(`${siteUrl}${oldUrl}/`);
- urlsToCheck.add(`${siteUrl}${oldUrl}`.replace(/\/$/, ""));
- }
- }
-
- // Compute legacy /content/ URL from current URL for old webmention.io targets
- // Pattern: /type/yyyy/MM/dd/slug/ → /content/type/yyyy-MM-dd-slug/
- const pathSegments = url.replace(/\/$/, "").split("/").filter(Boolean);
- if (pathSegments.length === 5) {
- const [type, year, month, day, slug] = pathSegments;
- const contentUrl = `/content/${type}/${year}-${month}-${day}-${slug}/`;
- urlsToCheck.add(`${siteUrl}${contentUrl}`);
- urlsToCheck.add(`${siteUrl}${contentUrl}`.replace(/\/$/, ""));
- }
-
- // Filter merged data matching any of our URLs
- const matched = merged.filter((wm) => urlsToCheck.has(wm["wm-target"]));
-
- // Deduplicate cross-source: same author + same interaction type = same mention
- // (webmention.io and conversations API may both report the same like/reply)
- const deduped = [];
- const authorActions = new Set();
- for (const wm of matched) {
- const authorUrl = wm.author?.url || wm.url || "";
- const action = wm["wm-property"] || "mention";
- const key = `${authorUrl}::${action}`;
- if (authorActions.has(key)) continue;
- authorActions.add(key);
- deduped.push(wm);
- }
- return deduped;
- });
-
- eleventyConfig.addFilter("webmentionsByType", function (mentions, type) {
- if (!mentions) return [];
- const typeMap = {
- likes: "like-of",
- reposts: "repost-of",
- bookmarks: "bookmark-of",
- replies: "in-reply-to",
- mentions: "mention-of",
- };
- const wmProperty = typeMap[type] || type;
- return mentions.filter((m) => m["wm-property"] === wmProperty);
- });
-
- // Post navigation — find previous/next post in a collection
- // (Nunjucks {% set %} inside {% for %} doesn't propagate, so we need filters)
- eleventyConfig.addFilter("previousInCollection", function (collection, page) {
- if (!collection || !page) return null;
- const index = collection.findIndex((p) => p.url === page.url);
- return index > 0 ? collection[index - 1] : null;
- });
-
- eleventyConfig.addFilter("nextInCollection", function (collection, page) {
- if (!collection || !page) return null;
- const index = collection.findIndex((p) => p.url === page.url);
- return index >= 0 && index < collection.length - 1
- ? collection[index + 1]
- : null;
- });
-
- // Posting frequency — compute posts-per-month for last 12 months (for sparkline).
- // Returns an inline SVG that uses currentColor for stroke and a semi-transparent
- // gradient fill. Wrap in a colored span to set the domain color via Tailwind.
- eleventyConfig.addFilter("postingFrequency", (posts) => {
- if (!Array.isArray(posts) || posts.length === 0) return "";
- const now = new Date();
- const counts = new Array(12).fill(0);
- for (const post of posts) {
- const postDate = new Date(post.date || post.data?.date);
- if (isNaN(postDate.getTime())) continue;
- const monthsAgo = (now.getFullYear() - postDate.getFullYear()) * 12 + (now.getMonth() - postDate.getMonth());
- if (monthsAgo >= 0 && monthsAgo < 12) {
- counts[11 - monthsAgo]++;
- }
- }
-
- // Extrapolate the current (partial) month to avoid false downward trend.
- // e.g. 51 posts in 5 days of a 31-day month projects to ~316.
- const dayOfMonth = now.getDate();
- const daysInMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate();
- if (dayOfMonth < daysInMonth && counts[11] > 0) {
- counts[11] = Math.round(counts[11] / dayOfMonth * daysInMonth);
- }
-
- const max = Math.max(...counts, 1);
- const w = 200;
- const h = 32;
- const pad = 2;
- const step = w / (counts.length - 1);
- const points = counts.map((v, i) => {
- const x = i * step;
- const y = h - pad - ((v / max) * (h - pad * 2));
- return `${x.toFixed(1)},${y.toFixed(1)}`;
- }).join(" ");
- // Closed polygon for gradient fill (line path + bottom corners)
- const fillPoints = `${points} ${w},${h} 0,${h}`;
- return [
- ``,
- ``,
- ` `,
- ` `,
- ` `,
- ` `,
- ` `,
- ` `,
- ].join("");
- });
-
- // Filter AI-involved posts (ai-text-level > "0" or aiTextLevel > "0")
- eleventyConfig.addFilter("aiPosts", (posts) => {
- if (!Array.isArray(posts)) return [];
- return posts.filter((post) => {
- const level = post.data?.aiTextLevel || post.data?.["ai-text-level"] || "0";
- return level !== "0" && level !== 0;
- });
- });
-
- // AI stats — returns { total, aiCount, percentage, byLevel }
- eleventyConfig.addFilter("aiStats", (posts) => {
- if (!Array.isArray(posts)) return { total: 0, aiCount: 0, percentage: 0, byLevel: {} };
- const total = posts.length;
- const byLevel = { 0: 0, 1: 0, 2: 0, 3: 0 };
- for (const post of posts) {
- const level = parseInt(post.data?.aiTextLevel || post.data?.["ai-text-level"] || "0", 10);
- byLevel[level] = (byLevel[level] || 0) + 1;
- }
- const aiCount = total - byLevel[0];
- return {
- total,
- aiCount,
- percentage: total > 0 ? ((aiCount / total) * 100).toFixed(1) : "0",
- byLevel,
- };
- });
-
- // Helper: exclude drafts from collections
- const isPublished = (item) => !item.data.draft;
-
- // Helper: exclude unlisted visibility from public listing surfaces
- const isListed = (item) => {
- const data = item?.data || {};
- const rawVisibility = data.visibility ?? data.properties?.visibility;
- const visibility = Array.isArray(rawVisibility) ? rawVisibility[0] : rawVisibility;
- return String(visibility ?? "").toLowerCase() !== "unlisted";
- };
-
- // Exclude unlisted posts from UI slices like homepage/sidebar recent-post lists.
- eleventyConfig.addFilter("excludeUnlistedPosts", (posts) => {
- if (!Array.isArray(posts)) return [];
- return posts.filter(isListed);
- });
-
- // Collections for different post types
- // Note: content path is content/ due to symlink structure
- // "posts" shows ALL content types combined
- eleventyConfig.addCollection("posts", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/**/*.md")
- .filter(isPublished)
- .sort((a, b) => b.date - a.date);
- });
-
- eleventyConfig.addCollection("listedPosts", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/**/*.md")
- .filter((item) => isPublished(item) && isListed(item))
- .sort((a, b) => b.date - a.date);
- });
-
- eleventyConfig.addCollection("notes", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/notes/**/*.md")
- .filter(isPublished)
- .sort((a, b) => b.date - a.date);
- });
-
- eleventyConfig.addCollection("listedNotes", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/notes/**/*.md")
- .filter((item) => isPublished(item) && isListed(item))
- .sort((a, b) => b.date - a.date);
- });
-
- eleventyConfig.addCollection("articles", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/articles/**/*.md")
- .filter(isPublished)
- .sort((a, b) => b.date - a.date);
- });
-
- eleventyConfig.addCollection("bookmarks", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/bookmarks/**/*.md")
- .filter(isPublished)
- .sort((a, b) => b.date - a.date);
- });
-
- eleventyConfig.addCollection("photos", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/photos/**/*.md")
- .filter(isPublished)
- .sort((a, b) => b.date - a.date);
- });
-
- eleventyConfig.addCollection("likes", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/likes/**/*.md")
- .filter(isPublished)
- .sort((a, b) => b.date - a.date);
- });
-
- // Replies collection - posts with inReplyTo/in_reply_to property
- // Supports both camelCase (Indiekit Eleventy preset) and underscore (legacy) names
- eleventyConfig.addCollection("replies", function (collectionApi) {
- return collectionApi
- .getAll()
- .filter((item) => isPublished(item) && (item.data.inReplyTo || item.data.in_reply_to))
- .sort((a, b) => b.date - a.date);
- });
-
- // Reposts collection - posts with repostOf/repost_of property
- // Supports both camelCase (Indiekit Eleventy preset) and underscore (legacy) names
- eleventyConfig.addCollection("reposts", function (collectionApi) {
- return collectionApi
- .getAll()
- .filter((item) => isPublished(item) && (item.data.repostOf || item.data.repost_of))
- .sort((a, b) => b.date - a.date);
- });
-
- // Pages collection - root-level slash pages (about, now, uses, etc.)
- // Includes both content/*.md (legacy) and content/pages/*.md (new post-type-page)
- // Created via Indiekit's page post type
- eleventyConfig.addCollection("pages", function (collectionApi) {
- const rootPages = collectionApi.getFilteredByGlob("content/*.md");
- const pagesDir = collectionApi.getFilteredByGlob("content/pages/*.md");
- return [...rootPages, ...pagesDir]
- .filter(page => isPublished(page) && !page.inputPath.includes('content.json') && !page.inputPath.includes('pages.json'))
- .sort((a, b) => (a.data.title || a.data.name || "").localeCompare(b.data.title || b.data.name || ""));
- });
-
- // All content combined for homepage feed
- eleventyConfig.addCollection("feed", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/**/*.md")
- .filter(isPublished)
- .sort((a, b) => b.date - a.date)
- .slice(0, 20);
- });
-
- // Categories collection - deduplicated by slug to avoid duplicate permalinks
- eleventyConfig.addCollection("categories", function (collectionApi) {
- const categoryMap = new Map(); // slug -> original name (first seen)
- const slugify = (str) => str.toLowerCase().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
-
- collectionApi.getAll().filter(isPublished).forEach((item) => {
- if (item.data.category) {
- const cats = Array.isArray(item.data.category) ? item.data.category : [item.data.category];
- cats.forEach((cat) => {
- if (cat && typeof cat === 'string' && cat.trim()) {
- const slug = slugify(cat.trim());
- if (slug && !categoryMap.has(slug)) {
- categoryMap.set(slug, cat.trim());
- }
- }
- });
- }
- });
- return [...categoryMap.values()].sort();
- });
-
- // Category feeds — pre-grouped posts for per-category RSS/JSON feeds
- eleventyConfig.addCollection("categoryFeeds", function (collectionApi) {
- const slugify = (str) => str.toLowerCase().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
- const grouped = new Map(); // slug -> { name, slug, posts[] }
-
- collectionApi
- .getFilteredByGlob("content/**/*.md")
- .filter(isPublished)
- .sort((a, b) => b.date - a.date)
- .forEach((item) => {
- if (!item.data.category) return;
- const cats = Array.isArray(item.data.category) ? item.data.category : [item.data.category];
- for (const cat of cats) {
- if (!cat || typeof cat !== "string" || !cat.trim()) continue;
- const slug = slugify(cat.trim());
- if (!slug) continue;
- if (!grouped.has(slug)) {
- grouped.set(slug, { name: cat.trim(), slug, posts: [] });
- }
- const entry = grouped.get(slug);
- if (entry.posts.length < 50) {
- entry.posts.push(item);
- }
- }
- });
-
- return [...grouped.values()].sort((a, b) => a.name.localeCompare(b.name));
- });
-
- // Recent posts for sidebar
- eleventyConfig.addCollection("recentPosts", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/**/*.md")
- .filter(isPublished)
- .sort((a, b) => b.date - a.date)
- .slice(0, 5);
- });
-
- // Featured posts — curated selection via `pinned: true` frontmatter
- // Property named "pinned" to avoid conflict with "featured" (hero image) in MF2/Micropub
- eleventyConfig.addCollection("featuredPosts", function (collectionApi) {
- return collectionApi
- .getFilteredByGlob("content/**/*.md")
- .filter(isPublished)
- .filter((item) => item.data.pinned === true || item.data.pinned === "true")
- .sort((a, b) => b.date - a.date);
- });
-
- // Weekly digests — posts grouped by ISO week for digest pages and RSS feed
- eleventyConfig.addCollection("weeklyDigests", function (collectionApi) {
- const allPosts = collectionApi
- .getFilteredByGlob("content/**/*.md")
- .filter(isPublished)
- .filter((item) => {
- // Exclude replies
- return !(item.data.inReplyTo || item.data.in_reply_to);
- })
- .sort((a, b) => b.date - a.date);
-
- // ISO week helpers
- const getISOWeek = (date) => {
- const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
- d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
- const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
- return Math.ceil(((d - yearStart) / 86400000 + 1) / 7);
- };
- const getISOYear = (date) => {
- const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
- d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
- return d.getUTCFullYear();
- };
-
- // Group by ISO week
- const weekMap = new Map();
-
- for (const post of allPosts) {
- const d = new Date(post.date);
- const week = getISOWeek(d);
- const year = getISOYear(d);
- const key = `${year}-W${String(week).padStart(2, "0")}`;
-
- if (!weekMap.has(key)) {
- // Calculate Monday (start) and Sunday (end) of ISO week
- const jan4 = new Date(Date.UTC(year, 0, 4));
- const dayOfWeek = jan4.getUTCDay() || 7;
- const monday = new Date(jan4);
- monday.setUTCDate(jan4.getUTCDate() - dayOfWeek + 1 + (week - 1) * 7);
- const sunday = new Date(monday);
- sunday.setUTCDate(monday.getUTCDate() + 6);
-
- weekMap.set(key, {
- year,
- week,
- slug: `${year}/W${String(week).padStart(2, "0")}`,
- label: `Week ${week}, ${year}`,
- startDate: monday.toISOString().slice(0, 10),
- endDate: sunday.toISOString().slice(0, 10),
- posts: [],
- });
- }
-
- weekMap.get(key).posts.push(post);
- }
-
- // Post type detection (matches blog.njk logic)
- const typeDetect = (post) => {
- if (post.data.likeOf || post.data.like_of) return "likes";
- if (post.data.bookmarkOf || post.data.bookmark_of) return "bookmarks";
- if (post.data.repostOf || post.data.repost_of) return "reposts";
- if (post.data.photo && post.data.photo.length) return "photos";
- if (post.data.title) return "articles";
- return "notes";
- };
-
- // Build byType for each week and convert to array
- const digests = [...weekMap.values()].map((entry) => {
- const byType = {};
- for (const post of entry.posts) {
- const type = typeDetect(post);
- if (!byType[type]) byType[type] = [];
- byType[type].push(post);
- }
- return { ...entry, byType };
- });
-
- // Sort newest-week-first
- digests.sort((a, b) => {
- if (a.year !== b.year) return b.year - a.year;
- return b.week - a.week;
- });
-
- return digests;
- });
-
- // Generate OpenGraph images for posts without photos
- // Runs on every build (including watcher rebuilds) — manifest caching makes it fast
- // for incremental: only new posts without an OG image get generated (~200ms each)
- eleventyConfig.on("eleventy.before", () => {
- const contentDir = resolve(__dirname, "content");
- const cacheDir = resolve(__dirname, ".cache");
- const siteName = process.env.SITE_NAME || "My IndieWeb Blog";
- try {
- execFileSync(process.execPath, [
- "--max-old-space-size=768",
- resolve(__dirname, "lib", "og-cli.js"),
- contentDir,
- cacheDir,
- siteName,
- ], {
- stdio: "inherit",
- env: { ...process.env, NODE_OPTIONS: "" },
- });
-
- // Sync new OG images to output directory.
- // During incremental builds, .cache/og is in watchIgnores so Eleventy's
- // passthrough copy won't pick up newly generated images. Copy them manually.
- const ogCacheDir = resolve(cacheDir, "og");
- const ogOutputDir = resolve(__dirname, "_site", "og");
- if (existsSync(ogCacheDir) && existsSync(resolve(__dirname, "_site"))) {
- mkdirSync(ogOutputDir, { recursive: true });
- let synced = 0;
- for (const file of readdirSync(ogCacheDir)) {
- if (file.endsWith(".png") && !existsSync(resolve(ogOutputDir, file))) {
- copyFileSync(resolve(ogCacheDir, file), resolve(ogOutputDir, file));
- synced++;
- }
- }
- if (synced > 0) {
- console.log(`[og] Synced ${synced} new image(s) to output`);
- }
- }
- } catch (err) {
- console.error("[og] Image generation failed:", err.message);
- }
- });
-
- // Pre-fetch unfurl metadata for all interaction URLs in content files.
- // Populates the disk cache BEFORE templates render, so the synchronous
- // unfurlCard filter (used in nested includes like recent-posts) has data.
- eleventyConfig.on("eleventy.before", async () => {
- const contentDir = resolve(__dirname, "content");
- if (!existsSync(contentDir)) return;
-
- const urls = new Set();
- const interactionProps = [
- "likeOf", "like_of", "bookmarkOf", "bookmark_of",
- "repostOf", "repost_of", "inReplyTo", "in_reply_to",
- ];
-
- const walk = (dir) => {
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
- const full = resolve(dir, entry.name);
- if (entry.isDirectory()) { walk(full); continue; }
- if (!entry.name.endsWith(".md")) continue;
- try {
- const { data } = matter(readFileSync(full, "utf-8"));
- for (const prop of interactionProps) {
- if (data[prop]) urls.add(data[prop]);
- }
- } catch { /* skip unparseable files */ }
- }
- };
- walk(contentDir);
-
- if (urls.size === 0) return;
- console.log(`[unfurl] Pre-fetching ${urls.size} interaction URLs...`);
- await Promise.all([...urls].map((url) => prefetchUrl(url)));
- console.log(`[unfurl] Pre-fetch complete.`);
- });
-
- // Post-build hook: pagefind indexing + WebSub notification
- // Pagefind runs once on the first build (initial or watcher's first full build), then never again.
- // WebSub runs on every non-incremental build.
- // Note: --incremental CLI flag sets incremental=true even for the watcher's first full build,
- // so we cannot use the incremental flag to guard pagefind. Use a one-shot flag instead.
- let pagefindDone = false;
- eleventyConfig.on("eleventy.after", async ({ dir, directories, runMode, incremental }) => {
- // Markdown for Agents — generate index.md alongside index.html for articles
- const mdEnabled = (process.env.MARKDOWN_AGENTS_ENABLED || "true").toLowerCase() === "true";
- if (mdEnabled && !incremental) {
- const outputDir = directories?.output || dir.output;
- const contentDir = resolve(__dirname, "content/articles");
- const aiTrain = process.env.MARKDOWN_AGENTS_AI_TRAIN || "yes";
- const search = process.env.MARKDOWN_AGENTS_SEARCH || "yes";
- const aiInput = process.env.MARKDOWN_AGENTS_AI_INPUT || "yes";
- const authorName = process.env.AUTHOR_NAME || "Blog Author";
- let mdCount = 0;
- try {
- const files = readdirSync(contentDir).filter(f => f.endsWith(".md"));
- for (const file of files) {
- const src = readFileSync(resolve(contentDir, file), "utf-8");
- const { data: fm, content: body } = matter(src);
- if (!fm || fm.draft) continue;
- // Derive the output path from the article's permalink or url
- const articleUrl = fm.permalink || fm.url;
- if (!articleUrl || !articleUrl.startsWith("/articles/")) continue;
- const mdDir = resolve(outputDir, articleUrl.replace(/^\//, "").replace(/\/$/, ""));
- const mdPath = resolve(mdDir, "index.md");
- const trimmedBody = body.trim();
- const tokens = Math.ceil(trimmedBody.length / 4);
- const title = (fm.title || "").replace(/"/g, '\\"');
- const date = fm.date ? new Date(fm.date).toISOString() : fm.published || "";
- let frontLines = [
- "---",
- `title: "${title}"`,
- `date: ${date}`,
- `author: ${authorName}`,
- `url: ${siteUrl}${articleUrl}`,
- ];
- if (fm.category && Array.isArray(fm.category) && fm.category.length > 0) {
- frontLines.push("categories:");
- for (const cat of fm.category) {
- frontLines.push(` - ${cat}`);
- }
- }
- if (fm.description) {
- frontLines.push(`description: "${fm.description.replace(/"/g, '\\"')}"`);
- }
- frontLines.push(`tokens: ${tokens}`);
- frontLines.push(`content_signal: ai-train=${aiTrain}, search=${search}, ai-input=${aiInput}`);
- frontLines.push("---");
- mkdirSync(mdDir, { recursive: true });
- writeFileSync(mdPath, frontLines.join("\n") + "\n\n# " + (fm.title || "") + "\n\n" + trimmedBody + "\n");
- mdCount++;
- }
- console.log(`[markdown-agents] Generated ${mdCount} article .md files`);
- } catch (err) {
- console.error("[markdown-agents] Error generating .md files:", err.message);
- }
- }
-
- // Pagefind indexing — run exactly once per process lifetime
- if (!pagefindDone) {
- pagefindDone = true;
- const outputDir = directories?.output || dir.output;
- try {
- console.log(`[pagefind] Indexing ${outputDir} (${runMode})...`);
- execFileSync("npx", ["pagefind", "--site", outputDir, "--output-subdir", "pagefind", "--glob", "**/*.html"], {
- stdio: "inherit",
- timeout: 120000,
- });
- console.log("[pagefind] Indexing complete");
- } catch (err) {
- console.error("[pagefind] Indexing failed:", err.message);
- }
-
- }
-
- // Syndication webhook — trigger after incremental rebuilds (new posts are now live)
- // Cuts syndication latency from ~2 min (poller) to ~5 sec (immediate trigger)
- if (incremental) {
- const syndicateUrl = process.env.SYNDICATE_WEBHOOK_URL;
- if (syndicateUrl) {
- try {
- const secretFile = process.env.SYNDICATE_SECRET_FILE || "/app/data/config/.secret";
- const secret = readFileSync(secretFile, "utf-8").trim();
-
- // Build a minimal HS256 JWT using built-in crypto (no jsonwebtoken dependency)
- const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
- const now = Math.floor(Date.now() / 1000);
- const payload = Buffer.from(JSON.stringify({
- me: siteUrl,
- scope: "update",
- iat: now,
- exp: now + 300, // 5 minutes
- })).toString("base64url");
- const signature = createHmac("sha256", secret)
- .update(`${header}.${payload}`)
- .digest("base64url");
- const token = `${header}.${payload}.${signature}`;
-
- const res = await fetch(`${syndicateUrl}?token=${token}`, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- signal: AbortSignal.timeout(30000),
- });
- console.log(`[syndicate-hook] Triggered syndication: ${res.status}`);
- } catch (err) {
- console.error(`[syndicate-hook] Failed:`, err.message);
- }
- }
- }
-
- // WebSub hub notification — skip on incremental rebuilds
- if (incremental) return;
- const hubUrl = "https://websubhub.com/hub";
- const feedUrls = [
- `${siteUrl}/`,
- `${siteUrl}/feed.xml`,
- `${siteUrl}/feed.json`,
- ];
-
- // Discover category feed URLs from build output
- const outputDir = directories?.output || dir.output;
- const categoriesDir = resolve(outputDir, "categories");
- try {
- for (const entry of readdirSync(categoriesDir, { withFileTypes: true })) {
- if (entry.isDirectory() && existsSync(resolve(categoriesDir, entry.name, "feed.xml"))) {
- feedUrls.push(`${siteUrl}/categories/${entry.name}/feed.xml`);
- feedUrls.push(`${siteUrl}/categories/${entry.name}/feed.json`);
- }
- }
- } catch {
- // categoriesDir may not exist on first build — ignore
- }
-
- console.log(`[websub] Notifying hub for ${feedUrls.length} URLs...`);
- for (const feedUrl of feedUrls) {
- try {
- const res = await fetch(hubUrl, {
- method: "POST",
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
- body: `hub.mode=publish&hub.url=${encodeURIComponent(feedUrl)}`,
- });
- console.log(`[websub] Notified hub for ${feedUrl}: ${res.status}`);
- } catch (err) {
- console.error(`[websub] Hub notification failed for ${feedUrl}:`, err.message);
- }
- }
- });
-
- return {
- dir: {
- input: ".",
- output: "_site",
- includes: "_includes",
- data: "_data",
- },
- markdownTemplateEngine: false, // Disable to avoid Nunjucks interpreting {{ in content
- htmlTemplateEngine: "njk",
- };
-}
diff --git a/theme/featured.njk b/theme/featured.njk
deleted file mode 100644
index 5e66927..0000000
--- a/theme/featured.njk
+++ /dev/null
@@ -1,186 +0,0 @@
----
-layout: layouts/base.njk
-title: Featured
-withSidebar: true
-pagination:
- data: collections.featuredPosts
- size: 20
- alias: paginatedFeatured
- generatePageOnEmptyData: true
-permalink: "featured/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
----
-
-
-
- Curated posts pinned as featured.
- ({{ collections.featuredPosts.length }} total)
-
-
- {% if paginatedFeatured.length > 0 %}
-
- {% for post in paginatedFeatured %}
- {# Detect post type from frontmatter properties #}
- {% set likedUrl = post.data.likeOf or post.data.like_of %}
- {% set bookmarkedUrl = post.data.bookmarkOf or post.data.bookmark_of %}
- {% set repostedUrl = post.data.repostOf or post.data.repost_of %}
- {% set replyToUrl = post.data.inReplyTo or post.data.in_reply_to %}
- {% set hasPhotos = post.data.photo and post.data.photo.length %}
-
- {# Determine border color by post type #}
- {% if likedUrl %}
- {% set borderClass = "border-l-red-400 dark:border-l-red-500" %}
- {% elif bookmarkedUrl %}
- {% set borderClass = "border-l-amber-400 dark:border-l-amber-500" %}
- {% elif repostedUrl %}
- {% set borderClass = "border-l-green-400 dark:border-l-green-500" %}
- {% elif replyToUrl %}
- {% set borderClass = "border-l-sky-400 dark:border-l-sky-500" %}
- {% elif hasPhotos %}
- {% set borderClass = "border-l-purple-400 dark:border-l-purple-500" %}
- {% else %}
- {% set borderClass = "border-l-surface-300 dark:border-l-surface-600" %}
- {% endif %}
-
-
-
- {% if likedUrl %}
- {# ── Like ── #}
-
- {{ likedUrl }}
- {% if post.templateContent %}
- {{ post.templateContent | safe }}
- {% endif %}
-
- {% elif bookmarkedUrl %}
- {# ── Bookmark ── #}
-
- {% if post.data.title %}
-
- {% endif %}
- {{ bookmarkedUrl }}
- {% if post.templateContent %}
- {{ post.templateContent | safe }}
- {% endif %}
-
- {% elif repostedUrl %}
- {# ── Repost ── #}
-
- {{ repostedUrl }}
- {% if post.templateContent %}
- {{ post.templateContent | safe }}
- {% endif %}
-
- {% elif replyToUrl %}
- {# ── Reply ── #}
-
- {{ replyToUrl }}
- {% if post.templateContent %}
- {{ post.templateContent | safe }}
- {% endif %}
-
- {% elif post.data.title %}
- {# ── Article/Page ── #}
-
-
- {{ post.date | dateDisplay }}
- {% if post.data.postType %}
- {{ post.data.postType }}
- {% endif %}
-
- {% if post.templateContent %}
- {{ post.templateContent | striptags | truncate(250) }}
- {% endif %}
- Read more →
-
- {% else %}
- {# ── Note ── #}
-
- {% if post.templateContent %}
- {{ post.templateContent | safe }}
- {% endif %}
-
- {% endif %}
-
-
- {% endfor %}
-
-
- {# Pagination controls #}
- {% if pagination.pages.length > 1 %}
-
- {% endif %}
-
- {% else %}
- {% set postType = "featured" %}
- {% include "components/empty-collection.njk" %}
- {% endif %}
-
diff --git a/theme/feed-json.njk b/theme/feed-json.njk
deleted file mode 100644
index 77d2291..0000000
--- a/theme/feed-json.njk
+++ /dev/null
@@ -1,67 +0,0 @@
----
-permalink: /feed.json
-eleventyExcludeFromCollections: true
-eleventyImport:
- collections:
- - feed
----
-{
- "version": "https://jsonfeed.org/version/1.1",
- "title": "{{ site.name }}",
- "home_page_url": "{{ site.url }}/",
- "feed_url": "{{ site.url }}/feed.json",
- "hubs": [
- {
- "type": "WebSub",
- "url": "https://websubhub.com/hub"
- }
- ],
- "description": "{{ site.description }}",
- "language": "{{ site.locale | default('en') }}",
- "authors": [
- {
- "name": "{{ site.author.name | default(site.name) }}",
- "url": "{{ site.url }}/"
- }
- ],
- "_textcasting": {
- "version": "1.0",
- "about": "https://textcasting.org/"
- {%- set hasSupport = site.support and (site.support.url or site.support.stripe or site.support.lightning or site.support.paymentPointer) %}
- {%- if hasSupport %},
- "support": {{ site.support | textcastingSupport | jsonEncode | safe }}
- {%- endif %}
- },
- {%- set listedFeedPosts = collections.feed | excludeUnlistedPosts %}
- "items": [
- {%- for post in listedFeedPosts %}
- {%- set absolutePostUrl = site.url + post.url %}
- {%- set postImage = post.data.photo %}
- {%- if postImage %}
- {# If photo is an array, use first element (check if first element looks like a URL) #}
- {%- if postImage[0] and (postImage[0] | length) > 10 %}
- {%- set postImage = postImage[0] %}
- {%- endif %}
- {%- endif %}
- {%- if not postImage or postImage == "" %}
- {%- set postImage = post.data.image or (post.content | extractFirstImage) %}
- {%- endif %}
- {
- "id": "{{ absolutePostUrl }}",
- "url": "{{ absolutePostUrl }}",
- "title": {% if post.data.title %}{{ post.data.title | jsonEncode | safe }}{% else %}null{% endif %},
- "content_html": {{ post.content | htmlToAbsoluteUrls(absolutePostUrl) | jsonEncode | safe }},
- "content_text": {{ post.content | striptags | jsonEncode | safe }},
- "date_published": "{{ post.date | dateToRfc3339 }}",
- "date_modified": "{{ (post.data.updated or post.date) | dateToRfc3339 }}"
- {%- if postImage and postImage != "" and (postImage | length) > 10 %},
- "image": "{{ postImage | url | absoluteUrl(site.url) }}"
- {%- endif %}
- {%- set attachments = post.data | feedAttachments %}
- {%- if attachments.length > 0 %},
- "attachments": {{ attachments | jsonEncode | safe }}
- {%- endif %}
- }{% if not loop.last %},{% endif %}
- {%- endfor %}
- ]
-}
diff --git a/theme/feed.njk b/theme/feed.njk
deleted file mode 100644
index ef53fd0..0000000
--- a/theme/feed.njk
+++ /dev/null
@@ -1,47 +0,0 @@
----
-permalink: /feed.xml
-eleventyExcludeFromCollections: true
-eleventyImport:
- collections:
- - feed
----
-
-
-
- {{ site.name }}
- {{ site.url }}/
- {{ site.description }}
- {{ site.locale | default('en') }}
-
-
- {%- set listedFeedPosts = collections.feed | excludeUnlistedPosts %}
- {%- if listedFeedPosts.length %}
- {{ listedFeedPosts | getNewestCollectionItemDate | dateToRfc822 }}
- {%- endif %}
- {%- for post in listedFeedPosts %}
- {%- set absolutePostUrl = site.url + post.url %}
- {%- set postImage = post.data.photo %}
- {%- if postImage %}
- {# If photo is an array, use first element (check if first element looks like a URL) #}
- {%- if postImage[0] and (postImage[0] | length) > 10 %}
- {%- set postImage = postImage[0] %}
- {%- endif %}
- {%- endif %}
- {%- if not postImage or postImage == "" %}
- {%- set postImage = post.data.image or (post.content | extractFirstImage) %}
- {%- endif %}
- -
-
{{ post.data.title | default(post.content | striptags | truncate(80)) | escape }}
- {{ absolutePostUrl }}
- {{ absolutePostUrl }}
- {{ post.date | dateToRfc822 }}
- {{ post.content | htmlToAbsoluteUrls(absolutePostUrl) | escape }}
- {%- if postImage and postImage != "" and (postImage | length) > 10 %}
- {%- set imageUrl = postImage | url | absoluteUrl(site.url) %}
-
-
- {%- endif %}
-
- {%- endfor %}
-
-
diff --git a/theme/funkwhale.njk b/theme/funkwhale.njk
deleted file mode 100644
index 8694d8f..0000000
--- a/theme/funkwhale.njk
+++ /dev/null
@@ -1,269 +0,0 @@
----
-layout: layouts/base.njk
-title: Funkwhale Listening Activity
-permalink: /funkwhale/
-withSidebar: true
----
-
-
-
- {# Now Playing / Recently Played Hero #}
- {% if funkwhaleActivity.nowPlaying and funkwhaleActivity.nowPlaying.status %}
-
-
-
- {% if funkwhaleActivity.nowPlaying.coverUrl %}
-
- {% else %}
-
- {% endif %}
-
-
-
- {% if funkwhaleActivity.nowPlaying.status == 'now-playing' %}
-
-
-
-
-
-
- Now Playing
-
- {% else %}
-
-
- Recently Played
-
- {% endif %}
-
-
-
- {% if funkwhaleActivity.nowPlaying.trackUrl %}
-
- {{ funkwhaleActivity.nowPlaying.track }}
-
- {% else %}
- {{ funkwhaleActivity.nowPlaying.track }}
- {% endif %}
-
-
{{ funkwhaleActivity.nowPlaying.artist }}
- {% if funkwhaleActivity.nowPlaying.album %}
-
{{ funkwhaleActivity.nowPlaying.album }}
- {% endif %}
-
{{ funkwhaleActivity.nowPlaying.relativeTime }}
-
-
-
-
- {% endif %}
-
- {# Stats Section with Tabs #}
- {% if funkwhaleActivity.stats %}
-
-
-
-
-
- Listening Statistics
-
-
- {# Tab buttons #}
-
-
- All Time
-
-
- This Month
-
-
- This Week
-
-
- Trends
-
-
-
- {# All Time Tab #}
-
- {% set summary = funkwhaleActivity.stats.summary.all %}
- {% set topArtists = funkwhaleActivity.stats.topArtists.all %}
- {% set topAlbums = funkwhaleActivity.stats.topAlbums.all %}
- {% include "components/funkwhale-stats-content.njk" %}
-
-
- {# This Month Tab #}
-
- {% set summary = funkwhaleActivity.stats.summary.month %}
- {% set topArtists = funkwhaleActivity.stats.topArtists.month %}
- {% set topAlbums = funkwhaleActivity.stats.topAlbums.month %}
- {% include "components/funkwhale-stats-content.njk" %}
-
-
- {# This Week Tab #}
-
- {% set summary = funkwhaleActivity.stats.summary.week %}
- {% set topArtists = funkwhaleActivity.stats.topArtists.week %}
- {% set topAlbums = funkwhaleActivity.stats.topAlbums.week %}
- {% include "components/funkwhale-stats-content.njk" %}
-
-
- {# Trends Tab #}
-
- {% if funkwhaleActivity.stats.trends and funkwhaleActivity.stats.trends.length %}
-
-
Daily Listening (Last 30 Days)
-
- {% set maxCount = 1 %}
- {% for day in funkwhaleActivity.stats.trends %}
- {% if day.count > maxCount %}
- {% set maxCount = day.count %}
- {% endif %}
- {% endfor %}
- {% for day in funkwhaleActivity.stats.trends %}
-
- {% endfor %}
-
-
- {{ funkwhaleActivity.stats.trends[0].date }}
- {{ funkwhaleActivity.stats.trends[funkwhaleActivity.stats.trends.length - 1].date }}
-
-
- {% else %}
-
No trend data available yet.
- {% endif %}
-
-
- {% endif %}
-
- {# Recent Listenings #}
-
-
-
-
-
- Recent Listens
-
-
- {% if funkwhaleActivity.listenings.length %}
-
- {% for listening in funkwhaleActivity.listenings | head(15) %}
-
- {% if listening.coverUrl %}
-
- {% else %}
-
- {% endif %}
-
-
-
- {% if listening.trackUrl %}
-
- {{ listening.track }}
-
- {% else %}
- {{ listening.track }}
- {% endif %}
-
-
{{ listening.artist }}
-
-
-
- {{ listening.relativeTime }}
- {% if listening.duration %}
- {{ listening.duration }}
- {% endif %}
-
-
- {% endfor %}
-
- {% else %}
- No recent listening history available.
- {% endif %}
-
-
- {# Favorites #}
- {% if funkwhaleActivity.favorites.length %}
-
-
-
-
-
- Favorite Tracks
-
-
-
- {% for favorite in funkwhaleActivity.favorites | head(10) %}
-
- {% if favorite.coverUrl %}
-
- {% else %}
-
- {% endif %}
-
-
-
- {% if favorite.trackUrl %}
-
- {{ favorite.track }}
-
- {% else %}
- {{ favorite.track }}
- {% endif %}
-
-
{{ favorite.artist }}
- {% if favorite.album %}
-
{{ favorite.album }}
- {% endif %}
-
-
- {% endfor %}
-
-
- {% endif %}
-
diff --git a/theme/github.njk b/theme/github.njk
deleted file mode 100644
index 48cdd64..0000000
--- a/theme/github.njk
+++ /dev/null
@@ -1,270 +0,0 @@
----
-layout: layouts/base.njk
-title: GitHub Activity
-permalink: /github/
-withSidebar: true
----
-
-
-
- {# Featured Projects Section #}
- {% if githubActivity.featured.length %}
-
-
-
-
-
- Featured Projects
-
-
-
- {% for repo in githubActivity.featured %}
-
-
-
- {% if repo.isPrivate %}
-
Private
- {% endif %}
-
-
- {% if repo.description %}
- {{ repo.description }}
- {% endif %}
-
-
- {% if repo.language %}
-
-
- {{ repo.language }}
-
- {% endif %}
-
-
-
-
- {{ repo.stars }}
-
- {% if repo.forks > 0 %}
-
-
-
-
- {{ repo.forks }}
-
- {% endif %}
-
-
- {% if repo.commits and repo.commits.length %}
-
-
- Recent commits ({{ repo.commits.length }})
-
-
- {% for commit in repo.commits %}
-
-
- {{ commit.sha }}
-
- {{ commit.message }}
-
- {% endfor %}
-
-
- {% endif %}
-
- {% endfor %}
-
-
- {% endif %}
-
- {# Recent Commits Section #}
-
-
-
-
-
- Recent Commits
-
-
- {% if githubActivity.commits.length %}
-
- {% for commit in githubActivity.commits %}
-
-
- {{ commit.sha }}
-
-
-
- {% endfor %}
-
- {% else %}
- No recent commits found.
- {% endif %}
-
-
- {# Contributions Section (PRs & Issues) #}
- {% if githubActivity.contributions.length %}
-
-
-
-
-
- Pull Requests & Issues
-
-
-
- {% for item in githubActivity.contributions %}
-
- {% if item.type == "pr" %}
-
PR
- {% else %}
-
Issue
- {% endif %}
-
-
- {% endfor %}
-
-
- {% endif %}
-
- {# My Repositories Section #}
-
-
-
-
-
- My Repositories
-
-
- {% if githubRepos.length %}
-
- {% for repo in githubRepos | head(6) %}
-
-
-
- {% if repo.description %}
- {{ repo.description | truncate(100) }}
- {% endif %}
-
-
- {% if repo.language %}
-
-
- {{ repo.language }}
-
- {% endif %}
-
-
-
-
- {{ repo.stargazers_count }}
-
-
-
-
-
- {{ repo.forks_count }}
-
-
-
- {% endfor %}
-
-
-
- View all repositories →
-
- {% else %}
- No repositories found.
- {% endif %}
-
-
- {# Starred Repos Section #}
-
-
-
-
-
- Starred Repositories
-
-
- {% if githubActivity.stars.length %}
-
- {% for repo in githubActivity.stars | head(10) %}
-
-
-
- {% if repo.description %}
- {{ repo.description }}
- {% endif %}
-
-
- {% for topic in repo.topics %}
-
- {{ topic }}
-
- {% endfor %}
-
-
-
- {% if repo.language %}
-
-
- {{ repo.language }}
-
- {% endif %}
-
-
-
-
- {{ repo.stars }}
-
-
-
- {% endfor %}
-
-
-
- View all {{ githubStarred.totalCount | default(githubActivity.stars | length) }} starred repos →
-
- {% else %}
- No starred repositories found.
- {% endif %}
-
-
diff --git a/theme/graph.njk b/theme/graph.njk
deleted file mode 100644
index e6ef5e6..0000000
--- a/theme/graph.njk
+++ /dev/null
@@ -1,18 +0,0 @@
----
-layout: layouts/base.njk
-title: Posting Activity
-permalink: /graph/
-withSidebar: true
----
-
-Posting Activity
-
-
- A contribution-style graph showing posting frequency across all years.
-
-
-{% if collections.posts and collections.posts.length %}
- {% postGraph collections.posts, { limit: 0 } %}
-{% else %}
- No posts found.
-{% endif %}
diff --git a/theme/images/default-avatar.svg b/theme/images/default-avatar.svg
deleted file mode 100644
index 3b15f50..0000000
--- a/theme/images/default-avatar.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/theme/images/favicon.svg b/theme/images/favicon.svg
deleted file mode 100644
index c15703d..0000000
--- a/theme/images/favicon.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- i
-
diff --git a/theme/images/og-default.png b/theme/images/og-default.png
deleted file mode 100644
index bfaee94..0000000
Binary files a/theme/images/og-default.png and /dev/null differ
diff --git a/theme/images/rick.jpg b/theme/images/rick.jpg
deleted file mode 100644
index f976d6d..0000000
Binary files a/theme/images/rick.jpg and /dev/null differ
diff --git a/theme/index.njk b/theme/index.njk
deleted file mode 100644
index 9d2a090..0000000
--- a/theme/index.njk
+++ /dev/null
@@ -1,8 +0,0 @@
----
-layout: layouts/home.njk
-title: Home
-eleventyImport:
- collections:
- - posts
- - feed
----
diff --git a/theme/interactions.njk b/theme/interactions.njk
deleted file mode 100644
index 206a600..0000000
--- a/theme/interactions.njk
+++ /dev/null
@@ -1,533 +0,0 @@
----
-layout: layouts/base.njk
-title: Interactions
-permalink: /interactions/
----
-
-
-
-
-
The inbound webmentions tab requires JavaScript to load data from the API. Enable JavaScript for the full interactive experience. Outbound interactions are shown below.
-
-
-
-{# Tab navigation for Outbound/Inbound #}
-
- {# Tab buttons #}
-
-
- My Activity
- (outbound)
-
-
- Received
- (inbound)
-
-
-
-
- {# ===== OUTBOUND TAB - My Activity ===== #}
-
-
Content I've interacted with across the web.
-
-
-
-
-
About IndieWeb Interactions
-
- These pages show different types of IndieWeb interactions I've made. Each type uses specific microformat properties
- to indicate the relationship to the original content.
-
-
- Likes use u-like-of
- Replies use u-in-reply-to
- Bookmarks use u-bookmark-of
- Reposts use u-repost-of
-
-
-
-
- {# ===== INBOUND TAB - Received Webmentions ===== #}
-
-
-
Webmentions and interactions others have made with my content.
-
-
-
-
-
-
-
-
- {# Loading state #}
-
-
-
Loading webmentions...
-
-
- {# Setup required state — shown when webmentions proxy is not configured #}
-
-
Webmentions Not Configured
-
- To receive inbound webmentions, you need to set up the webmentions proxy plugin
- (@rmdes/indiekit-endpoint-webmentions-proxy).
-
-
- Register your domain at webmention.io and get your API token
- Set the WEBMENTION_IO_TOKEN environment variable
- Ensure the webmentions proxy plugin is installed and configured in your Indiekit config
- Restart Indiekit to apply the changes
-
-
-
- {# Error state — only shown for real errors, not missing config #}
-
-
- {# Filter by type #}
-
-
- All
-
-
- ❤️ Likes
-
-
- 🔄 Reposts
-
-
- 💬 Replies
-
-
- 📣 Mentions
-
-
-
- {# Webmentions list #}
-
-
-
-
- {# Author avatar #}
-
-
-
-
-
- {# Header with author, type badge, and date #}
-
-
-
- {# Type badge #}
-
- ❤️ liked
-
-
- 🔄 reposted
-
-
- 💬 replied
-
-
- 📣 mentioned
-
-
- 🔖 bookmarked
-
-
- {# Platform badge (from conversations API) #}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {# Content (for replies) #}
-
-
- {# Target URL - which of my posts this is about #}
-
-
-
-
-
-
- {# Empty state #}
-
-
No webmentions found for this filter.
-
-
- {# Pagination / Load more #}
-
-
-
-
-
-
-
- {# Info box #}
-
-
About Webmentions
-
- Webmentions are a W3C standard for cross-site communication. When someone likes, reposts, or replies to my content
- from their own site (or via Bluesky/Mastodon bridges), I receive a webmention notification.
-
-
- Likes - Someone appreciated this post
- Reposts - Someone shared this post
- Replies - Someone responded to this post
- Mentions - Someone linked to this post
-
-
-
-
-
-
diff --git a/theme/interactive/architecture.html b/theme/interactive/architecture.html
deleted file mode 100644
index b029d63..0000000
--- a/theme/interactive/architecture.html
+++ /dev/null
@@ -1,1162 +0,0 @@
-
-
-
-
-
-Indiekit Architecture Guide
-
-
-
-
-
- Indiekit
-
-
-
-
-
-
-
diff --git a/theme/js/admin.js b/theme/js/admin.js
deleted file mode 100644
index 66b11ec..0000000
--- a/theme/js/admin.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * Admin UI auth detection
- * Checks if the user is logged in to Indiekit by probing /session/login.
- * Dispatches a custom event for Alpine.js components to react to.
- */
-
-(function () {
- const cacheKey = 'indiekit-auth-status';
- const cacheTTL = 5 * 60 * 1000; // 5 minutes
-
- function getCachedStatus() {
- try {
- const cached = sessionStorage.getItem(cacheKey);
- if (!cached) return null;
- const parsed = JSON.parse(cached);
- if (Date.now() - parsed.ts > cacheTTL) {
- sessionStorage.removeItem(cacheKey);
- return null;
- }
- return parsed.loggedIn;
- } catch {
- return null;
- }
- }
-
- function setCachedStatus(loggedIn) {
- try {
- sessionStorage.setItem(cacheKey, JSON.stringify({ ts: Date.now(), loggedIn: loggedIn }));
- } catch {
- // sessionStorage full or unavailable
- }
- }
-
- function dispatch(loggedIn) {
- window.dispatchEvent(new CustomEvent('indiekit:auth', { detail: { loggedIn: loggedIn } }));
- if (loggedIn) {
- document.body.setAttribute('data-indiekit-auth', 'true');
- } else {
- document.body.removeAttribute('data-indiekit-auth');
- }
- }
-
- function checkAuth() {
- return fetch('/session/login', { credentials: 'same-origin', redirect: 'manual', cache: 'no-store' })
- .then(function (response) {
- // opaqueredirect means 302 → user is logged in
- return response.type === 'opaqueredirect';
- })
- .catch(function () {
- return false;
- });
- }
-
- // Cache-then-verify: show from cache instantly, correct in background
- var cached = getCachedStatus();
- if (cached !== null) {
- dispatch(cached);
- }
-
- checkAuth().then(function (loggedIn) {
- setCachedStatus(loggedIn);
- // Only re-dispatch if different from cache or no cache existed
- if (cached === null || cached !== loggedIn) {
- dispatch(loggedIn);
- }
- });
-})();
diff --git a/theme/js/comments.js b/theme/js/comments.js
deleted file mode 100644
index 11219e4..0000000
--- a/theme/js/comments.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * Client-side comments component (Alpine.js)
- * Handles IndieAuth flow, comment submission, and display
- *
- * Registered via Alpine.data() so the component is available
- * regardless of script loading order.
- */
-
-document.addEventListener("alpine:init", () => {
- Alpine.data("commentsSection", (targetUrl) => ({
- targetUrl,
- user: null,
- meUrl: "",
- commentText: "",
- comments: [],
- loading: true,
- authLoading: false,
- submitting: false,
- statusMessage: "",
- statusType: "info",
- maxLength: 2000,
- showForm: false,
-
- async init() {
- await this.checkSession();
- await this.loadComments();
- this.handleAuthReturn();
- },
-
- async checkSession() {
- try {
- const res = await fetch("/comments/api/session", {
- credentials: "include",
- });
- if (res.ok) {
- const data = await res.json();
- if (data.user) this.user = data.user;
- }
- } catch {
- // No session
- }
- },
-
- handleAuthReturn() {
- const params = new URLSearchParams(window.location.search);
- const authError = params.get("auth_error");
- if (authError) {
- this.showStatus(`Authentication failed: ${authError}`, "error");
- window.history.replaceState(
- {},
- "",
- window.location.pathname + "#comments",
- );
- }
- },
-
- async loadComments() {
- this.loading = true;
- try {
- const url = `/comments/api/comments?target=${encodeURIComponent(this.targetUrl)}`;
- const res = await fetch(url);
- if (res.ok) {
- const data = await res.json();
- this.comments = data.children || [];
- }
- } catch (e) {
- console.error("[Comments] Load error:", e);
- } finally {
- this.loading = false;
- }
- },
-
- async startAuth() {
- this.authLoading = true;
- try {
- const res = await fetch("/comments/api/auth", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({
- me: this.meUrl,
- returnUrl: window.location.pathname + "#comments",
- }),
- credentials: "include",
- });
-
- if (!res.ok) {
- const data = await res.json();
- this.showStatus(data.error || "Auth failed", "error");
- return;
- }
-
- const data = await res.json();
- if (data.authUrl) {
- window.location.href = data.authUrl;
- }
- } catch {
- this.showStatus("Failed to start authentication", "error");
- } finally {
- this.authLoading = false;
- }
- },
-
- async submitComment() {
- if (!this.commentText.trim()) return;
- this.submitting = true;
-
- try {
- const res = await fetch("/comments/api/submit", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({
- content: this.commentText,
- target: this.targetUrl,
- }),
- credentials: "include",
- });
-
- if (res.ok) {
- const data = await res.json();
- if (data.comment) {
- this.comments.unshift(data.comment);
- }
- this.commentText = "";
- this.showStatus("Comment posted!", "success");
- } else {
- const data = await res.json();
- this.showStatus(data.error || "Failed to post", "error");
- }
- } catch {
- this.showStatus("Error posting comment", "error");
- } finally {
- this.submitting = false;
- }
- },
-
- signOut() {
- document.cookie =
- "comment_session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
- this.user = null;
- this.showStatus("Signed out", "info");
- },
-
- showStatus(message, type = "info") {
- this.statusMessage = message;
- this.statusType = type;
- setTimeout(() => {
- this.statusMessage = "";
- }, 5000);
- },
- }));
-});
diff --git a/theme/js/fediverse-interact.js b/theme/js/fediverse-interact.js
deleted file mode 100644
index 82e3ef7..0000000
--- a/theme/js/fediverse-interact.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * Fediverse interaction & sharing component (Alpine.js)
- *
- * Two modes:
- * - "interact" (default): redirect to authorize_interaction for like/boost/reply/follow
- * - "share": redirect to /share?text=... for composing a new post
- *
- * Stores multiple domains in localStorage with usage tracking.
- * Registered via Alpine.data() so the component is available
- * regardless of script loading order.
- */
-
-const STORAGE_KEY = "fediverse_domains_v1";
-const OLD_STORAGE_KEY = "fediverse_instance";
-
-function loadDomains() {
- try {
- const json = localStorage.getItem(STORAGE_KEY);
- if (json) return JSON.parse(json);
- } catch { /* corrupted data */ }
-
- // Migrate from old single-domain key
- const old = localStorage.getItem(OLD_STORAGE_KEY);
- if (old) {
- const domains = [{ domain: old, used: 1, lastUsed: new Date().toISOString() }];
- localStorage.setItem(STORAGE_KEY, JSON.stringify(domains));
- localStorage.removeItem(OLD_STORAGE_KEY);
- return domains;
- }
-
- return [];
-}
-
-function saveDomains(domains) {
- localStorage.setItem(STORAGE_KEY, JSON.stringify(domains));
-}
-
-function addDomain(domain) {
- const domains = loadDomains();
- const existing = domains.find((d) => d.domain === domain);
- if (existing) {
- existing.used += 1;
- existing.lastUsed = new Date().toISOString();
- } else {
- domains.push({ domain, used: 1, lastUsed: new Date().toISOString() });
- }
- saveDomains(domains);
- return domains;
-}
-
-function removeDomain(domain) {
- const domains = loadDomains().filter((d) => d.domain !== domain);
- saveDomains(domains);
- return domains;
-}
-
-function isValidDomain(str) {
- try {
- return new URL(`https://${str}`).hostname === str;
- } catch {
- return false;
- }
-}
-
-document.addEventListener("alpine:init", () => {
- Alpine.data("fediverseInteract", (targetUrl, mode) => ({
- targetUrl,
- mode: mode || "interact",
- showModal: false,
- instance: "",
- savedDomains: [],
- showInput: false,
- error: "",
-
- handleClick(event) {
- event.preventDefault();
- this.savedDomains = loadDomains().sort((a, b) => b.used - a.used);
-
- if (this.savedDomains.length === 1 && !event.shiftKey) {
- addDomain(this.savedDomains[0].domain);
- this.redirectToInstance(this.savedDomains[0].domain);
- return;
- }
-
- if (this.savedDomains.length === 0) {
- this.showInput = true;
- } else {
- this.showInput = false;
- }
-
- this.instance = "";
- this.error = "";
- this.showModal = true;
- },
-
- showAddNew() {
- this.showInput = true;
- this.instance = "";
- this.error = "";
- this.$nextTick(() => {
- const input = this.$refs.instanceInput;
- if (input) input.focus();
- });
- },
-
- confirm() {
- let domain = this.instance.trim();
- if (!domain) return;
- // Strip protocol and trailing slashes
- domain = domain.replace(/^https?:\/\//, "").replace(/\/+$/, "");
-
- if (!isValidDomain(domain)) {
- this.error = "Please enter a valid domain (e.g. mastodon.social)";
- return;
- }
-
- this.error = "";
- this.savedDomains = addDomain(domain);
- this.showModal = false;
- this.redirectToInstance(domain);
- },
-
- useSaved(domain) {
- this.savedDomains = addDomain(domain);
- this.showModal = false;
- this.redirectToInstance(domain);
- },
-
- deleteSaved(domain) {
- this.savedDomains = removeDomain(domain);
- if (this.savedDomains.length === 0) {
- this.showInput = true;
- }
- },
-
- redirectToInstance(domain) {
- if (this.mode === "share") {
- window.location.href = `https://${domain}/share?text=${encodeURIComponent(this.targetUrl)}`;
- } else {
- window.location.href = `https://${domain}/authorize_interaction?uri=${encodeURIComponent(this.targetUrl)}`;
- }
- },
- }));
-});
diff --git a/theme/js/lightbox.js b/theme/js/lightbox.js
deleted file mode 100644
index 07e440b..0000000
--- a/theme/js/lightbox.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Alpine.js lightbox component for article images.
- * Registers via alpine:init so it's available before Alpine starts.
- * Click any image inside .e-content to view fullscreen.
- * Navigate with arrow keys, close with Escape or click outside.
- */
-document.addEventListener("alpine:init", () => {
- Alpine.data("lightbox", () => ({
- open: false,
- src: "",
- alt: "",
- images: [],
- currentIndex: 0,
-
- init() {
- const container = this.$root;
- const imgs = container.querySelectorAll(
- ".e-content img:not(.u-photo), .photo-gallery img.u-photo"
- );
- this.images = Array.from(imgs);
-
- this.images.forEach((img, i) => {
- img.style.cursor = "zoom-in";
- img.addEventListener("click", (e) => {
- e.preventDefault();
- this.show(i);
- });
- });
- },
-
- show(index) {
- this.currentIndex = index;
- const img = this.images[index];
- // Use the largest source available
- const picture = img.closest("picture");
- if (picture) {
- const source = picture.querySelector("source");
- if (source) {
- // Extract the URL from srcset (strip width descriptor)
- const srcset = source.getAttribute("srcset") || "";
- this.src = srcset.split(/\s+/)[0] || img.src;
- } else {
- this.src = img.src;
- }
- } else {
- this.src = img.src;
- }
- this.alt = img.alt || "";
- this.open = true;
- document.body.style.overflow = "hidden";
- },
-
- close() {
- this.open = false;
- this.src = "";
- document.body.style.overflow = "";
- },
-
- next() {
- if (this.images.length > 1) {
- this.show((this.currentIndex + 1) % this.images.length);
- }
- },
-
- prev() {
- if (this.images.length > 1) {
- this.show(
- (this.currentIndex - 1 + this.images.length) % this.images.length
- );
- }
- },
-
- onKeydown(e) {
- if (!this.open) return;
- if (e.key === "Escape") this.close();
- if (e.key === "ArrowRight") this.next();
- if (e.key === "ArrowLeft") this.prev();
- },
- }));
-});
diff --git a/theme/js/save-later.js b/theme/js/save-later.js
deleted file mode 100644
index eff4f33..0000000
--- a/theme/js/save-later.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Save for Later — shared frontend module
- * Handles save button clicks on blogroll, podroll, listening, and news pages.
- * Only active when user is logged in (body[data-indiekit-auth="true"]).
- */
-(function () {
- function isLoggedIn() {
- return document.body.getAttribute('data-indiekit-auth') === 'true';
- }
-
- async function saveForLater(button) {
- var url = button.dataset.saveUrl;
- var title = button.dataset.saveTitle || url;
- var source = button.dataset.saveSource || 'manual';
- if (!url) return;
-
- button.disabled = true;
-
- try {
- var response = await fetch('/readlater/save', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ url: url, title: title, source: source }),
- credentials: 'same-origin'
- });
-
- if (response.ok) {
- button.classList.add('save-later--saved');
- button.title = 'Saved';
- button.setAttribute('aria-label', 'Saved');
- var label = button.querySelector('.save-later-label');
- if (label) label.textContent = 'Saved';
- var icon = button.querySelector('.save-later-icon');
- if (icon) icon.textContent = '🔖';
- } else {
- button.disabled = false;
- }
- } catch (e) {
- button.disabled = false;
- }
- }
-
- document.addEventListener('click', function (e) {
- if (!isLoggedIn()) return;
- var button = e.target.closest('.save-later-btn');
- if (button) {
- e.preventDefault();
- saveForLater(button);
- }
- });
-})();
diff --git a/theme/js/share-post.js b/theme/js/share-post.js
deleted file mode 100644
index 9165613..0000000
--- a/theme/js/share-post.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Share Post — frontend module
- * Opens the Indiekit post creation form in a popup window.
- * Provides a dropdown menu with post type choices.
- * Only active when user is logged in (body[data-indiekit-auth="true"]).
- */
-(function () {
- var POST_TYPES = [
- { value: 'note', label: 'Note' },
- { value: 'bookmark', label: 'Bookmark' },
- { value: 'reply', label: 'Reply' },
- { value: 'like', label: 'Like' },
- { value: 'repost', label: 'Repost' },
- { value: 'article', label: 'Article' }
- ];
-
- function isLoggedIn() {
- return document.body.getAttribute('data-indiekit-auth') === 'true';
- }
-
- function openPostPopup(type, url, title) {
- var createUrl = '/posts/create'
- + '?type=' + encodeURIComponent(type)
- + '&url=' + encodeURIComponent(url)
- + '&name=' + encodeURIComponent(title);
-
- window.open(
- createUrl,
- 'PostCreator',
- 'resizable,scrollbars,status=0,toolbar=0,menubar=0,titlebar=0,width=620,height=780,location=0'
- );
- }
-
- function createDropdown(button) {
- if (button.querySelector('.post-type-dropdown')) return;
-
- var url = button.dataset.shareUrl;
- var title = button.dataset.shareTitle || '';
-
- var dropdown = document.createElement('div');
- dropdown.className = 'post-type-dropdown';
-
- POST_TYPES.forEach(function (pt) {
- var item = document.createElement('button');
- item.type = 'button';
- item.className = 'post-type-dropdown-item';
- item.textContent = pt.label;
- item.addEventListener('click', function (e) {
- e.stopPropagation();
- openPostPopup(pt.value, url, title);
- closeAllDropdowns();
- });
- dropdown.appendChild(item);
- });
-
- button.style.position = 'relative';
- button.appendChild(dropdown);
- }
-
- function closeAllDropdowns() {
- document.querySelectorAll('.post-type-dropdown.open').forEach(function (d) {
- d.classList.remove('open');
- });
- }
-
- document.addEventListener('click', function (e) {
- if (!isLoggedIn()) return;
-
- var button = e.target.closest('.share-post-btn');
- if (button) {
- e.preventDefault();
- e.stopPropagation();
- createDropdown(button);
- var dropdown = button.querySelector('.post-type-dropdown');
- var wasOpen = dropdown.classList.contains('open');
- closeAllDropdowns();
- if (!wasOpen) {
- dropdown.classList.add('open');
- }
- return;
- }
-
- // Click outside closes dropdowns
- closeAllDropdowns();
- });
-})();
diff --git a/theme/js/time-difference.js b/theme/js/time-difference.js
deleted file mode 100644
index 792de54..0000000
--- a/theme/js/time-difference.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Web Component
- * Progressively enhances elements with relative date display.
- * Falls back to static date text when JS is unavailable.
- *
- * Usage: February 15, 2026
- *
- * Inspired by zachleat.com's time-difference component.
- */
-class TimeDifference extends HTMLElement {
- static register(tagName = "time-difference") {
- if ("customElements" in window) {
- customElements.define(tagName, TimeDifference);
- }
- }
-
- connectedCallback() {
- this.update();
- // Auto-update every 60 seconds
- this._interval = setInterval(() => this.update(), 60000);
- }
-
- disconnectedCallback() {
- clearInterval(this._interval);
- }
-
- update() {
- const time = this.querySelector("time[datetime]");
- if (!time) return;
-
- const datetime = time.getAttribute("datetime");
- if (!datetime) return;
-
- const date = new Date(datetime);
- if (isNaN(date.getTime())) return;
-
- const now = new Date();
- const diffMs = now - date;
-
- // Don't show relative time for future dates
- if (diffMs < 0) return;
-
- const diffSec = Math.floor(diffMs / 1000);
- const diffMin = Math.floor(diffSec / 60);
- const diffHour = Math.floor(diffMin / 60);
- const diffDay = Math.floor(diffHour / 24);
- const diffWeek = Math.floor(diffDay / 7);
- const diffMonth = Math.floor(diffDay / 30.44);
- const diffYear = Math.floor(diffDay / 365.25);
-
- let value, unit;
-
- if (diffSec < 60) {
- value = -diffSec;
- unit = "second";
- } else if (diffMin < 60) {
- value = -diffMin;
- unit = "minute";
- } else if (diffHour < 24) {
- value = -diffHour;
- unit = "hour";
- } else if (diffDay < 7) {
- value = -diffDay;
- unit = "day";
- } else if (diffWeek < 4) {
- value = -diffWeek;
- unit = "week";
- } else if (diffMonth < 12) {
- value = -diffMonth;
- unit = "month";
- } else {
- value = -diffYear;
- unit = "year";
- }
-
- try {
- const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
- const relative = rtf.format(value, unit);
-
- // Store original text as title for hover tooltip
- if (!time.hasAttribute("title")) {
- time.setAttribute("title", time.textContent.trim());
- }
- time.textContent = relative;
- } catch {
- // Intl.RelativeTimeFormat not supported, keep static text
- }
- }
-}
-
-TimeDifference.register();
diff --git a/theme/js/vendor/alpine-collapse.min.js b/theme/js/vendor/alpine-collapse.min.js
deleted file mode 100644
index a865343..0000000
--- a/theme/js/vendor/alpine-collapse.min.js
+++ /dev/null
@@ -1 +0,0 @@
-(()=>{function g(n){n.directive("collapse",e),e.inline=(t,{modifiers:i})=>{i.includes("min")&&(t._x_doShow=()=>{},t._x_doHide=()=>{})};function e(t,{modifiers:i}){let r=l(i,"duration",250)/1e3,h=l(i,"min",0),u=!i.includes("min");t._x_isShown||(t.style.height=`${h}px`),!t._x_isShown&&u&&(t.hidden=!0),t._x_isShown||(t.style.overflow="hidden");let c=(d,s)=>{let o=n.setStyles(d,s);return s.height?()=>{}:o},f={transitionProperty:"height",transitionDuration:`${r}s`,transitionTimingFunction:"cubic-bezier(0.4, 0.0, 0.2, 1)"};t._x_transition={in(d=()=>{},s=()=>{}){u&&(t.hidden=!1),u&&(t.style.display=null);let o=t.getBoundingClientRect().height;t.style.height="auto";let a=t.getBoundingClientRect().height;o===a&&(o=h),n.transition(t,n.setStyles,{during:f,start:{height:o+"px"},end:{height:a+"px"}},()=>t._x_isShown=!0,()=>{Math.abs(t.getBoundingClientRect().height-a)<1&&(t.style.overflow=null)})},out(d=()=>{},s=()=>{}){let o=t.getBoundingClientRect().height;n.transition(t,c,{during:f,start:{height:o+"px"},end:{height:h+"px"}},()=>t.style.overflow="hidden",()=>{t._x_isShown=!1,t.style.height==`${h}px`&&u&&(t.style.display="none",t.hidden=!0)})}}}}function l(n,e,t){if(n.indexOf(e)===-1)return t;let i=n[n.indexOf(e)+1];if(!i)return t;if(e==="duration"){let r=i.match(/([0-9]+)ms/);if(r)return r[1]}if(e==="min"){let r=i.match(/([0-9]+)px/);if(r)return r[1]}return i}document.addEventListener("alpine:init",()=>{window.Alpine.plugin(g)});})();
diff --git a/theme/js/vendor/alpine.min.js b/theme/js/vendor/alpine.min.js
deleted file mode 100644
index 8e339a2..0000000
--- a/theme/js/vendor/alpine.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-(()=>{var ie=!1,oe=!1,Y=[],se=-1,ae=!1;function We(t){Bn(t)}function Ge(){ae=!0}function Je(){ae=!1,Xe()}function Bn(t){Y.includes(t)||Y.push(t),Xe()}function Ye(t){let e=Y.indexOf(t);e!==-1&&e>se&&Y.splice(e,1)}function Xe(){if(!oe&&!ie){if(ae)return;ie=!0,queueMicrotask(zn)}}function zn(){ie=!1,oe=!0;for(let t=0;tt.effect(e,{scheduler:r=>{ce?We(r):r()}}),le=t.raw}function ue(t){D=t}function tr(t){let e=()=>{};return[n=>{let i=D(n);return t._x_effects||(t._x_effects=new Set,t._x_runEffects=()=>{t._x_effects.forEach(o=>o())}),t._x_effects.add(i),e=()=>{i!==void 0&&(t._x_effects.delete(i),z(i))},i},()=>{e()}]}function Ot(t,e){let r=!0,n,i=D(()=>{let o=t();if(JSON.stringify(o),!r&&(typeof o=="object"||o!==n)){let s=n;queueMicrotask(()=>{e(o,s)})}n=o,r=!1});return()=>z(i)}async function er(t){Ge();try{await t(),await Promise.resolve()}finally{Je()}}var rr=[],nr=[],ir=[];function or(t){ir.push(t)}function it(t,e){typeof e=="function"?(t._x_cleanups||(t._x_cleanups=[]),t._x_cleanups.push(e)):(e=t,nr.push(e))}function Tt(t){rr.push(t)}function Rt(t,e,r){t._x_attributeCleanups||(t._x_attributeCleanups={}),t._x_attributeCleanups[e]||(t._x_attributeCleanups[e]=[]),t._x_attributeCleanups[e].push(r)}function fe(t,e){t._x_attributeCleanups&&Object.entries(t._x_attributeCleanups).forEach(([r,n])=>{(e===void 0||e.includes(r))&&(n.forEach(i=>i()),delete t._x_attributeCleanups[r])})}function sr(t){for(t._x_effects?.forEach(Ye);t._x_cleanups?.length;)t._x_cleanups.pop()()}var de=new MutationObserver(_e),pe=!1;function mt(){de.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),pe=!0}function me(){Hn(),de.disconnect(),pe=!1}var pt=[];function Hn(){let t=de.takeRecords();pt.push(()=>t.length>0&&_e(t));let e=pt.length;queueMicrotask(()=>{if(pt.length===e)for(;pt.length>0;)pt.shift()()})}function h(t){if(!pe)return t();me();let e=t();return mt(),e}var he=!1,Ct=[];function ar(){he=!0}function cr(){he=!1,_e(Ct),Ct=[]}function _e(t){if(he){Ct=Ct.concat(t);return}let e=[],r=new Set,n=new Map,i=new Map;for(let o=0;o{s.nodeType===1&&s._x_marker&&r.add(s)}),t[o].addedNodes.forEach(s=>{if(s.nodeType===1){if(r.has(s)){r.delete(s);return}s._x_marker||e.push(s)}})),t[o].type==="attributes")){let s=t[o].target,a=t[o].attributeName,c=t[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{fe(s,o)}),n.forEach((o,s)=>{rr.forEach(a=>a(s,o))});for(let o of r)e.some(s=>s.contains(o))||nr.forEach(s=>s(o));for(let o of e)o.isConnected&&ir.forEach(s=>s(o));e=null,r=null,n=null,i=null}function Mt(t){return I(H(t))}function P(t,e,r){return t._x_dataStack=[e,...H(r||t)],()=>{t._x_dataStack=t._x_dataStack.filter(n=>n!==e)}}function H(t){return t._x_dataStack?t._x_dataStack:typeof ShadowRoot=="function"&&t instanceof ShadowRoot?H(t.host):t.parentNode?H(t.parentNode):[]}function I(t){return new Proxy({objects:t},Kn)}var Kn={ownKeys({objects:t}){return Array.from(new Set(t.flatMap(e=>Object.keys(e))))},has({objects:t},e){return e==Symbol.unscopables?!1:t.some(r=>Object.prototype.hasOwnProperty.call(r,e)||Reflect.has(r,e))},get({objects:t},e,r){return e=="toJSON"?Vn:Reflect.get(t.find(n=>Reflect.has(n,e))||{},e,r)},set({objects:t},e,r,n){let i=t.find(s=>Object.prototype.hasOwnProperty.call(s,e))||t[t.length-1],o=Object.getOwnPropertyDescriptor(i,e);return o?.set&&o?.get?o.set.call(n,r)||!0:Reflect.set(i,e,r)}};function Vn(){return Reflect.ownKeys(this).reduce((e,r)=>(e[r]=Reflect.get(this,r),e),{})}function ot(t){let e=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0||typeof s=="object"&&s!==null&&s.__v_skip)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(t,c,o):e(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(t)}function Nt(t,e=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return t(this.initialValue,()=>Un(n,i),s=>ge(n,i,s),i,o)}};return e(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function Un(t,e){return e.split(".").reduce((r,n)=>r[n],t)}function ge(t,e,r){if(typeof e=="string"&&(e=e.split(".")),e.length===1)t[e[0]]=r;else{if(e.length===0)throw error;return t[e[0]]||(t[e[0]]={}),ge(t[e[0]],e.slice(1),r)}}var lr={};function y(t,e){lr[t]=e}function U(t,e){let r=qn(e);return Object.entries(lr).forEach(([n,i])=>{Object.defineProperty(t,`$${n}`,{get(){return i(e,r)},enumerable:!1})}),t}function qn(t){let[e,r]=xe(t),n={interceptor:Nt,...e};return it(t,r),n}function ur(t,e,r,...n){try{return r(...n)}catch(i){st(i,t,e)}}function st(...t){return fr(...t)}var fr=Wn;function dr(t){fr=t}function Wn(t,e,r=void 0){t=Object.assign(t??{message:"No error message given."},{el:e,expression:r}),console.warn(`Alpine Expression Error: ${t.message}
-
-${r?'Expression: "'+r+`"
-
-`:""}`,e),setTimeout(()=>{throw t},0)}var at=!0;function kt(t){let e=at;at=!1;let r=t();return at=e,r}function N(t,e,r={}){let n;return x(t,e)(i=>n=i,r),n}function x(...t){return pr(...t)}var pr=be;function mr(t){pr=t}var hr;function _r(t){hr=t}function be(t,e){let r={};U(r,t);let n=[r,...H(t)],i=typeof e=="function"?Gn(n,e):Yn(n,e,t);return ur.bind(null,t,e,i)}function Gn(t,e){return(r=()=>{},{scope:n={},params:i=[],context:o}={})=>{if(!at){ht(r,e,I([n,...t]),i);return}let s=e.apply(I([n,...t]),i);ht(r,s)}}var ye={};function Jn(t,e){if(ye[t])return ye[t];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(t.trim())||/^(let|const)\s/.test(t.trim())?`(async()=>{ ${t} })()`:t,o=(()=>{try{let s=new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`);return Object.defineProperty(s,"name",{value:`[Alpine] ${t}`}),s}catch(s){return st(s,e,t),Promise.resolve()}})();return ye[t]=o,o}function Yn(t,e,r){let n=Jn(e,r);return(i=()=>{},{scope:o={},params:s=[],context:a}={})=>{n.result=void 0,n.finished=!1;let c=I([o,...t]);if(typeof n=="function"){let l=n.call(a,n,c).catch(u=>st(u,r,e));n.finished?(ht(i,n.result,c,s,r),n.result=void 0):l.then(u=>{ht(i,u,c,s,r)}).catch(u=>st(u,r,e)).finally(()=>n.result=void 0)}}}function ht(t,e,r,n,i){if(at&&typeof e=="function"){let o=e.apply(r,n);o instanceof Promise?o.then(s=>ht(t,s,r,n)).catch(s=>st(s,i,e)):t(o)}else typeof e=="object"&&e instanceof Promise?e.then(o=>t(o)):t(e)}function gr(...t){return hr(...t)}function xr(t,e,r={}){let n={};U(n,t);let i=[n,...H(t)],o=I([r.scope??{},...i]),s=r.params??[];if(e.includes("await")){let a=Object.getPrototypeOf(async function(){}).constructor,c=/^[\n\s]*if.*\(.*\)/.test(e.trim())||/^(let|const)\s/.test(e.trim())?`(async()=>{ ${e} })()`:e;return new a(["scope"],`with (scope) { let __result = ${c}; return __result }`).call(r.context,o)}else{let a=/^[\n\s]*if.*\(.*\)/.test(e.trim())||/^(let|const)\s/.test(e.trim())?`(()=>{ ${e} })()`:e,l=new Function(["scope"],`with (scope) { let __result = ${a}; return __result }`).call(r.context,o);return typeof l=="function"&&at?l.apply(o,s):l}}var ve="x-";function T(t=""){return ve+t}function yr(t){ve=t}var Dt={};function d(t,e){return Dt[t]=e,{before(r){if(!Dt[r]){console.warn(String.raw`Cannot find directive \`${r}\`. \`${t}\` will use the default order of execution`);return}let n=X.indexOf(r);X.splice(n>=0?n:X.indexOf("DEFAULT"),0,t)}}}function br(t){return Object.keys(Dt).includes(t)}function gt(t,e,r){if(e=Array.from(e),t._x_virtualDirectives){let o=Object.entries(t._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=Se(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),e=e.concat(o)}let n={};return e.map(vr((o,s)=>n[o]=s)).filter(Ar).map(Zn(n,r)).sort(Qn).map(o=>Xn(t,o))}function Se(t){return Array.from(t).map(vr()).filter(e=>!Ar(e))}var we=!1,_t=new Map,wr=Symbol();function Er(t){we=!0;let e=Symbol();wr=e,_t.set(e,[]);let r=()=>{for(;_t.get(e).length;)_t.get(e).shift()();_t.delete(e)},n=()=>{we=!1,r()};t(r),n()}function xe(t){let e=[],r=a=>e.push(a),[n,i]=tr(t);return e.push(i),[{Alpine:K,effect:n,cleanup:r,evaluateLater:x.bind(x,t),evaluate:N.bind(N,t)},()=>e.forEach(a=>a())]}function Xn(t,e){let r=()=>{},n=Dt[e.type]||r,[i,o]=xe(t);Rt(t,e.original,o);let s=()=>{t._x_ignore||t._x_ignoreSelf||(n.inline&&n.inline(t,e,i),n=n.bind(n,t,e,i),we?_t.get(wr).push(n):n())};return s.runCleanups=o,s}var Pt=(t,e)=>({name:r,value:n})=>(r.startsWith(t)&&(r=r.replace(t,e)),{name:r,value:n}),It=t=>t;function vr(t=()=>{}){return({name:e,value:r})=>{let{name:n,value:i}=Sr.reduce((o,s)=>s(o),{name:e,value:r});return n!==e&&t(n,e),{name:n,value:i}}}var Sr=[];function ct(t){Sr.push(t)}function Ar({name:t}){return Or().test(t)}var Or=()=>new RegExp(`^${ve}([^:^.]+)\\b`);function Zn(t,e){return({name:r,value:n})=>{r===n&&(n="");let i=r.match(Or()),o=r.match(/:([a-zA-Z0-9\-_:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=e||t[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var Ee="DEFAULT",X=["ignore","ref","data","id","anchor","bind","init","for","model","modelable","transition","show","if",Ee,"teleport"];function Qn(t,e){let r=X.indexOf(t.type)===-1?Ee:t.type,n=X.indexOf(e.type)===-1?Ee:e.type;return X.indexOf(r)-X.indexOf(n)}function Z(t,e,r={}){t.dispatchEvent(new CustomEvent(e,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function $(t,e){if(typeof ShadowRoot=="function"&&t instanceof ShadowRoot){Array.from(t.children).forEach(i=>$(i,e));return}let r=!1;if(e(t,()=>r=!0),r)return;let n=t.firstElementChild;for(;n;)$(n,e,!1),n=n.nextElementSibling}function w(t,...e){console.warn(`Alpine Warning: ${t}`,...e)}var Cr=!1;function Tr(){Cr&&w("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),Cr=!0,document.body||w("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's `
diff --git a/theme/notes.njk b/theme/notes.njk
deleted file mode 100644
index 1dc616d..0000000
--- a/theme/notes.njk
+++ /dev/null
@@ -1,97 +0,0 @@
----
-layout: layouts/base.njk
-title: Notes
-withSidebar: true
-pagination:
- data: collections.listedNotes
- size: 20
- alias: paginatedNotes
- generatePageOnEmptyData: true
-permalink: "notes/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
----
-
-
-
Notes
- {% set sparklineSvg = collections.listedNotes | postingFrequency %}
- {% if sparklineSvg %}
- {{ sparklineSvg | safe }}
- {% endif %}
-
-
- Short thoughts, updates, and quick posts.
- ({{ collections.listedNotes.length }} total)
-
-
- {% if paginatedNotes.length > 0 %}
-
- {% for post in paginatedNotes %}
-
-
-
- {{ post.templateContent | safe }}
-
-
-
- {% endfor %}
-
-
- {# Pagination controls #}
- {% if pagination.pages.length > 1 %}
-
- {% endif %}
-
- {% else %}
- {% set postType = "note" %}
- {% include "components/empty-collection.njk" %}
- {% endif %}
-
diff --git a/theme/package-lock.json b/theme/package-lock.json
deleted file mode 100644
index 18944ab..0000000
--- a/theme/package-lock.json
+++ /dev/null
@@ -1,6452 +0,0 @@
-{
- "name": "indiekit-eleventy-theme",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "indiekit-eleventy-theme",
- "version": "1.0.0",
- "dependencies": {
- "@11ty/eleventy": "^3.0.0",
- "@11ty/eleventy-fetch": "^4.0.1",
- "@11ty/eleventy-img": "^6.0.0",
- "@11ty/eleventy-plugin-rss": "^2.0.2",
- "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
- "@11ty/is-land": "^5.0.1",
- "@alpinejs/collapse": "^3.15.8",
- "@atproto/api": "^0.12.0",
- "@chrisburnell/eleventy-cache-webmentions": "^2.2.7",
- "@fontsource/inter": "^5.2.8",
- "@quasibit/eleventy-plugin-sitemap": "^2.2.0",
- "@resvg/resvg-js": "^2.6.2",
- "@rknightuk/eleventy-plugin-post-graph": "^1.0.8",
- "@zachleat/filter-container": "^4.0.0",
- "@zachleat/table-saw": "^1.0.7",
- "alpinejs": "^3.15.8",
- "eleventy-plugin-embed-everything": "^1.21.0",
- "gray-matter": "^4.0.3",
- "html-minifier-terser": "^7.0.0",
- "lite-youtube-embed": "^0.3.2",
- "markdown-it": "^14.0.0",
- "markdown-it-anchor": "^9.2.0",
- "pagefind": "^1.3.0",
- "rss-parser": "^3.13.0",
- "satori": "^0.19.2",
- "unfurl.js": "^6.4.0"
- },
- "devDependencies": {
- "@tailwindcss/typography": "^0.5.0",
- "autoprefixer": "^10.4.0",
- "postcss": "^8.4.0",
- "postcss-cli": "^11.0.0",
- "tailwindcss": "^3.4.0"
- }
- },
- "node_modules/@11ty/dependency-tree": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@11ty/dependency-tree/-/dependency-tree-4.0.2.tgz",
- "integrity": "sha512-RTF6VTZHatYf7fSZBUN3RKwiUeJh5dhWV61gDPrHhQF2/gzruAkYz8yXuvGLx3w3ZBKreGrR+MfYpSVkdbdbLA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.1"
- }
- },
- "node_modules/@11ty/dependency-tree-esm": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@11ty/dependency-tree-esm/-/dependency-tree-esm-2.0.4.tgz",
- "integrity": "sha512-MYKC0Ac77ILr1HnRJalzKDlb9Z8To3kXQCltx299pUXXUFtJ1RIONtULlknknqW8cLe19DLVgmxVCtjEFm7h0A==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.7",
- "acorn": "^8.15.0",
- "dependency-graph": "^1.0.0",
- "normalize-path": "^3.0.0"
- }
- },
- "node_modules/@11ty/eleventy": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy/-/eleventy-3.1.2.tgz",
- "integrity": "sha512-IcsDlbXnBf8cHzbM1YBv3JcTyLB35EK88QexmVyFdVJVgUU6bh9g687rpxryJirHzo06PuwnYaEEdVZQfIgRGg==",
- "license": "MIT",
- "dependencies": {
- "@11ty/dependency-tree": "^4.0.0",
- "@11ty/dependency-tree-esm": "^2.0.0",
- "@11ty/eleventy-dev-server": "^2.0.8",
- "@11ty/eleventy-plugin-bundle": "^3.0.6",
- "@11ty/eleventy-utils": "^2.0.7",
- "@11ty/lodash-custom": "^4.17.21",
- "@11ty/posthtml-urls": "^1.0.1",
- "@11ty/recursive-copy": "^4.0.2",
- "@sindresorhus/slugify": "^2.2.1",
- "bcp-47-normalize": "^2.3.0",
- "chokidar": "^3.6.0",
- "debug": "^4.4.1",
- "dependency-graph": "^1.0.0",
- "entities": "^6.0.1",
- "filesize": "^10.1.6",
- "gray-matter": "^4.0.3",
- "iso-639-1": "^3.1.5",
- "js-yaml": "^4.1.0",
- "kleur": "^4.1.5",
- "liquidjs": "^10.21.1",
- "luxon": "^3.6.1",
- "markdown-it": "^14.1.0",
- "minimist": "^1.2.8",
- "moo": "^0.5.2",
- "node-retrieve-globals": "^6.0.1",
- "nunjucks": "^3.2.4",
- "picomatch": "^4.0.2",
- "please-upgrade-node": "^3.2.0",
- "posthtml": "^0.16.6",
- "posthtml-match-helper": "^2.0.3",
- "semver": "^7.7.2",
- "slugify": "^1.6.6",
- "tinyglobby": "^0.2.14"
- },
- "bin": {
- "eleventy": "cmd.cjs"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/eleventy-dev-server": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-dev-server/-/eleventy-dev-server-2.0.8.tgz",
- "integrity": "sha512-15oC5M1DQlCaOMUq4limKRYmWiGecDaGwryr7fTE/oM9Ix8siqMvWi+I8VjsfrGr+iViDvWcH/TVI6D12d93mA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.1",
- "chokidar": "^3.6.0",
- "debug": "^4.4.0",
- "finalhandler": "^1.3.1",
- "mime": "^3.0.0",
- "minimist": "^1.2.8",
- "morphdom": "^2.7.4",
- "please-upgrade-node": "^3.2.0",
- "send": "^1.1.0",
- "ssri": "^11.0.0",
- "urlpattern-polyfill": "^10.0.0",
- "ws": "^8.18.1"
- },
- "bin": {
- "eleventy-dev-server": "cmd.js"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/eleventy-fetch": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-fetch/-/eleventy-fetch-4.0.1.tgz",
- "integrity": "sha512-yIiLM5ziBmg86i4TlXpBdcIygJHvh/GgPJyAiFOckO9H4y9cQDM8eIcJCUQ4Mum0NEVui/OjhEut2R08xw0vlQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.4",
- "flat-cache": "^3.0.4",
- "node-fetch": "^2.6.7",
- "p-queue": "^6.6.2"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/eleventy-img": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-img/-/eleventy-img-6.0.4.tgz",
- "integrity": "sha512-jSy9BmubVs0mN76dcXWfSYDgRU+1+/rq/SxUR3MgIvTUAJRDop5pFW+Z1f56CDcOlEHaiPqHgnfOlqRmJvXl7g==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-fetch": "^5.1.0",
- "@11ty/eleventy-utils": "^2.0.7",
- "brotli-size": "^4.0.0",
- "debug": "^4.4.0",
- "entities": "^6.0.0",
- "image-size": "^1.2.1",
- "p-queue": "^6.6.2",
- "sharp": "^0.33.5"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/eleventy-img/node_modules/@11ty/eleventy-fetch": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-fetch/-/eleventy-fetch-5.1.1.tgz",
- "integrity": "sha512-/xFJLCrqKlcnRKIfO9Qjd1QOs4IpvypljXET955+EgdRPFA+h8Or6bDnZBbcwr6KS7yeUuzp5k1DhXgbentSTA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.7",
- "@rgrove/parse-xml": "^4.2.0",
- "debug": "^4.4.3",
- "flatted": "^3.3.3",
- "p-queue": "6.6.2"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/eleventy-plugin-bundle": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-bundle/-/eleventy-plugin-bundle-3.0.7.tgz",
- "integrity": "sha512-QK1tRFBhQdZASnYU8GMzpTdsMMFLVAkuU0gVVILqNyp09xJJZb81kAS3AFrNrwBCsgLxTdWHJ8N64+OTTsoKkA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.2",
- "debug": "^4.4.0",
- "posthtml-match-helper": "^2.0.3"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/eleventy-plugin-rss": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-rss/-/eleventy-plugin-rss-2.0.4.tgz",
- "integrity": "sha512-LF60sGVlxGTryQe3hTifuzrwF8R7XbrNsM2xfcDcNMSliLN4kmB+7zvoLRySRx0AQDjqhPTAeeeT0ra6/9zHUQ==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.0",
- "@11ty/posthtml-urls": "^1.0.1",
- "debug": "^4.4.0",
- "posthtml": "^0.16.6"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/eleventy-plugin-syntaxhighlight": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-syntaxhighlight/-/eleventy-plugin-syntaxhighlight-5.0.2.tgz",
- "integrity": "sha512-T6xVVRDJuHlrFMHbUiZkHjj5o1IlLzZW+1IL9eUsyXFU7rY2ztcYhZew/64vmceFFpQwzuSfxQOXxTJYmKkQ+A==",
- "license": "MIT",
- "dependencies": {
- "prismjs": "^1.30.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/eleventy-utils": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-utils/-/eleventy-utils-2.0.7.tgz",
- "integrity": "sha512-6QE+duqSQ0GY9rENXYb4iPR4AYGdrFpqnmi59tFp9VrleOl0QSh8VlBr2yd6dlhkdtj7904poZW5PvGr9cMiJQ==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/is-land": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@11ty/is-land/-/is-land-5.0.1.tgz",
- "integrity": "sha512-Rh/sLhE4vrc2JaSjeY385v2UxnDY9BhnQtitETb3SKyr0A48Q5Vn06q2AvDBHObtk9+dcFWsoZX4jhT+O9g+xQ==",
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/lodash-custom": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/@11ty/lodash-custom/-/lodash-custom-4.17.21.tgz",
- "integrity": "sha512-Mqt6im1xpb1Ykn3nbcCovWXK3ggywRJa+IXIdoz4wIIK+cvozADH63lexcuPpGS/gJ6/m2JxyyXDyupkMr5DHw==",
- "license": "MIT",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@11ty/posthtml-urls": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@11ty/posthtml-urls/-/posthtml-urls-1.0.2.tgz",
- "integrity": "sha512-0vaV3Wt0surZ+oS1VdKKe0axeeupuM+l7W/Z866WFQwF+dGg2Tc/nmhk/5l74/Y55P8KyImnLN9CdygNw2huHg==",
- "license": "MIT",
- "dependencies": {
- "evaluate-value": "^2.0.0",
- "http-equiv-refresh": "^2.0.1",
- "list-to-array": "^1.1.0",
- "parse-srcset": "^1.0.2"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/@11ty/recursive-copy": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/@11ty/recursive-copy/-/recursive-copy-4.0.3.tgz",
- "integrity": "sha512-SX48BTLEGX8T/OsKWORsHAAeiDsbFl79Oa/0Wg/mv/d27b7trCVZs7fMHvpSgDvZz/fZqx5rDk8+nx5oyT7xBw==",
- "license": "ISC",
- "dependencies": {
- "errno": "^1.0.0",
- "junk": "^3.1.0",
- "maximatch": "^0.1.0",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@alloc/quick-lru": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
- "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@alpinejs/collapse": {
- "version": "3.15.8",
- "resolved": "https://registry.npmjs.org/@alpinejs/collapse/-/collapse-3.15.8.tgz",
- "integrity": "sha512-zZhD8DHdHuzGFe8+cHNH99K//oFutzKwcy6vagydb3KFlTzmqxTnHZo5sSV81lAazhV7qKsYCKtNV14tR9QkJw==",
- "license": "MIT"
- },
- "node_modules/@atproto/api": {
- "version": "0.12.29",
- "resolved": "https://registry.npmjs.org/@atproto/api/-/api-0.12.29.tgz",
- "integrity": "sha512-PyzPLjGWR0qNOMrmj3Nt3N5NuuANSgOk/33Bu3j+rFjjPrHvk9CI6iQPU6zuDaDCoyOTRJRafw8X/aMQw+ilgw==",
- "license": "MIT",
- "dependencies": {
- "@atproto/common-web": "^0.3.0",
- "@atproto/lexicon": "^0.4.0",
- "@atproto/syntax": "^0.3.0",
- "@atproto/xrpc": "^0.5.0",
- "await-lock": "^2.2.2",
- "multiformats": "^9.9.0",
- "tlds": "^1.234.0"
- }
- },
- "node_modules/@atproto/common-web": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@atproto/common-web/-/common-web-0.3.2.tgz",
- "integrity": "sha512-Vx0JtL1/CssJbFAb0UOdvTrkbUautsDfHNOXNTcX2vyPIxH9xOameSqLLunM1hZnOQbJwyjmQCt6TV+bhnanDg==",
- "license": "MIT",
- "dependencies": {
- "graphemer": "^1.4.0",
- "multiformats": "^9.9.0",
- "uint8arrays": "3.0.0",
- "zod": "^3.23.8"
- }
- },
- "node_modules/@atproto/lex-data": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.0.8.tgz",
- "integrity": "sha512-1Y5tz7BkS7380QuLNXaE8GW8Xba+mRWugt8BKM4BUFYjjUZdmirU8lr72iM4XlEBrzRu8Cfvj+MbsbYaZv+IgA==",
- "license": "MIT",
- "dependencies": {
- "@atproto/syntax": "0.4.2",
- "multiformats": "^9.9.0",
- "tslib": "^2.8.1",
- "uint8arrays": "3.0.0",
- "unicode-segmenter": "^0.14.0"
- }
- },
- "node_modules/@atproto/lex-data/node_modules/@atproto/syntax": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.2.tgz",
- "integrity": "sha512-X9XSRPinBy/0VQ677j8VXlBsYSsUXaiqxWVpGGxJYsAhugdQRb0jqaVKJFtm6RskeNkV6y9xclSUi9UYG/COrA==",
- "license": "MIT"
- },
- "node_modules/@atproto/lex-json": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/@atproto/lex-json/-/lex-json-0.0.8.tgz",
- "integrity": "sha512-w1Qmkae1QhmNz+i1Zm3xr3jp0UPPRENmdlpU0qIrdxWDo9W4Mzkeyc3eSoa+Zs+zN8xkRSQw7RLZte/B7Ipdwg==",
- "license": "MIT",
- "dependencies": {
- "@atproto/lex-data": "0.0.8",
- "tslib": "^2.8.1"
- }
- },
- "node_modules/@atproto/lexicon": {
- "version": "0.4.14",
- "resolved": "https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.4.14.tgz",
- "integrity": "sha512-jiKpmH1QER3Gvc7JVY5brwrfo+etFoe57tKPQX/SmPwjvUsFnJAow5xLIryuBaJgFAhnTZViXKs41t//pahGHQ==",
- "license": "MIT",
- "dependencies": {
- "@atproto/common-web": "^0.4.2",
- "@atproto/syntax": "^0.4.0",
- "iso-datestring-validator": "^2.2.2",
- "multiformats": "^9.9.0",
- "zod": "^3.23.8"
- }
- },
- "node_modules/@atproto/lexicon/node_modules/@atproto/common-web": {
- "version": "0.4.12",
- "resolved": "https://registry.npmjs.org/@atproto/common-web/-/common-web-0.4.12.tgz",
- "integrity": "sha512-3aCJemqM/fkHQrVPbTCHCdiVstKFI+2LkFLvUhO6XZP0EqUZa/rg/CIZBKTFUWu9I5iYiaEiXL9VwcDRpEevSw==",
- "license": "MIT",
- "dependencies": {
- "@atproto/lex-data": "0.0.8",
- "@atproto/lex-json": "0.0.8",
- "zod": "^3.23.8"
- }
- },
- "node_modules/@atproto/lexicon/node_modules/@atproto/syntax": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.2.tgz",
- "integrity": "sha512-X9XSRPinBy/0VQ677j8VXlBsYSsUXaiqxWVpGGxJYsAhugdQRb0jqaVKJFtm6RskeNkV6y9xclSUi9UYG/COrA==",
- "license": "MIT"
- },
- "node_modules/@atproto/syntax": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/@atproto/syntax/-/syntax-0.3.4.tgz",
- "integrity": "sha512-8CNmi5DipOLaVeSMPggMe7FCksVag0aO6XZy9WflbduTKM4dFZVCs4686UeMLfGRXX+X966XgwECHoLYrovMMg==",
- "license": "MIT"
- },
- "node_modules/@atproto/xrpc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/@atproto/xrpc/-/xrpc-0.5.0.tgz",
- "integrity": "sha512-swu+wyOLvYW4l3n+VAuJbHcPcES+tin2Lsrp8Bw5aIXIICiuFn1YMFlwK9JwVUzTH21Py1s1nHEjr4CJeElJog==",
- "license": "MIT",
- "dependencies": {
- "@atproto/lexicon": "^0.4.0",
- "zod": "^3.21.4"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
- "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
- "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
- "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.0"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
- "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@chrisburnell/eleventy-cache-webmentions": {
- "version": "2.2.7",
- "resolved": "https://registry.npmjs.org/@chrisburnell/eleventy-cache-webmentions/-/eleventy-cache-webmentions-2.2.7.tgz",
- "integrity": "sha512-9Z4fD5MdTBvOprzcNcRGOyyaVo0ETyoQEiotNgV/eFFJiSidV3VRcab69yybJCkrq7L+aqWRrCdrx7ilL8YKTg==",
- "funding": [
- {
- "type": "buymeacoffee",
- "url": "https://buymeacoffee.com/chrisburnell"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/chrisburnell"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-fetch": "^5.1.1",
- "sanitize-html": "^2.17.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@chrisburnell/eleventy-cache-webmentions/node_modules/@11ty/eleventy-fetch": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-fetch/-/eleventy-fetch-5.1.1.tgz",
- "integrity": "sha512-/xFJLCrqKlcnRKIfO9Qjd1QOs4IpvypljXET955+EgdRPFA+h8Or6bDnZBbcwr6KS7yeUuzp5k1DhXgbentSTA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.7",
- "@rgrove/parse-xml": "^4.2.0",
- "debug": "^4.4.3",
- "flatted": "^3.3.3",
- "p-queue": "6.6.2"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@emnapi/runtime": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz",
- "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@fontsource/inter": {
- "version": "5.2.8",
- "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.2.8.tgz",
- "integrity": "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg==",
- "license": "OFL-1.1",
- "funding": {
- "url": "https://github.com/sponsors/ayuhito"
- }
- },
- "node_modules/@iarna/toml": {
- "version": "2.2.5",
- "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
- "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==",
- "license": "ISC"
- },
- "node_modules/@img/sharp-darwin-arm64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
- "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-darwin-arm64": "1.0.4"
- }
- },
- "node_modules/@img/sharp-darwin-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
- "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-darwin-x64": "1.0.4"
- }
- },
- "node_modules/@img/sharp-libvips-darwin-arm64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
- "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-darwin-x64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
- "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-arm": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
- "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
- "cpu": [
- "arm"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-arm64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
- "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-s390x": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz",
- "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==",
- "cpu": [
- "s390x"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-x64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
- "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
- "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linuxmusl-x64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
- "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-linux-arm": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
- "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
- "cpu": [
- "arm"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm": "1.0.5"
- }
- },
- "node_modules/@img/sharp-linux-arm64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
- "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm64": "1.0.4"
- }
- },
- "node_modules/@img/sharp-linux-s390x": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz",
- "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==",
- "cpu": [
- "s390x"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-s390x": "1.0.4"
- }
- },
- "node_modules/@img/sharp-linux-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
- "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-x64": "1.0.4"
- }
- },
- "node_modules/@img/sharp-linuxmusl-arm64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
- "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
- }
- },
- "node_modules/@img/sharp-linuxmusl-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
- "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-x64": "1.0.4"
- }
- },
- "node_modules/@img/sharp-wasm32": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz",
- "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==",
- "cpu": [
- "wasm32"
- ],
- "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/runtime": "^1.2.0"
- },
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-win32-ia32": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz",
- "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==",
- "cpu": [
- "ia32"
- ],
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-win32-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
- "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/source-map": {
- "version": "0.3.11",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
- "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@pagefind/darwin-arm64": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.4.0.tgz",
- "integrity": "sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@pagefind/darwin-x64": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.4.0.tgz",
- "integrity": "sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@pagefind/freebsd-x64": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.4.0.tgz",
- "integrity": "sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@pagefind/linux-arm64": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.4.0.tgz",
- "integrity": "sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@pagefind/linux-x64": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.4.0.tgz",
- "integrity": "sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@pagefind/windows-x64": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.4.0.tgz",
- "integrity": "sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@quasibit/eleventy-plugin-sitemap": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@quasibit/eleventy-plugin-sitemap/-/eleventy-plugin-sitemap-2.2.0.tgz",
- "integrity": "sha512-7YoU4jjipLjifBhZwttLWbAAkImmBfeMQ0+1ST6mJO45z2mFLHZcgnfHwGF2joNk74wiYNsNOB1ennouzQFZIQ==",
- "license": "MIT",
- "dependencies": {
- "array-flat-polyfill": "^1.0.1",
- "sitemap": "^6.3.2"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/@resvg/resvg-js": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js/-/resvg-js-2.6.2.tgz",
- "integrity": "sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q==",
- "license": "MPL-2.0",
- "engines": {
- "node": ">= 10"
- },
- "optionalDependencies": {
- "@resvg/resvg-js-android-arm-eabi": "2.6.2",
- "@resvg/resvg-js-android-arm64": "2.6.2",
- "@resvg/resvg-js-darwin-arm64": "2.6.2",
- "@resvg/resvg-js-darwin-x64": "2.6.2",
- "@resvg/resvg-js-linux-arm-gnueabihf": "2.6.2",
- "@resvg/resvg-js-linux-arm64-gnu": "2.6.2",
- "@resvg/resvg-js-linux-arm64-musl": "2.6.2",
- "@resvg/resvg-js-linux-x64-gnu": "2.6.2",
- "@resvg/resvg-js-linux-x64-musl": "2.6.2",
- "@resvg/resvg-js-win32-arm64-msvc": "2.6.2",
- "@resvg/resvg-js-win32-ia32-msvc": "2.6.2",
- "@resvg/resvg-js-win32-x64-msvc": "2.6.2"
- }
- },
- "node_modules/@resvg/resvg-js-android-arm-eabi": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-android-arm-eabi/-/resvg-js-android-arm-eabi-2.6.2.tgz",
- "integrity": "sha512-FrJibrAk6v29eabIPgcTUMPXiEz8ssrAk7TXxsiZzww9UTQ1Z5KAbFJs+Z0Ez+VZTYgnE5IQJqBcoSiMebtPHA==",
- "cpu": [
- "arm"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-android-arm64": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-android-arm64/-/resvg-js-android-arm64-2.6.2.tgz",
- "integrity": "sha512-VcOKezEhm2VqzXpcIJoITuvUS/fcjIw5NA/w3tjzWyzmvoCdd+QXIqy3FBGulWdClvp4g+IfUemigrkLThSjAQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-darwin-arm64": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-darwin-arm64/-/resvg-js-darwin-arm64-2.6.2.tgz",
- "integrity": "sha512-nmok2LnAd6nLUKI16aEB9ydMC6Lidiiq2m1nEBDR1LaaP7FGs4AJ90qDraxX+CWlVuRlvNjyYJTNv8qFjtL9+A==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-darwin-x64": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-darwin-x64/-/resvg-js-darwin-x64-2.6.2.tgz",
- "integrity": "sha512-GInyZLjgWDfsVT6+SHxQVRwNzV0AuA1uqGsOAW+0th56J7Nh6bHHKXHBWzUrihxMetcFDmQMAX1tZ1fZDYSRsw==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-linux-arm-gnueabihf": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm-gnueabihf/-/resvg-js-linux-arm-gnueabihf-2.6.2.tgz",
- "integrity": "sha512-YIV3u/R9zJbpqTTNwTZM5/ocWetDKGsro0SWp70eGEM9eV2MerWyBRZnQIgzU3YBnSBQ1RcxRZvY/UxwESfZIw==",
- "cpu": [
- "arm"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-linux-arm64-gnu": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm64-gnu/-/resvg-js-linux-arm64-gnu-2.6.2.tgz",
- "integrity": "sha512-zc2BlJSim7YR4FZDQ8OUoJg5holYzdiYMeobb9pJuGDidGL9KZUv7SbiD4E8oZogtYY42UZEap7dqkkYuA91pg==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-linux-arm64-musl": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm64-musl/-/resvg-js-linux-arm64-musl-2.6.2.tgz",
- "integrity": "sha512-3h3dLPWNgSsD4lQBJPb4f+kvdOSJHa5PjTYVsWHxLUzH4IFTJUAnmuWpw4KqyQ3NA5QCyhw4TWgxk3jRkQxEKg==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-linux-x64-gnu": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-x64-gnu/-/resvg-js-linux-x64-gnu-2.6.2.tgz",
- "integrity": "sha512-IVUe+ckIerA7xMZ50duAZzwf1U7khQe2E0QpUxu5MBJNao5RqC0zwV/Zm965vw6D3gGFUl7j4m+oJjubBVoftw==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-linux-x64-musl": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-x64-musl/-/resvg-js-linux-x64-musl-2.6.2.tgz",
- "integrity": "sha512-UOf83vqTzoYQO9SZ0fPl2ZIFtNIz/Rr/y+7X8XRX1ZnBYsQ/tTb+cj9TE+KHOdmlTFBxhYzVkP2lRByCzqi4jQ==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-win32-arm64-msvc": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-arm64-msvc/-/resvg-js-win32-arm64-msvc-2.6.2.tgz",
- "integrity": "sha512-7C/RSgCa+7vqZ7qAbItfiaAWhyRSoD4l4BQAbVDqRRsRgY+S+hgS3in0Rxr7IorKUpGE69X48q6/nOAuTJQxeQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-win32-ia32-msvc": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-ia32-msvc/-/resvg-js-win32-ia32-msvc-2.6.2.tgz",
- "integrity": "sha512-har4aPAlvjnLcil40AC77YDIk6loMawuJwFINEM7n0pZviwMkMvjb2W5ZirsNOZY4aDbo5tLx0wNMREp5Brk+w==",
- "cpu": [
- "ia32"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@resvg/resvg-js-win32-x64-msvc": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-x64-msvc/-/resvg-js-win32-x64-msvc-2.6.2.tgz",
- "integrity": "sha512-ZXtYhtUr5SSaBrUDq7DiyjOFJqBVL/dOBN7N/qmi/pO0IgiWW/f/ue3nbvu9joWE5aAKDoIzy/CxsY0suwGosQ==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@rgrove/parse-xml": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/@rgrove/parse-xml/-/parse-xml-4.2.0.tgz",
- "integrity": "sha512-UuBOt7BOsKVOkFXRe4Ypd/lADuNIfqJXv8GvHqtXaTYXPPKkj2nS2zPllVsrtRjcomDhIJVBnZwfmlI222WH8g==",
- "license": "ISC",
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/@rknightuk/eleventy-plugin-post-graph/-/eleventy-plugin-post-graph-1.0.8.tgz",
- "integrity": "sha512-GRllThUf7HKigjjnxsqj4G23UGq3sIShNN+wfbqQMSOuNtIQbS2l2eHI6hn2UErvK/W9n3RKc0eYmMpDMyO98w==",
- "license": "ISC",
- "dependencies": {
- "@11ty/eleventy": "^2.0.1",
- "moment": "^2.29.4"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/@11ty/dependency-tree": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@11ty/dependency-tree/-/dependency-tree-2.0.1.tgz",
- "integrity": "sha512-5R+DsT9LJ9tXiSQ4y+KLFppCkQyXhzAm1AIuBWE/sbU0hSXY5pkhoqQYEcPJQFg/nglL+wD55iv2j+7O96UAvg==",
- "license": "MIT"
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/@11ty/eleventy": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy/-/eleventy-2.0.1.tgz",
- "integrity": "sha512-t8XVUbCJByhVEa1RzO0zS2QzbL3wPY8ot1yUw9noqiSHxJWUwv6jiwm1/MZDPTYtkZH2ZHvdQIRQ5/SjG9XmLw==",
- "license": "MIT",
- "dependencies": {
- "@11ty/dependency-tree": "^2.0.1",
- "@11ty/eleventy-dev-server": "^1.0.4",
- "@11ty/eleventy-utils": "^1.0.1",
- "@11ty/lodash-custom": "^4.17.21",
- "@iarna/toml": "^2.2.5",
- "@sindresorhus/slugify": "^1.1.2",
- "bcp-47-normalize": "^1.1.1",
- "chokidar": "^3.5.3",
- "cross-spawn": "^7.0.3",
- "debug": "^4.3.4",
- "dependency-graph": "^0.11.0",
- "ejs": "^3.1.9",
- "fast-glob": "^3.2.12",
- "graceful-fs": "^4.2.11",
- "gray-matter": "^4.0.3",
- "hamljs": "^0.6.2",
- "handlebars": "^4.7.7",
- "is-glob": "^4.0.3",
- "iso-639-1": "^2.1.15",
- "kleur": "^4.1.5",
- "liquidjs": "^10.7.0",
- "luxon": "^3.3.0",
- "markdown-it": "^13.0.1",
- "micromatch": "^4.0.5",
- "minimist": "^1.2.8",
- "moo": "^0.5.2",
- "multimatch": "^5.0.0",
- "mustache": "^4.2.0",
- "normalize-path": "^3.0.0",
- "nunjucks": "^3.2.3",
- "path-to-regexp": "^6.2.1",
- "please-upgrade-node": "^3.2.0",
- "posthtml": "^0.16.6",
- "posthtml-urls": "^1.0.0",
- "pug": "^3.0.2",
- "recursive-copy": "^2.0.14",
- "semver": "^7.3.8",
- "slugify": "^1.6.6"
- },
- "bin": {
- "eleventy": "cmd.js"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/@11ty/eleventy-dev-server": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-dev-server/-/eleventy-dev-server-1.0.4.tgz",
- "integrity": "sha512-qVBmV2G1KF/0o5B/3fITlrrDHy4bONUI2YuN3/WJ3BNw4NU1d/we8XhKrlgq13nNvHoBx5czYp3LZt8qRG53Fg==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^1.0.1",
- "chokidar": "^3.5.3",
- "debug": "^4.3.4",
- "dev-ip": "^1.0.1",
- "finalhandler": "^1.2.0",
- "mime": "^3.0.0",
- "minimist": "^1.2.8",
- "morphdom": "^2.7.0",
- "please-upgrade-node": "^3.2.0",
- "ssri": "^8.0.1",
- "ws": "^8.13.0"
- },
- "bin": {
- "eleventy-dev-server": "cmd.js"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/@11ty/eleventy-utils": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-utils/-/eleventy-utils-1.0.3.tgz",
- "integrity": "sha512-nULO91om7vQw4Y/UBjM8i7nJ1xl+/nyK4rImZ41lFxiY2d+XUz7ChAj1CDYFjrLZeu0utAYJTZ45LlcHTkUG4g==",
- "license": "MIT",
- "dependencies": {
- "normalize-path": "^3.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/@sindresorhus/slugify": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-1.1.2.tgz",
- "integrity": "sha512-V9nR/W0Xd9TSGXpZ4iFUcFGhuOJtZX82Fzxj1YISlbSgKvIiNa7eLEZrT0vAraPOt++KHauIVNYgGRgjc13dXA==",
- "license": "MIT",
- "dependencies": {
- "@sindresorhus/transliterate": "^0.1.1",
- "escape-string-regexp": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/@sindresorhus/transliterate": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-0.1.2.tgz",
- "integrity": "sha512-5/kmIOY9FF32nicXH+5yLNTX4NJ4atl7jRgqAJuIn/iyDFXBktOKDxCvyGE/EzmF4ngSUvjXxQUQlQiZ5lfw+w==",
- "license": "MIT",
- "dependencies": {
- "escape-string-regexp": "^2.0.0",
- "lodash.deburr": "^4.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/@sindresorhus/transliterate/node_modules/escape-string-regexp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
- "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/bcp-47": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-1.0.8.tgz",
- "integrity": "sha512-Y9y1QNBBtYtv7hcmoX0tR+tUNSFZGZ6OL6vKPObq8BbOhkCoyayF6ogfLTgAli/KuAEbsYHYUNq2AQuY6IuLag==",
- "license": "MIT",
- "dependencies": {
- "is-alphabetical": "^1.0.0",
- "is-alphanumerical": "^1.0.0",
- "is-decimal": "^1.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/bcp-47-match": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-1.0.3.tgz",
- "integrity": "sha512-LggQ4YTdjWQSKELZF5JwchnBa1u0pIQSZf5lSdOHEdbVP55h0qICA/FUp3+W99q0xqxYa1ZQizTUH87gecII5w==",
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/bcp-47-normalize": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-1.1.1.tgz",
- "integrity": "sha512-jWZ1Jdu3cs0EZdfCkS0UE9Gg01PtxnChjEBySeB+Zo6nkqtFfnvtoQQgP1qU1Oo4qgJgxhTI6Sf9y/pZIhPs0A==",
- "license": "MIT",
- "dependencies": {
- "bcp-47": "^1.0.0",
- "bcp-47-match": "^1.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/dependency-graph": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
- "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6.0"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/entities": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
- "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/is-alphabetical": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
- "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/is-alphanumerical": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
- "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
- "license": "MIT",
- "dependencies": {
- "is-alphabetical": "^1.0.0",
- "is-decimal": "^1.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/is-decimal": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
- "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/iso-639-1": {
- "version": "2.1.15",
- "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-2.1.15.tgz",
- "integrity": "sha512-7c7mBznZu2ktfvyT582E2msM+Udc1EjOyhVRE/0ZsjD9LBtWSm23h3PtiRh2a35XoUsTQQjJXaJzuLjXsOdFDg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/linkify-it": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
- "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
- "license": "MIT",
- "dependencies": {
- "uc.micro": "^1.0.1"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/markdown-it": {
- "version": "13.0.2",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz",
- "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==",
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1",
- "entities": "~3.0.1",
- "linkify-it": "^4.0.1",
- "mdurl": "^1.0.1",
- "uc.micro": "^1.0.5"
- },
- "bin": {
- "markdown-it": "bin/markdown-it.js"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/mdurl": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
- "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
- "license": "MIT"
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/ssri": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
- "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.1.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@rknightuk/eleventy-plugin-post-graph/node_modules/uc.micro": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
- "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
- "license": "MIT"
- },
- "node_modules/@shuding/opentype.js": {
- "version": "1.4.0-beta.0",
- "resolved": "https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz",
- "integrity": "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==",
- "license": "MIT",
- "dependencies": {
- "fflate": "^0.7.3",
- "string.prototype.codepointat": "^0.2.1"
- },
- "bin": {
- "ot": "bin/ot"
- },
- "engines": {
- "node": ">= 8.0.0"
- }
- },
- "node_modules/@sindresorhus/slugify": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-2.2.1.tgz",
- "integrity": "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==",
- "license": "MIT",
- "dependencies": {
- "@sindresorhus/transliterate": "^1.0.0",
- "escape-string-regexp": "^5.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@sindresorhus/transliterate": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-1.6.0.tgz",
- "integrity": "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==",
- "license": "MIT",
- "dependencies": {
- "escape-string-regexp": "^5.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@tailwindcss/typography": {
- "version": "0.5.19",
- "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.19.tgz",
- "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "postcss-selector-parser": "6.0.10"
- },
- "peerDependencies": {
- "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
- }
- },
- "node_modules/@types/linkify-it": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
- "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
- "license": "MIT",
- "peer": true
- },
- "node_modules/@types/markdown-it": {
- "version": "14.1.2",
- "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
- "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@types/linkify-it": "^5",
- "@types/mdurl": "^2"
- }
- },
- "node_modules/@types/mdurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
- "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
- "license": "MIT",
- "peer": true
- },
- "node_modules/@types/minimatch": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
- "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "14.18.63",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz",
- "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==",
- "license": "MIT"
- },
- "node_modules/@types/sax": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz",
- "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==",
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@vue/reactivity": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz",
- "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==",
- "license": "MIT",
- "dependencies": {
- "@vue/shared": "3.1.5"
- }
- },
- "node_modules/@vue/shared": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz",
- "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==",
- "license": "MIT"
- },
- "node_modules/@zachleat/filter-container": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@zachleat/filter-container/-/filter-container-4.0.0.tgz",
- "integrity": "sha512-4etUifhHciQTMtlDymb4cus03qYZrKiuK0gY0cOU4Jrt0LA3ZvPVTwO6esqUdvbpte5ypodmpx84wwbT3Fy5Jw==",
- "license": "MIT"
- },
- "node_modules/@zachleat/table-saw": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@zachleat/table-saw/-/table-saw-1.0.7.tgz",
- "integrity": "sha512-AxYShldkUoofdzqyH/pgbiXBgoRbFtoQYKbCjTK7diViqepM2SqZoMZm7ofc9UeGaDWgktAOmoJg3T+yN0SAxA==",
- "license": "MIT"
- },
- "node_modules/a-sync-waterfall": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
- "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==",
- "license": "MIT"
- },
- "node_modules/acorn": {
- "version": "8.15.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
- "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-walk": {
- "version": "8.3.4",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
- "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.11.0"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/alpinejs": {
- "version": "3.15.8",
- "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.15.8.tgz",
- "integrity": "sha512-zxIfCRTBGvF1CCLIOMQOxAyBuqibxSEwS6Jm1a3HGA9rgrJVcjEWlwLcQTVGAWGS8YhAsTRLVrtQ5a5QT9bSSQ==",
- "license": "MIT",
- "dependencies": {
- "@vue/reactivity": "~3.1.1"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/any-promise": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "license": "ISC",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/anymatch/node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/arg": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
- "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
- "license": "MIT"
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "license": "Python-2.0"
- },
- "node_modules/array-differ": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
- "integrity": "sha512-LeZY+DZDRnvP7eMuQ6LHfCzUGxAAIViUBliK24P3hWXL6y4SortgR6Nim6xrkfSLlmH0+k+9NYNwVC2s53ZrYQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/array-flat-polyfill": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/array-flat-polyfill/-/array-flat-polyfill-1.0.1.tgz",
- "integrity": "sha512-hfJmKupmQN0lwi0xG6FQ5U8Rd97RnIERplymOv/qpq8AoNKPPAnxJadjFA23FNWm88wykh9HmpLJUUwUtNU/iw==",
- "license": "CC0-1.0",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/array-union": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
- "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==",
- "license": "MIT",
- "dependencies": {
- "array-uniq": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/array-uniq": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
- "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/asap": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
- "license": "MIT"
- },
- "node_modules/assert-never": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz",
- "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==",
- "license": "MIT"
- },
- "node_modules/async": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
- "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
- "license": "MIT"
- },
- "node_modules/autoprefixer": {
- "version": "10.4.23",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz",
- "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/autoprefixer"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "browserslist": "^4.28.1",
- "caniuse-lite": "^1.0.30001760",
- "fraction.js": "^5.3.4",
- "picocolors": "^1.1.1",
- "postcss-value-parser": "^4.2.0"
- },
- "bin": {
- "autoprefixer": "bin/autoprefixer"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- },
- "peerDependencies": {
- "postcss": "^8.1.0"
- }
- },
- "node_modules/await-lock": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.2.2.tgz",
- "integrity": "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==",
- "license": "MIT"
- },
- "node_modules/babel-walk": {
- "version": "3.0.0-canary-5",
- "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz",
- "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==",
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.9.6"
- },
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "license": "MIT"
- },
- "node_modules/base64-js": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
- "integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/baseline-browser-mapping": {
- "version": "2.9.17",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.17.tgz",
- "integrity": "sha512-agD0MgJFUP/4nvjqzIB29zRPUuCF7Ge6mEv9s8dHrtYD7QWXRcx75rOADE/d5ah1NI+0vkDl0yorDd5U852IQQ==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "baseline-browser-mapping": "dist/cli.js"
- }
- },
- "node_modules/bcp-47": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz",
- "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==",
- "license": "MIT",
- "dependencies": {
- "is-alphabetical": "^2.0.0",
- "is-alphanumerical": "^2.0.0",
- "is-decimal": "^2.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/bcp-47-match": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz",
- "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==",
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/bcp-47-normalize": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-2.3.0.tgz",
- "integrity": "sha512-8I/wfzqQvttUFz7HVJgIZ7+dj3vUaIyIxYXaTRP1YWoSDfzt6TUmxaKZeuXR62qBmYr+nvuWINFRl6pZ5DlN4Q==",
- "license": "MIT",
- "dependencies": {
- "bcp-47": "^2.0.0",
- "bcp-47-match": "^2.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/brotli-size": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/brotli-size/-/brotli-size-4.0.0.tgz",
- "integrity": "sha512-uA9fOtlTRC0iqKfzff1W34DXUA3GyVqbUaeo3Rw3d4gd1eavKVCETXrn3NzO74W+UVkG3UHu8WxUi+XvKI/huA==",
- "license": "MIT",
- "dependencies": {
- "duplexer": "0.1.1"
- },
- "engines": {
- "node": ">= 10.16.0"
- }
- },
- "node_modules/browserslist": {
- "version": "4.28.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
- "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "baseline-browser-mapping": "^2.9.0",
- "caniuse-lite": "^1.0.30001759",
- "electron-to-chromium": "^1.5.263",
- "node-releases": "^2.0.27",
- "update-browserslist-db": "^1.2.0"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "license": "MIT"
- },
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/camel-case": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
- "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
- "license": "MIT",
- "dependencies": {
- "pascal-case": "^3.1.2",
- "tslib": "^2.0.3"
- }
- },
- "node_modules/camelcase-css": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
- "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/camelize": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
- "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001766",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz",
- "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
- "node_modules/character-parser": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
- "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==",
- "license": "MIT",
- "dependencies": {
- "is-regex": "^1.0.3"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "license": "MIT",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/clean-css": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
- "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
- "license": "MIT",
- "dependencies": {
- "source-map": "~0.6.0"
- },
- "engines": {
- "node": ">= 10.0"
- }
- },
- "node_modules/cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/color": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
- "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1",
- "color-string": "^1.9.0"
- },
- "engines": {
- "node": ">=12.5.0"
- }
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "license": "MIT"
- },
- "node_modules/color-string": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
- "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
- "license": "MIT",
- "dependencies": {
- "color-name": "^1.0.0",
- "simple-swizzle": "^0.2.2"
- }
- },
- "node_modules/commander": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
- "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
- "license": "MIT",
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "license": "MIT"
- },
- "node_modules/constantinople": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
- "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==",
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.6.0",
- "@babel/types": "^7.6.1"
- }
- },
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/css-background-parser": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz",
- "integrity": "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==",
- "license": "MIT"
- },
- "node_modules/css-box-shadow": {
- "version": "1.0.0-3",
- "resolved": "https://registry.npmjs.org/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz",
- "integrity": "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==",
- "license": "MIT"
- },
- "node_modules/css-color-keywords": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
- "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
- "license": "ISC",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/css-gradient-parser": {
- "version": "0.0.17",
- "resolved": "https://registry.npmjs.org/css-gradient-parser/-/css-gradient-parser-0.0.17.tgz",
- "integrity": "sha512-w2Xy9UMMwlKtou0vlRnXvWglPAceXCTtcmVSo8ZBUvqCV5aXEFP/PC6d+I464810I9FT++UACwTD5511bmGPUg==",
- "license": "MIT",
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/css-to-react-native": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
- "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
- "license": "MIT",
- "dependencies": {
- "camelize": "^1.0.0",
- "css-color-keywords": "^1.0.0",
- "postcss-value-parser": "^4.0.2"
- }
- },
- "node_modules/cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "cssesc": "bin/cssesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/deepmerge": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/dependency-graph": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz",
- "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/detect-libc": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/dev-ip": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz",
- "integrity": "sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==",
- "bin": {
- "dev-ip": "lib/dev-ip.js"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/didyoumean": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
- "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/dlv": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
- "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/doctypes": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
- "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==",
- "license": "MIT"
- },
- "node_modules/dom-serializer": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
- "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.0.1",
- "domhandler": "^4.2.0",
- "entities": "^2.0.0"
- },
- "funding": {
- "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
- }
- },
- "node_modules/dom-serializer/node_modules/entities": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
- "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
- "license": "BSD-2-Clause",
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/domelementtype": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
- "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fb55"
- }
- ],
- "license": "BSD-2-Clause"
- },
- "node_modules/domhandler": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
- "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "domelementtype": "^2.2.0"
- },
- "engines": {
- "node": ">= 4"
- },
- "funding": {
- "url": "https://github.com/fb55/domhandler?sponsor=1"
- }
- },
- "node_modules/domutils": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
- "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "dom-serializer": "^1.0.1",
- "domelementtype": "^2.2.0",
- "domhandler": "^4.2.0"
- },
- "funding": {
- "url": "https://github.com/fb55/domutils?sponsor=1"
- }
- },
- "node_modules/dot-case": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
- "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
- "license": "MIT",
- "dependencies": {
- "no-case": "^3.0.4",
- "tslib": "^2.0.3"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/duplexer": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
- "integrity": "sha512-sxNZ+ljy+RA1maXoUReeqBBpBC6RLKmg5ewzV+x+mSETmWNoKdZN6vcQjpFROemza23hGFskJtFNoUWUaQ+R4Q=="
- },
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
- "license": "MIT"
- },
- "node_modules/ejs": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
- "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
- "license": "Apache-2.0",
- "dependencies": {
- "jake": "^10.8.5"
- },
- "bin": {
- "ejs": "bin/cli.js"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/electron-to-chromium": {
- "version": "1.5.277",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.277.tgz",
- "integrity": "sha512-wKXFZw4erWmmOz5N/grBoJ2XrNJGDFMu2+W5ACHza5rHtvsqrK4gb6rnLC7XxKB9WlJ+RmyQatuEXmtm86xbnw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/eleventy-plugin-embed-bluesky": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-bluesky/-/eleventy-plugin-embed-bluesky-1.0.1.tgz",
- "integrity": "sha512-6+0A92TIiJ5MJaJhcMshX5a2R4pdAJjAYz7EvDOk7T2zyr59Tyq9bRm9lEx2IRdZ5fx6CiRNMgLb+KXkzlLd2A==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-fetch": "^5.1.0",
- "string-replace-async": "^3.0.2"
- }
- },
- "node_modules/eleventy-plugin-embed-bluesky/node_modules/@11ty/eleventy-fetch": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-fetch/-/eleventy-fetch-5.1.1.tgz",
- "integrity": "sha512-/xFJLCrqKlcnRKIfO9Qjd1QOs4IpvypljXET955+EgdRPFA+h8Or6bDnZBbcwr6KS7yeUuzp5k1DhXgbentSTA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.7",
- "@rgrove/parse-xml": "^4.2.0",
- "debug": "^4.4.3",
- "flatted": "^3.3.3",
- "p-queue": "6.6.2"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/eleventy-plugin-embed-everything": {
- "version": "1.21.1",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-everything/-/eleventy-plugin-embed-everything-1.21.1.tgz",
- "integrity": "sha512-Ucr27//kAkmpAKGvzSYbtlSCTVu+F7iJF5Smw+81PxAaofouiHhusJUQA6GJkJ1A7WgTDuwHWJjZ5mAXJWNtuA==",
- "license": "MIT",
- "dependencies": {
- "deepmerge": "^4.3.1",
- "eleventy-plugin-embed-bluesky": "^1.0.1",
- "eleventy-plugin-embed-instagram": "^1.3.0",
- "eleventy-plugin-embed-mastodon": "^1.0.2",
- "eleventy-plugin-embed-openstreetmap": "^1.1.0",
- "eleventy-plugin-embed-soundcloud": "^1.2.10",
- "eleventy-plugin-embed-spotify": "^1.3.0",
- "eleventy-plugin-embed-ted": "^1.0.1",
- "eleventy-plugin-embed-tiktok": "^1.1.8",
- "eleventy-plugin-embed-twitch": "^1.2.8",
- "eleventy-plugin-embed-twitter": "^1.4.3",
- "eleventy-plugin-vimeo-embed": "^1.4.0",
- "eleventy-plugin-youtube-embed": "^1.13.1"
- }
- },
- "node_modules/eleventy-plugin-embed-instagram": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-instagram/-/eleventy-plugin-embed-instagram-1.3.0.tgz",
- "integrity": "sha512-uF63snWEViwLQzr85ZAbKRXlWcLdPwepxuy7gERQVPzTNYWiPU1ruyf8H40qmznWPo7kWHa9Nnb5p4tM2Ilcjg==",
- "license": "MIT"
- },
- "node_modules/eleventy-plugin-embed-mastodon": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-mastodon/-/eleventy-plugin-embed-mastodon-1.0.2.tgz",
- "integrity": "sha512-JPDUcec2UouQ+tP1087ENMzfo0j8t0JXIYGfTjt+7HxF3cVUmPk+ZZhqX367OJmK2XSbeM5ZfPDORJ4Lhep8uQ==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-fetch": "^5.1.0",
- "deepmerge": "^4.3.1",
- "regex": "^6.0.1",
- "string-replace-async": "^3.0.2"
- }
- },
- "node_modules/eleventy-plugin-embed-mastodon/node_modules/@11ty/eleventy-fetch": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-fetch/-/eleventy-fetch-5.1.1.tgz",
- "integrity": "sha512-/xFJLCrqKlcnRKIfO9Qjd1QOs4IpvypljXET955+EgdRPFA+h8Or6bDnZBbcwr6KS7yeUuzp5k1DhXgbentSTA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.7",
- "@rgrove/parse-xml": "^4.2.0",
- "debug": "^4.4.3",
- "flatted": "^3.3.3",
- "p-queue": "6.6.2"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/eleventy-plugin-embed-openstreetmap": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-openstreetmap/-/eleventy-plugin-embed-openstreetmap-1.1.0.tgz",
- "integrity": "sha512-XKwEziI7feVZCkJXGSzgAlXR3ee9HeQ/WuTLS6KJKBQ+qGjOQHoi1seoTzsxeC/qt5V0pzgSD1xCgypQUlJ6Bw==",
- "license": "MIT",
- "dependencies": {
- "deepmerge": "^4.3.1"
- }
- },
- "node_modules/eleventy-plugin-embed-soundcloud": {
- "version": "1.2.10",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-soundcloud/-/eleventy-plugin-embed-soundcloud-1.2.10.tgz",
- "integrity": "sha512-4G8z4rmbPJDGi43kJG6K9pRWyVxWCo+CdFpWDUlkvUX5XyKfEzVNbO/8ML0ci4WU79U9FyjLtF1yKlGPEAO2lg==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-fetch": "^5.1.0"
- }
- },
- "node_modules/eleventy-plugin-embed-soundcloud/node_modules/@11ty/eleventy-fetch": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-fetch/-/eleventy-fetch-5.1.1.tgz",
- "integrity": "sha512-/xFJLCrqKlcnRKIfO9Qjd1QOs4IpvypljXET955+EgdRPFA+h8Or6bDnZBbcwr6KS7yeUuzp5k1DhXgbentSTA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.7",
- "@rgrove/parse-xml": "^4.2.0",
- "debug": "^4.4.3",
- "flatted": "^3.3.3",
- "p-queue": "6.6.2"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/eleventy-plugin-embed-spotify": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-spotify/-/eleventy-plugin-embed-spotify-1.3.0.tgz",
- "integrity": "sha512-waVUtW5PO9aKYQEjnvHG4P5bPyKj+SSUBuDtqfF2K+j7dGItmEDD4DP7CmBz6lkn/LlJGmJ7uT4Mr6L4jAP4bg==",
- "license": "MIT"
- },
- "node_modules/eleventy-plugin-embed-ted": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-ted/-/eleventy-plugin-embed-ted-1.0.1.tgz",
- "integrity": "sha512-F1CayKC05sGDAcdEgaZUP3Cs/71mwLT717sIUUiZWu+Gjd1Lp7m2gqL1R/uKnHN/CFxKYTpAA6ZNN/LCjg0ufw==",
- "license": "MIT"
- },
- "node_modules/eleventy-plugin-embed-tiktok": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-tiktok/-/eleventy-plugin-embed-tiktok-1.1.8.tgz",
- "integrity": "sha512-U0J7LV0lXmRbEt05E0NzbXiPw8V0Rr5eEQSyFwzAMrdrsxhoCSYFuE2L6+b7SXbV8ZzFjbPX07n1c4hgLfvfrQ==",
- "license": "MIT",
- "dependencies": {
- "deepmerge": "^4.3.1",
- "regex": "^6.0.1"
- }
- },
- "node_modules/eleventy-plugin-embed-twitch": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-twitch/-/eleventy-plugin-embed-twitch-1.2.8.tgz",
- "integrity": "sha512-ScjROm5sOwcClyE0DvZQ+6qF67lV4Yycsvb8p189QyJz3/wFw+9SQhyToY1FINRmUURIFRfLgp7AUXb3xAHmfg==",
- "license": "MIT"
- },
- "node_modules/eleventy-plugin-embed-twitter": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-embed-twitter/-/eleventy-plugin-embed-twitter-1.4.3.tgz",
- "integrity": "sha512-gHpoz7OFfpw/8QuK+m1ENQuzOdLAdGiP4R0cfAdMBAJMjMpB0moW6L3CDfG6Ai7R/Y8KwnTwnmLEznLv5v68BA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-fetch": "^5.1.0",
- "deepmerge": "^4.3.1"
- }
- },
- "node_modules/eleventy-plugin-embed-twitter/node_modules/@11ty/eleventy-fetch": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-fetch/-/eleventy-fetch-5.1.1.tgz",
- "integrity": "sha512-/xFJLCrqKlcnRKIfO9Qjd1QOs4IpvypljXET955+EgdRPFA+h8Or6bDnZBbcwr6KS7yeUuzp5k1DhXgbentSTA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.7",
- "@rgrove/parse-xml": "^4.2.0",
- "debug": "^4.4.3",
- "flatted": "^3.3.3",
- "p-queue": "6.6.2"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/eleventy-plugin-vimeo-embed": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-vimeo-embed/-/eleventy-plugin-vimeo-embed-1.4.0.tgz",
- "integrity": "sha512-GaDCi3b4gFx+TSzTEPjHlcGPqDBc8tQwJIQqkFMfkFBEnwMpC8fYLh8x31DLJ9C7R7Qh1FGVrb+A6qgKt//IqA==",
- "license": "MIT"
- },
- "node_modules/eleventy-plugin-youtube-embed": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/eleventy-plugin-youtube-embed/-/eleventy-plugin-youtube-embed-1.13.1.tgz",
- "integrity": "sha512-JfmPyNan5x9FC08RjLQIeBexpo1u+g06FCnEuQMkRbORh4dy/6LILJGcsPkrAHP6fw7ZnD/bogfTTuW5lCyukA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-fetch": "^5.1.0",
- "deepmerge": "^4.3.1",
- "lite-youtube-embed": "^0.3.4",
- "string-replace-async": "^3.0.2"
- }
- },
- "node_modules/eleventy-plugin-youtube-embed/node_modules/@11ty/eleventy-fetch": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@11ty/eleventy-fetch/-/eleventy-fetch-5.1.1.tgz",
- "integrity": "sha512-/xFJLCrqKlcnRKIfO9Qjd1QOs4IpvypljXET955+EgdRPFA+h8Or6bDnZBbcwr6KS7yeUuzp5k1DhXgbentSTA==",
- "license": "MIT",
- "dependencies": {
- "@11ty/eleventy-utils": "^2.0.7",
- "@rgrove/parse-xml": "^4.2.0",
- "debug": "^4.4.3",
- "flatted": "^3.3.3",
- "p-queue": "6.6.2"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/11ty"
- }
- },
- "node_modules/eleventy-plugin-youtube-embed/node_modules/lite-youtube-embed": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/lite-youtube-embed/-/lite-youtube-embed-0.3.4.tgz",
- "integrity": "sha512-aXgxpwK7AIW58GEbRzA8EYaY4LWvF3FKak6B9OtSJmuNyLhX2ouD4cMTxz/yR5HFInhknaYd2jLWOTRTvT8oAw==",
- "license": "Apache-2.0"
- },
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/emoji-regex-xs": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-2.0.1.tgz",
- "integrity": "sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==",
- "license": "MIT",
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/entities": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
- "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/errno": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/errno/-/errno-1.0.0.tgz",
- "integrity": "sha512-3zV5mFS1E8/1bPxt/B0xxzI1snsg3uSCIh6Zo1qKg6iMw93hzPANk9oBFzSFBFrwuVoQuE3rLoouAUfwOAj1wQ==",
- "license": "MIT",
- "dependencies": {
- "prr": "~1.0.1"
- },
- "bin": {
- "errno": "cli.js"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
- "license": "MIT"
- },
- "node_modules/escape-string-regexp": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
- "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/esm-import-transformer": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/esm-import-transformer/-/esm-import-transformer-3.0.5.tgz",
- "integrity": "sha512-1GKLvfuMnnpI75l8c6sHoz0L3Z872xL5akGuBudgqTDPv4Vy6f2Ec7jEMKTxlqWl/3kSvNbHELeimJtnqgYniw==",
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.15.0"
- }
- },
- "node_modules/esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "license": "BSD-2-Clause",
- "bin": {
- "esparse": "bin/esparse.js",
- "esvalidate": "bin/esvalidate.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/evaluate-value": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/evaluate-value/-/evaluate-value-2.0.0.tgz",
- "integrity": "sha512-VonfiuDJc0z4sOO7W0Pd130VLsXN6vmBWZlrog1mCb/o7o/Nl5Lr25+Kj/nkCCAhG+zqeeGjxhkK9oHpkgTHhQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/eventemitter3": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
- "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
- "license": "MIT"
- },
- "node_modules/extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
- "license": "MIT",
- "dependencies": {
- "is-extendable": "^0.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/fast-glob": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
- "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.8"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fastq": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
- "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "node_modules/fflate": {
- "version": "0.7.4",
- "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
- "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==",
- "license": "MIT"
- },
- "node_modules/filelist": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz",
- "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==",
- "license": "Apache-2.0",
- "dependencies": {
- "minimatch": "^5.0.1"
- }
- },
- "node_modules/filelist/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/filelist/node_modules/minimatch": {
- "version": "5.1.9",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
- "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/filesize": {
- "version": "10.1.6",
- "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz",
- "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">= 10.4.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/finalhandler": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
- "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==",
- "license": "MIT",
- "dependencies": {
- "debug": "2.6.9",
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "on-finished": "~2.4.1",
- "parseurl": "~1.3.3",
- "statuses": "~2.0.2",
- "unpipe": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/finalhandler/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/finalhandler/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
- "node_modules/flat-cache": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
- "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
- "license": "MIT",
- "dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.3",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/flatted": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
- "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
- "license": "ISC"
- },
- "node_modules/fraction.js": {
- "version": "5.3.4",
- "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
- "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/rawify"
- }
- },
- "node_modules/fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
- "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/fs-extra": {
- "version": "11.3.3",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz",
- "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=14.14"
- }
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "license": "ISC"
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": "6.* || 8.* || >= 10.*"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "license": "ISC"
- },
- "node_modules/graphemer": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
- "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
- "license": "MIT"
- },
- "node_modules/gray-matter": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz",
- "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==",
- "license": "MIT",
- "dependencies": {
- "js-yaml": "^3.13.1",
- "kind-of": "^6.0.2",
- "section-matter": "^1.0.0",
- "strip-bom-string": "^1.0.0"
- },
- "engines": {
- "node": ">=6.0"
- }
- },
- "node_modules/gray-matter/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "license": "MIT",
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
- "node_modules/gray-matter/node_modules/js-yaml": {
- "version": "3.14.2",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
- "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
- "license": "MIT",
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/hamljs": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/hamljs/-/hamljs-0.6.2.tgz",
- "integrity": "sha512-/chXRp4WpL47I+HX1vCCdSbEXAljEG2FBMmgO7Am0bYsqgnEjreeWzUdX1onXqwZtcfgxbCg5WtEYYvuZ5muBg=="
- },
- "node_modules/handlebars": {
- "version": "4.7.8",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
- "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
- "license": "MIT",
- "dependencies": {
- "minimist": "^1.2.5",
- "neo-async": "^2.6.2",
- "source-map": "^0.6.1",
- "wordwrap": "^1.0.0"
- },
- "bin": {
- "handlebars": "bin/handlebars"
- },
- "engines": {
- "node": ">=0.4.7"
- },
- "optionalDependencies": {
- "uglify-js": "^3.1.4"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-tostringtag": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
- "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "license": "MIT",
- "dependencies": {
- "has-symbols": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/he": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
- "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
- "license": "MIT",
- "bin": {
- "he": "bin/he"
- }
- },
- "node_modules/hex-rgb": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz",
- "integrity": "sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/html-minifier-terser": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz",
- "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==",
- "license": "MIT",
- "dependencies": {
- "camel-case": "^4.1.2",
- "clean-css": "~5.3.2",
- "commander": "^10.0.0",
- "entities": "^4.4.0",
- "param-case": "^3.0.4",
- "relateurl": "^0.2.7",
- "terser": "^5.15.1"
- },
- "bin": {
- "html-minifier-terser": "cli.js"
- },
- "engines": {
- "node": "^14.13.1 || >=16.0.0"
- }
- },
- "node_modules/html-minifier-terser/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/htmlparser2": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz",
- "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==",
- "funding": [
- "https://github.com/fb55/htmlparser2?sponsor=1",
- {
- "type": "github",
- "url": "https://github.com/sponsors/fb55"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.0.1",
- "domhandler": "^4.2.2",
- "domutils": "^2.8.0",
- "entities": "^3.0.1"
- }
- },
- "node_modules/htmlparser2/node_modules/entities": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
- "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/http-equiv-refresh": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/http-equiv-refresh/-/http-equiv-refresh-2.0.1.tgz",
- "integrity": "sha512-XJpDL/MLkV3dKwLzHwr2dY05dYNfBNlyPu4STQ8WvKCFdc6vC5tPXuq28of663+gHVg03C+16pHHs/+FmmDjcw==",
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/http-errors": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
- "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
- "license": "MIT",
- "dependencies": {
- "depd": "~2.0.0",
- "inherits": "~2.0.4",
- "setprototypeof": "~1.2.0",
- "statuses": "~2.0.2",
- "toidentifier": "~1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/image-size": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
- "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==",
- "license": "MIT",
- "dependencies": {
- "queue": "6.0.2"
- },
- "bin": {
- "image-size": "bin/image-size.js"
- },
- "engines": {
- "node": ">=16.x"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
- "license": "ISC",
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/is-alphabetical": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
- "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/is-alphanumerical": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
- "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
- "license": "MIT",
- "dependencies": {
- "is-alphabetical": "^2.0.0",
- "is-decimal": "^2.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/is-arrayish": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz",
- "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
- "license": "MIT"
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "license": "MIT",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
- "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
- "license": "MIT",
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-decimal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
- "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/is-expression": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz",
- "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==",
- "license": "MIT",
- "dependencies": {
- "acorn": "^7.1.1",
- "object-assign": "^4.1.1"
- }
- },
- "node_modules/is-expression/node_modules/acorn": {
- "version": "7.4.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
- "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/is-extendable": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
- "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-json": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz",
- "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==",
- "license": "ISC"
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-plain-object": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
- "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-promise": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
- "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
- "license": "MIT"
- },
- "node_modules/is-regex": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
- "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "gopd": "^1.2.0",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "license": "ISC"
- },
- "node_modules/iso-639-1": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.5.tgz",
- "integrity": "sha512-gXkz5+KN7HrG0Q5UGqSMO2qB9AsbEeyLP54kF1YrMsIxmu+g4BdB7rflReZTSTZGpfj8wywu6pfPBCylPIzGQA==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0"
- }
- },
- "node_modules/iso-datestring-validator": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz",
- "integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==",
- "license": "MIT"
- },
- "node_modules/jake": {
- "version": "10.9.4",
- "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz",
- "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==",
- "license": "Apache-2.0",
- "dependencies": {
- "async": "^3.2.6",
- "filelist": "^1.0.4",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "jake": "bin/cli.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/jiti": {
- "version": "1.21.7",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
- "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jiti": "bin/jiti.js"
- }
- },
- "node_modules/js-stringify": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
- "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==",
- "license": "MIT"
- },
- "node_modules/js-yaml": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
- "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "license": "MIT"
- },
- "node_modules/jsonfile": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz",
- "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "universalify": "^2.0.0"
- },
- "optionalDependencies": {
- "graceful-fs": "^4.1.6"
- }
- },
- "node_modules/jstransformer": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
- "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==",
- "license": "MIT",
- "dependencies": {
- "is-promise": "^2.0.0",
- "promise": "^7.0.1"
- }
- },
- "node_modules/junk": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz",
- "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
- "license": "MIT",
- "dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/kind-of": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/kleur": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
- "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/lilconfig": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
- "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antonk52"
- }
- },
- "node_modules/linebreak": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz",
- "integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==",
- "license": "MIT",
- "dependencies": {
- "base64-js": "0.0.8",
- "unicode-trie": "^2.0.0"
- }
- },
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/linkify-it": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
- "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
- "license": "MIT",
- "dependencies": {
- "uc.micro": "^2.0.0"
- }
- },
- "node_modules/liquidjs": {
- "version": "10.25.0",
- "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.0.tgz",
- "integrity": "sha512-XpO7AiGULTG4xcTlwkcTI5JreFG7b6esLCLp+aUSh7YuQErJZEoUXre9u9rbdb0057pfWG4l0VursvLd5Q/eAw==",
- "license": "MIT",
- "dependencies": {
- "commander": "^10.0.0"
- },
- "bin": {
- "liquid": "bin/liquid.js",
- "liquidjs": "bin/liquid.js"
- },
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/liquidjs"
- }
- },
- "node_modules/list-to-array": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/list-to-array/-/list-to-array-1.1.0.tgz",
- "integrity": "sha512-+dAZZ2mM+/m+vY9ezfoueVvrgnHIGi5FvgSymbIgJOFwiznWyA59mav95L+Mc6xPtL3s9gm5eNTlNtxJLbNM1g==",
- "license": "MIT"
- },
- "node_modules/lite-youtube-embed": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/lite-youtube-embed/-/lite-youtube-embed-0.3.2.tgz",
- "integrity": "sha512-b1dgKyF4PHhinonmr3PB172Nj0qQgA/7DE9EmeIXHR1ksnFEC2olWjNJyJGdsN2cleKHRjjsmrziKlwXtPlmLQ==",
- "license": "Apache-2.0"
- },
- "node_modules/lodash.deburr": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz",
- "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==",
- "license": "MIT"
- },
- "node_modules/lower-case": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
- "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
- "license": "MIT",
- "dependencies": {
- "tslib": "^2.0.3"
- }
- },
- "node_modules/luxon": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
- "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/markdown-it": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
- "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1",
- "entities": "^4.4.0",
- "linkify-it": "^5.0.0",
- "mdurl": "^2.0.0",
- "punycode.js": "^2.3.1",
- "uc.micro": "^2.1.0"
- },
- "bin": {
- "markdown-it": "bin/markdown-it.mjs"
- }
- },
- "node_modules/markdown-it-anchor": {
- "version": "9.2.0",
- "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-9.2.0.tgz",
- "integrity": "sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg==",
- "license": "Unlicense",
- "peerDependencies": {
- "@types/markdown-it": "*",
- "markdown-it": "*"
- }
- },
- "node_modules/markdown-it/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/maximatch": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/maximatch/-/maximatch-0.1.0.tgz",
- "integrity": "sha512-9ORVtDUFk4u/NFfo0vG/ND/z7UQCVZBL539YW0+U1I7H1BkZwizcPx5foFv7LCPcBnm2U6RjFnQOsIvN4/Vm2A==",
- "license": "MIT",
- "dependencies": {
- "array-differ": "^1.0.0",
- "array-union": "^1.0.1",
- "arrify": "^1.0.0",
- "minimatch": "^3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/mdurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
- "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
- "license": "MIT"
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/micromatch/node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/mime": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
- "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
- "license": "MIT",
- "bin": {
- "mime": "cli.js"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/mime-db": {
- "version": "1.54.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
- "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
- "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "^1.54.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "license": "ISC",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/mkdirp": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
- "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
- "license": "MIT",
- "dependencies": {
- "minimist": "^1.2.6"
- },
- "bin": {
- "mkdirp": "bin/cmd.js"
- }
- },
- "node_modules/moment": {
- "version": "2.30.1",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
- "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/moo": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
- "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==",
- "license": "BSD-3-Clause"
- },
- "node_modules/morphdom": {
- "version": "2.7.8",
- "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.8.tgz",
- "integrity": "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==",
- "license": "MIT"
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/multiformats": {
- "version": "9.9.0",
- "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
- "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==",
- "license": "(Apache-2.0 AND MIT)"
- },
- "node_modules/multimatch": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz",
- "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==",
- "license": "MIT",
- "dependencies": {
- "@types/minimatch": "^3.0.3",
- "array-differ": "^3.0.0",
- "array-union": "^2.1.0",
- "arrify": "^2.0.1",
- "minimatch": "^3.0.4"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/multimatch/node_modules/array-differ": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
- "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/multimatch/node_modules/array-union": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/multimatch/node_modules/arrify": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
- "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/mustache": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
- "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
- "license": "MIT",
- "bin": {
- "mustache": "bin/mustache"
- }
- },
- "node_modules/mz": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
- "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "any-promise": "^1.0.0",
- "object-assign": "^4.0.1",
- "thenify-all": "^1.0.0"
- }
- },
- "node_modules/nanoid": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/neo-async": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
- "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
- "license": "MIT"
- },
- "node_modules/no-case": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
- "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
- "license": "MIT",
- "dependencies": {
- "lower-case": "^2.0.2",
- "tslib": "^2.0.3"
- }
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/node-releases": {
- "version": "2.0.27",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
- "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/node-retrieve-globals": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/node-retrieve-globals/-/node-retrieve-globals-6.0.1.tgz",
- "integrity": "sha512-j0DeFuZ/Wg3VlklfbxUgZF/mdHMTEiEipBb3q0SpMMbHaV3AVfoUQF8UGxh1s/yjqO0TgRZd4Pi/x2yRqoQ4Eg==",
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.14.1",
- "acorn-walk": "^8.3.4",
- "esm-import-transformer": "^3.0.3"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/nunjucks": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz",
- "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "a-sync-waterfall": "^1.0.0",
- "asap": "^2.0.3",
- "commander": "^5.1.0"
- },
- "bin": {
- "nunjucks-precompile": "bin/precompile"
- },
- "engines": {
- "node": ">= 6.9.0"
- },
- "peerDependencies": {
- "chokidar": "^3.3.0"
- },
- "peerDependenciesMeta": {
- "chokidar": {
- "optional": true
- }
- }
- },
- "node_modules/nunjucks/node_modules/commander": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
- "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "license": "MIT",
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/p-finally": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/p-queue": {
- "version": "6.6.2",
- "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz",
- "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==",
- "license": "MIT",
- "dependencies": {
- "eventemitter3": "^4.0.4",
- "p-timeout": "^3.2.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-timeout": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
- "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
- "license": "MIT",
- "dependencies": {
- "p-finally": "^1.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pagefind": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.4.0.tgz",
- "integrity": "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==",
- "license": "MIT",
- "bin": {
- "pagefind": "lib/runner/bin.cjs"
- },
- "optionalDependencies": {
- "@pagefind/darwin-arm64": "1.4.0",
- "@pagefind/darwin-x64": "1.4.0",
- "@pagefind/freebsd-x64": "1.4.0",
- "@pagefind/linux-arm64": "1.4.0",
- "@pagefind/linux-x64": "1.4.0",
- "@pagefind/windows-x64": "1.4.0"
- }
- },
- "node_modules/pako": {
- "version": "0.2.9",
- "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
- "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==",
- "license": "MIT"
- },
- "node_modules/param-case": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
- "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
- "license": "MIT",
- "dependencies": {
- "dot-case": "^3.0.4",
- "tslib": "^2.0.3"
- }
- },
- "node_modules/parse-css-color": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/parse-css-color/-/parse-css-color-0.2.1.tgz",
- "integrity": "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==",
- "license": "MIT",
- "dependencies": {
- "color-name": "^1.1.4",
- "hex-rgb": "^4.1.0"
- }
- },
- "node_modules/parse-srcset": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
- "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==",
- "license": "MIT"
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/pascal-case": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
- "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
- "license": "MIT",
- "dependencies": {
- "no-case": "^3.0.4",
- "tslib": "^2.0.3"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "license": "MIT"
- },
- "node_modules/path-to-regexp": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
- "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
- "license": "MIT"
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pirates": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
- "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/please-upgrade-node": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
- "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
- "license": "MIT",
- "dependencies": {
- "semver-compare": "^1.0.0"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.6",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
- "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.11",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/postcss-cli": {
- "version": "11.0.1",
- "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-11.0.1.tgz",
- "integrity": "sha512-0UnkNPSayHKRe/tc2YGW6XnSqqOA9eqpiRMgRlV1S6HdGi16vwJBx7lviARzbV1HpQHqLLRH3o8vTcB0cLc+5g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chokidar": "^3.3.0",
- "dependency-graph": "^1.0.0",
- "fs-extra": "^11.0.0",
- "picocolors": "^1.0.0",
- "postcss-load-config": "^5.0.0",
- "postcss-reporter": "^7.0.0",
- "pretty-hrtime": "^1.0.3",
- "read-cache": "^1.0.0",
- "slash": "^5.0.0",
- "tinyglobby": "^0.2.12",
- "yargs": "^17.0.0"
- },
- "bin": {
- "postcss": "index.js"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "postcss": "^8.0.0"
- }
- },
- "node_modules/postcss-cli/node_modules/slash": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
- "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/postcss-import": {
- "version": "15.1.0",
- "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
- "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "postcss-value-parser": "^4.0.0",
- "read-cache": "^1.0.0",
- "resolve": "^1.1.7"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "postcss": "^8.0.0"
- }
- },
- "node_modules/postcss-js": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
- "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "camelcase-css": "^2.0.1"
- },
- "engines": {
- "node": "^12 || ^14 || >= 16"
- },
- "peerDependencies": {
- "postcss": "^8.4.21"
- }
- },
- "node_modules/postcss-load-config": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-5.1.0.tgz",
- "integrity": "sha512-G5AJ+IX0aD0dygOE0yFZQ/huFFMSNneyfp0e3/bT05a8OfPC5FUoZRPfGijUdGOJNMewJiwzcHJXFafFzeKFVA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "lilconfig": "^3.1.1",
- "yaml": "^2.4.2"
- },
- "engines": {
- "node": ">= 18"
- },
- "peerDependencies": {
- "jiti": ">=1.21.0",
- "postcss": ">=8.0.9",
- "tsx": "^4.8.1"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- },
- "postcss": {
- "optional": true
- },
- "tsx": {
- "optional": true
- }
- }
- },
- "node_modules/postcss-nested": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
- "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "postcss-selector-parser": "^6.1.1"
- },
- "engines": {
- "node": ">=12.0"
- },
- "peerDependencies": {
- "postcss": "^8.2.14"
- }
- },
- "node_modules/postcss-nested/node_modules/postcss-selector-parser": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
- "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/postcss-reporter": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.1.0.tgz",
- "integrity": "sha512-/eoEylGWyy6/DOiMP5lmFRdmDKThqgn7D6hP2dXKJI/0rJSO1ADFNngZfDzxL0YAxFvws+Rtpuji1YIHj4mySA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "picocolors": "^1.0.0",
- "thenby": "^1.3.4"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "postcss": "^8.1.0"
- }
- },
- "node_modules/postcss-selector-parser": {
- "version": "6.0.10",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
- "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "license": "MIT"
- },
- "node_modules/posthtml": {
- "version": "0.16.7",
- "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.7.tgz",
- "integrity": "sha512-7Hc+IvlQ7hlaIfQFZnxlRl0jnpWq2qwibORBhQYIb0QbNtuicc5ZxvKkVT71HJ4Py1wSZ/3VR1r8LfkCtoCzhw==",
- "license": "MIT",
- "dependencies": {
- "posthtml-parser": "^0.11.0",
- "posthtml-render": "^3.0.0"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/posthtml-match-helper": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/posthtml-match-helper/-/posthtml-match-helper-2.0.3.tgz",
- "integrity": "sha512-p9oJgTdMF2dyd7WE54QI1LvpBIkNkbSiiECKezNnDVYhGhD1AaOnAkw0Uh0y5TW+OHO8iBdSqnd8Wkpb6iUqmw==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "posthtml": "^0.16.6"
- }
- },
- "node_modules/posthtml-parser": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz",
- "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==",
- "license": "MIT",
- "dependencies": {
- "htmlparser2": "^7.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/posthtml-render": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz",
- "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==",
- "license": "MIT",
- "dependencies": {
- "is-json": "^2.0.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/posthtml-urls": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/posthtml-urls/-/posthtml-urls-1.0.0.tgz",
- "integrity": "sha512-CMJ0L009sGQVUuYM/g6WJdscsq6ooAwhUuF6CDlYPMLxKp2rmCYVebEU+wZGxnQstGJhZPMvXsRhtqekILd5/w==",
- "license": "MIT",
- "dependencies": {
- "http-equiv-refresh": "^1.0.0",
- "list-to-array": "^1.1.0",
- "parse-srcset": "^1.0.2",
- "promise-each": "^2.2.0"
- },
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/posthtml-urls/node_modules/http-equiv-refresh": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/http-equiv-refresh/-/http-equiv-refresh-1.0.0.tgz",
- "integrity": "sha512-TScO04soylRN9i/QdOdgZyhydXg9z6XdaGzEyOgDKycePeDeTT4KvigjBcI+tgfTlieLWauGORMq5F1eIDa+1w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/pretty-hrtime": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
- "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/prismjs": {
- "version": "1.30.0",
- "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
- "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/promise": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
- "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
- "license": "MIT",
- "dependencies": {
- "asap": "~2.0.3"
- }
- },
- "node_modules/promise-each": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/promise-each/-/promise-each-2.2.0.tgz",
- "integrity": "sha512-67roqt1k3QDA41DZ8xi0V+rF3GoaMiX7QilbXu0vXimut+9RcKBNZ/t60xCRgcsihmNUsEjh48xLfNqOrKblUg==",
- "license": "MIT",
- "dependencies": {
- "any-promise": "^0.1.0"
- }
- },
- "node_modules/promise-each/node_modules/any-promise": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-0.1.0.tgz",
- "integrity": "sha512-lqzY9o+BbeGHRCOyxQkt/Tgvz0IZhTmQiA+LxQW8wSNpcTbj8K+0cZiSEvbpNZZP9/11Gy7dnLO3GNWUXO4d1g==",
- "license": "MIT"
- },
- "node_modules/prr": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
- "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
- "license": "MIT"
- },
- "node_modules/pug": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.3.tgz",
- "integrity": "sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==",
- "license": "MIT",
- "dependencies": {
- "pug-code-gen": "^3.0.3",
- "pug-filters": "^4.0.0",
- "pug-lexer": "^5.0.1",
- "pug-linker": "^4.0.0",
- "pug-load": "^3.0.0",
- "pug-parser": "^6.0.0",
- "pug-runtime": "^3.0.1",
- "pug-strip-comments": "^2.0.0"
- }
- },
- "node_modules/pug-attrs": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz",
- "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==",
- "license": "MIT",
- "dependencies": {
- "constantinople": "^4.0.1",
- "js-stringify": "^1.0.2",
- "pug-runtime": "^3.0.0"
- }
- },
- "node_modules/pug-code-gen": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.3.tgz",
- "integrity": "sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==",
- "license": "MIT",
- "dependencies": {
- "constantinople": "^4.0.1",
- "doctypes": "^1.1.0",
- "js-stringify": "^1.0.2",
- "pug-attrs": "^3.0.0",
- "pug-error": "^2.1.0",
- "pug-runtime": "^3.0.1",
- "void-elements": "^3.1.0",
- "with": "^7.0.0"
- }
- },
- "node_modules/pug-error": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz",
- "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==",
- "license": "MIT"
- },
- "node_modules/pug-filters": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz",
- "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==",
- "license": "MIT",
- "dependencies": {
- "constantinople": "^4.0.1",
- "jstransformer": "1.0.0",
- "pug-error": "^2.0.0",
- "pug-walk": "^2.0.0",
- "resolve": "^1.15.1"
- }
- },
- "node_modules/pug-lexer": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz",
- "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==",
- "license": "MIT",
- "dependencies": {
- "character-parser": "^2.2.0",
- "is-expression": "^4.0.0",
- "pug-error": "^2.0.0"
- }
- },
- "node_modules/pug-linker": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz",
- "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==",
- "license": "MIT",
- "dependencies": {
- "pug-error": "^2.0.0",
- "pug-walk": "^2.0.0"
- }
- },
- "node_modules/pug-load": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz",
- "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==",
- "license": "MIT",
- "dependencies": {
- "object-assign": "^4.1.1",
- "pug-walk": "^2.0.0"
- }
- },
- "node_modules/pug-parser": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz",
- "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==",
- "license": "MIT",
- "dependencies": {
- "pug-error": "^2.0.0",
- "token-stream": "1.0.0"
- }
- },
- "node_modules/pug-runtime": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz",
- "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==",
- "license": "MIT"
- },
- "node_modules/pug-strip-comments": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz",
- "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==",
- "license": "MIT",
- "dependencies": {
- "pug-error": "^2.0.0"
- }
- },
- "node_modules/pug-walk": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz",
- "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==",
- "license": "MIT"
- },
- "node_modules/punycode.js": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
- "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/queue": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
- "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
- "license": "MIT",
- "dependencies": {
- "inherits": "~2.0.3"
- }
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/read-cache": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
- "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "pify": "^2.3.0"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "license": "MIT",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/readdirp/node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/recursive-copy": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/recursive-copy/-/recursive-copy-2.0.14.tgz",
- "integrity": "sha512-K8WNY8f8naTpfbA+RaXmkaQuD1IeW9EgNEfyGxSqqTQukpVtoOKros9jUqbpEsSw59YOmpd8nCBgtqJZy5nvog==",
- "license": "ISC",
- "dependencies": {
- "errno": "^0.1.2",
- "graceful-fs": "^4.1.4",
- "junk": "^1.0.1",
- "maximatch": "^0.1.0",
- "mkdirp": "^0.5.1",
- "pify": "^2.3.0",
- "promise": "^7.0.1",
- "rimraf": "^2.7.1",
- "slash": "^1.0.0"
- }
- },
- "node_modules/recursive-copy/node_modules/errno": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
- "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
- "license": "MIT",
- "dependencies": {
- "prr": "~1.0.1"
- },
- "bin": {
- "errno": "cli.js"
- }
- },
- "node_modules/recursive-copy/node_modules/junk": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/junk/-/junk-1.0.3.tgz",
- "integrity": "sha512-3KF80UaaSSxo8jVnRYtMKNGFOoVPBdkkVPsw+Ad0y4oxKXPduS6G6iHkrf69yJVff/VAaYXkV42rtZ7daJxU3w==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/recursive-copy/node_modules/rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- }
- },
- "node_modules/recursive-copy/node_modules/slash": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
- "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/regex": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz",
- "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==",
- "license": "MIT",
- "dependencies": {
- "regex-utilities": "^2.3.0"
- }
- },
- "node_modules/regex-utilities": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz",
- "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==",
- "license": "MIT"
- },
- "node_modules/relateurl": {
- "version": "0.2.7",
- "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
- "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.11",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
- "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
- "license": "MIT",
- "dependencies": {
- "is-core-module": "^2.16.1",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/reusify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
- "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
- "license": "MIT",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/rss-parser": {
- "version": "3.13.0",
- "resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.13.0.tgz",
- "integrity": "sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==",
- "license": "MIT",
- "dependencies": {
- "entities": "^2.0.3",
- "xml2js": "^0.5.0"
- }
- },
- "node_modules/rss-parser/node_modules/entities": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
- "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
- "license": "BSD-2-Clause",
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "license": "MIT"
- },
- "node_modules/sanitize-html": {
- "version": "2.17.0",
- "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.0.tgz",
- "integrity": "sha512-dLAADUSS8rBwhaevT12yCezvioCA+bmUTPH/u57xKPT8d++voeYE6HeluA/bPbQ15TwDBG2ii+QZIEmYx8VdxA==",
- "license": "MIT",
- "dependencies": {
- "deepmerge": "^4.2.2",
- "escape-string-regexp": "^4.0.0",
- "htmlparser2": "^8.0.0",
- "is-plain-object": "^5.0.0",
- "parse-srcset": "^1.0.2",
- "postcss": "^8.3.11"
- }
- },
- "node_modules/sanitize-html/node_modules/dom-serializer": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
- "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.2",
- "entities": "^4.2.0"
- },
- "funding": {
- "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
- }
- },
- "node_modules/sanitize-html/node_modules/domhandler": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
- "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "domelementtype": "^2.3.0"
- },
- "engines": {
- "node": ">= 4"
- },
- "funding": {
- "url": "https://github.com/fb55/domhandler?sponsor=1"
- }
- },
- "node_modules/sanitize-html/node_modules/domutils": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
- "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "dom-serializer": "^2.0.0",
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.3"
- },
- "funding": {
- "url": "https://github.com/fb55/domutils?sponsor=1"
- }
- },
- "node_modules/sanitize-html/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/sanitize-html/node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/sanitize-html/node_modules/htmlparser2": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
- "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
- "funding": [
- "https://github.com/fb55/htmlparser2?sponsor=1",
- {
- "type": "github",
- "url": "https://github.com/sponsors/fb55"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.3",
- "domutils": "^3.0.1",
- "entities": "^4.4.0"
- }
- },
- "node_modules/satori": {
- "version": "0.19.2",
- "resolved": "https://registry.npmjs.org/satori/-/satori-0.19.2.tgz",
- "integrity": "sha512-71plFHWcq6WJBM5sf/n0eHOmTBiKLUB/G8du7SmLTTLHKEKrV3TPHGKcEVIoyjnbhnjvu9HhLyF9MATB/zzL7g==",
- "license": "MPL-2.0",
- "dependencies": {
- "@shuding/opentype.js": "1.4.0-beta.0",
- "css-background-parser": "^0.1.0",
- "css-box-shadow": "1.0.0-3",
- "css-gradient-parser": "^0.0.17",
- "css-to-react-native": "^3.0.0",
- "emoji-regex-xs": "^2.0.1",
- "escape-html": "^1.0.3",
- "linebreak": "^1.1.0",
- "parse-css-color": "^0.2.1",
- "postcss-value-parser": "^4.2.0",
- "yoga-layout": "^3.2.1"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/sax": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz",
- "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=11.0.0"
- }
- },
- "node_modules/section-matter": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
- "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==",
- "license": "MIT",
- "dependencies": {
- "extend-shallow": "^2.0.1",
- "kind-of": "^6.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/semver-compare": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
- "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
- "license": "MIT"
- },
- "node_modules/send": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
- "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.3",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.1",
- "mime-types": "^3.0.2",
- "ms": "^2.1.3",
- "on-finished": "^2.4.1",
- "range-parser": "^1.2.1",
- "statuses": "^2.0.2"
- },
- "engines": {
- "node": ">= 18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "license": "ISC"
- },
- "node_modules/sharp": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
- "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
- "hasInstallScript": true,
- "license": "Apache-2.0",
- "dependencies": {
- "color": "^4.2.3",
- "detect-libc": "^2.0.3",
- "semver": "^7.6.3"
- },
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-darwin-arm64": "0.33.5",
- "@img/sharp-darwin-x64": "0.33.5",
- "@img/sharp-libvips-darwin-arm64": "1.0.4",
- "@img/sharp-libvips-darwin-x64": "1.0.4",
- "@img/sharp-libvips-linux-arm": "1.0.5",
- "@img/sharp-libvips-linux-arm64": "1.0.4",
- "@img/sharp-libvips-linux-s390x": "1.0.4",
- "@img/sharp-libvips-linux-x64": "1.0.4",
- "@img/sharp-libvips-linuxmusl-arm64": "1.0.4",
- "@img/sharp-libvips-linuxmusl-x64": "1.0.4",
- "@img/sharp-linux-arm": "0.33.5",
- "@img/sharp-linux-arm64": "0.33.5",
- "@img/sharp-linux-s390x": "0.33.5",
- "@img/sharp-linux-x64": "0.33.5",
- "@img/sharp-linuxmusl-arm64": "0.33.5",
- "@img/sharp-linuxmusl-x64": "0.33.5",
- "@img/sharp-wasm32": "0.33.5",
- "@img/sharp-win32-ia32": "0.33.5",
- "@img/sharp-win32-x64": "0.33.5"
- }
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/simple-swizzle": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz",
- "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
- "license": "MIT",
- "dependencies": {
- "is-arrayish": "^0.3.1"
- }
- },
- "node_modules/sitemap": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-6.4.0.tgz",
- "integrity": "sha512-DoPKNc2/apQZTUnfiOONWctwq7s6dZVspxAZe2VPMNtoqNq7HgXRvlRnbIpKjf+8+piQdWncwcy+YhhTGY5USQ==",
- "license": "MIT",
- "dependencies": {
- "@types/node": "^14.14.28",
- "@types/sax": "^1.2.1",
- "arg": "^5.0.0",
- "sax": "^1.2.4"
- },
- "bin": {
- "sitemap": "dist/cli.js"
- },
- "engines": {
- "node": ">=10.3.0",
- "npm": ">=5.6.0"
- }
- },
- "node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/slugify": {
- "version": "1.6.6",
- "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
- "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
- "license": "MIT",
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-support": {
- "version": "0.5.21",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
- "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
- "license": "MIT",
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
- "node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "license": "BSD-3-Clause"
- },
- "node_modules/ssri": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-11.0.0.tgz",
- "integrity": "sha512-aZpUoMN/Jj2MqA4vMCeiKGnc/8SuSyHbGSBdgFbZxP8OJGF/lFkIuElzPxsN0q8TQQ+prw3P4EDfB3TBHHgfXw==",
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.3"
- },
- "engines": {
- "node": "^16.14.0 || >=18.0.0"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/string-replace-async": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/string-replace-async/-/string-replace-async-3.0.2.tgz",
- "integrity": "sha512-s6hDtXJ7FKyRap/amefqrOMpkEQvxUDueyvJygQeHxCK5Za90dOMgdibCCrPdfdAYAkr8imrZ1PPXW7DOf0RzQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 14.0.0"
- }
- },
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/string.prototype.codepointat": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
- "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==",
- "license": "MIT"
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-bom-string": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
- "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/sucrase": {
- "version": "3.35.1",
- "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz",
- "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.2",
- "commander": "^4.0.0",
- "lines-and-columns": "^1.1.6",
- "mz": "^2.7.0",
- "pirates": "^4.0.1",
- "tinyglobby": "^0.2.11",
- "ts-interface-checker": "^0.1.9"
- },
- "bin": {
- "sucrase": "bin/sucrase",
- "sucrase-node": "bin/sucrase-node"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/sucrase/node_modules/commander": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
- "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/tailwindcss": {
- "version": "3.4.19",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz",
- "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@alloc/quick-lru": "^5.2.0",
- "arg": "^5.0.2",
- "chokidar": "^3.6.0",
- "didyoumean": "^1.2.2",
- "dlv": "^1.1.3",
- "fast-glob": "^3.3.2",
- "glob-parent": "^6.0.2",
- "is-glob": "^4.0.3",
- "jiti": "^1.21.7",
- "lilconfig": "^3.1.3",
- "micromatch": "^4.0.8",
- "normalize-path": "^3.0.0",
- "object-hash": "^3.0.0",
- "picocolors": "^1.1.1",
- "postcss": "^8.4.47",
- "postcss-import": "^15.1.0",
- "postcss-js": "^4.0.1",
- "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
- "postcss-nested": "^6.2.0",
- "postcss-selector-parser": "^6.1.2",
- "resolve": "^1.22.8",
- "sucrase": "^3.35.0"
- },
- "bin": {
- "tailwind": "lib/cli.js",
- "tailwindcss": "lib/cli.js"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/tailwindcss/node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/tailwindcss/node_modules/postcss-selector-parser": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
- "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/terser": {
- "version": "5.46.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz",
- "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "@jridgewell/source-map": "^0.3.3",
- "acorn": "^8.15.0",
- "commander": "^2.20.0",
- "source-map-support": "~0.5.20"
- },
- "bin": {
- "terser": "bin/terser"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/terser/node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "license": "MIT"
- },
- "node_modules/thenby": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz",
- "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/thenify": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
- "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "any-promise": "^1.0.0"
- }
- },
- "node_modules/thenify-all": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
- "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "thenify": ">= 3.1.0 < 4"
- },
- "engines": {
- "node": ">=0.8"
- }
- },
- "node_modules/tiny-inflate": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
- "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==",
- "license": "MIT"
- },
- "node_modules/tinyglobby": {
- "version": "0.2.15",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
- "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
- "license": "MIT",
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
- "node_modules/tlds": {
- "version": "1.261.0",
- "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.261.0.tgz",
- "integrity": "sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==",
- "license": "MIT",
- "bin": {
- "tlds": "bin.js"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/token-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz",
- "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==",
- "license": "MIT"
- },
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "license": "MIT"
- },
- "node_modules/ts-interface-checker": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
- "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/tslib": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "license": "0BSD"
- },
- "node_modules/uc.micro": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
- "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
- "license": "MIT"
- },
- "node_modules/uglify-js": {
- "version": "3.19.3",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
- "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
- "license": "BSD-2-Clause",
- "optional": true,
- "bin": {
- "uglifyjs": "bin/uglifyjs"
- },
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/uint8arrays": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.0.0.tgz",
- "integrity": "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==",
- "license": "MIT",
- "dependencies": {
- "multiformats": "^9.4.2"
- }
- },
- "node_modules/unfurl.js": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/unfurl.js/-/unfurl.js-6.4.0.tgz",
- "integrity": "sha512-DogJFWPkOWMcu2xPdpmbcsL+diOOJInD3/jXOv6saX1upnWmMK8ndAtDWUfJkuInqNI9yzADud4ID9T+9UeWCw==",
- "license": "ISC",
- "dependencies": {
- "debug": "^3.2.7",
- "he": "^1.2.0",
- "htmlparser2": "^8.0.1",
- "iconv-lite": "^0.4.24",
- "node-fetch": "^2.6.7"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/unfurl.js/node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.1"
- }
- },
- "node_modules/unfurl.js/node_modules/dom-serializer": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
- "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.2",
- "entities": "^4.2.0"
- },
- "funding": {
- "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
- }
- },
- "node_modules/unfurl.js/node_modules/domhandler": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
- "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "domelementtype": "^2.3.0"
- },
- "engines": {
- "node": ">= 4"
- },
- "funding": {
- "url": "https://github.com/fb55/domhandler?sponsor=1"
- }
- },
- "node_modules/unfurl.js/node_modules/domutils": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
- "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "dom-serializer": "^2.0.0",
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.3"
- },
- "funding": {
- "url": "https://github.com/fb55/domutils?sponsor=1"
- }
- },
- "node_modules/unfurl.js/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/unfurl.js/node_modules/htmlparser2": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
- "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
- "funding": [
- "https://github.com/fb55/htmlparser2?sponsor=1",
- {
- "type": "github",
- "url": "https://github.com/sponsors/fb55"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "domelementtype": "^2.3.0",
- "domhandler": "^5.0.3",
- "domutils": "^3.0.1",
- "entities": "^4.4.0"
- }
- },
- "node_modules/unicode-segmenter": {
- "version": "0.14.5",
- "resolved": "https://registry.npmjs.org/unicode-segmenter/-/unicode-segmenter-0.14.5.tgz",
- "integrity": "sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==",
- "license": "MIT"
- },
- "node_modules/unicode-trie": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz",
- "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==",
- "license": "MIT",
- "dependencies": {
- "pako": "^0.2.5",
- "tiny-inflate": "^1.0.0"
- }
- },
- "node_modules/universalify": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
- "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/update-browserslist-db": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
- "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/urlpattern-polyfill": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz",
- "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==",
- "license": "MIT"
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/void-elements": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
- "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "license": "BSD-2-Clause"
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "license": "MIT",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/with": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz",
- "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==",
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.9.6",
- "@babel/types": "^7.9.6",
- "assert-never": "^1.2.1",
- "babel-walk": "3.0.0-canary-5"
- },
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
- "license": "MIT"
- },
- "node_modules/wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
- },
- "node_modules/ws": {
- "version": "8.19.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
- "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
- "license": "MIT",
- "engines": {
- "node": ">=10.0.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": ">=5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
- "node_modules/xml2js": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
- "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
- "license": "MIT",
- "dependencies": {
- "sax": ">=0.6.0",
- "xmlbuilder": "~11.0.0"
- },
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/xmlbuilder": {
- "version": "11.0.1",
- "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
- "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
- "license": "MIT",
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "license": "ISC"
- },
- "node_modules/yaml": {
- "version": "2.8.2",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz",
- "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/eemeli"
- }
- },
- "node_modules/yargs": {
- "version": "17.7.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
- "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yoga-layout": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz",
- "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==",
- "license": "MIT"
- },
- "node_modules/zod": {
- "version": "3.25.76",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
- "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- }
- }
-}
diff --git a/theme/package.json b/theme/package.json
deleted file mode 100644
index 67f95e5..0000000
--- a/theme/package.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "name": "indiekit-eleventy-theme",
- "version": "1.0.0",
- "description": "Eleventy theme for Indiekit — IndieWeb-ready personal website",
- "type": "module",
- "scripts": {
- "build": "eleventy",
- "dev": "eleventy --serve --watch",
- "build:css": "postcss css/tailwind.css -o css/style.css"
- },
- "dependencies": {
- "@11ty/eleventy": "^3.0.0",
- "@11ty/eleventy-fetch": "^4.0.1",
- "@11ty/eleventy-img": "^6.0.0",
- "@11ty/eleventy-plugin-rss": "^2.0.2",
- "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
- "@11ty/is-land": "^5.0.1",
- "@alpinejs/collapse": "^3.15.8",
- "@atproto/api": "^0.12.0",
- "@chrisburnell/eleventy-cache-webmentions": "^2.2.7",
- "@fontsource/inter": "^5.2.8",
- "@quasibit/eleventy-plugin-sitemap": "^2.2.0",
- "@resvg/resvg-js": "^2.6.2",
- "@rknightuk/eleventy-plugin-post-graph": "^1.0.8",
- "@zachleat/filter-container": "^4.0.0",
- "@zachleat/table-saw": "^1.0.7",
- "alpinejs": "^3.15.8",
- "eleventy-plugin-embed-everything": "^1.21.0",
- "gray-matter": "^4.0.3",
- "html-minifier-terser": "^7.0.0",
- "lite-youtube-embed": "^0.3.2",
- "markdown-it": "^14.0.0",
- "markdown-it-anchor": "^9.2.0",
- "pagefind": "^1.3.0",
- "rss-parser": "^3.13.0",
- "satori": "^0.19.2",
- "unfurl.js": "^6.4.0"
- },
- "devDependencies": {
- "@tailwindcss/typography": "^0.5.0",
- "autoprefixer": "^10.4.0",
- "postcss": "^8.4.0",
- "postcss-cli": "^11.0.0",
- "tailwindcss": "^3.4.0"
- }
-}
diff --git a/theme/podroll.njk b/theme/podroll.njk
deleted file mode 100644
index d1e8f54..0000000
--- a/theme/podroll.njk
+++ /dev/null
@@ -1,386 +0,0 @@
----
-layout: layouts/base.njk
-title: Podroll
-permalink: /podroll/
----
-
-
-
diff --git a/theme/postcss.config.js b/theme/postcss.config.js
deleted file mode 100644
index 2e7af2b..0000000
--- a/theme/postcss.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- },
-}
diff --git a/theme/readlater.njk b/theme/readlater.njk
deleted file mode 100644
index 01de949..0000000
--- a/theme/readlater.njk
+++ /dev/null
@@ -1,250 +0,0 @@
----
-layout: layouts/base.njk
-title: Reading List
-permalink: /readlater/
----
-
-
-
diff --git a/theme/replies.njk b/theme/replies.njk
deleted file mode 100644
index 48666de..0000000
--- a/theme/replies.njk
+++ /dev/null
@@ -1,139 +0,0 @@
----
-layout: layouts/base.njk
-title: Replies
-withSidebar: true
-pagination:
- data: collections.replies
- size: 20
- alias: paginatedReplies
- generatePageOnEmptyData: true
-permalink: "replies/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
----
-
-
-
Replies
- {% set sparklineSvg = collections.replies | postingFrequency %}
- {% if sparklineSvg %}
- {{ sparklineSvg | safe }}
- {% endif %}
-
-
- My responses to posts across the web.
- ({{ collections.replies.length }} total)
-
-
- {% if paginatedReplies.length > 0 %}
-
- {% for post in paginatedReplies %}
-
-
-
- {% endfor %}
-
-
- {# Pagination controls #}
- {% if pagination.pages.length > 1 %}
-
- {% endif %}
-
- {% else %}
- {% set postType = "reply" %}
- {% include "components/empty-collection.njk" %}
- {% endif %}
-
diff --git a/theme/reposts.njk b/theme/reposts.njk
deleted file mode 100644
index 45bdf0b..0000000
--- a/theme/reposts.njk
+++ /dev/null
@@ -1,115 +0,0 @@
----
-layout: layouts/base.njk
-title: Reposts
-withSidebar: true
-pagination:
- data: collections.reposts
- size: 20
- alias: paginatedReposts
- generatePageOnEmptyData: true
-permalink: "reposts/{% if pagination.pageNumber > 0 %}page/{{ pagination.pageNumber + 1 }}/{% endif %}"
----
-
-
-
Reposts
- {% set sparklineSvg = collections.reposts | postingFrequency %}
- {% if sparklineSvg %}
- {{ sparklineSvg | safe }}
- {% endif %}
-
-
- Content I've shared from others.
- ({{ collections.reposts.length }} total)
-
-
- {% if paginatedReposts.length > 0 %}
-
- {% for post in paginatedReposts %}
-
-
-
- {% endfor %}
-
-
- {# Pagination controls #}
- {% if pagination.pages.length > 1 %}
-
- {% endif %}
-
- {% else %}
- {% set postType = "repost" %}
- {% include "components/empty-collection.njk" %}
- {% endif %}
-
diff --git a/theme/search.njk b/theme/search.njk
deleted file mode 100644
index 73d065c..0000000
--- a/theme/search.njk
+++ /dev/null
@@ -1,39 +0,0 @@
----
-layout: layouts/base.njk
-title: Search
-permalink: /search/
-eleventyExcludeFromCollections: true
-pagefindIgnore: true
----
-
-
-
-
-
-
Search requires JavaScript to be enabled. Please enable JavaScript in your browser settings to use the search feature.
-
Alternatively, you can browse content via the blog archive or categories .
-
-
-
-
diff --git a/theme/slashes.njk b/theme/slashes.njk
deleted file mode 100644
index 8ef470a..0000000
--- a/theme/slashes.njk
+++ /dev/null
@@ -1,162 +0,0 @@
----
-layout: layouts/base.njk
-title: Slash Pages
-withSidebar: true
-permalink: /slashes/
-eleventyImport:
- collections:
- - pages
----
-
-
Slash Pages
-
- Root-level pages on this site. Inspired by slashpages.net .
-
-
- {# Dynamic pages (created via Indiekit) #}
-
-
Pages
- {% if collections.pages.length > 0 %}
-
- {% for page in collections.pages %}
-
-
- {% if page.data.summary %}
- {{ page.data.summary }}
- {% elif page.data.title %}
- {{ page.data.title }}
- {% endif %}
- {% if page.data.updated %}
-
- Updated: {{ page.data.updated | dateDisplay }}
-
- {% endif %}
-
- {% endfor %}
-
- {% else %}
-
-
- No root pages yet. To create pages like /now, /uses, or /colophon, you need two plugins:
-
-
- @rmdes/indiekit-post-type-page — registers the "page" post type with Indiekit, using root-level URL paths (/slug instead of /type/YYYY/MM/DD/slug)
- @rmdes/indiekit-endpoint-posts — publishing UI that sends the h=page Micropub type so pages are created at root level
-
-
- Once both plugins are installed, "Page" appears as a post type in the Indiekit admin UI, and pages are published directly at /slug.
-
-
- {% endif %}
-
-
- {# Activity pages — only show when their plugin backend is available #}
- {% set hasActivityPages = (funkwhaleActivity and funkwhaleActivity.source == "indiekit") or
- (githubActivity and githubActivity.source != "error") or
- (lastfmActivity and lastfmActivity.source == "indiekit") or
- (newsActivity and newsActivity.source == "indiekit") or
- (youtubeChannel and youtubeChannel.source == "indiekit") or
- (blogrollStatus and blogrollStatus.source == "indiekit") or
- (podrollStatus and podrollStatus.source == "indiekit") or
- (whereCheckins and whereCheckins.source != "error") %}
- {% if hasActivityPages %}
-
-
Activity Feeds
-
- {% if blogrollStatus and blogrollStatus.source == "indiekit" %}
-
-
- Sites I follow
-
- {% endif %}
- {% if funkwhaleActivity and funkwhaleActivity.source == "indiekit" %}
-
-
- Funkwhale activity
-
- {% endif %}
- {% if githubActivity and githubActivity.source != "error" %}
-
-
- GitHub activity
-
- {% endif %}
- {% if lastfmActivity and lastfmActivity.source == "indiekit" %}
-
-
- Last.fm scrobbles
-
- {% endif %}
- {% if newsActivity and newsActivity.source == "indiekit" %}
-
-
- RSS feed aggregator
-
- {% endif %}
- {% if podrollStatus and podrollStatus.source == "indiekit" %}
-
-
- Podcasts I listen to
-
- {% endif %}
- {% if youtubeChannel and youtubeChannel.source == "indiekit" %}
-
-
- YouTube channel
-
- {% endif %}
-
-
- Location check-ins from OwnYourSwarm
-
-
-
- {% endif %}
-
- {# Inspiration section #}
-
-
Want more slash pages?
-
- Check out slashpages.net
- for inspiration on pages like /now, /uses, /colophon, /blogroll, and more.
-
-
-
diff --git a/theme/starred.njk b/theme/starred.njk
deleted file mode 100644
index ca2262b..0000000
--- a/theme/starred.njk
+++ /dev/null
@@ -1,446 +0,0 @@
----
-layout: layouts/base.njk
-title: Starred Repositories
-permalink: /github/starred/
-eleventyExcludeFromCollections: true
----
-
-
-
-
- {# Loading state #}
-
-
-
-
Loading starred repositories…
-
-
-
- {# Error state #}
-
-
-
-
- {# Main content — shown after loading #}
-
-
-
- {# ===== TAB BAR ===== #}
-
-
- {# ===== CONTROLS BAR ===== #}
-
- {# Search + Sort row #}
-
- {# Search #}
-
-
- {# Sort dropdown #}
-
- Sort: Stars
- Sort: Recently Starred
- Sort: Recently Updated
- Sort: Name
-
-
-
- {# Filters row #}
-
- {# Language filter #}
-
- All Languages
-
-
-
-
-
- {# Star count filter #}
-
-
-
-
-
-
- {# Archived toggle #}
-
-
- Show archived
-
-
- {# Active filter summary #}
-
- Clear filters
-
-
-
-
- {# ===== RESULTS SUMMARY ===== #}
-
-
-
-
- {# ===== REPO GRID ===== #}
-
-
-
-
-
-
-
-
-
-
-
- Archived
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {# ===== EMPTY FILTERED STATE ===== #}
-
-
-
No repos match your current filters.
-
Clear all filters
-
-
-
- {# ===== LOAD MORE ===== #}
-
-
-
- Load More
-
-
-
-
-
-
-
-
-
-{# Alpine.js component #}
-
diff --git a/theme/tailwind.config.js b/theme/tailwind.config.js
deleted file mode 100644
index 8b5b1b0..0000000
--- a/theme/tailwind.config.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import typography from "@tailwindcss/typography";
-
-/** @type {import('tailwindcss').Config} */
-export default {
- content: [
- "./*.njk",
- "./content/**/*.md",
- "./docs/**/*.md",
- "./.interface-design/**/*.md",
- "./_includes/**/*.njk",
- "./_includes/**/*.md",
- "./js/**/*.js",
- "./lib/**/*.js",
- ],
- darkMode: "class",
- theme: {
- extend: {
- colors: {
- // Warm stone — surfaces, text, structure
- surface: {
- 50: "#faf8f5",
- 100: "#f4f2ee",
- 200: "#e8e5df",
- 300: "#d5d0c8",
- 400: "#a09a90",
- 500: "#7a746a",
- 600: "#5c5750",
- 700: "#3f3b35",
- 800: "#2a2722",
- 900: "#1c1b19",
- 950: "#0f0e0d",
- },
- // Warm amber — default interactive, CTAs, focus rings
- accent: {
- 50: "#fffbeb",
- 100: "#fef3c7",
- 200: "#fde68a",
- 300: "#fcd34d",
- 400: "#fbbf24",
- 500: "#f59e0b",
- 600: "#d97706",
- 700: "#b45309",
- 800: "#92400e",
- 900: "#78350f",
- 950: "#451a03",
- },
- // Legacy — kept for compatibility, not used in templates
- primary: {
- 50: "#eff6ff",
- 100: "#dbeafe",
- 200: "#bfdbfe",
- 300: "#93c5fd",
- 400: "#60a5fa",
- 500: "#3b82f6",
- 600: "#2563eb",
- 700: "#1d4ed8",
- 800: "#1e40af",
- 900: "#1e3a8a",
- 950: "#172554",
- },
- },
- fontFamily: {
- sans: [
- '"Inter"',
- "system-ui",
- "-apple-system",
- "BlinkMacSystemFont",
- "Segoe UI",
- "Roboto",
- "sans-serif",
- ],
- mono: [
- "ui-monospace",
- "SF Mono",
- "Monaco",
- "Cascadia Code",
- "monospace",
- ],
- },
- maxWidth: {
- content: "720px",
- wide: "1200px",
- },
- typography: (theme) => ({
- DEFAULT: {
- css: {
- "--tw-prose-links": theme("colors.accent.600"),
- maxWidth: "none",
- },
- },
- invert: {
- css: {
- "--tw-prose-links": theme("colors.accent.400"),
- },
- },
- }),
- },
- },
- plugins: [typography],
-};
diff --git a/theme/webmention-debug.njk b/theme/webmention-debug.njk
deleted file mode 100644
index 172a933..0000000
--- a/theme/webmention-debug.njk
+++ /dev/null
@@ -1,124 +0,0 @@
----
-layout: layouts/base.njk
-title: Webmention Debug
-permalink: /debug/webmentions/
-eleventyExcludeFromCollections: true
-pagefindIgnore: true
----
-
-
-
- {# Summary #}
-
- Summary
-
-
-
Total URL Mappings
- {{ urlAliases.aliases | length }}
-
-
-
Total Webmentions
- {{ webmentions | length }}
-
-
-
-
- {# Recent Posts with Webmentions #}
-
- Posts with Webmentions
-
-
-
-
- Current URL
- Legacy URLs
- Webmentions
-
-
-
- {% for post in collections.posts | head(50) %}
- {% set allMentions = webmentions | webmentionsForUrl(post.url, urlAliases, conversationMentions) %}
- {% set legacyUrls = urlAliases.getOldUrls(post.url) %}
- {% if allMentions.length > 0 or legacyUrls.length > 0 %}
-
-
-
- {{ post.url }}
-
-
-
- {% if legacyUrls.length %}
- {% for legacyUrl in legacyUrls %}
- {{ legacyUrl }}
- {% endfor %}
- {% else %}
- -
- {% endif %}
-
-
- {% if allMentions.length %}
-
- {{ allMentions.length }}
-
- {% else %}
- 0
- {% endif %}
-
-
- {% endif %}
- {% endfor %}
-
-
-
-
-
- {# URL Alias Sample #}
-
- URL Alias Sample (first 20)
-
-
-
-
- New URL
- Old URL(s)
-
-
-
- {% set aliasEntries = urlAliases.aliases | dictsort %}
- {% for newUrl, oldUrls in aliasEntries | head(20) %}
-
- {{ newUrl }}
-
- {% for oldUrl in oldUrls %}
- {{ oldUrl }}
- {% endfor %}
-
-
- {% endfor %}
-
-
-
-
-
- {# Raw Webmention Targets (for debugging) #}
-
- Recent Webmention Targets
-
- Shows which URLs webmentions were sent to (useful for verifying legacy URL matches).
-
-
- {% for wm in webmentions | head(30) %}
-
- {{ wm["wm-property"] }}:
- {{ wm["wm-target"] }}
-
- {% endfor %}
-
-
-
diff --git a/theme/youtube.njk b/theme/youtube.njk
deleted file mode 100644
index 28cfb2c..0000000
--- a/theme/youtube.njk
+++ /dev/null
@@ -1,262 +0,0 @@
----
-layout: layouts/base.njk
-title: YouTube Channels
-permalink: /youtube/
-withSidebar: true
----
-
-
-
- {# Multi-channel tabs #}
- {% if youtubeChannel.isMultiChannel and youtubeChannel.channels.length > 1 %}
-
-
- {% for channel in youtubeChannel.channels %}
-
- {{ channel.configName or channel.title }}
-
- {% endfor %}
-
-
- {% endif %}
-
- {# Channel sections #}
- {% for channel in youtubeChannel.channels %}
-
- {# Channel Header #}
-
-
- {% if channel.thumbnail %}
-
- {% else %}
-
- {% endif %}
-
-
-
- {% if channel.customUrl %}
-
{{ channel.customUrl }}
- {% endif %}
-
-
-
-
-
- {{ channel.subscriberCountFormatted }} subscribers
-
-
-
-
-
- {{ channel.videoCountFormatted }} videos
-
-
-
-
-
-
- {{ channel.viewCountFormatted }} views
-
-
-
-
- {# Live Status Badge for this channel #}
- {% set channelLiveStatus = youtubeChannel.liveStatuses | selectattr("channelConfigName", "equalto", channel.configName) | first %}
-
- {% if channelLiveStatus and channelLiveStatus.isLive %}
-
-
- LIVE
-
- {% elif channelLiveStatus and channelLiveStatus.isUpcoming %}
-
-
-
-
- Upcoming
-
- {% else %}
-
- Offline
-
- {% endif %}
-
-
-
-
- {# Live Stream Section for this channel #}
- {% set channelLiveStatus = youtubeChannel.liveStatuses | selectattr("channelConfigName", "equalto", channel.configName) | first %}
- {% if channelLiveStatus and channelLiveStatus.stream and (channelLiveStatus.isLive or channelLiveStatus.isUpcoming) %}
-
- {% endif %}
-
- {# Videos Grid for this channel #}
-
-
-
-
-
- Latest Videos
-
-
- {% set channelName = channel.configName or channel.title %}
- {% set channelVideos = youtubeChannel.videosByChannel[channelName] %}
- {% if channelVideos and channelVideos.length %}
-
-
-
- {% else %}
- No videos available yet.
- {% endif %}
-
-
- {% endfor %}
-
- {# Fallback for no channels #}
- {% if not youtubeChannel.channels.length %}
-
No YouTube channels configured.
- {% endif %}
-
-
- -- Comments - -
- -Sign in with your website to comment:
- -Loading comments...
- - - -No comments yet. Be the first to share your thoughts!
- -